介绍
MongoDB 是一个免费和开源的面向文档的数据库。 它被归类为 NoSQL 数据库,因为它不依赖于传统的基于表的关系数据库结构。 相反,它使用具有动态模式的类似 JSON 的文档。 与关系数据库不同,MongoDB 在将数据添加到数据库之前不需要预定义模式。 您可以随时根据需要随时更改模式,而无需使用更新的模式设置新数据库。
在本教程的第一部分中,我们将使用 MongoDB 存储库来安装最新版本的 MongoDB。 在第二部分中,我们将启用身份验证以在本地系统上保护它。 最后,在第三部分中,我们将展示如何在需要时更安全地允许远程连接。
先决条件
要遵循本教程,您将需要:
- 按照 Ubuntu 16.04 初始服务器设置指南 配置一个非 root
sudo
用户和防火墙的 Ubuntu 16.04 服务器。
完成后,您就可以继续跟进了。
第 1 部分:设置服务器
第 1 步 - 添加 MongoDB 存储库
MongoDB 已包含在 Ubuntu 软件包存储库中,但官方 MongoDB 存储库提供了最新版本,并且是推荐的软件安装方式。 在这一步中,我们将把这个官方存储库添加到我们的服务器。
Ubuntu 通过验证软件包是否使用 GPG 密钥签名来确保软件包的真实性,因此我们首先要导入官方 MongoDB 存储库的密钥。
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6
以下输出确认我们已成功导入密钥:
输出
Executing: /tmp/tmp.IdwenTia0s/gpg.1.sh --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6 gpg: requesting key A15703C6 from hkp server keyserver.ubuntu.com gpg: key A15703C6: public key "MongoDB 3.4 Release Signing Key <packaging@mongodb.com>" imported gpg: Total number processed: 1 gpg: imported: 1 (RSA: 1)
接下来,我们将添加 MongoDB 存储库详细信息,以便 apt
知道在哪里下载包。 发出以下命令为 MongoDB 创建一个列表文件。
echo "deb [ arch=amd64,arm64 ] http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.4.list
最后,我们将更新软件包列表。
sudo apt-get update
现在我们已准备好安装 MongoDB。
第 2 步 — 安装 MongoDB
我们将在服务器上安装 mongodb-org
元包,其中包括守护程序、配置和初始化脚本、shell 和管理工具。
sudo apt-get install mongodb-org
出现提示时按 enter 或键入 Y
继续。 安装完成后,我们将启动 Mongo 守护进程:
sudo systemctl start mongod
由于 systemctl
不提供输出,我们将检查状态以验证服务是否已正常启动。
sudo systemctl status mongod
输出
● mongod.service - High-performance, schema-free document-oriented database Loaded: loaded (/lib/systemd/system/mongod.service; disabled; vendor preset: enabled) Active: active (running) since Fri 2017-02-17 18:57:26 UTC; 17min ago Docs: https://docs.mongodb.org/manual Main PID: 2811 (mongod) Tasks: 17 Memory: 56.8M CPU: 7.294s CGroup: /system.slice/mongod.service └─2811 /usr/bin/mongod --quiet --config /etc/mongod.conf
按 q
退出。 现在我们已经手动启动了守护进程并验证了它正在运行,我们将确保它在启动时自动重新启动:
sudo systemctl enable mongod
以下输出确认命令成功:
OutputCreated symlink from /etc/systemd/system/multi-user.target.wants/mongod.service to /lib/systemd/system/mongod.service.
接下来,我们将采取必要措施来保护我们的数据库。
第二部分:保护 MongoDB
早期版本的 MongoDB 容易受到自动攻击,因为默认情况下不需要身份验证来与数据库交互。 默认情况下,任何用户都可以创建和销毁数据库,以及读取和写入其内容。 情况更加复杂,因为这些早期版本还将 MongoDB 守护进程配置为默认侦听所有接口,这意味着自动化脚本可以检测不受防火墙保护的 MongoDB 实例,并且如果尚未启用身份验证,则可以获得完全访问权限到 MongoDB。
这种情况在 3.x 版本以及一些包管理器提供的早期版本中得到了缓解,因为守护程序现在绑定到 127.0.0.1,因此它只接受 Unix 套接字上的连接。 它不会自动向 Internet 开放。
但是,默认情况下仍然禁用身份验证,因此本地系统上的任何用户都可以完全访问数据库。 为了确保这一点,我们将创建一个管理用户,启用身份验证和测试。
第 1 步 — 添加管理用户
要添加我们的用户,我们将连接到 Mongo shell:
mongo
我们使用 Mongo shell 时的输出警告我们没有为数据库启用访问控制,并且对数据和配置的读/写访问是不受限制的。
OutputMongoDB shell version v3.4.2 connecting to: mongodb://127.0.0.1:27017 MongoDB server version: 3.4.2 Welcome to the MongoDB shell. For interactive help, type "help". For more comprehensive documentation, see http://docs.mongodb.org/ Questions? Try the support group http://groups.google.com/group/mongodb-user Server has startup warnings: 2017-02-21T19:10:42.446+0000 I STORAGE [initandlisten] 2017-02-21T19:10:42.446+0000 I STORAGE [initandlisten] ** WARNING: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine 2017-02-21T19:10:42.446+0000 I STORAGE [initandlisten] ** See http://dochub.mongodb.org/core/prodnotes-filesystem 2017-02-21T19:10:42.534+0000 I CONTROL [initandlisten] 2017-02-21T19:10:42.534+0000 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database. 2017-02-21T19:10:42.534+0000 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted. 2017-02-21T19:10:42.534+0000 I CONTROL [initandlisten] >
我们可以自由选择管理用户的名称,因为权限级别来自角色 userAdminAnyDatabase
的分配。 数据库 admin
指定存储凭证的位置。 您可以在 MongoDB Security Authentication 部分了解有关身份验证的更多信息。
设置您选择的用户名,并确保选择您自己的安全密码并在以下命令中替换它们:
use admin db.createUser( { user: "AdminSammy", pwd: "AdminSammy'sSecurePassword", roles: [ { role: "userAdminAnyDatabase", db: "admin" } ] } )
当我们发出 db.createUser
命令时,shell 会在每行之前添加三个点,直到命令完成。 之后,添加用户后,我们应该会收到如下反馈。
Output> use admin switched to db admin > db.createUser( ... { ... user: "AdminSammy", ... pwd: "AdminSammy'sSecurePassword", ... roles: [ { role: "userAdminAnyDatabase", db: "admin" } ] ... } ... ) Successfully added user: { "user" : "AdminSammy", "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" } ] }
键入“exit”并按 ENTER
或使用 CTRL+C
离开客户端。
此时,我们的用户将被允许输入凭据,但在我们启用身份验证并重新启动 MongoDB 守护程序之前,他们不会 需要 这样做。
第 2 步 — 启用身份验证
在 mongod.conf
文件中启用了身份验证。 一旦我们启用它并重新启动 mongod
,用户仍然可以在不进行身份验证的情况下连接到 Mongo,但他们需要提供用户名和密码才能进行交互。
让我们打开配置文件:
sudo nano /etc/mongod.conf
在 #security
部分中,我们将删除 security
前面的哈希以启用该节。 然后我们将添加授权设置。 完成后,这些行应该类似于下面的摘录:
mongodb.conf
. . . security: authorization: "enabled" . . .
注意“security”行开头没有空格,“authorization”行必须缩进两个空格
保存并退出文件后,我们将重新启动守护进程:
sudo systemctl restart mongod
如果我们在配置中出错,守护进程将无法启动。 由于 systemctl
不提供输出,我们将使用它的 status
选项来确保它提供:。
sudo systemctl status mongod
如果我们在输出中看到 Active: active (running)
并且它以如下文本结尾,我们可以确定 restart
命令是成功的:
OutputJan 23 19:15:42 MongoHost systemd[1]: Started High-performance, schema-free document-oriented database.
验证守护程序已启动,让我们测试身份验证。
第 3 步 - 验证未经身份验证的用户是否受到限制
首先,让我们在没有凭据的情况下进行连接,以验证我们的操作是否受到限制:
mongo
现在我们已经启用了身份验证,所有早期的警告都已解决。
OutputMongoDB shell version v3.4.2 connecting to: mongodb://127.0.0.1:27017 MongoDB server version: 3.4.2
我们已连接到 test
数据库。 我们将使用 show dbs
命令测试我们的访问是否受到限制:
show dbs
Output2017-02-21T19:20:42.919+0000 E QUERY [thread1] Error: listDatabases failed:{ "ok" : 0, "errmsg" : "not authorized on admin to execute command { listDatabases: 1.0 }", "code" : 13, "codeName" : "Unauthorized" . . .
如果不进行身份验证,我们将无法创建用户或类似的特权任务。
让我们退出 shell 继续:
exit
接下来,我们将确保我们的管理用户 确实 具有访问权限。
第 4 步 — 验证管理用户的访问权限
我们将以管理员身份使用 -u
选项连接以提供用户名和 -p
以提示输入密码。 我们还需要使用 --authenticationDatabase
选项提供我们存储用户身份验证凭据的数据库。
mongo -u AdminSammy -p --authenticationDatabase admin
系统将提示我们输入密码,因此请提供密码。 一旦我们输入正确的密码,我们将被放入 shell,我们可以在其中发出 show dbs
命令:
OutputMongoDB shell version v3.4.2 Enter password: connecting to: mongodb://127.0.0.1:27017 MongoDB server version: 3.4.2 >
我们应该看到可用的数据库,而不是被拒绝访问:
show dbs
Outputadmin 0.000GB local 0.000GB
键入 exit
或按 CTRL+C
退出。
请参阅 MongoDB 文档以了解有关 Authentication、Role-Based Access Control 和 Users and Roles 的更多信息。
第三部分:配置远程访问(可选)
在我们开始使用允许远程连接的安装之前,理想情况下,我们将 MongoDB 置于外部防火墙之后,由虚拟专用网络 (VPN) 保护,或通过堡垒主机进行限制。 然而,当我们朝着这个方向努力时,我们可以采取稍微不那么复杂的步骤,即在数据库服务器上启用防火墙并限制对特定主机或需要它的主机的访问。
第 1 步 - 启用 UFW
在 Initial Server Setup with Ubuntu 16.04 先决条件中,我们启用了 UFW 并且只允许 SSH 连接。 在为客户端机器打开端口之前,让我们验证 UFW 的状态:
sudo ufw status
注意:如果输出表明防火墙是inactive
,激活它:
sudo ufw enable
启用后,重新运行状态命令,sudo ufw status
将显示规则。 如有必要,请务必允许 SSH。
sudo ufw allow OpenSSH
<$>
除非我们对先决条件进行了更改,否则输出应该显示只允许 OpenSSH:
OutputStatus: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6)
接下来,我们将允许访问默认的 MongoDB 端口 27017,但将该访问限制为特定主机。 如果您更改了默认端口,请务必在下面的命令中更新它。
sudo ufw allow from client_ip_address to any port 27017
使用需要访问的每个其他客户端的 IP 地址重新运行此命令。 要仔细检查规则,我们将再次运行 ufw status
:
sudo ufw status
OutputTo Action From -- ------ ---- OpenSSH ALLOW Anywhere 27017 ALLOW client_ip_address OpenSSH (v6) ALLOW Anywhere (v6)
<$>[注] 笔记: 如果您是 UFW 的新手,您可以在指南中了解更多信息, UFW Essentials:通用防火墙规则和命令 .
有了这个防火墙规则,我们就可以配置 MongoDB 来监听它的公共接口了。
第 2 步 — 配置公共 bindIP
为了允许远程连接,我们将主机的可公开路由的 IP 地址添加到 mongod.conf
文件中。
sudo nano /etc/mongod.conf
在 net
节中,将 MongoHost
的 IP 添加到 bindIp
行:
/etc/mongod.conf 的摘录
. . . net: port: 27017 bindIp: 127.0.0.1,IP_of_MongoHost . . .
我们将保存并退出文件,然后重新启动守护程序:
sudo systemctl restart mongod
正如我们之前所做的,我们将确认重启成功:
sudo systemctl status mongod
输出应该包含 Active: active (running)
,我们可以进行最终测试。 Mongo 现在正在侦听其默认端口。
第 3 步 — 测试远程连接
我们将通过在 mongodb.conf
文件中添加带有 IP 地址的 --host
标志来测试 Mongo 是否正在侦听其公共接口。
mongo -u AdminSammy -p --authenticationDatabase admin --host IP_address_of_MongoHost
MongoDB shell version v3.4.2 Enter password: connecting to: mongodb://107.170.233.82:27017/ MongoDB server version: 3.4.2
到达提示确认守护程序正在侦听其公共 IP。 此时,远程连接和 MongoDB 主机之间的任何事务都是未加密的,因此下一步,在测试防火墙之前,应该保护这些事务。 有关这方面的帮助,请参阅 MongoDB 的关于 Transport Encryption 的安全文档。
结论
在本教程中,我们已将 MongoDB 存储库添加到我们的包列表中,以安装最新可用版本的 MongoDB、添加管理用户并启用身份验证。
我们还展示了如何配置 MongoDB 以接受远程连接,但通过将服务器的防火墙配置为仅允许来自需要访问的主机的连接来防止广告 MongoDB 安装。
下一步:
- 要加密传输中的数据,请参阅 MongoDB 的安全文档 Transport Encryption
- 在 这些 DigitalOcean 社区文章 中了解有关使用和管理 MongoDB 的更多信息。