—— AlmaLinux 9 + TLS 单向认证 + 账号密码认证版

(适用于生产环境,2025 最新实践)

只要求服务器 TLS 证书、客户端仅需用户名密码登录


集群拓扑

节点角色主机名IP 地址操作系统
PRIMARYmongo1192.168.6.111AlmaLinux 9
SECONDARYmongo2192.168.6.112AlmaLinux 9
SECONDARYmongo3192.168.6.113AlmaLinux 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
EOF

2️⃣ 安装 MongoDB

sudo dnf remove -y mongodb-org*  # 如有旧版本先卸载
sudo dnf clean all
sudo dnf install -y mongodb-org

3️⃣ 配置主机名解析

编辑 /etc/hosts:

192.168.6.111  mongo1
192.168.6.112  mongo2
192.168.6.113  mongo3

4️⃣ 创建证书存放目录

sudo mkdir -p /etc/mongodb/pki
sudo chown -R mongod:mongod /etc/mongodb/pki
sudo chmod 700 /etc/mongodb/pki

5️⃣ 防火墙与 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.key

2️⃣ 创建 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.key

3️⃣ 分发到其他节点

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.key

2️⃣ 启动并设置开机自启

sudo systemctl enable mongod --now

3️⃣ 初始化副本集(仅在 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.pem

2️⃣ 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