—— AlmaLinux 9 + TLS 单向认证 + 账号密码认证版
(适用于生产环境,2025 最新实践)
只要求服务器 TLS 证书、客户端仅需用户名密码登录
集群拓扑
| 节点角色 | 主机名 | IP 地址 | 操作系统 |
|---|---|---|---|
| PRIMARY | mongo1 | 192.168.6.111 | AlmaLinux 9 |
| SECONDARY | mongo2 | 192.168.6.112 | AlmaLinux 9 |
| SECONDARY | mongo3 | 192.168.6.113 | AlmaLinux 9 |
副本集名称:test1
MongoDB 版本:8.2.x
认证方式:用户名 + 密码(SCRAM-SHA-256)
加密通信:TLS 单向认证(仅服务端证书)
🧩 阶段 0:基础环境准备(所有节点执行)
1️⃣ 添加 MongoDB Yum 源
sudo tee /etc/yum.repos.d/mongodb-org-8.2.repo <<EOF
[mongodb-org-8.2]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/9/mongodb-org/8.2/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://pgp.mongodb.com/server-8.0.asc
EOF2️⃣ 安装 MongoDB
sudo dnf remove -y mongodb-org* # 如有旧版本先卸载
sudo dnf clean all
sudo dnf install -y mongodb-org3️⃣ 配置主机名解析
编辑 /etc/hosts:
192.168.6.111 mongo1
192.168.6.112 mongo2
192.168.6.113 mongo34️⃣ 创建证书存放目录
sudo mkdir -p /etc/mongodb/pki
sudo chown -R mongod:mongod /etc/mongodb/pki
sudo chmod 700 /etc/mongodb/pki5️⃣ 防火墙与 SELinux 设置
sudo firewall-cmd --zone=public --add-port=27017/tcp --permanent
sudo firewall-cmd --reload
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config🧩 阶段 1:生成与分发安全凭证(仅在 mongo1 执行)
1️⃣ 生成内部认证 KeyFile
sudo openssl rand -base64 756 > /etc/mongodb/pki/mongodb.key
sudo chmod 400 /etc/mongodb/pki/mongodb.key
sudo chown mongod:mongod /etc/mongodb/pki/mongodb.key2️⃣ 创建 TLS 服务端证书(CA + Server)
cd /etc/mongodb/pki
# 创建 CA 根证书
openssl genrsa -out ca.key 4096
openssl req -x509 -new -key ca.key -days 3650 -out root.pem -subj "/C=CN/ST=Beijing/L=Beijing/O=TianhaoTech/CN=MongoCA"
# 创建服务器证书
openssl genrsa -out server.key 4096
openssl req -new -key server.key -out server.csr -subj "/C=CN/ST=Beijing/L=Beijing/O=TianhaoTech/CN=mongodb-cluster"
openssl x509 -req -in server.csr -CA root.pem -CAkey ca.key -CAcreateserial -out server.crt -days 3650 -extensions v3_req \
-extfile <(printf "[v3_req]\nsubjectAltName=DNS:mongo1,DNS:mongo2,DNS:mongo3,IP:192.168.6.111,IP:192.168.6.112,IP:192.168.6.113")
# 合并为 PEM
cat server.key server.crt > server.pem
# 设置权限
sudo chown mongod:mongod /etc/mongodb/pki/*
sudo chmod 600 /etc/mongodb/pki/*.pem
sudo chmod 400 /etc/mongodb/pki/ca.key3️⃣ 分发到其他节点
scp /etc/mongodb/pki/{mongodb.key,root.pem,server.pem} root@mongo2:/etc/mongodb/pki/
scp /etc/mongodb/pki/{mongodb.key,root.pem,server.pem} root@mongo3:/etc/mongodb/pki/
ssh root@mongo2 "chown -R mongod:mongod /etc/mongodb/pki && chmod 700 /etc/mongodb/pki"
ssh root@mongo3 "chown -R mongod:mongod /etc/mongodb/pki && chmod 700 /etc/mongodb/pki"🧩 阶段 2:配置与初始化副本集
1️⃣ 所有节点配置
/etc/mongod.conf
systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log
storage:
dbPath: /var/lib/mongo
journal:
enabled: true
net:
port: 27017
bindIp: 0.0.0.0
tls:
mode: requireTLS
certificateKeyFile: /etc/mongodb/pki/server.pem
CAFile: /etc/mongodb/pki/root.pem
allowConnectionsWithoutCertificates: true
replication:
replSetName: "test1"
security:
authorization: "enabled"
keyFile: /etc/mongodb/pki/mongodb.key2️⃣ 启动并设置开机自启
sudo systemctl enable mongod --now3️⃣ 初始化副本集(仅在 mongo1 上执行)
mongosh --host mongo1 --tls \
--tlsCAFile /etc/mongodb/pki/root.pem \
--tlsCertificateKeyFile /etc/mongodb/pki/server.pem在 mongosh 中执行:
rs.initiate({
_id: "test1",
members: [
{ _id: 0, host: "mongo1:27017" },
{ _id: 1, host: "mongo2:27017" },
{ _id: 2, host: "mongo3:27017" }
]
})等待状态为 PRIMARY:
rs.status()🧩 阶段 3:创建管理员用户
在 mongo1 (PRIMARY) 节点中执行:
use admin
db.createUser({
user: "admin",
pwd: passwordPrompt(),
roles: [ { role: "root", db: "admin" } ]
})
exit🧩 阶段 4:验证集群连接
1️⃣ 管理员验证
mongosh "mongodb://admin@mongo1:27017,mongo2:27017,mongo3:27017/admin?replicaSet=test1" \
--tls --tlsCAFile /etc/mongodb/pki/root.pem输入密码后执行:
rs.status()应看到 PRIMARY + 2 个 SECONDARY。
🧩 阶段 5:客户端连接方式(单向 TLS)
✅ 客户端仅需:
root.pem(CA 根证书)
用户名 + 密码
无需客户端证书(因为 allowConnectionsWithoutCertificates: true 已启用)
1️⃣ mongosh 命令示例
mongosh "mongodb://admin@mongo1:27017,mongo2:27017,mongo3:27017/admin?replicaSet=test1" \
--tls --tlsCAFile /path/to/root.pem2️⃣ Java 连接示例
String uri = "mongodb://admin:Hmsk@88..@mongo1:27017,mongo2:27017,mongo3:27017/admin?replicaSet=test1&tls=true&tlsCAFile=/path/to/root.pem";
MongoClient mongoClient = MongoClients.create(uri);✅ 验证通过后,你的最终安全体系是:
| 模块 | 认证机制 | 说明 |
|---|---|---|
| 副本集内部通信 | keyFile | 三节点自动同步认证 |
| 管理用户登录 | SCRAM-SHA-256 | 用户名密码 |
| 通信加密 | TLS 单向认证 | 客户端验证服务器证书 |
| 客户端证书 | ❌ 不需要 | 因为已启用 allowConnectionsWithoutCertificates: true |