本教程的早期版本由 Melissa Anderson 编写。
介绍
MongoDB,也称为 Mongo,是一个开源文档数据库,用于许多现代 Web 应用程序。 它被归类为 NoSQL 数据库,因为它不依赖于传统的基于表的关系数据库结构。 相反,它使用具有动态模式的类似 JSON 的文档。
MongoDB 默认不启用身份验证,这意味着任何有权访问安装数据库的服务器的用户都可以不受限制地添加和删除数据。 为了保护此漏洞,本教程将引导您创建管理用户并启用身份验证。 然后,您将进行测试以确认只有此管理用户有权访问数据库。
先决条件
要完成本教程,您将需要以下内容:
- 要完成本教程,您需要一台运行 CentOS 8 的服务器。 此服务器应具有具有管理权限的非 root 用户和配置为
firewalld
的防火墙。 要进行此设置,请按照我们的 CentOS 8 初始服务器设置指南进行操作。 - MongoDB 安装在您的服务器上。 本教程使用 MongoDB 版本 4.4 进行了验证,尽管它通常也适用于旧版本的 MongoDB。 要在您的服务器上安装 Mongo,请按照我们关于 如何在 CentOS 8 上安装 MongoDB 的教程进行操作。
第 1 步 — 添加管理用户
自 3.0 版本发布以来,MongoDB 守护进程被配置为仅接受来自本地 Unix 套接字的连接,并且不会自动向更广泛的 Internet 开放。 但是,默认情况下仍禁用身份验证。 这意味着任何可以访问安装了 MongoDB 的服务器的用户也可以完全访问数据库。
作为保护此漏洞的第一步,您将创建一个管理用户。 稍后,您将启用身份验证并以该管理用户身份连接以访问数据库。
要添加管理用户,您必须首先连接到 Mongo shell。 由于禁用了身份验证,因此您可以使用 mongo
命令执行此操作,无需任何其他选项:
mongo
Mongo shell 提示符上方会有一些输出。 因为您尚未启用身份验证,这将包括一个警告,即未为数据库启用访问控制,并且对数据的读写访问权限以及数据库的配置不受限制:
OutputMongoDB shell version v4.4.1 . . . --- The server generated these startup warnings when booting: 2020-10-02T14:38:03.448+00:00: ***** SERVER RESTARTED ***** 2020-10-02T14:38:04.209+00:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted --- . . . >
第二个警告会在您启用身份验证后消失,但现在这意味着任何可以访问您的 CentOS 服务器的人也可以控制您的数据库。
注意:如果您按照先决条件中链接的教程以外的教程安装了 MongoDB,则提示中可能会出现另一个警告:
Output. . . 2020-10-02T14:38:04.633+00:00: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. We suggest setting it to 'never' . . .
此警告涉及透明巨页 (THP),这是默认情况下在 CentOS 8 上启用的 Linux 内存管理系统。 THP 使用超大内存页面来减少翻译后备缓冲区查找对具有大量内存的计算机的影响。 但是,正如此警告所示,此系统可能会对数据库性能产生负面影响,MongoDB 文档建议您禁用它。
如果您想了解有关如何禁用透明大页面的详细信息,请参阅我们关于 如何在 CentOS 8 上安装 MongoDB 的指南的第 2 步。
为了说明,运行 Mongo 的 show dbs
命令:
show dbs
此命令返回服务器上每个数据库的列表。 但是,启用身份验证后,列表会根据 Mongo 用户的 角色 或它对某些数据库的访问级别而更改。 但是,由于禁用了身份验证,它将返回当前系统上的每个数据库,而不受限制:
Outputadmin 0.000GB config 0.000GB local 0.000GB
在此示例输出中,仅显示默认数据库。 但是,如果您的系统上有任何数据库保存敏感数据,则任何用户都可以使用此命令找到它们。
作为缓解此漏洞的一部分,此步骤的重点是添加管理用户。 为此,您必须首先连接到 admin
数据库。 这是存储有关用户的信息(例如用户名、密码和角色)的位置:
use admin
Outputswitched to db admin
MongoDB 安装了 一些基于 JavaScript 的 shell 方法 ,您可以使用它们来管理数据库。 其中之一,db.createUser
方法,用于在运行该方法的数据库上创建新用户。
启动 db.createUser
方法:
db.createUser(
此方法要求您指定用户的用户名和密码,以及您希望用户拥有的任何角色。 回想一下,MongoDB 将其数据存储在类似 JSON 的文档中。 当您创建一个新用户时,您所做的就是创建一个文档来保存适当的用户数据作为单独的字段。
与 JSON 中的对象一样,MongoDB 中的文档以大括号({
和 }
)开始和结束。 要开始添加用户,请输入左大括号:
注意:在输入右括号之前,Mongo 不会将 db.createUser
方法注册为完整的。 在您这样做之前,提示将从大于号 (>
) 变为省略号 (...
)。
{
接下来,输入 user:
字段,将所需的用户名作为双引号中的值,后跟逗号。 以下示例指定用户名 AdminSammy,但您可以输入任何您喜欢的用户名:
user: "AdminSammy",
接下来,输入一个 pwd
字段,其值为 passwordPrompt()
方法。 当您执行 db.createUser
方法时,passwordPrompt()
方法将提示您输入密码。 这比替代方法更安全,即像输入用户名一样以明文形式输入密码。
注意:passwordPrompt()
方法只兼容MongoDB版本4.2及更新的版本。 如果您使用的是旧版本的 Mongo,则必须以明文形式写出密码,类似于写出用户名的方式:
pwd: "password",
请务必在此字段后面加上逗号:
pwd: passwordPrompt(),
然后输入您希望管理用户拥有的角色。 因为您正在创建管理用户,所以您至少应该授予他们 admin
数据库上的 userAdminAnyDatabase
角色。 这将允许管理用户创建和修改新用户和角色。 因为管理用户在 admin
数据库中具有此角色,这也将授予它 对整个集群 的超级用户访问权限。
此外,以下示例还授予管理用户 readWriteAnyDatabase
角色。 这使管理用户能够读取和修改集群中任何数据库上的数据,除了 config
和 local
数据库,它们主要供内部使用:
roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]
之后,输入一个右大括号来表示文档的结束:
}
然后输入右括号关闭并执行db.createUser
方法:
)
总之,你的 db.createUser
方法应该是这样的:
> db.createUser( ... { ... user: "AdminSammy", ... pwd: passwordPrompt(), ... roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ] ... } ... )
如果每一行的语法正确,该方法将正确执行,并提示您输入密码:
OutputEnter password:
输入您选择的强密码。 然后,您将收到用户已添加的确认信息:
OutputSuccessfully added user: { "user" : "AdminSammy", "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" }, "readWriteAnyDatabase" ] }
之后,您可以退出 MongoDB 客户端:
exit
此时,您的用户将被允许输入凭据。 但是,在您启用身份验证并重新启动 MongoDB 守护程序之前,不需要他们这样做。
第 2 步 — 启用身份验证
要启用身份验证,您必须编辑 MongoDB 的配置文件 mongod.conf
。 启用它并重新启动 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 + X
、Y
,然后按 ENTER
。
然后重新启动守护程序以使这些新更改生效:
sudo systemctl restart mongod
接下来,检查服务的状态以确保它正确重新启动:
sudo systemctl status mongod
如果 restart
命令成功,您将收到指示 mongod
服务处于活动状态并且最近启动的输出:
Output● mongod.service - MongoDB Database Server Loaded: loaded (/usr/lib/systemd/system/mongod.service; enabled; vendor preset: disabled) Active: active (running) since Fri 2020-10-02 14:57:31 UTC; 7s ago Docs: https://docs.mongodb.org/manual Process: 15667 ExecStart=/usr/bin/mongod $OPTIONS (code=exited, status=0/SUCCESS) Process: 15665 ExecStartPre=/usr/bin/chmod 0755 /var/run/mongodb (code=exited, status=0/SUCCESS) Process: 15662 ExecStartPre=/usr/bin/chown mongod:mongod /var/run/mongodb (code=exited, status=0/SUCCESS) Process: 15659 ExecStartPre=/usr/bin/mkdir -p /var/run/mongodb (code=exited, status=0/SUCCESS) Main PID: 15669 (mongod) Memory: 159.2M CGroup: /system.slice/mongod.service └─15669 /usr/bin/mongod -f /etc/mongod.conf
验证守护程序已备份并运行后,您可以测试您添加的身份验证设置是否按预期工作。
第 3 步 — 测试身份验证设置
要开始测试您在上一步中添加的身份验证要求是否正常工作,请先连接而不指定任何凭据,以验证您的操作确实受到限制:
mongo
现在您已经启用了身份验证,您之前遇到的任何警告都不会出现:
OutputMongoDB shell version v4.4.1 connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb Implicit session: session { "id" : UUID("d57987e5-24dc-427e-89b7-9ab362ebac6b") } MongoDB server version: 4.4.1 >
通过再次运行 show dbs
命令确认您的访问是否受到限制:
show dbs
回想第 1 步,您的服务器上至少有几个默认数据库。 但是,在这种情况下,该命令不会有任何输出,因为您尚未作为特权用户进行身份验证。
由于此命令不返回任何信息,因此可以肯定地说身份验证设置按预期工作。 如果没有先进行身份验证,您也将无法创建用户或执行其他特权任务。
继续并退出 MongoDB shell:
注意:不要像之前在步骤 1 中那样运行以下 exit
命令,关闭 shell 的另一种方法是只需按 CTRL + C
。
exit
接下来,通过运行以下 mongo
命令以该用户身份连接,确保您的管理用户能够正确进行身份验证。 此命令包含 -u
标志,它位于您要连接的用户名之前。 请务必将 AdminSammy 替换为您自己的管理用户的用户名。 它还包括 -p
标志,它将提示您输入用户密码,并指定 admin
作为创建指定用户名的身份验证数据库:
mongo -u AdminSammy -p --authenticationDatabase admin
出现提示时输入用户密码,然后您将进入 shell。 在那里,尝试再次发出 show dbs
命令:
show dbs
这一次,由于您已正确验证,该命令将成功返回服务器上当前所有数据库的列表:
Outputadmin 0.000GB config 0.000GB local 0.000GB
这确认身份验证已成功启用。
结论
通过完成本指南,您已经设置了一个管理 MongoDB 用户,您可以使用它来创建和修改新用户和角色,并以其他方式管理您的 MongoDB 实例。 您还将 MongoDB 实例配置为要求用户使用有效的用户名和密码进行身份验证,然后才能与任何数据进行交互。
有关如何管理 MongoDB 用户的更多信息,请查看有关该主题的官方文档。 您可能也有兴趣了解有关 身份验证如何在 MongoDB 上工作的更多信息。
此外,如果您计划与您的 MongoDB 实例进行远程交互,您可以按照我们关于 How To Configure Remote Access for MongoDB on CentOS 8 的指南进行操作。