MongoDB是一个开源的NoSQL数据库. 传统的MongoDB设置缺乏一些安全功能,如果你担心数据安全,你会想要的。
有几种方法可以保护运行数据库的服务器。 首先,您可以设置VPN并限制只对连接到VPN的客户端的访问。 然后您可以使用证书加密客户端和服务器之间的传输层。 在本教程中,您将做这两件事。 此外,您将使用Docker(https://www.docker.com/)来运行您的MongoDB实例,以确保您的MongoDB配置和证书在多个服务器上可重复使用。
前提条件
要完成这个教程,你需要:
- 一个 OpenVPN 服务器,你可以根据教程(How To Set Up an OpenVPN Server on Ubuntu 16.04)(https://andsky.com/tech/tutorials/how-to-set-up-an-openvpn-server-on-ubuntu-16-04)来设置,请确保你在创建服务器时检查 私人网络框
- 安装了 Docker 的 Ubuntu 16.04 机器。这就是你将创建你的 MongoDB Docker 图像的地方,你将在容器中运行 MongoDB。 要创建它,请单击 Create Droplet 在 DigitalOcean 管理控制台中,选择 One-click 应用程序,然后选择 Docker 1.x 在 16.04 上。 也可以在这个服务器上启用私人网络 一个在两个服务器上具有 sudo 特权的非根基用户。 [Inaliti
步骤 1 – 将VPN配置为私人IP地址
如果你遵循了OpenVPN文章的先决条件,你很可能会配置你的服务器将请求转发到公共网络接口,但不是私人接口. 在本教程中,我们将配置MongoDB服务器,以便它只能通过其私人接口访问,我们只能通过我们的VPN连接访问。
连接到你的OpenVPN服务器。
1[environment local]
2ssh sammy@vpn_server_public_ip
然后进入DigitalOcean仪表板,选择您的VPN Droplet,并找到其私人IP地址。
一旦你有私人IP地址,在VPN Droplet上执行此命令,以识别使用该IP地址的网络接口:
1[environment second]
2sudo nano /etc/ufw/before.rules
3ip route | grep vpn_server_private_ip
你应该看到类似于以下的输出:
1[secondary_label Output]
2[environment second]
310.132.0.0/16 dev eth1 proto kernel scope link src vpn_server_private_ip
在此示例中,接口为eth1
,但您的接口可能不同。
一旦您确定了私人网络接口,请编辑文件 /etc/ufw/before.rules
:
1[environment second]
2sudo nano /etc/ufw/before.rules
在先决条件教程中找到您定义的部分,它看起来像这样:
1[label /etc/ufw/before.rules]
2# START OPENVPN RULES
3# NAT table rules
4*nat
5:POSTROUTING ACCEPT [0:0]
6# Allow traffic from OpenVPN client to eth0
7-A POSTROUTING -s 10.8.0.0/8 -o eth0 -j MASQUERADE
8COMMIT
9# END OPENVPN RULES
添加私人网络接口的新规则:
1[label /etc/ufw/before.rules]
2# START OPENVPN RULES
3# NAT table rules
4*nat
5:POSTROUTING ACCEPT [0:0]
6# Allow traffic from OpenVPN client to eth0
7-A POSTROUTING -s 10.8.0.0/8 -o eth0 -j MASQUERADE
8-A POSTROUTING -s 10.8.0.0/8 -o eth1 -j MASQUERADE
9COMMIT
10# END OPENVPN RULES
请确保用您的私人网络的界面代替eth1
,然后保存文件并退出编辑器。
禁用和重新启用防火墙:
1[environment second]
2sudo ufw disable
3sudo ufw enable
然后退出您的VPN服务器。
1[environment second]
2exit
现在,从您的本地计算机建立一个VPN连接到您的VPN服务器。
现在让我们使用其私人 IP 地址连接到 MongoDB 服务器并配置其防火墙。
步骤 2 – 设置 MongoDB 服务器的防火墙
我们将使用其私有 IP 地址连接到 MongoDB 服务器。如果您没有它,请回到 DigitalOcean 仪表板并找到 MongoDB Docker Droplet 的私有 IP 地址。您将使用它在这里连接到服务器,然后使用它直接连接到 MongoDB,因为我们将限制访问数据库服务器给 VPN 客户端。
确保您已连接到 VPN,并使用其私人 IP 将 SSH 连接到 MongoDB 服务器:
1[environment local]
2ssh sammy@mongodb_server_private_ip
一旦登录,请删除所有现有的防火墙规则,以防止来自外部世界的访问:
1sudo ufw delete limit ssh
2sudo ufw delete allow 2375/tcp
3sudo ufw delete allow 2376/tcp
然后添加两个新的规则,允许SSH和MongoDB仅从连接到您的VPN的计算机访问。
1sudo ufw allow from vpn_server_private_ip to any port 22 proto tcp
2sudo ufw allow from vpn_server_private_ip to any port 28018 proto tcp
确保这些是唯一配置的两个规则:
1sudo ufw status
你应该看到以下结果:
1[secondary_label Output]
2To Action From
3-- ------ ----
422/tcp ALLOW vpn_server_private_ip
528018/tcp ALLOW vpn_server_private_ip
启用防火墙并退出服务器:
1sudo ufw enable
2exit
然后重新登录到 MongoDB 服务器,以确保在启用 IP 过滤器后仍然可以访问服务器。
1[environment local]
2ssh sammy@mongodb_server_private_ip
如果您无法建立 SSH 连接,请确保您已连接到 VPN,并已设置 VPN 服务器来在私人网络中传输流量。如果这不起作用,请使用 DigitalOcean Console登录并检查防火墙规则。
若要了解更多有关UFW的信息,请参阅 DigitalOcean UFW 教程。
现在你已经配置了基本的安全措施,继续配置 MongoDB。
步骤 3 – 创建 MongoDB 配置文件
在此步骤中,我们将创建一个自定义的 MongoDB 配置,将 MongoDB 配置为使用 SSL 证书。
我们将创建一个名为mongoconf
的目录,然后为我们的配置文件创建一个config
目录。
使用以下命令创建结构:
1mkdir -p ~/mongoconf/config/ssl
然后切换到 ~/mongoconf/config
文件夹:
1cd ~/mongoconf/config
使用您的文本编辑器打开名为 `mongod.conf’的新文件:
1nano mongod.conf
首先,将数据库设置为连接到每个网络接口上的端口 28018
。 连接到 0.0.0.0
在这种情况下不是安全问题,因为防火墙不会允许来自外部世界的连接,但我们需要允许VPN内部的客户端连接。
1[label mongodb.conf]
2net:
3 bindIp: 0.0.0.0
4 port: 28018
此外,在net
部分,设置到SSL证书的路径并指定证书passphrase. 我们将很快创建实际的证书文件和passphrase。
1[label mongodb.conf]
2net:
3. . .
4 ssl:
5 CAFile: /etc/mongo/ssl/client.pem
6 PEMKeyFile: /etc/mongo/ssl/server.pem
7 PEMKeyPassword: test
8 mode: requireSSL
最后,设置默认存储目录并启用日志。
1[label mongodb.conf]
2. . .
3storage:
4 dbPath: /mongo/db
5 journal:
6 enabled: true
要了解所有可用的配置选项,请阅读MongoDB的文档(https://docs.mongodb.com/manual/reference/configuration-options/)。
现在,保存文件并退出编辑器,是时候生成我们将使用的SSL证书了。
第4步:生成SSL证书
为了确保数据传输,您需要为 MongoDB 生成两个 SSL 证书 - 一个用于服务器,一个用于访问数据库的客户端。
<$>[注] **注:**我们在本教程中创建自签证书.在生产环境中,您将使用可信证书权威来生成它们。
要做到这一点,您需要 设置私人 DNS 解析器。然后, 使用 Let's Encrypt DNS 挑战来验证新创建的内网域名并为其发行证书。
首先,切换到 ~/mongoconf/config/ssl
目录并生成服务器证书密钥对。 请用您所选择的信息填写提示书。 请注意 Common Name
和 `PEM Passphrase' 字段。
1cd ~/mongoconf/config/ssl
2openssl req -new -x509 -days 365 -out server.crt -keyout server.key
您将看到以下输出,并将被要求在途中提供一些细节:
1[secondary_label Server certificate-key generation]
2. . .
3Enter PEM pass phrase: test
4Verifying - Enter PEM pass phrase: test
5. . .
6Common Name (e.g. server FQDN or YOUR name) []: mongodb_server_private_ip
7. . .
当您被要求使用 PEM 通行语句时,请确保您在上一步中使用了 MongoDB 配置文件中的相同值。
MongoDB 不接受单独的密钥和证书文件,所以将它们合并为一个单一的.pem 文件:
1cat server.crt server.key >> server.pem
接下来,为客户端生成证书密钥对:
1openssl req -new -x509 -days 365 -out client.crt -keyout client.key
您将遵循与之前相同的过程,但这一次,使用VPN服务器的私人IP。
1[secondary_label Client certificate-key generation]
2. . .
3Enter PEM pass phrase: secret_password
4Verifying - Enter PEM pass phrase: secret_password
5. . .
6Common Name (e.g. server FQDN or YOUR name) []: vpn_server_private_ip
7. . .
将您刚刚生成的文件合并为一个单一的 .pem
文件:
1cat client.crt client.key >> client.pem
接下来,将两个证书文件复制到您的本地机器,以便您可以远程连接到 MongoDB 服务器。
1[environment local]
2scp sammy@mongodb_server_private_ip:/home/sammy/mongoconf/config/ssl/\{client.pem,server.pem\} .
或者,您可以按照教程(How To Use SFTP to Secure Transfer Files with a Remote Server)(https://andsky.com/tech/tutorials/how-to-use-sftp-to-securely-transfer-files-with-a-remote-server)将client.pem
和server.pem
文件传输到本地机器。
现在,让我们创建Docker图像并在容器中运行数据库引擎,以便此配置更便携式。
步骤 5 — 创建 MongoDB Docker 图像并运行容器
您已经创建了一个安全的 MongoDB 配置并生成证书,现在让我们用 Docker 将其进行便携。我们将为 MongoDB 创建一个自定义图像,但当我们运行容器时,我们将通过我们的配置文件和证书。
要创建一个图像,你需要一个Dockerfile。
<$>[注]
注:要在没有sudo
的情况下运行docker
,请将 sammy添加到 docker组:
1sudo usermod -aG docker sammy
然后退出服务器并再次登录,以便新的组权限生效 <$>
切换到项目的根目录,并在编辑器中打开一个空的Dockerfile:
1cd ~/mongoconf
2nano Dockerfile
将以下内容添加到新文件中:
1[label Dockerfile]
2FROM ubuntu:xenial
3
4RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6
5RUN echo "deb http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.4 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-3.4.list
6RUN apt-get update && apt-get install -y mongodb-org
7RUN mkdir -p /mongo/db /etc/mongo
8
9EXPOSE 28018
10ENTRYPOINT ["mongod", "--config", "/etc/mongo/mongod.conf"]
这个文件告诉Docker创建基于Ubuntu 16.04 Xenial的图像,下载最新的MongoDB二进制,并创建一些目录,在那里我们将存储配置文件和数据库。
<$>[注] **注:**为了简单,我们的图像是基于Ubuntu的,但是,建在Alpine Linux等轻量级发行版上的容器使用更少的磁盘空间。
保存文件并离开编辑器,然后构建图像:
1docker build -t mongo .
一旦图像被构建,运行一个基于图像的容器. 我们将安装config
目录作为容器内部的卷,以便我们的自定义配置和密钥可见于容器内部的MongoDB实例:
1docker run \
2--detach \
3--publish 28018:28018 \
4--volume $PWD/config:/etc/mongo \
5--name mongodb \
6mongo
现在你有一个运行 MongoDB 实例,可以从本地计算机访问它。
步骤 6 – 访问 MongoDB
在本地计算机上的新终端中,使用 MongoDB 服务器的私人 IP 地址连接到数据库,您将提供您下载到本地计算机的 client.pem 和 server.pem 文件,以及您创建客户端证书时使用的密码短语。
1[environment local]
2mongo \
3--ssl \
4--sslCAFile path_to_server_pem \
5--sslPEMKeyFile path_to_client_pem \
6--sslPEMKeyPassword pem_key_passphrase \
7--host mongodb_server_private_ip \
8--port 28018
如果一切顺利,你应该看到MongoDB提示。
如果出现错误,请双重检查您是否正在连接到MongoDB服务器的私人IP,而不是VPN服务器的IP地址。
结论
现在你有一个自定义 MongoDB 运行在 Docker 容器中。它的安全性通过 SSL 客户端服务器身份验证和运输加密提供。你通过配置防火墙来增加额外的安全性,以限制连接到 VPN 服务器的客户端的数据库连接。
虽然这个设置是测试的最佳,但请记住,在生产环境中,你应该使用可信的证书权威和签名的证书。此外,你必须分析你的安全需求,并相应地采取行动。例如,你可能希望在数据库中设置用户,密码和角色。