MongoDB在启用TLS/SSL加密通信后,一旦服务端证书超过有效期,客户端连接就会立即中断并抛出错误。其中故障码1170是与SSL证书验证失败直接相关的错误,典型场景就是证书已经过期,客户端在校验服务端证书链时发现有效期不合法,从而拒绝建立连接。这个问题看似简单,但在副本集和分片集群中处理起来有讲究,直接换证书可能导致集群内部通信中断,下面结合实际运维经验详细展开。

一、错误码1170的现象与产生原因
错误码1170通常出现在客户端日志或应用日志中,报错信息一般包含类似The server certificate is expired或SSL peer certificate validation failed的描述。此时无论使用mongosh、旧版mongo shell还是各类驱动程序连接,都会失败。部分客户端可能显示为通用的连接超时,需要打开verbose日志才能看到真正的1170错误。
产生这个错误的根本原因是X.509证书中的notAfter字段所标记的到期时间已经过去。MongoDB服务端在启动时加载证书,只要进程不重启,即使证书过期,服务端仍会继续使用旧证书运行,此时客户端主动校验证书有效期就会失败。这就造成一个容易迷惑的现象:服务端日志看起来一切正常,replication也在工作,但新客户端就是连不上。
还有一种情况是中间CA证书过期。服务端叶子证书本身还有效,但签发它的中间CA过期了,客户端在构建信任链时同样会校验失败,报的也是1170。排查时务必检查整条证书链,而不仅仅是叶子证书。
二、如何确认证书是否真的过期
第一步是查看服务端证书文件的有效期。可以使用openssl工具直接读取PEM格式证书的起止时间:
# 查看证书的起止日期 openssl x509 -in /etc/ssl/mongodb/server.crt -noout -dates # 输出示例: # notBefore=Jan 1 08:00:00 2024 GMT # notAfter=Dec 31 08:00:00 2025 GMT # 查看完整信息包括颁发者 openssl x509 -in /etc/ssl/mongodb/server.crt -noout -subject -issuer -dates
除了直接查看文件,还可以通过端口在线探测。即使证书过期,MongoDB的TLS握手仍会返回证书内容,用s_client连接27017端口即可:
echo | openssl s_client -connect 127.0.0.1:27017 \ -showcerts 2>/dev/null | openssl x509 -noout -dates
如果两处时间一致且确实超过了notAfter时间,就可以确认是证书过期。建议同时检查CA证书文件,确认中间证书链的每一级都在有效期内。对于集群部署,还要逐台检查成员证书,因为各节点证书的申请时间可能不同,到期时间也会错开。
三、更换证书并恢复连接的完整步骤
确认证书过期后,需要生成或申请新证书。如果使用的是CA签发的证书,流程是向CA重新申请并下载新的PEM文件;如果是内部PKI,可以用现有CA重新签发;如果是自签名证书,则需要重新生成。下面以自签名证书为例演示完整过程:
# 生成新的私钥 openssl genrsa -out mongodb.key 2048 # 生成证书签名请求 openssl req -new -key mongodb.key -out mongodb.csr \ -subj "/CN=mongodb.ippipp.com/O=MyOrg" # 用自建CA签发证书,有效期365天 openssl x509 -req -in mongodb.csr \ -CA /etc/ssl/mongodb/ca.crt \ -CAkey /etc/ssl/mongodb/ca.key \ -CAcreateserial \ -out mongodb.crt -days 365 # 合并私钥和证书为MongoDB要求的PEM文件 cat mongodb.crt mongodb.key > /etc/ssl/mongodb/mongodb.pem
拿到新的PEM文件后,修改mongod或mongos配置文件中的证书路径(如果文件名没变则无需修改),然后重启服务:
# 重启前先校验新证书与私钥是否匹配 openssl x509 -noout -modulus -in mongodb.crt | openssl md5 openssl rsa -noout -modulus -in mongodb.key | openssl md5 # 两个MD5值必须一致,否则mongod会启动失败 systemctl restart mongod
需要注意,重启副本集成员时要逐台操作,确保主节点最后处理,避免触发不必要的选举。重启完成后,用mongosh带TLS参数验证连接是否恢复:
mongosh "mongodb://mongodb.ippipp.com:27017" \ --tls \ --tlsCAFile /etc/ssl/mongodb/ca.crt \ --tlsCertificateKeyFile /etc/ssl/mongodb/client.pem
四、副本集滚动更新证书的避坑要点
副本集环境不能简单粗暴地一次性替换所有节点证书。正确做法是滚动更新:先把新旧证书合并成一个PEM文件分发到所有成员,逐台重启使集群同时接受新旧证书,最后再分发只含新证书的文件并逐台重启。这样集群内部通信在任何时刻都不断裂。
具体操作时,第一步将新旧两个证书和私钥合并为一个临时PEM:
# 合并新证书与旧证书,过渡期使用 cat new-server.crt new-server.key old-server.crt old-server.key \ > /etc/ssl/mongodb/mongodb-transitional.pem
第二步逐台将配置指向这个过渡文件并重启。全部成员重启完毕后,集群已经同时信任新旧证书。第三步再把配置切换回只含新证书的PEM文件,同样逐台重启。整个过程中可以用rs.status()观察成员健康状态,确保每次只操作一台。
另外要提醒一点:如果使用的是成员间X.509集群认证,证书中的clusterAuthExpr相关DN字段必须保持一致,否则成员间认证会失败。新证书的Subject DN要与旧证书匹配,或者提前调整security.clusterAuthX509相关配置。
五、预防措施与自动化监控建议
证书过期问题的最好处理方式是提前发现。建议部署定时监控,在证书到期前30天和7天分别触发告警。可以用一个简单的shell脚本配合crontab实现:
#!/bin/bash CERT="/etc/ssl/mongodb/mongodb.pem" EXPIRE_DATE=$(echo | openssl s_client -connect 127.0.0.1:27017 2>/dev/null \ | openssl x509 -noout -enddate | cut -d= -f2) EXPIRE_TS=$(date -d "$EXPIRE_DATE" +%s) NOW_TS=$(date +%s) DAYS_LEFT=$(( (EXPIRE_TS - NOW_TS) / 86400 )) if [ $DAYS_LEFT -lt 30 ]; then echo "警告:MongoDB证书剩余 $DAYS_LEFt 天" | mail -s "证书即将过期" ops@ippipp.com fi
对于使用内部CA的团队,更彻底的方案是搭建自动签发与轮换流程,例如结合HashiCorp Vault或cert-manager统一管理证书生命周期,将续期动作自动化。同时建议在运维文档中记录每个MongoDB集群的证书到期时间,纳入变更管理台账,避免因人员交接导致证书无人知晓、无人续期的情况再次发生。
MongoDB 1170SSL证书过期MongoDB连接失败修改时间:2026-09-08 23:49:00