Nginx 通过 $ssl_client_s_dn 获取客户端证书DN字符串,需启用mTLS并完成验证;配合 map 和正则可提取CN等字段,透传至后端需注意编码与日志调试。
Nginx 可以通过
变量获取客户端证书的可分辨名称(Subject Distinguished Name),前提是已启用双向 TLS(mTLS)并成功完成客户端证书验证。这个变量是字符串格式,包含类似
的内容,需进一步解析才能提取具体字段(如 CN、OU、O 等)。
确保客户端证书验证已启用
仅配置
和
不足以让
生效;必须实际完成证书校验流程:
—— 指定受信任的 CA 证书(用于验证客户端证书签名)
—— 推荐设为
强制验证;设为
时,无证书请求仍继续,但变量为空
—— 根据客户端证书链深度合理设置(通常 1 或 2)
直接使用 $
ssl
_client_s_dn 传递身份信息
该变量在 SSL 握手完成后即可用,常用于透传给后端服务(如通过 HTTP Header):
—— 后端可通过该 header 获取完整 DN 字符串
—— PHP-FPM 场景下注入 CGI 变量
注意:DN 中可能含逗号、等号、空格或特殊字符(如 UTF-8),若需 URL 安全传输,建议用
(Nginx 1.19.4+ 支持)或自定义 map 编码
提取特定字段(如 CN)需借助 map 指令解析
Nginx 原生不提供 DN 字段切分函数,但可通过正则 +
提取常用项。例如提取 CN:
Nginx
在宝塔面板中轻松管理Nginx高性能Web服务器。提供可视化配置反向代理、负载均衡、SSL证书及HTTP缓存功能,一键优化高并发性能,助您高效搭建稳定、快速的网站运行环境。
下载
然后在 location 中使用:
正则注意大小写(
表示忽略大小写),匹配到第一个
即止;多个 CN(极少见)只取首个
类似可定义
(
)、
(
)等
若 DN 含引号或转义(如
),正则需增强:
,并合并捕获组逻辑
调试与常见问题
开发阶段建议开启日志确认变量值是否正确生成:
在 log_format 中加入
或
,例如:
若变量为空:检查证书是否被 CA 正确签名、客户端是否实际发送了证书、
是否为
或握手失败
若字段提取为空:用 log 输出原始
,确认格式是否符合正则预期(如字段顺序、分隔符、大小写、是否存在引号)
注意:
仅在 HTTPS server block 及其子 location 中有效;HTTP 块中该变量始终为空
$ssl_client_s_dnCN=alice,OU=dev,O=example.comssl_client_certificatessl_verify_client$ssl_client_s_dnssl_client_certificate /path/to/ca-bundle.crt;ssl_verify_client on | optional | optional_no_ca;onoptionalssl_verify_depth 2;proxy_set_header X-Client-DN $ssl_client_s_dn;fastcgi_param SSL_CLIENT_S_DN $ssl_client_s_dn;$ssl_client_s_dn_encodedmapmap $ssl_client_s_dn $client_cn {
~*CN=([^,;]+) $1;
default "";
}proxy_set_header X-Client-CN $client_cn;~*CN=xxx$client_ou~*OU=([^,;]+)$client_o~*O=([^,;]+)CN="Alice Doe"~*CN=(?:"([^"]+)"|([^,;"\]+))$ssl_client_s_dn$client_cnlog_format main '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$ssl_client_s_dn"';ssl_verify_clientoff$ssl_client_s_dn$ssl_client_s_dn