An earlier version of this tutorial was written by Melissa Anderson.
本教程的早期版本由Melissa Anderson编写。
介绍 (Introduction)
MongoDB, also known as Mongo, is an open-source document database used in many modern web applications. It is classified as a NoSQL database because it does not rely on a traditional table-based relational database structure. Instead, it uses JSON-like documents with dynamic schemas.
MongoDB ,也称为Mongo ,是许多现代Web应用程序中使用的开源文档数据库。 它被归类为NoSQL数据库,因为它不依赖于传统的基于表的关系数据库结构。 相反,它使用具有动态模式的类JSON文档。
MongoDB doesn’t have authentication enabled by default, meaning that any user with access to the server where the database is installed can add and delete data without restriction. In order to secure this vulnerability, this tutorial will walk you through creating an administrative user and enabling authentication. You’ll then test to confirm that only this administrative user has access to the database.
MongoDB默认情况下未启用身份验证,这意味着有权访问安装数据库的服务器的任何用户都可以无限制地添加和删除数据。 为了保护此漏洞,本教程将引导您逐步创建管理用户并启用身份验证。 然后,您将进行测试以确认只有该管理用户可以访问数据库。
先决条件 (Prerequisites)
To complete this tutorial, you will need the following:
要完成本教程,您将需要以下内容:
A server running Ubuntu 20.04. This server should have a non-root administrative user and a firewall configured with UFW. Set this up by following our initial server setup guide for Ubuntu 20.04.
运行Ubuntu 20.04的服务器。 此服务器应具有非root用户管理权限,并应使用UFW配置防火墙。 请遵循我们针对Ubuntu 20.04的初始服务器设置指南进行设置 。
MongoDB installed on your server. This tutorial was validated using MongoDB version 4.4, though it should generally work for older versions of MongoDB as well. To install Mongo on your server, follow our tutorial on How To Install MongoDB on Ubuntu 20.04.
服务器上安装了MongoDB。 本教程已使用MongoDB 4.4版进行了验证,尽管它通常也适用于MongoDB的旧版本。 要在您的服务器上安装Mongo,请遵循有关如何在Ubuntu 20.04上安装MongoDB的教程。
第1步-添加管理用户 (Step 1 — Adding an Administrative User)
Since the release of version 3.0, the MongoDB daemon is configured to only accept connections from the local Unix socket, and it is not automatically open to the wider Internet. However, authentication is still disabled by default. This means that any users that have access to the server where MongoDB is installed also have complete access to the databases.
自版本3.0发行以来,MongoDB守护程序已配置为仅接受来自本地Unix套接字的连接,并且不会自动向更广泛的Internet开放。 但是,默认情况下仍禁用身份验证。 这意味着,有权访问安装了MongoDB的服务器的所有用户也都具有对数据库的完全访问权。
As a first step to securing this vulnerability, you will create an administrative user. Later, you’ll enable authentication and connect as this administrative user to access the database.
作为保护此漏洞的第一步,您将创建一个管理用户。 稍后,您将启用身份验证并以该管理用户身份连接以访问数据库。
To add an administrative user, you must first connect to the Mongo shell. Because authentication is disabled you can do so with the mongo
command, without any other options:
要添加管理用户,必须首先连接到Mongo Shell。 因为禁用了身份验证,所以可以使用mongo
命令来执行此操作,而无需任何其他选项:
- mongo 蒙哥
There will be some output above the Mongo shell prompt. Because you haven’t yet enabled authentication, this will include a warning that access control isn’t enabled for the database and that read and write access to data and and the database’s configuration are unrestricted:
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.
. . .
>
These warnings will disappear after you enable authentication, but for now they mean anyone who can access your Ubuntu server could also take control over your database.
启用身份验证后,这些警告将消失,但现在它们意味着可以访问Ubuntu服务器的任何人都可以控制您的数据库。
To illustrate, run Mongo’s show dbs
command:
为了说明,请运行Mongo的show dbs
命令:
- show dbs 显示数据库
This command returns a list of every database on the server. However, when authentication is enabled, the list changes based on the Mongo user’s role, or what level of access it has to certain databases. Because authentication is disabled, though, it will return every database currently on the system without restrictions:
此命令返回服务器上每个数据库的列表。 但是,启用身份验证后,列表会根据Mongo用户的角色或对某些数据库的访问级别而变化。 但是,由于禁用了身份验证,它将无限制地返回系统上当前的每个数据库:
Output
admin 0.000GB
config 0.000GB
local 0.000GB
In this example output, only the default databases appear. However, if you have any databases holding sensitive data on your system, any user could find them with this command.
在此示例输出中,仅显示默认数据库。 但是,如果您有任何数据库在系统上保存敏感数据,则任何用户都可以使用此命令找到它们。
As part of mitigating this vulnerability, this step is focused on adding an administrative user. To do this, you must first connect to the admin
database. This is where information about users, like their usernames, passwords, and roles, are stored:
作为缓解此漏洞的一部分,此步骤着重于添加管理用户。 为此,您必须首先连接到admin
数据库。 在此存储有关用户的信息,例如用户名,密码和角色:
- use admin 使用管理员
Output
switched to db admin
MongoDB comes installed with a number of JavaScript-based shell methods you can use to manage your database. One of these, the db.createUser
method, is used to create new users on the database on which the method is run.
MongoDB随附了许多基于JavaScript的Shell方法 ,可用于管理数据库。 db.createUser
方法是db.createUser
一种,用于在运行该方法的数据库上创建新用户。
Initiate the db.createUser
method:
初始化db.createUser
方法:
- db.createUser( db.createUser(
This method requires you to specify a username and password for the user, as well as any roles you want the user to have. Recall that MongoDB stores its data in JSON-like documents. As such, when you create a new user, all you’re doing is creating a document to hold the appropriate user data as individual fields.
此方法要求您为用户指定用户名和密码,以及您希望用户具有的任何角色。 回想一下,MongoDB将其数据存储在类似JSON的文档中。 这样,当您创建一个新用户时,您要做的就是创建一个文档来将适当的用户数据保存为单独的字段。
As with objects in JSON, documents in MongoDB begin and end with curly braces ({
and }
). To begin adding a user, enter an opening curly brace:
与JSON中的对象一样,MongoDB中的文档以大括号( {
和}
)开头和结尾。 要开始添加用户,请输入一个大括号:
Note: Mongo won’t register the db.createUser
method as complete until you enter a closing parenthesis. Until you do, the prompt will change from a greater than sign (>
) to an ellipsis (...
).
注意 :在您输入db.createUser
括号之前,Mongo不会将db.createUser
方法注册为完整方法。 在执行此操作之前,提示将从大号( >
)变为省略号( ...
)。
- { {
Next, enter a user:
field, with your desired username as the value in double quotes followed by a comma. The following example specifies the username AdminSammy, but you can enter whatever username you like:
接下来,输入一个user:
字段,将所需的用户名作为双引号后跟一个逗号的值。 以下示例指定用户名AdminSammy ,但是您可以输入所需的任何用户名:
user: "AdminSammy",
用户:“ AdminSammy ”,
Next, enter a pwd
field with the passwordPrompt()
method as its value. When you execute the db.createUser
method, the passwordPrompt()
method will provide a prompt for you to enter your password. This is more secure than the alternative, which is to type out your password in cleartext as you did for your username.
接下来,输入一个带有passwordPrompt()
方法作为其值的pwd
字段。 当执行db.createUser
方法时, passwordPrompt()
方法将提示您输入密码。 这比另一种方法安全得多,后者与使用用户名一样,以明文形式输入密码。
Note: The passwordPrompt()
method is only compatible with MongoDB versions 4.2 and newer. If you’re using an older version of Mongo, then you will have to write out your password in cleartext, similarly to how you wrote out your username:
注意 : passwordPrompt()
方法仅与MongoDB 4.2及更高版本兼容。 如果您使用的是Mongo的旧版本,则必须以明文形式写出密码,类似于写出用户名的方式:
pwd: "password",
pwd:“ 密码 ”,
Be sure to follow this field with a comma as well:
请务必在此字段后面加上逗号:
- pwd: passwordPrompt(), pwd:passwordPrompt(),
Then enter the roles you want your administrative user to have. Because you’re creating an administrative user, at a minimum you should grant them the userAdminAnyDatabase
role over the admin
database. This will allow the administrative user to create and modify new users and roles. Because the administrative user has this role in the admin
database, this will also grant it superuser access to the entire cluster.
然后输入您希望管理用户拥有的角色。 由于您正在创建管理用户,因此至少应授予他们对admin
数据库的userAdminAnyDatabase
角色。 这将允许管理用户创建和修改新用户和角色。 由于管理用户在admin
数据库中具有此角色,因此还将向其授予超级用户对整个集群的访问权限 。
In addition, the following example also grants the administrative user the readWriteAnyDatabase
role. This grants the administrative user the ability to read and modify data on any database in the cluster except for the config
and local
databases, which are mostly for internal use:
此外,以下示例还向管理用户授予readWriteAnyDatabase
角色。 这使管理用户可以读取和修改集群中任何数据库上的数据, config
和local
数据库除外,这些数据主要供内部使用:
- roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ] 角色:[{角色:“ userAdminAnyDatabase”,db:“ admin”},“ readWriteAnyDatabase”]
Following that, enter a closing brace to signify the end of the document:
之后,输入一个右括号来表示文档的结尾:
- } }
Then enter a closing parenthesis to close and execute the db.createUser
method:
然后输入db.createUser
括号以关闭并执行db.createUser
方法:
- ) )
All together, here’s what your db.createUser
method should look like:
总之,这是db.createUser
方法的外观:
> db.createUser(
... {
... user: "AdminSammy",
... pwd: passwordPrompt(),
... roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]
... }
... )
If each line’s syntax is correct, the method will execute properly and you’ll be prompted to enter a password:
如果每一行的语法正确,则该方法将正确执行,并提示您输入密码:
Output
Enter password:
Enter a strong password of your choosing. Then, you’ll receive a confirmation that the user was added:
输入您选择的强密码。 然后,您将收到确认已添加用户的确认:
Output
Successfully added user: {
"user" : "AdminSammy",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
},
"readWriteAnyDatabase"
]
}
Following that, you can exit the MongoDB client:
之后,您可以退出MongoDB客户端:
- exit 出口
At this point, your user will be allowed to enter credentials. However, they will not be required to do so until you enable authentication and restart the MongoDB daemon.
此时,将允许您的用户输入凭据。 但是,在启用身份验证并重新启动MongoDB守护程序之前,不需要这样做。
步骤2 —启用身份验证 (Step 2 — Enabling Authentication)
To enable authentication, you must edit mongod.conf
, MongoDB’s configuration file. Once you enable it and restart the Mongo service, users will still be able to connect to the database without authenticating. However, they won’t be able to read or modify any data until they provide a correct username and password.
要启用身份验证,必须编辑MongoDB的配置文件mongod.conf
。 一旦启用它并重新启动Mongo服务,用户仍将能够连接到数据库而无需进行身份验证。 但是,只有提供正确的用户名和密码,他们才能读取或修改任何数据。
Open the configuration file with your preferred text editor. Here, we’ll use nano
:
使用首选的文本编辑器打开配置文件。 在这里,我们将使用nano
:
- sudo nano /etc/mongod.conf 须藤nano /etc/mongod.conf
Scroll down to find the commented-out security
section:
向下滚动以找到已注释掉的security
部分:
. . .
#security:
#operationProfiling:
. . .
Uncomment this line by removing the pound sign (#
):
通过删除井号( #
)取消注释此行:
. . .
security:
#operationProfiling:
. . .
Then add the authorization
parameter and set it to "enabled"
. When you’re done, the lines should look like this:
然后添加authorization
参数并将其设置为"enabled"
。 完成后,这些行应如下所示:
. . .
security:
authorization: "enabled"
. . .
Note that the security:
line has no spaces at the beginning, while the authorization:
line is indented with two spaces.
请注意, security:
行开头没有空格,而authorization:
行缩进了两个空格。
After adding these lines, save and close the file. If you used nano
to open the file, do so by pressing CTRL + X
, Y
, then ENTER
.
添加这些行之后,保存并关闭文件。 如果您使用nano
打开文件,请按CTRL + X
, Y
,然后按ENTER
。
Then restart the daemon to put these new changes into effect:
然后重新启动守护程序以使这些新更改生效:
- sudo systemctl restart mongod sudo systemctl重新启动mongod
Next, check the service’s status to make sure that it restarted correctly:
接下来,检查服务的状态以确保其正确重新启动:
- sudo systemctl status mongod sudo systemctl status mongod
If the restart
command was successful, you’ll receive output that indicates that the mongod
service is active and was recently started:
如果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.
Having verified the daemon is back up and running, you can test that the authentication setting you added works as expected.
验证守护程序已备份并正在运行后,您可以测试添加的身份验证设置是否按预期工作。
步骤3 —测试身份验证设置 (Step 3 — Testing Authentication Settings)
To begin testing that the authentication requirements you added in the previous step are working correctly, start by connecting without specifying any credentials to verify that your actions are indeed restricted:
要开始测试您在上一步中添加的身份验证要求是否正常工作,请从连接开始而不指定任何凭据来验证您的操作确实受到限制:
- mongo 蒙哥
Now that you’ve enabled authentication, none of the warnings you encountered previously will appear:
现在,您已经启用身份验证,以前遇到的所有警告都不会出现:
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
>
Confirm whether your access is restricted by running the show dbs
command again:
再次运行show dbs
命令,确认您的访问是否受到限制:
- show dbs 显示数据库
Recall from Step 1 that there are at least a few default databases on your server. However, in this case the command won’t have any output because you haven’t authenticated as a privileged user.
回想一下第1步,您的服务器上至少有一些默认数据库。 但是,在这种情况下,该命令将没有任何输出,因为您尚未经过身份验证为特权用户。
Because this command doesn’t return any information, it’s safe to say the authentication setting is working as expected. You also won’t be able to create users or perform other privileged tasks without first authenticating.
因为此命令不返回任何信息,所以可以肯定地说身份验证设置正在按预期工作。 如果没有先进行身份验证,您将无法创建用户或执行其他特权任务。
Go ahead and exit the MongoDB shell:
继续并退出MongoDB shell:
Note: Instead of running the following exit
command as you did previously in Step 1, an alternative way to close the shell is to just press CTRL + C
.
注意 :不是像在第1步中之前那样运行以下exit
命令,而是关闭Shell的另一种方法是仅按CTRL + C
- exit 出口
Next, make sure that your administrative user is able to authenticate properly by running the following mongo
command to connect as this user. This command includes the -u
flag, which precedes the name of the user you want to connect as. Be sure to replace AdminSammy with your own administrative user’s username. It also includes the -p
flag, which will prompt you for the user’s password, and specifies admin
as the authentication database where the specified username was created:
接下来,通过运行以下mongo
命令以该用户身份进行连接,以确保您的管理用户能够正确进行身份验证。 此命令包含-u
标志,该标志位于您要连接的用户名称的前面。 确保将AdminSammy替换为您自己的管理用户的用户名。 它还包括-p
标志,它将提示您输入用户密码,并将admin
指定为创建指定用户名的身份验证数据库:
mongo -u AdminSammy -p --authenticationDatabase admin
mongo -u AdminSammy -p --authentication数据库管理员
Enter the user’s password when prompted, and then you’ll be dropped into the shell. Once there, try issuing the show dbs
command again:
在提示时输入用户密码,然后您将进入外壳。 到达那里后,尝试再次发出show dbs
命令:
- show dbs 显示数据库
This time, because you’ve authenticated properly, the command will successfully return a list of all the databases currently on the server:
这次,由于您已正确进行身份验证,因此该命令将成功返回服务器上当前所有数据库的列表:
Output
admin 0.000GB
config 0.000GB
local 0.000GB
This confirms that authentication was enabled successfully.
这确认身份验证已成功启用。
结论 (Conclusion)
By completing this guide, you’ve set up an administrative MongoDB user which you can employ to create and modify new users and roles, and otherwise manage your MongoDB instance. You also configured your MongoDB instance to require that users authenticate with a valid username and password before they can interact with any data.
通过完成本指南,您已经设置了MongoDB管理用户,可用来创建和修改新用户和角色以及以其他方式管理MongoDB实例。 您还配置了MongoDB实例,要求用户使用有效的用户名和密码进行身份验证,然后才能与任何数据进行交互。
For more information on how to manage MongoDB users, check out the official documentation on the subject. You may also be interested in learning more about how authentication works on MongoDB.
有关如何管理MongoDB用户的更多信息,请参阅关于此主题的官方文档 。 您可能也有兴趣了解有关认证如何在MongoDB上工作的更多信息。
Also, if you plan to interact with your MongoDB instance remotely, you can follow our guide on How To Configure Remote Access for MongoDB on Ubuntu 20.04.
另外,如果您打算与MongoDB实例进行远程交互,则可以按照我们的指南如何在Ubuntu 20.04上为MongoDB配置远程访问 。
翻译自: https://www.digitalocean.com/community/tutorials/how-to-secure-mongodb-on-ubuntu-20-04