如何在 Ubuntu 20.04 上保护 MongoDB

本教程的早期版本由Melissa Anderson编写

介绍

MongoDB,也称为Mongo,是许多现代 Web 应用程序中使用的开源文档数据库。它被归类为NoSQL 数据库,因为它不依赖于传统的基于表的关系数据库结构。相反,它使用具有动态模式的类 JSON 文档。

MongoDB 默认不启用身份验证,这意味着任何有权访问安装数据库的服务器的用户都可以不受限制地添加和删除数据。为了保护此漏洞,本教程将引导您创建管理用户并启用身份验证。然后,您将进行测试以确认只有该管理用户有权访问数据库。

先决条件

要完成本教程,您将需要以下内容:

第 1 步 – 添加管理用户

3.0版本发布以来,MongoDB 守护进程被配置为仅接受来自本地 Unix 套接字的连接,并且不会自动向更广泛的 Internet 开放。但是,默认情况下仍禁用身份验证。这意味着可以访问安装了 MongoDB 的服务器的任何用户也可以完全访问数据库。

作为保护此漏洞的第一步,您将创建一个管理用户。稍后,您将启用身份验证并以此管理用户身份连接以访问数据库。

要添加管理用户,您必须首先连接到 Mongo shell。因为身份验证被禁用,您可以使用该mongo命令执行此操作,无需任何其他选项:

  • mongo

Mongo shell 提示上方会有一些输出。因为您还没有启用身份验证,这将包括一个警告,指出未为数据库启用访问控制,并且对数据和数据库的配置的读写访问不受限制:

Output
MongoDB shell version v4.4.0 . . . 2020-06-09T13:26:51.391+0000 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database. 2020-06-09T13:26:51.391+0000 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted. . . . >

在您启用身份验证后,这些警告将消失,但就目前而言,它们意味着任何可以访问您的 Ubuntu 服务器的人也可以控制您的数据库。

为了说明,运行 Mongo 的show dbs命令:

  • show dbs

此命令返回服务器上每个数据库的列表。但是,启用身份验证后,列表会根据 Mongo 用户的角色或它对某些数据库的访问级别而更改。但是,由于身份验证被禁用,它将无限制地返回系统上当前的每个数据库:

Output
admin 0.000GB config 0.000GB local 0.000GB

在此示例输出中,仅显示默认数据库。但是,如果您的系统上有任何保存敏感数据的数据库,任何用户都可以使用此命令找到它们。

作为缓解此漏洞的一部分,此步骤的重点是添加管理用户。为此,您必须首先连接到admin数据库。这是有关用户的信息(如用户名、密码和角色)的存储位置:

  • use admin
Output
switched to db admin

MongoDB 随附了许多可用于管理数据库的基于 JavaScript 的 shell 方法其中之一是db.createUser方法,用于在运行该方法的数据库上创建新用户。

启动db.createUser方法:

  • db.createUser(

此方法要求您为用户指定用户名和密码,以及您希望用户拥有的任何角色。回想一下,MongoDB 将其数据存储在类似 JSON 的文档中。因此,当您创建新用户时,您所做的只是创建一个文档,将适当的用户数据保存为单独的字段。

与 JSON 中的对象一样,MongoDB 中的文档以花括号 ( {and })开头和结尾要开始添加用户,请输入左花括号:

注意db.createUser在您输入右括号之前,Mongo 不会将该方法注册为完整的。在您这样做之前,提示将从大于号 ( >) 变为省略号 ( ...)。

  • {

接下来,输入一个user:字段,将您想要的用户名作为双引号中的值,后跟一个逗号。以下示例指定用户名AdminSammy,但您可以输入任何您喜欢的用户名:

  • user: "AdminSammy",

接下来,输入一个pwdpasswordPrompt()方法作为其值字段当您执行该db.createUser方法时,该passwordPrompt()方法将提示您输入密码。这比替代方法更安全,替代方法是像输入用户名一样以明文形式输入密码。

注意:该passwordPrompt()方法仅与 MongoDB 4.2及更新版本兼容如果您使用的是旧版本的 Mongo,那么您必须以明文形式写出密码,类似于您写出用户名的方式:

  • pwd: "password",

请务必在此字段后面加上逗号:

  • pwd: passwordPrompt(),

然后输入您希望管理用户具有的角色。因为您正在创建一个管理用户,所以您至少应该授予他们userAdminAnyDatabaseadmin数据库角色这将允许管理用户创建和修改新用户和角色。因为管理用户在admin数据库中有这个角色,这也将授予它对整个集群的超级用户访问权限

此外,以下示例还授予管理用户readWriteAnyDatabase角色。这使管理用户能够读取和修改集群中任何数据库上的数据,除了主要供内部使用configlocal数据库:

  • roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]

然后,输入一个右大括号来表示文档的结尾:

  • }

然后输入一个右括号来关闭并执行该db.createUser方法:

  • )

总之,您的db.createUser方法应该如下所示:

> db.createUser(
... {
... user: "AdminSammy",
... pwd: passwordPrompt(),
... roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]
... }
... )

如果每一行的语法正确,该方法将正确执行,并提示您输入密码:

Output
Enter password:

输入您选择的强密码。然后,您将收到添加用户的确认信息:

Output
Successfully added user: { "user" : "AdminSammy", "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" }, "readWriteAnyDatabase" ] }

之后,您可以退出 MongoDB 客户端:

  • exit

此时,您的用户将被允许输入凭据。但是,在您启用身份验证并重新启动 MongoDB 守护程序之前,他们不需要这样做。

第 2 步 – 启用身份验证

要启用身份验证,您必须编辑mongod.confMongoDB 的配置文件。启用它并重新启动 Mongo 服务后,用户仍然可以在不进行身份验证的情况下连接到数据库。但是,在他们提供正确的用户名和密码之前,他们将无法读取或修改任何数据。

使用您喜欢的文本编辑器打开配置文件。在这里,我们将使用nano

  • sudo nano /etc/mongod.conf

向下滚动以找到注释掉的security部分:

/etc/mongod.conf
. . .
#security:

#operationProfiling:

. . .

通过删除井号 ( #)取消注释此行

/etc/mongod.conf
. . .
security:

#operationProfiling:

. . .

然后添加authorization参数并将其设置为enabled. 完成后,这些行应如下所示:

/etc/mongod.conf
. . .
security:
  authorization: enabled
. . . 

请注意,该security:行开头没有空格,而该authorization:行缩进了两个空格。

添加这些行后,保存并关闭文件。如果您曾经nano打开过该文件,请按CTRL + XY来打开ENTER

然后重新启动守护程序以使这些新更改生效:

  • sudo systemctl restart mongod

接下来,检查服务的状态以确保它正确重启:

  • sudo systemctl status mongod

如果restart命令成功,您将收到指示该mongod服务处于活动状态且最近已启动的输出:

Output
● mongod.service - MongoDB Database Server Loaded: loaded (/lib/systemd/system/mongod.service; enabled; vendor preset: enabled) Active: active (running) since Tue 2020-06-09 22:06:20 UTC; 7s ago Docs: https://docs.mongodb.org/manual Main PID: 15370 (mongod) Memory: 170.1M CGroup: /system.slice/mongod.service └─15370 /usr/bin/mongod --config /etc/mongod.conf Jun 09 22:06:20 your_host systemd[1]: Started MongoDB Database Server.

验证守护程序已备份并运行后,您可以测试您添加的身份验证设置是否按预期工作。

第 3 步 – 测试身份验证设置

要开始测试您在上一步中添加的身份验证要求是否正常工作,请先在不指定任何凭据的情况下进行连接,以验证您的操作确实受到限制:

  • mongo

现在您已启用身份验证,您之前遇到的任何警告都不会出现:

Output
MongoDB shell version v4.4.0 connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb Implicit session: session { "id" : UUID("5d50ed96-f7e1-493a-b4da-076067b2d898") } MongoDB server version: 4.4.0 >

通过show dbs再次运行命令确认您的访问是否受到限制

  • show dbs

回忆第 1 步,您的服务器上至少有几个默认数据库。但是,在这种情况下,该命令不会有任何输出,因为您尚未作为特权用户进行身份验证。

由于此命令不返回任何信息,因此可以肯定地说身份验证设置按预期工作。如果没有首先进行身份验证,您也将无法创建用户或执行其他特权任务。

继续并退出 MongoDB shell:

注意:不是exit像您之前在第 1 步中那样运行以下命令,另一种关闭 shell 的方法是按CTRL + C

  • exit

接下来,通过运行以下mongo命令以该用户身份进行连接,确保您的管理用户能够正确进行身份验证此命令包含-u标志,该标志位于您要连接的用户名之前。请务必将AdminSammy替换为您自己的管理用户的用户名。它还包括-p标志,它会提示您输入用户的密码,并指定admin为创建指定用户名的身份验证数据库:

  • mongo -u AdminSammy -p --authenticationDatabase admin

出现提示时输入用户的密码,然后您将进入 shell。到达那里后,show dbs再次尝试发出命令:

  • show dbs

这一次,因为您已正确进行身份验证,该命令将成功返回服务器上当前所有数据库的列表:

Output
admin 0.000GB config 0.000GB local 0.000GB

这确认身份验证已成功启用。

结论

通过完成本指南,您已经设置了一个管理 MongoDB 用户,您可以使用该用户来创建和修改新用户和角色,以及管理您的 MongoDB 实例。您还配置了 MongoDB 实例,要求用户在与任何数据交互之前使用有效的用户名和密码进行身份验证。

有关如何管理 MongoDB 用户的更多信息,请查看关于该主题的官方文档您可能也有兴趣了解有关身份验证如何在 MongoDB 上工作的更多信息

此外,如果您计划远程与您的 MongoDB 实例交互,您可以按照我们关于如何在 Ubuntu 20.04 上为 MongoDB 配置远程访问的指南进行操作

觉得文章有用?

点个广告表达一下你的爱意吧 !😁