**如何配置 ReplicaSet 以支持 TLS/SSL?
我们将在本地环境中部署一个 3 节点 ReplicaSet,并使用自签名证书。请勿在生产环境中使用自签名证书。
**如何将客户端连接到此 ReplicaSet? 我们将连接 Mongo Shell。
关于 TLS/SSL、PKI(公钥基础设施)证书和证书颁发机构的描述超出了本文档的范围。
Section 18.1: 如何配置 ReplicaSet 以支持 TLS/SSL?
创建根证书 根证书(又名 CA 文件)将用于签署和识别证书。要生成根证书,请运行以下命令。
openssl req -nodes -out ca.pem -new -x509 -keyout ca.key
请妥善保管根证书及其密钥,它们都将用于签署您的证书。根证书也可能被客户使用。
生成证书请求和私钥
生成证书签名请求(又称 CSR)时,请在通用名称(又称 CN)字段中输入节点的准确主机名(或 IP)。其他字段的值必须完全相同。您可能需要修改 /etc/hosts 文件。
下面的命令将生成 CSR 文件和 RSA 私钥(4096 位)。
openssl req -nodes -newkey rsa:4096 -sha256 -keyout mongodb_node_1.key -out mongodb_node_1.csr
openssl req -nodes -newkey rsa:4096 -sha256 -keyout mongodb_node_2.key -out mongodb_node_2.csr
openssl req -nodes -newkey rsa:4096 -sha256 -keyout mongodb_node_3.key -out mongodb_node_3.csr
您必须为 ReplicaSet 的每个节点生成一个 CSR。请记住,不同节点的通用名称是不一样的。不要将多个 CSR 建立在同一个私钥的基础上。
现在您必须有 3 个 CSR 和 3 个私钥。
mongodb_node_1.key - mongodb_node_2.key - mongodb_node_3.key
mongodb_node_1.csr - mongodb_node_2.csr - mongodb_node_3.csr
签署证书请求
运行下面的命令,使用之前生成的 CA 文件 (ca.pem) 及其私钥 (ca.key) 签署每个证书请求。
openssl x509 -req -in mongodb_node_1.csr -CA ca.pem -CAkey ca.key -set_serial 00 -out
mongodb_node_1.crt
openssl x509 -req -in mongodb_node_2.csr -CA ca.pem -CAkey ca.key -set_serial 00 -out
mongodb_node_2.crt
openssl x509 -req -in mongodb_node_3.csr -CA ca.pem -CAkey ca.key -set_serial 00 -out
mongodb_node_3.crt
**您必须签署每份 CSR。
现在你必须有 3 个 CSR、3 个私钥和 3 个自签名证书。MongoDB 将只使用私钥和证书。
mongodb_node_1.key - mongodb_node_2.key - mongodb_node_3.key
mongodb_node_1.csr - mongodb_node_2.csr - mongodb_node_3.csr
mongodb_node_1.crt - mongodb_node_2.crt - mongodb_node_3.crt
每个证书对应一个节点。请仔细记住您为每个 CSR 提供的 CN/主机名。
将每个节点证书与其密钥在一起
运行以下命令,将每个节点证书及其密钥连接到一个文件中(MongoDB 要求)。
cat mongodb_node_1.key mongodb_node_1.crt > mongodb_node_1.pem
cat mongodb_node_2.key mongodb_node_2.crt > mongodb_node_2.pem
cat mongodb_node_3.key mongodb_node_3.crt > mongodb_node_3.pem
现在您必须有 3 个 PEM 文件。
mongodb_node_1.pem - mongodb_node_2.pem - mongodb_node_3.pem
部署副本集
我们假设你的 pem 文件位于当前文件夹以及 data/data1、data/data2 和 data/data3 中。
运行以下命令,部署监听端口为 27017、27018 和 27019 的 3 节点 ReplicaSet。
mongod --dbpath data/data_1 --replSet rs0 --port 27017 --sslMode requireSSL --sslPEMKeyFile
mongodb_node_1.pem
mongod --dbpath data/data_2 --replSet rs0 --port 27018 --sslMode requireSSL --sslPEMKeyFile
mongodb_node_2.pem
mongod --dbpath data/data_3 --replSet rs0 --port 27019 --sslMode requireSSL --sslPEMKeyFile
mongodb_node_3.pem
现在,您已在本地环境中部署了一个 3 节点 ReplicaSet,其所有事务都已加密。如果不使用 TLS,则无法连接到此 ReplicaSet。
为相互 SSL / 相互信任部署 ReplicaSet
要强制客户提供客户证书(相互 SSL),必须在运行实例时添加 CA 文件。
mongod --dbpath data/data_1 --replSet rs0 --port 27017 --sslMode requireSSL --sslPEMKeyFile
mongodb_node_1.pem --sslCAFile ca.pem
mongod --dbpath data/data_2 --replSet rs0 --port 27018 --sslMode requireSSL --sslPEMKeyFile
mongodb_node_2.pem --sslCAFile ca.pem
mongod --dbpath data/data_3 --replSet rs0 --port 27019 --sslMode requireSSL --sslPEMKeyFile
mongodb_node_3.pem --sslCAFile ca.pem
现在,您已在本地环境中部署了一个 3 节点 ReplicaSet,其所有事务均已加密。
如果不使用 TLS 或不提供 CA 信任的客户端证书,就无法连接到该 ReplicaSet。
Section 18.2: 如何将客户端(Mongo Shell)连接到 ReplicaSet?
无相互 SSL 在本示例中,我们可能会使用在 "如何配置 ReplicaSet 以支持 TLS/SSL?我们假设 CA 文件位于当前文件夹中。
我们将假设 3 个节点分别运行在 mongo1:27017、mongo2:27018 和 mongo3:27019。(您可能需要修改 /etc/hosts 文件)。
从 MongoDB 3.2.6 开始,如果 CA 文件已在操作系统信任存储中注册,则无需提供 CA 文件即可连接到 ReplicaSet。
mongo --ssl --host rs0/mongo1:27017,mongo2:27018,mongo3:27019
否则,您必须提供 CA 文件。
mongo --ssl --sslCAFile ca.pem --host rs0/mongo1:27017,mongo2:27018,mongo3:27019
您现在已连接到 ReplicaSet,Mongo Shell 和 ReplicaSet 之间的所有事务都已加密。
使用相互 SSL
如果 ReplicaSet 要求提供客户证书,你必须提供由 ReplicaSet 部署使用的 CA 签发的证书。生成客户端证书的步骤与生成服务器证书的步骤几乎相同。
事实上,您只需在创建 CSR 时修改 Common Name 字段。您需要提供所有 ReplicaSet 主机名,而不是在 Common Name 字段中提供 1 个节点主机名,中间用逗号隔开。
openssl req -nodes -newkey rsa:4096 -sha256 -keyout mongodb_client.key -out1,
"stateStr" : "PRIMARY",
...........................
},
{
"_id" : 1,
"name" : "<hostname>:27018",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
...........................
},
{
"_id" : 2,
"name" : "<hostname>:27019",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
...........................
}
],
"ok" : 1
}