nginx虚拟主机启用双向认证的关键在于server块内完整配置ssl参数:必须监听443 ssl、配置ssl_certificate与key、ssl_client_certificate指向可信ca、ssl_verify_client on,并设置ssl_verify_depth;各server块可独立控制,互不影响。

Virtual Host(虚拟主机)本身不决定是否启用双向认证,真正起作用的是该 server 块内的 SSL 配置。只要在某个 server 块中正确配置了证书、客户端验证参数和信任根,这个虚拟主机就支持双向认证——和其他 server 块互不影响。
确保 Virtual Host 启用 HTTPS 并监听 443
双向认证必须基于 HTTPS,所以虚拟主机必须明确监听 443 端口并启用 SSL:
- 不能只写
listen 80;或未启用 ssl 的 443 监听 - 推荐写法:
listen 443 ssl http2;(http2 可选但建议) -
server_name要与客户端证书中的 Common Name(CN)或 SAN 匹配,否则部分客户端(如浏览器)会拒绝提交证书
为该 Virtual Host 单独配置双向认证参数
每个 server 块可独立控制是否要求客户端证书。只需在对应块内加入以下核心指令:
-
ssl_verify_client on;—— 强制客户端提供有效证书 -
ssl_client_certificate /path/to/ca-bundle.crt;—— 指向你信任的根证书或中间证书链(PEM 格式),用于验证客户端证书签名 -
ssl_verify_depth 2;—— 设置证书链验证深度,一般 2 级足够(根 → 中间 → 客户端) - 配套基础 HTTPS 配置不能少:包括
ssl_certificate(服务端证书)、ssl_certificate_key(服务端私钥)
区分不同 Virtual Host 的认证策略
你可以让一个域名(如 api.example.com)强制双向认证,另一个(如 www.example.com)仅单向 HTTPS:
- 两个 server 块分别定义,各自指定
server_name - 只有需要双向认证的块才加
ssl_verify_client on和ssl_client_certificate - 不需要的块保持默认单向配置即可,互不干扰
错误处理与日志辅助
客户端没证书或证书无效时,默认返回 HTTP 495(SSL certificate error)或 496(SSL certificate required)。建议显式拦截并返回清晰提示:
error_page 495 496 = @ssl_error;location @ssl_error { return 403 "Client certificate is missing or invalid."; }- 开启
ssl_log_level warn;(在 http 或 server 块中)有助于排查握手失败原因











