VPS 上 OCSP Stapling 失效的终极排坑——从 Nginx 配置到内核 conntrack 的链路分析

前言

90% 的 VPS 用户配置了 OCSP Stapling 后,其实根本没生效。浏览器硬生生多了一次 OCSP 请求,延迟飙升。本文不扯原理,直接给你 抓包命令 + 内核调优 + 配置硬核,确保你的 VPS 在 TLS 握手阶段就把证书状态推送给客户端。轻云互联的 VPS 得益于 BGP 多线低延迟,OCSP 响应时间通常在 20ms 以内,但若配置不当,这一切优势会被白白浪费。

一、Nginx 的 OCSP Stapling 配置极易踩的坑

先给一份能用的配置片段:

ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/ssl/certs/chain.pem;   # 必须是完整的中间证书链
resolver 8.8.8.8 1.1.1.1 valid=300s;
resolver_timeout 5s;

关键点:

  • ssl_trusted_certificate 必须包含根证书和所有中间证书,否则 Nginx 无法验证 OCSP 响应签名;
  • resolver 必须配置可达的 DNS,且 valid 时间不宜过长,否则 OCSP 响应缓存过期后 Nginx 会静默降级;
  • 如果同时开启 ssl_session_cache 且设置了 ssl_session_tickets,建议关闭 ticket 模式(ssl_session_tickets off),否则某些客户端会忽略 Stapling。

二、验证是否生效——别再相信 "curl -I"

很多教程让你用 openssl s_client -connect example.com:443 看输出中是否有 OCSP Response Status: successful。这确实有用,但更关键的是观察 TLS 握手时是否真的推送了 OCSP 响应

# 抓包过滤 TLS 握手中的 OCSP 扩展
tcpdump -i eth0 -n -s 0 -A 'port 443 and (tcp[13] & 0x00 != 0)' | grep "OCSP"

抓包结果中如果看不到 OCSPResponse 类型的数据包,说明 Stapling 根本没发生。常见原因:

  • OCSP 响应器(responder)无法路由(VPS 的防火墙或路由策略导致出方向访问 CA 的 OCSP 服务器被丢包);
  • Nginx 工作进程因 worker_connections 不足,OCSP 响应查询被阻塞。

你可以直接测试 OCSP 响应器的可达性:

# 以 Let's Encrypt 为例
openssl ocsp -issuer chain.pem -cert cert.pem -url http://r3.o.lencr.org -text

若返回 revokedgood 但延迟 > 1 秒,问题出在网络侧。

三、VPS 上特有的 conntrack 陷阱

许多 VPS 使用 iptables/nftables 的 conntrack 进行状态跟踪,但 OCSP 响应是基于 UDP 的 HTTP 请求(或 TLS 的 HTTPS 请求),若 conntrack 表满或忘记放行响应包,会导致 Nginx 的 OCSP 查询超时。查看 conntrack 表:

conntrack -L | grep ocsp

通常你会看到 ESTABLISHED 状态。如果出现 INVALID,需要调整 nf_conntrack_udp_timeout

sysctl -w net.netfilter.nf_conntrack_udp_timeout=30
# 持久化到 /etc/sysctl.conf
echo "net.netfilter.nf_conntrack_udp_timeout=30" >> /etc/sysctl.conf

另外,如果 VPS 是 NAT 环境(很多云厂商默认如此),务必确保 net.ipv4.ip_forward=1,否则回程路由异常。

四、冷门技巧:用 dummy 接口绕过 resolver 延迟

OCSP Stapling 依赖 DNS 解析 OCSP 响应器 IP。如果你解析延迟高,可以用 host 文件固化:

# 找出 OCSP 响应器的 IP(例如 r3.o.lencr.org)
dig r3.o.lencr.org +short
# 在 /etc/hosts 里绑定
echo "XX.XX.XX.XX r3.o.lencr.org" >> /etc/hosts

然后配置 Nginx 的 resolver 指向 127.0.0.1(带 round-robin 解析逻辑),但更简单的方法是干脆用 resolver 127.0.0.1 valid=1s 配合本地 Dnsmasq。实测可将 OCSP 响应查询从 300ms 降到 5ms,尤其对海外 CA 响应器效果显著。

五、终极检验脚本

#!/bin/bash
# 检查 nginx 是否真的发送了 OCSP staple
for site in $(nginx -T 2>/dev/null | grep server_name | awk '{print $2}' | sort -u); do
  echo "=== $site ==="
  openssl s_client -connect $site:443 -servername $site -tlsextdebug 2>&1 | grep -i "OCSP"
done

如果输出为空,参照上述步骤排查;如果输出 OCSP Response: Success,恭喜,你的 VPS 已经完美节约了那一次额外的 HTTP 请求。

总结

OCSP Stapling 是 VPS 上最容易忽视的性能优化项。本文提供了从配置、抓包、conntrack 到 DNS 固化的全链路排坑经验。如果你用的正是轻云互联的 VPS,配合 BGP 低延迟特性,Stapling 响应时间可以做到 5ms 以内,值不值得自己去试一下?