使用 mkcert 本地部署启动了 TLS/SSL 加密通讯的 MongoDB 副本集和分片集群

news/2025/2/11 18:12:07/

在这里插入图片描述

MongoDB 是支持客户端与 MongoDB 服务器之间启用 TLS/SSL 进行加密通讯的, 对于 MongoDB 副本集和分片集群内部的通讯, 也可以开启 TLS/SSL 认证. 本文会使用 mkcert 创建 TLS/SSL 证书, 基于创建的证书, 介绍 MongoDB 副本集、分片集群中启动 TLS/SSL 通讯的方法.

我们将会在本地部署启用了 SSL/TLS 通讯的副本集、分片集群.

安装 mkcert 和 MongoDB

在介绍 MongoDB 副本集和 MongoDB 分片集群中启用 SSL/TLS 通讯前, 我们先在本地安装好 MongoDB 和 mkcert.

mkcert 是一个 Go 实现的命令行工具, 方便我们使用一行命令就创建好 TLS/SSL 证书. 这里我们以 Ubuntu Linux 为例子:

# 需要安装有 Go
go install filippo.io/mkcert@latest

你也可以参考 mkcert 文章中描述的安装方法进行安装: mkcert installation.

接下来我们安装 MongoDB Server 和 MongoDB Shell 命令行工具. 你可以在 https://www.mongodb.com/try/download/community 下载到对应的二进制 (mongod、mongos) 文件压缩包. 后续我们将会以 MongoDB@2.0.26 版本为例:

❯ mongod --version
db version v5.0.26
Build Info: {"version": "5.0.26","gitVersion": "0b4f1ea980b5380a66425a90b414106a191365f4","openSSLVersion": "OpenSSL 1.1.1f  31 Mar 2020","modules": [],"allocator": "tcmalloc","environment": {"distmod": "ubuntu2004","distarch": "x86_64","target_arch": "x86_64"}
}

注意, 如果你使用了高本版的 MongoDB, 需要单独下载 MongoDB Shell 命令行客户端工具. 可以在这里下载 https://www.mongodb.com/try/download/shell.

接下来让我们看看如何在 MongoDB 中启用 TLS/SSL 通讯.

MongoDB 副本集中启用 TLS/SSL

让我们先看看怎么在副本集中启用 SSL/TLS.

  1. 第一步, 我们先使用 mkcert 生成待会 MongoDB 服务器 mongod 使用的证书
# 将 CA 证书存放在 mkcert 目录下
export CAROOT=$(pwd)/mkcert
# 安装 CA
mkcert -install
# 将证书和密钥合并, 后续 mongod 会使用到, 一般用来校验客户端使用的证书
cat mkcert/rootCA.pem mkcert/rootCA-key.pem > mkcert/CA.pem# 生成 mongod 使用的服务器证书, 这个证书在通信的时候会传递给客户端校验合法性
mkcert -cert-file mongo-tls.crt -key-file mongo-tls.key localhost 127.0.0.1 ::1
# 同样, 合并证书和密钥
cat mongo-tls.crt mongo-tls.key > mongo-tls.pem# 生成 mongo 客户端使用的证书, 这个证书后续不只用于客户端于服务器的通讯, 也用于副本集成员内部认证时使用
mkcert -client -cert-file mongo-tls-client.crt -key-file mongo-tls-client.key localhost 127.0.0.1 ::1
cat mongo-tls-client.crt mongo-tls-client.key > mongo-tls-client.pem
  1. 第二步, 我们使用上述生成的证书 pem 文件来启动副本集, 副本集各成员使用的配置文件如下:
❯ cat etc/primary.conf.yaml
replication:replSetName: mongo_replica_setstorage:dbPath: build/mongo_replica_set/mongodata_primary# where to write logging data.
systemLog:destination: filelogAppend: truepath: logs/mongo_replica_set_mongod_primary.logverbosity: 0# network interfaces
net:tls:mode: requireTLSCAFile: mkcert/CA.pemcertificateKeyFile: mongo-tls.pemclusterFile: mongo-tls-client.pem # https://www.mongodb.com/docs/manual/tutorial/configure-ssl/#member-certificate-requirementsallowConnectionsWithoutCertificates: trueport: 47017bindIp: 127.0.0.1,localhostcompression:compressors: zlib# how the process runs
processManagement:fork: truetimeZoneInfo: /usr/share/zoneinfo# Member x.509 Certificate
# https://www.mongodb.com/docs/manual/tutorial/configure-x509-member-authentication/
security:clusterAuthMode: x509
❯ cat etc/secondary_a.conf.yaml 
replication:replSetName: mongo_replica_setstorage:dbPath: build/mongo_replica_set/mongodata_secondary_a# where to write logging data.
systemLog:destination: filelogAppend: truepath: logs/mongo_replica_set_mongod_secondary_a.logverbosity: 0# network interfaces
net:tls:mode: requireTLSCAFile: mkcert/CA.pemcertificateKeyFile: mongo-tls.pemclusterFile: mongo-tls-client.pem # https://www.mongodb.com/docs/manual/tutorial/configure-ssl/#member-certificate-requirementsallowConnectionsWithoutCertificates: trueport: 47018bindIp: 127.0.0.1,localhostcompression:compressors: zlib# how the process runs
processManagement:fork: truetimeZoneInfo: /usr/share/zoneinfo# Member x.509 Certificate
# https://www.mongodb.com/docs/manual/tutorial/configure-x509-member-authentication/
security:clusterAuthMode: x509
❯ cat etc/secondary_b.conf.yaml
replication:replSetName: mongo_replica_setstorage:dbPath: build/mongo_replica_set/mongodata_secondary_b# where to write logging data.
systemLog:destination: filelogAppend: truepath: logs/mongo_replica_set_mongod_secondary_b.logverbosity: 0# network interfaces
net:tls:mode: requireTLSCAFile: mkcert/CA.pemcertificateKeyFile: mongo-tls.pemclusterFile: mongo-tls-client.pem # https://www.mongodb.com/docs/manual/tutorial/configure-ssl/#member-certificate-requirementsallowConnectionsWithoutCertificates: trueport: 47019bindIp: 127.0.0.1,localhostcompression:compressors: zlib# how the process runs
processManagement:fork: truetimeZoneInfo: /usr/share/zoneinfo# Member x.509 Certificate
# https://www.mongodb.com/docs/manual/tutorial/configure-x509-member-authentication/
security:clusterAuthMode: x509

其中主节点(primary)监听的地址为 127.0.0.1:47017, 从节点监听的地址为 127.0.0.1:47018127.0.0.1:47019. 这是典型的 PSS 架构部署的 MongoDB 副本集, 网络拓扑如下:

在这里插入图片描述

我们使用 mongod 启用上述配置文件, 注意配置文件中 certificate 相关字段引用到的 mkcert 生成的配置文件, mongod 启用命令如下:

mkdir logs
mkdir buildmongod --config "etc/primary.conf.yaml"
mongod --config "etc/secondary_a.conf.yaml"
mongod --config "etc/secondary_b.conf.yaml"# 初始化副本集
mongo --port 47017 --tls <<EOF
db.adminCommand({replSetInitiate: { _id: "mongo_replica_set", members: [{ _id: 0, host: "127.0.0.1:47017", priority: 2}, { _id: 1, host: "127.0.0.1:47018", priority: 1}, { _id: 2, host: "127.0.0.1:47019", priority: 1} ],settings: {electionTimeoutMillis: 3000}
}})
EOF

启动完成后, 我们使用 MongoDB Shell 命令客户端尝试连接主 (primary) 节点 127.0.0.1:47017, 命令如下:

❯ mongo --port 47017
MongoDB shell version v5.0.26
connecting to: mongodb://127.0.0.1:47017/?compressors=disabled&gssapiServiceName=mongodb
Error: network error while attempting to run command 'isMaster' on host '127.0.0.1:47017'  :
connect@src/mongo/shell/mongo.js:372:17
@(connect):2:6
exception: connect failed
exiting with code 1

会看到连接会失败, 这是因为 MongoDB 服务器强制开启了 TLS/SSL 通讯, 配置文件中相关字段如下:

net:tls:mode: requireTLS

这时候 mongo 客户端连接的使用需要走 TLS/SSL, 命令如下:

❯ mongo --port 47017 --tls
MongoDB shell version v5.0.26
connecting to: mongodb://127.0.0.1:47017/?compressors=disabled&gssapiServiceName=mongodb
{"t":{"$date":"2025-02-06T14:22:24.093Z"},"s":"I",  "c":"NETWORK",  "id":5490002, "ctx":"thread4","msg":"Started a new thread for the timer service"}
Implicit session: session { "id" : UUID("0a5698d1-81b5-4aee-800b-809da69baf58") }
MongoDB server version: 5.0.26
================
Warning: the "mongo" shell has been superseded by "mongosh",
which delivers improved usability and compatibility.The "mongo" shell has been deprecated and will be removed in
an upcoming release.
For installation instructions, see
https://docs.mongodb.com/mongodb-shell/install/
================
mongo_replica_set:PRIMARY>

可以看到我们能正常连接到副本集. 通过 tcpdump 能网络抓包工具, 我们可以看到通信流量是被加密过的. 接下来我们看看如何在 MongoDB 分片集群 (Sharding Cluster) 中启用 TLS/SSL.

MongoDB 分片集群中启用 TLS/SSL

接下来我们将本地部署的 MongoDB 分片集群拓扑大致如下, 其中两个 mongos、一个 config shard、一个数据分片 mongo shard a:

在这里插入图片描述

  1. 同样, 我们也需要生成 mongod、mongos、mongo 客户端使用的证书:
# 将 CA 证书存放在 mkcert 目录下
export CAROOT=$(pwd)/mkcert
# 安装 CA
mkcert -install
# 将证书和密钥合并, 后续 mongod 会使用到, 一般用来校验客户端使用的证书
cat mkcert/rootCA.pem mkcert/rootCA-key.pem > mkcert/CA.pem# 生成 mongod 使用的服务器证书, 这个证书在通信的时候会传递给客户端校验合法性
mkcert -cert-file mongo-tls.crt -key-file mongo-tls.key localhost 127.0.0.1 ::1
# 同样, 合并证书和密钥
cat mongo-tls.crt mongo-tls.key > mongo-tls.pem# 生成 mongo 客户端使用的证书, 这个证书后续不只用于客户端于服务器的通讯, 也用于副本集成员内部认证时使用
mkcert -client -cert-file mongo-tls-client.crt -key-file mongo-tls-client.key localhost 127.0.0.1 ::1
cat mongo-tls-client.crt mongo-tls-client.key > mongo-tls-client.pem
  1. 我们先启用 mongo config shard 集群配置分片, 一般用于存储集群的路由信息等数据, 主节点启动配置如下, clusterFile 字段指定了集群成员间内部认证使用的证书:
> cat etc/mongo_config_shard/mongo_cfg_primary.yaml
sharding:clusterRole: configsvrreplication:replSetName: config_shard_replstorage:dbPath: build/config_shard_repl/mongodata_primary# where to write logging data.
systemLog:destination: filelogAppend: truepath: logs/config_shard_repl_mongod_primary.logverbosity: 0# network interfaces
net:tls:mode: requireTLSCAFile: mkcert/CA.pemcertificateKeyFile: mongo-tls.pemclusterFile: mongo-tls-client.pem # https://www.mongodb.com/docs/manual/tutorial/configure-ssl/#member-certificate-requirementsallowConnectionsWithoutCertificates: trueport: 27017bindIp: localhost,127.0.0.1compression:compressors: zlib# how the process runs
processManagement:fork: truetimeZoneInfo: /usr/share/zoneinfo# https://www.mongodb.com/docs/manual/tutorial/configure-x509-member-authentication/
security:clusterAuthMode: x509

从节点使用的配置可以在这里看到: ShardingCluster/etc/mongo_config_shard, 启动命令如下:

mongod --config "etc/mongo_config_shard/mongo_cfg_primary.yaml"
mongod --config "etc/mongo_config_shard/mongo_cfg_secondary_a.yaml"
mongod --config "etc/mongo_config_shard/mongo_cfg_secondary_b.yaml"# 初始化副本集
mongo --port 27017 --tls <<EOF
db.adminCommand({replSetInitiate: { _id: "config_shard_repl", members: [{ _id: 0, host: "127.0.0.1:27017", priority: 2}, { _id: 1, host: "127.0.0.1:27018", priority: 1}, { _id: 2, host: "127.0.0.1:27019", priority: 1} ],settings: {electionTimeoutMillis: 3000}
}})
EOF
  1. 启动数据分片 (mongo shard a), 这个分片一般用于存储业务数据, 实际的生产使用会有多个, 主从节点配置文件可以在 ShardingCluster/etc/mongo_shard_a 中找到, 与配置分片的各节点配置除访问地址外大致相同, 各节点启用命令如下:
mongod --config "etc/mongo_shard_a/mongo_cfg_primary.yaml"
mongod --config "etc/mongo_shard_a/mongo_cfg_secondary_a.yaml"
mongod --config "etc/mongo_shard_a/mongo_cfg_secondary_b.yaml"# 初始化副本集
mongo --port 37017 --tls <<EOF
db.adminCommand({replSetInitiate: { _id: "shard_a_repl", members: [{ _id: 0, host: "127.0.0.1:37017", priority: 2}, { _id: 1, host: "127.0.0.1:37018", priority: 1}, { _id: 2, host: "127.0.0.1:37019", priority: 1} ],settings: {electionTimeoutMillis: 3000}
}})
EOF
  1. 接下来我们通过如下配置启动 mongos 路由器, mongo 客户端一般通过 mongos 访问业务数据, mongos 的启用配置如下:
❯ cat etc/mongos/mongos_a_cfg.yaml 
# network interfaces
net:tls:mode: requireTLSCAFile: mkcert/CA.pemcertificateKeyFile: mongo-tls.pemclusterFile: mongo-tls-client.pem # https://www.mongodb.com/docs/manual/tutorial/configure-ssl/#member-certificate-requirementsallowConnectionsWithoutCertificates: trueport: 27011bindIp: localhost,127.0.0.1
sharding:configDB: config_shard_repl/127.0.0.1:27017,127.0.0.1:27018,127.0.0.1:27019
systemLog:destination: filelogAppend: truepath: logs/mongos_a.logverbosity: 0# https://www.mongodb.com/docs/manual/tutorial/configure-x509-member-authentication/
security:clusterAuthMode: x509
❯ cat etc/mongos/mongos_b_cfg.yaml
# network interfaces
net:tls:mode: requireTLSCAFile: mkcert/CA.pemcertificateKeyFile: mongo-tls.pemclusterFile: mongo-tls-client.pem # https://www.mongodb.com/docs/manual/tutorial/configure-ssl/#member-certificate-requirementsallowConnectionsWithoutCertificates: trueport: 27012bindIp: localhost,127.0.0.1
sharding:configDB: config_shard_repl/127.0.0.1:27017,127.0.0.1:27018,127.0.0.1:27019
systemLog:destination: filelogAppend: truepath: logs/mongos_b.logverbosity: 0# https://www.mongodb.com/docs/manual/tutorial/configure-x509-member-authentication/
security:clusterAuthMode: x509

mongos 启动命令如下:

mongos --config "etc/mongos/mongos_a_cfg.yaml"
mongos --config "etc/mongos/mongos_b_cfg.yaml"# Cluster Member enable X503 authenticate, need auth access for db
mongo --port 27011 --tls <<EOF
use admin
db.createUser({user: "mongo_super_user",pwd: "mongo_super_user_pwd",roles: [{ role: "userAdminAnyDatabase", db: "admin" },{ role: "readWriteAnyDatabase", db: "admin" },{ role: "clusterAdmin", "db" : "admin" }]}
)
EOF# mongos 添加分片
mongo --port 27011 --tls --username mongo_super_user --password mongo_super_user_pwd <<EOF
sh.addShard( "shard_a_repl/127.0.0.1:37017,127.0.0.1:37018,127.0.0.1:37019")
EOF
mongo --port 27012 --tls --username mongo_super_user --password mongo_super_user_pwd <<EOF
sh.addShard( "shard_a_repl/127.0.0.1:37017,127.0.0.1:37018,127.0.0.1:37019")
EOF
  1. 待分片集群初始化完成后, 我们即可通过如下命令走 TLS/SSL 加密通讯访问分片集群数据:
mongo --port 27011 --tls --username mongo_super_user --password mongo_super_user_pwd <<EOF
show dbs;quit();
EOF

Good~

结语

好了, 相信你跟着本篇文章成功在本地环境部署了开启 TLS/SSL 加密通讯的副本集或者 MongoDB 分片集群, 我已经将相关配置文件整理到了 GitHub 仓库中方便你后续快速参考使用, 访问地址为: https://github.com/yeshan333/mongo-deployment-with-tls.

git clone git@github.com:yeshan333/mongo-deployment-with-tls.git
cd /mongo-deployment-with-tlsbash run.sh ReplicaSet

参考

  • MongoDB configure-ssl

本文由博客一文多发平台 OpenWrite 发布!


http://www.ppmy.cn/news/1571218.html

相关文章

计算机网络知识速记:TCP 与 UDP

计算机网络知识速记&#xff1a;TCP 与 UDP 一、概念 TCP (Transmission Control Protocol): 一个面向连接的协议&#xff0c;确保数据在传输过程中完整无误。通过建立连接和数据确认机制&#xff0c;提高数据传输的可靠性。是面向字节传输的。 UDP (User Datagram Protocol)…

Python3+Request+Pytest+Allure+Jenkins 接口自动化测试[手动写的和AI写的对比]

我手动写的参考 总篇:Python3+Request+Pytest+Allure+Jenkins接口自动化框架设计思路_jenkins python3+request-CSDN博客 https://blog.csdn.net/fen_fen/article/details/144269072 下面是AI写的:Python3+Request+Pytest+Allure+Jenkins 接口自动化测试[AI文章框架] 在软…

DeepSeek与人工智能的结合:探索搜索技术的未来

云边有个稻草人-CSDN博客 目录 引言 一、DeepSeek的技术背景 1.1 传统搜索引擎的局限性 1.2 深度学习在搜索中的优势 二、DeepSeek与人工智能的结合 2.1 自然语言处理&#xff08;NLP&#xff09; 示例代码&#xff1a;基于BERT的语义搜索 2.2 多模态搜索 示例代码&…

面试经典150题——字典树

文章目录 1、实现 Trie (前缀树)1.1 题目链接1.2 题目描述1.3 解题代码1.4 解题思路 2、添加与搜索单词 - 数据结构设计2.1 题目链接2.2 题目描述2.3 解题代码2.4 解题思路 3、单词搜索 II3.1 题目链接3.2 题目描述3.3 解题代码3.4 解题思路 对于字典树而言&#xff0c;之前做过…

C++ labmbd表达式

文章目录 C++ Lambda 表达式详解1. Lambda 表达式的组成部分:2. Lambda 语法示例(1) 最简单的 Lambda(2) 带参数的 Lambda(3) 指定返回类型的 Lambda3. 捕获外部变量(1) 值捕获(复制)(2) 引用捕获(3) 捕获所有变量4. Lambda 在 STL 中的应用5. Lambda 作为 `std::function`6…

web前端录制canvas视频和video的声音,并合并成一个文件进行下载

一、captureStream ‌captureStream‌是一个Web API方法&#xff0c;用于捕获指定元素的媒体流。该方法通常用于从<video>、<audio>或<canvas>元素中捕获实时视频流或音频流&#xff0c;以便进行进一步的处理&#xff0c;如直播、录制或分析‌。 captureStr…

Elasticsearch 7 集群搭建问题排查:常见故障解决方案与优化技巧

引言 Elasticsearch 作为一种强大的分布式搜索引擎,已被广泛应用于各种场景,特别是在日志聚合、数据分析等领域中。然而,在实际部署中,尤其是集群搭建阶段,许多用户都会遇到配置问题,导致集群无法成功建立。在本文中,我们将通过一个实际的案例,详细分析和排查 Elastic…

collabora online+nextcloud+mariadb在线文档协助

1、环境 龙蜥os 8.9 docker 2、安装docker dnf -y install dnf-plugins-core dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sed -i shttps://download.docker.comhttps://mirrors.tuna.tsinghua.edu.cn/docker-ce /etc/yum.repos.…