如何在Ubuntu20.04上保护MongoDB

来自菜鸟教程
跳转至:导航、​搜索

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

介绍

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

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

先决条件

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

  • 运行 Ubuntu 20.04 的服务器。 此服务器应具有非 root 管理用户和配置了 UFW 的防火墙。 按照我们的 Ubuntu 20.04 初始服务器设置指南进行设置。
  • MongoDB 安装在您的服务器上。 本教程使用 MongoDB 版本 4.4 进行了验证,尽管它通常也适用于旧版本的 MongoDB。 要在您的服务器上安装 Mongo,请按照我们关于 如何在 Ubuntu 20.04 上安装 MongoDB 的教程进行操作。

第 1 步 — 添加管理用户

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

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

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

mongo

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

OutputMongoDB 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 用户的 角色 或它对某些数据库的访问级别而更改。 但是,由于禁用了身份验证,它将返回当前系统上的每个数据库,而不受限制:

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及更新的版本。 如果您使用的是旧版本的 MongoDB,那么您必须以明文形式写出密码,类似于您写出用户名的方式:

pwd: "password",

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

pwd: passwordPrompt(),

然后输入您希望管理用户拥有的角色。 因为您正在创建管理用户,所以您至少应该授予他们 admin 数据库上的 userAdminAnyDatabase 角色。 这将允许管理用户创建和修改新用户和角色。 因为管理用户在 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" ]
... }
... )

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

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 + 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 

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

OutputMongoDB 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:

注意:不要像之前在步骤 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 实例进行远程交互,您可以按照我们关于 如何在 Ubuntu 20.04 上为 MongoDB 配置远程访问的指南进行操作。