ssl双向认证(mtls)本质是客户端与服务端互相出示并验证数字证书,需同时准备服务端证书+私钥、客户端证书+私钥及ca根证书(pem格式),nginx配置须含ssl_certificate、ssl_certificate_key、ssl_client_certificate、ssl_verify_client on等指令,并确保权限、路径与证书链正确。

SSL 双向认证(mTLS)本质是让客户端和服务端互相出示并验证数字证书,不是只靠服务端“亮证”,而是双方都得“验身份”。配置本身不难,但容易卡在证书格式、路径权限或关键参数漏设上。
证书准备:三样东西缺一不可
必须准备好三类文件,且全部为 PEM 格式:
-
服务端证书 + 私钥:如
server.crt和server.key,由可信 CA 签发,含正确的subjectAltName(DNS 或 IP); -
客户端证书 + 私钥:如
client.crt和client.key,也必须由同一 CA(或其子 CA)签发; -
CA 根证书:即
ca.crt,仅含公钥,不含私钥,用于校验客户端证书签名——Nginx、MongoDB、brpc 等都靠它做信任锚点。
注意:客户端证书建议带 extendedKeyUsage = clientAuth,服务端证书必须带 serverAuth;自签名场景下,CA 证书要同时提供给服务端和客户端使用。
Nginx 反向代理配置要点
在 server 块中加入以下指令:
-
ssl_certificate /path/to/server.crt;和ssl_certificate_key /path/to/server.key;—— 加载服务端身份凭证; -
ssl_client_certificate /path/to/ca.crt;—— 指定用来验证客户端证书的根 CA; -
ssl_verify_client on;—— 强制校验,生产环境不能用optional; -
ssl_verify_depth 1;—— 一般设为 1,除非用了多级中间 CA; - 如需透传信息给后端,加:
proxy_set_header X-Client-Verify $ssl_client_verify;和proxy_set_header X-Client-DN $ssl_client_s_dn;。
验证前确认:所有证书文件权限为 600 或 644(私钥必须 600),Nginx 用户有读取权限,且证书链完整(无缺失中间证书)。
MongoDB 启用 mTLS 的关键陷阱
别只设 sslMode: requireSSL —— 这只是加密通道,不校验客户端证书。真正启用双向认证必须同时满足:
-
sslMode: requireSSL(开启 TLS); -
net.ssl.allowConnectionsWithoutCertificates: false(拒绝无证书连接); - 若用副本集,
net.ssl.clusterFile必须单独提供,内容是该节点的私钥 + 证书(不能混用对外证书); - 客户端连接时必须指定
--sslCAFile ca.pem,否则报unable to get local issuer certificate。
服务端证书必须含完整 subjectAltName(所有可访问域名/IP),客户端证书虽不强制 SAN,但建议加上,便于后续按 subjectName 绑定角色。
通用调试建议
配置完先做三件事:
- 用
openssl s_client -connect host:port -cert client.crt -key client.key -CAfile ca.crt手动测试握手是否成功; - 检查服务日志是否有
SSL_do_handshake failed或certificate verify failed类错误; - 确认客户端证书是否被吊销(如需 CRL 支持,Nginx 要配
ssl_crl,MongoDB 需额外部署 OCSP 响应器)。
只要证书可信、路径正确、参数到位,mTLS 就能稳稳跑起来。它不复杂,但每一步都得对得上。











