先决条件
要完成本教程,您需要:- 一个OpenVPN服务器,您可以通过以下教程设置如何在Ubuntu 16.04上设置OpenVPN服务器 。 确保在创建服务器时检查“ 专用网络 ”框。
- 安装了Docker的Ubuntu 16.04机器。 您将在此创建您的MongoDB Docker映像,以及在容器中运行MongoDB的位置。 要创建它,请在DigitalOcean管理控制台中单击Create Droplet ,然后选择一键应用 ,然后在16.04上选择Docker 1.x。启用此服务器上的私有网络。
- 在两台服务器上都具有sudo权限的非root用户。Ubuntu 16.04的初始设置指南说明了如何设置它。
- MongoDB安装在本地机器上 。您将使用它来测试您的MongoDB服务器的连接。
第1步 - 配置VPN转发到私有IP地址
如果您遵循先决条件的OpenVPN文章,您很可能会将服务器配置为将请求转发到公共网络接口,而不是私有接口。在本教程中,我们将配置MongoDB服务器,以便只能在其专用接口上访问,我们只能通过VPN连接进行访问。我们需要修改VPN服务器上的IP保护规则,以便来自VPN客户端的流量也被路由到专用网络。 连接到您的OpenVPN服务器。ssh sammy@vpn_server_public_ip
然后转到DigitalOcean仪表板,选择您的VPN Droplet,并找到其专用IP地址。 一旦拥有私有IP地址,请在VPN Droplet上执行此命令,以确定使用该IP地址的网络接口:
sudo nano /etc/ufw/before.rules
ip route | grep vpn_server_private_ip
您应该看到类似以下的输出:
Output10.132.0.0/16 dev eth1 proto kernel scope link src vpn_server_private_ip
注意输出中的网络接口。在这个例子中,接口是
eth1
,但是你可能会有所不同。 确定专用网络界面后,编辑文件
/etc/ufw/before.rules
:
sudo nano /etc/ufw/before.rules
找到您在先决条件教程中定义的部分,如下所示:
/etc/ufw/before.rules
# START OPENVPN RULES
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]
# Allow traffic from OpenVPN client to eth0
-A POSTROUTING -s 10.8.0.0/8 -o eth0 -j MASQUERADE
COMMIT
# END OPENVPN RULES
为专用网络接口添加新规则:
/etc/ufw/before.rules
# START OPENVPN RULES
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]
# Allow traffic from OpenVPN client to eth0
-A POSTROUTING -s 10.8.0.0/8 -o eth0 -j MASQUERADE
-A POSTROUTING -s 10.8.0.0/8 -o eth1 -j MASQUERADE
COMMIT
# END OPENVPN RULES
确保用专用网络的接口替换
eth1
。然后保存文件并退出编辑器。 禁用并重新启用防火墙:
sudo ufw disable
sudo ufw enable
然后退出您的VPN服务器。
exit
现在建立从本地计算机到VPN服务器的VPN连接。在本教程中保持此连接。 现在让我们使用其私有IP地址连接到MongoDB服务器,并配置其防火墙。
第2步 - 设置MongoDB服务器的防火墙
我们将使用其私有IP地址连接到MongoDB服务器。如果没有,请返回到DigitalOcean仪表板,找到MongoDB Docker Droplet的私有IP地址。您将在此使用它来连接到服务器,随后将使用它直接连接到MongoDB,因为我们要限制对VPN客户端的数据库服务器的访问。这样你就可以避免暴露公开的数据库,这是一个必须的安全措施。 确保您已连接到您的VPN,并使用其私有IP将SSH连接到MongoDB服务器:ssh sammy@mongodb_server_private_ip
登录后,删除所有现有的防火墙规则,以防止外界访问:
sudo ufw delete limit ssh
sudo ufw delete allow 2375/tcp
sudo ufw delete allow 2376/tcp
然后添加两个新规则,允许SSH和MongoDB仅从连接到VPN的计算机访问。为此,请使用VPN服务器的私有IP地址作为源IP:
sudo ufw allow from vpn_server_private_ip to any port 22 proto tcp
sudo ufw allow from vpn_server_private_ip to any port 28018 proto tcp
确保这些是仅配置的两个规则:
sudo ufw status
您应该看到以下输出:
OutputTo Action From
-- ------ ----
22/tcp ALLOW vpn_server_private_ip
28018/tcp ALLOW vpn_server_private_ip
启用防火墙并退出服务器:
sudo ufw enable
exit
然后重新登录MongoDB服务器,以确保在启用IP过滤器后仍然可以访问服务器。
ssh sammy@mongodb_server_private_ip
如果您无法建立SSH连接,请确保已连接到VPN,并且已设置VPN服务器以转发专用网络上的流量。如果这不起作用,请使用
DigitalOcean Console登录并检查防火墙规则。确保您已经在规则中指定了VPN服务器的私有IP,而不是您的MongoDB服务器的私有IP。 要了解有关UFW的更多信息,请浏览
此DigitalOcean UFW教程 。 现在您已经配置了基本的安全措施,请继续配置MongoDB。
第3步 - 创建MongoDB配置文件
在此步骤中,我们将创建一个自定义MongoDB配置,配置MongoDB以使用SSL证书。 我们创建一个目录结构来保存我们的配置和相关文件。我们将创建一个名为mongoconf
,然后为其
config
文件创建一个
config
目录。 在
config
目录下,我们将创建一个名为
ssl
目录,我们将在其中存储证书。 使用以下命令创建结构:
mkdir -p ~/mongoconf/config/ssl
然后切换到
~/mongoconf/config
文件夹:
cd ~/mongoconf/config
用文本编辑器打开一个名为
mongod.conf
的新文件:
nano mongod.conf
首先,将数据库设置为绑定到端口
28018
上的每个网络接口。 在这种情况下绑定到
0.0.0.0
不是安全问题,因为防火墙将不允许外部连接。但我们确实需要允许VPN内的客户端进行连接。将以下内容添加到文件中:
mongodb.conf
net:
bindIp: 0.0.0.0
port: 28018
同样在网段中,设置SSL证书的路径并指定证书密码。我们将尽快创建实际的认证文件和密码。
mongodb.conf
net:
. . .
ssl:
CAFile: /etc/mongo/ssl/client.pem
PEMKeyFile: /etc/mongo/ssl/server.pem
PEMKeyPassword: test
mode: requireSSL
最后,设置默认存储目录并启用日志记录。
mongodb.conf
. . .
storage:
dbPath: /mongo/db
journal:
enabled: true
要了解所有可用的配置选项,
请阅读MongoDB的文档 。 现在,保存文件并退出编辑器。现在是生成我们将要使用的SSL证书的时候了。
第4步 - 生成SSL证书
为了保护数据传输,您需要为MongoDB生成两个SSL证书 - 一个用于服务器,一个用于访问数据库的客户端。 注意:我们在本教程中创建自签名证书。在生产环境中,您将使用受信任的证书颁发机构来生成它们。 为此,您需要 设置一个私有DNS解析器 。 然后, 使用我们的加密DNS挑战来验证新创建的内部网域,并为其颁发证书。 首先,转到~/mongoconf/config/ssl
目录并生成服务器证书 - 密钥对。 填写您选择的信息提示。 注意
Common Name
和
PEM Passphrase
字段。
cd ~/mongoconf/config/ssl
openssl req -new -x509 -days 365 -out server.crt -keyout server.key
您将看到以下输出,并将被要求提供一些细节:
Server certificate-key generation. . .
Enter PEM pass phrase: test
Verifying - Enter PEM pass phrase: test
. . .
Common Name (e.g. server FQDN or YOUR name) []: mongodb_server_private_ip
. . .
当您被要求提供PEM密码时,请确保在上一步中使用与MongoDB配置文件中使用的相同的值。 MongoDB不接受单独的密钥和证书文件,因此将它们组合成一个
.pem
文件:
cat server.crt server.key >> server.pem
接下来,为客户端生成证书密钥对:
openssl req -new -x509 -days 365 -out client.crt -keyout client.key
您将遵循与以前相同的过程,但这次使用VPN服务器的私有IP。 PEM通行短语可以是您想要的这一步。
Client certificate-key generation. . .
Enter PEM pass phrase: secret_password
Verifying - Enter PEM pass phrase: secret_password
. . .
Common Name (e.g. server FQDN or YOUR name) []: vpn_server_private_ip
. . .
将刚生成的文件连接到一个
.pem
文件中:
cat client.crt client.key >> client.pem
接下来,将两个证书文件复制到本地计算机,以便远程连接到MongoDB服务器。您可以使用本地计算机上的
scp
命令执行此操作:
scp sammy@mongodb_server_private_ip:/home/sammy/mongoconf/config/ssl/\{client.pem,server.pem\} .
或者,您可以按照教程
如何使用SFTP将远程服务器安全地传输文件,将
client.pem
和
server.pem
文件传输到本地计算机。 现在让我们创建一个Docker镜像,并在一个容器中运行数据库引擎,这样配置就可以更便于携带了。
第5步 - 创建MongoDB Docker映像并运行容器
您创建了一个安全的MongoDB配置并生成了证书。现在让它让它与Docker便携。我们将为MongoDB创建一个自定义映像,但是当我们运行容器时,我们会传入我们的配置文件和证书。 要建立一个图像,你需要一个Dockerfile。 注意 :要运行没有sudo
,请将
sammy添加到
docker组:
sudo usermod -aG docker sammy
然后退出服务器并重新登录,以便新的组权限生效。 切换到项目的根目录,并在编辑器中打开一个空的Dockerfile:
cd ~/mongoconf
nano Dockerfile
将以下内容添加到新文件中:
Dockerfile
FROM ubuntu:xenial
RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6
RUN 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
RUN apt-get update && apt-get install -y mongodb-org
RUN mkdir -p /mongo/db /etc/mongo
EXPOSE 28018
ENTRYPOINT ["mongod", "--config", "/etc/mongo/mongod.conf"]
该文件告诉Docker创建一个基于Ubuntu 16.04 Xenial的映像,下载最新的MongoDB二进制文件,并创建一些目录,我们将存储配置文件和数据库。它使容器的端口
28018
可用于主机,并在每次用户重新启动容器时运行Mongo。
注意:为了简单起见,我们的形象基于Ubuntu。然而,像Alpine Linux这样的轻量级发行版建造的容器占用较少的磁盘空间。 保存文件并退出编辑器。然后构建图像:
docker build -t mongo .
一旦图像建立,请根据图像运行容器。我们将把容器目录作为一个容器装载到容器中,这样我们可以在容器内的MongoDB实例中看到自定义的配置和密钥:
docker run \
--detach \
--publish 28018:28018 \
--volume $PWD/config:/etc/mongo \
--name mongodb \
mongo
现在你有一个正在运行的MongoDB实例,从本地计算机访问它。
第6步 - 访问MongoDB
在本地机器上的新终端中,使用MongoDB服务器的私有IP地址连接到数据库。您将提供您下载到本地计算机的client.pem和server.pem文件,以及创建客户端证书时使用的密码。执行此命令:mongo \
--ssl \
--sslCAFile path_to_server_pem \
--sslPEMKeyFile path_to_client_pem \
--sslPEMKeyPassword pem_key_passphrase \
--host mongodb_server_private_ip \
--port 28018
如果一切正常,您应该看到MongoDB提示符。
如果出现错误,请仔细检查您是否连接到MongoDB服务器的专用IP,而不是VPN服务器的IP地址。还要验证密钥位置和密码是否正确,并且您与VPN的连接仍在运行。