要在 nginx 的 location 块中正确传递客户端真实 ssl 证书信息,需先启用客户端证书验证(ssl_client_certificate + ssl_verify_client),再通过 proxy_set_header 将 $sslclient* 变量映射为 http 头透传给后端,注意 $ssl_client_cert 需处理换行(推荐用 $ssl_client_raw_cert 或 lua),并确保仅在可信内网使用且防止头伪造。

要在 Nginx 的 location 块中正确传递客户端真实的 SSL 证书信息(例如用于后端服务做双向 TLS 认证或证书身份校验),关键不是“代理证书”,而是把客户端在 TLS 握手时提供的证书信息,以 HTTP 头形式安全地透传给上游服务。
启用客户端证书验证并提取证书字段
必须先在 server 或 location 级别开启 SSL 客户端认证,否则 Nginx 不会接收和解析客户端证书:
- 设置
ssl_client_certificate指向受信任的 CA 证书文件(用于验证客户端证书签名) - 启用
ssl_verify_client on(或optional,按需选择) - 使用
ssl_verify_depth控制证书链验证深度(通常设为 2 即可)
用内置变量映射证书信息到请求头
Nginx 提供了多个 $ssl_client_* 变量,可在 location 中通过 proxy_set_header 传递给后端:
-
proxy_set_header X-SSL-Client-Verify $ssl_client_verify;(值为 SUCCESS / FAILED / NONE) -
proxy_set_header X-SSL-Client-DN $ssl_client_s_dn;(客户端证书的完整可分辨名称,如CN=user,OU=dev,O=org) -
proxy_set_header X-SSL-Client-CN $ssl_client_s_dn_legacy;(兼容旧版,仅取 CN 部分;注意该变量已弃用,推荐用正则从$ssl_client_s_dn提取) -
proxy_set_header X-SSL-Client-Cert $ssl_client_cert;(Base64 编码的 PEM 格式证书,含换行符;需用map或lua清理换行为单行,否则 HTTP 头非法)
安全传递证书内容(避免头注入与格式错误)
直接使用 $ssl_client_cert 会因换行符导致 400 错误。推荐做法:
- 定义 map 块预处理证书(放在 http 块中):
map $ssl_client_cert $ssl_client_cert_base64 {<br> default ""; # 避免未认证时出错<br> "~^(?P<cert>.*)$" $cert;<br>}</cert>
再配合proxy_set_header X-SSL-Client-Cert $ssl_client_cert_base64;仍不可靠——更稳妥的是用 Lua 模块(如ngx_http_lua_module)做 Base64 行合并,或改用$ssl_client_raw_cert(Nginx 1.23.3+ 支持,返回无换行的 Base64) - 若后端只需识别身份,优先传
X-SSL-Client-DN或提取 CN/Email 字段,比传整证书更轻量、安全 - 确保后端服务校验这些头可信——它们由 Nginx 生成,但需防止外部伪造,因此务必只在内部可信网络中启用,并关闭 client 可写同名 header 的能力(如用
underscores_in_headers off+ 严格命名)
完整 location 示例(带基础校验与透传)
以下是一个最小可行配置片段:
location /api/ {<br> proxy_pass https://backend;<br> proxy_set_header Host $host;<br> proxy_set_header X-Real-IP $remote_addr;<br> proxy_set_header X-SSL-Client-Verify $ssl_client_verify;<br> proxy_set_header X-SSL-Client-DN $ssl_client_s_dn;<br> # Nginx ≥1.23.3 才可用:<br> proxy_set_header X-SSL-Client-Cert $ssl_client_raw_cert;<br> # 否则建议省略证书体,或用 Lua 处理<br>}- 注意:该 location 必须位于已配置
ssl_certificate、ssl_certificate_key且启用ssl_client_certificate的 server 块内











