nginx无法基于客户端实际tls版本做a/b分流,因$ssl_protocol在split_clients执行后才可用,且ssl_preread不暴露tls版本;推荐用$http2作为高置信度代理指标,结合cookie实现稳定分流。

Nginx 本身不直接解析或识别 TLS/SSL 协议版本(如 TLS 1.2、TLS 1.3),也无法在 HTTP 层获取加密握手阶段的协议信息。因此,无法基于客户端实际使用的 TLS 版本做流量分流或 A/B 测试。这是由网络分层模型决定的:TLS 握手发生在 TCP 之上、HTTP 之下,Nginx 的 HTTP 模块(包括 split_clients、map、if)在连接建立并完成解密后才处理请求,此时原始 TLS 版本已不可见。
为什么不能用 $ssl_protocol 或类似变量做 A/B 分流?
虽然 Nginx 提供了 $ssl_protocol 变量(需启用 HTTPS 并配置 SSL),但它反映的是Nginx 与客户端协商成功的 TLS 版本,仅在 ssl_preread 阶段不可用,且该变量只能用于日志记录、响应头或条件判断(如限流、拒绝低版本),不能用于 split_clients 的哈希输入——因为 split_clients 在请求解析前执行,而 $ssl_protocol 在 SSL 握手完成后才可用,二者生命周期不重叠。
常见误区:
- 试图在
http { split_clients "$ssl_protocol" $variant { ... } }中使用 —— 会报错或始终为空 - 在
stream块中用ssl_preread on读取 SNI,但ssl_preread不提供 TLS 版本字段(OpenSSL 和 Nginx 当前均未暴露该信息)
可行的替代路径:间接关联 TLS 版本特征
若业务强依赖“支持 TLS 1.3 的用户”作为实验人群,可通过以下稳定、可观测的代理指标逼近:
-
Client Hello 扩展指纹:TLS 1.3 客户端必然携带
supported_versions扩展,且通常伴随key_share、signature_algorithms_cert等特征。但 Nginx 无原生能力提取这些字段 -
User-Agent + 时间窗口组合:主流浏览器(Chrome 70+、Firefox 63+、Safari 12.1+)在启用 TLS 1.3 后,UA 字符串隐含支持能力。可构建 UA 映射表,用
map指令粗筛:map $http_user_agent $tls13_capable {<br> ~*Chrome/[7-9]\d|Edge/[8-9]\d|Firefox/[^1] | Safari/[^1] "1";<br> default "0";<br>} -
HTTP/2 使用状态:绝大多数 TLS 1.3 部署同时启用 HTTP/2(因 ALPN 协商强绑定)。Nginx 可通过
$http2变量准确识别:map $http2 $ab_group { "h2" "v2"; default "v1"; }—— 这是目前最可靠、零侵入的代理指标
推荐落地方案:HTTP/2 作为 TLS 1.3 流量代理标签
将 HTTP/2 连接视为 TLS 1.3 用户高置信度子集,配合 Cookie 实现稳定分流:
- 首次访问时,检查
$http2;若为"h2",设Set-Cookie: ab_group=v2; Path=/; Max-Age=604800 - 后续请求优先读
$cookie_ab_group,确保同一用户始终命中同一版本 - 后端路由示例:
upstream backend_v1 { server 10.0.1.10:3000; }<br>upstream backend_v2 { server 10.0.1.11:3000; }<br>map $cookie_ab_group $target_upstream {<br> default backend_v1;<br> "v2" backend_v2;<br>}<br>server {<br> location / { proxy_pass http://$target_upstream; }<br>}
进阶提醒:监控与验证必须跟上
仅靠分流逻辑不够,需确认实际效果:
- 在 access_log 中加入
$http2和$cookie_ab_group字段,统计 v2 组中 h2 连接占比(应 >95%) - 对比两组用户的首字节时间(TTFB)、错误率、JS 执行成功率,验证 TLS 1.3 带来的性能收益是否真实体现
- 避免将
$http2等同于“所有 TLS 1.3 用户”——部分旧设备或企业网关可能降级到 HTTP/1.1,但仍在用 TLS 1.3;不过该场景占比极低,对 A/B 结论影响可控











