nginx 不支持客户端证书引脚(hpkp)校验,因 hpkp 已被主流浏览器弃用;应改用 ocsp stapling + 证书透明度(ct)+ 强 tls 策略,并通过双向 tls(mtls)实现客户端公钥级可信验证。

Nginx 本身不支持客户端证书引脚(Public Key Pinning)的主动校验,也不能在服务端对客户端公钥做“硬性绑定”式校验。但可通过两种互补路径强化身份真实性、阻断中间人攻击:一是启用 HTTP 公钥固定(HPKP)——已被主流浏览器弃用;二是改用更可靠、仍在广泛支持的 证书透明度(CT)日志 + OCSP Stapling + 强 TLS 策略组合,辅以客户端证书双向认证(mTLS)实现端到端可信链。关键不是“配置公钥引脚”,而是用当前有效机制替代它。
别再用 HPKP:已被淘汰且风险高
HTTP Public-Key-Pins(HPKP)曾允许网站声明哪些公钥可为自身签发证书,防止 CA 被入侵后误发证书。但因配置失误易导致站点“自锁”(如主备 pin 全失效即无法访问),Chrome、Firefox 等自 2018 年起已全面移除支持。Nginx 中即使写入 add_header Public-Key-Pins ...,现代浏览器也直接忽略。强行启用反而误导运维认知,增加维护负担。
用 OCSP Stapling + 证书透明度(CT)代替引脚逻辑
这是当前最务实的身份保障方案:让浏览器能快速、可信地验证证书是否被吊销,并确认该证书已在公开日志中备案,杜绝私下发证或伪造可能。
-
开启 OCSP Stapling:服务器主动向 CA 查询证书状态并缓存,随 TLS 握手一并发送给客户端,避免浏览器直连 OCSP 服务器造成延迟或隐私泄露
ssl_stapling on;<br> ssl_stapling_verify on;<br> ssl_trusted_certificate /etc/nginx/ssl/fullchain.pem; # 必须含完整信任链<br> resolver 8.8.8.8 1.1.1.1 valid=300s;
-
强制证书提交至 CT 日志:申请 Let’s Encrypt 或商业证书时,确保启用 CT(Certification Authority Authorization + Signed Certificate Timestamps)。Nginx 不直接配置 CT,但可通过响应头提示浏览器验证:
add_header Expect-CT "enforce, max-age=86400";
(虽非强制,但配合现代 CA 实际已默认满足)
真正可靠的“公钥级校验”:启用双向 TLS(mTLS)
当需要服务端严格校验客户端身份(例如内部 API、管理后台、设备接入),应部署双向 TLS。此时 Nginx 可加载 CA 证书,强制客户端提供由该 CA 签发的有效证书,并提取其公钥指纹用于访问控制或审计。
- 在 server 块中启用客户端证书验证:
ssl_client_certificate /etc/nginx/ssl/ca.crt; # 根 CA 证书<br> ssl_verify_client on; # 或 optional(按需校验)<br> ssl_verify_depth 2;
- 可进一步在 location 或 if 中提取客户端证书信息做策略判断:
if ($ssl_client_s_dn ~* "CN=trusted-device-[0-9]+") {<br> set $allowed "1";<br> }<br> if ($allowed != "1") { return 403; }
基础但不可少:TLS 协议与密钥交换加固
没有强 TLS 底层,任何上层校验都形同虚设。必须同步落实:
- 仅启用 TLSv1.2 和 TLSv1.3:
ssl_protocols TLSv1.2 TLSv1.3; - 禁用 RSA 密钥交换,强制 ECDHE 前向保密:
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:...'; - 隐藏服务器标识:
server_tokens off;防止暴露 Nginx 版本供针对性攻击











