nginx 不提供 $ssl_cipher_extensions 变量,该变量不存在于任何稳定版本中;真实可用的 tls 相关变量包括 $ssl_cipher、$ssl_ciphers、$ssl_protocol、$ssl_server_name 等,可用于间接推断客户端 tls 能力。

Nginx 不提供 $ssl_cipher_extensions 这个变量,它并不存在于官方文档或任何稳定版本的 Nginx(包括 1.25.x、1.26.x 及主线最新版)中。
你可能混淆了以下真实存在的、但用途完全不同的变量:
-
$ssl_cipher:✅ 实际协商成功的加密套件名称,如ECDHE-ECDSA-AES128-GCM-SHA256 -
$ssl_ciphers:✅ 客户端在 ClientHello 中声明支持的全部套件列表(以冒号分隔的长字符串,可能被截断) -
$ssl_protocol:✅ 实际使用的 TLS 协议版本,如TLSv1.2 -
$ssl_server_name:✅ SNI 域名(若客户端发送) -
$ssl_curves/$ssl_ecdh_curve:✅ 客户端支持的椭圆曲线列表或服务端选定的曲线
⚠️ 没有 $ssl_cipher_extensions、$ssl_extension_* 或类似命名的内置变量。Nginx 不解析或暴露 TLS 扩展字段(如 ALPN、supported_groups、signature_algorithms、key_share 等)为日志变量。
如果你想通过 Nginx 间接推断客户端特性,可依赖以下真实变量组合分析:
1. 用 $ssl_ciphers 推断客户端 TLS 能力和年代
该变量记录客户端 ClientHello 中发送的完整套件列表(OpenSSL 格式),从中可反推:
- 是否支持 TLS 1.3(含
TLS_AES_128_GCM_SHA256等 IANA 命名套件) - 是否支持 ECDHE(含
ECDHE-前缀)→ 判断前向保密能力 - 是否含
CHACHA20→ 暗示移动设备或旧 OpenSSL(如 Android 4.4、BoringSSL) - 是否仅含
RSA-套件(无 ECDHE/DHE)→ 极可能是 WinXP IE6、Java 6、老旧嵌入式设备
示例日志片段(需开启
log_format ... $ssl_ciphers):"ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:CHACHA20-POLY1305-SHA256"
⚠️ 注意:
$ssl_ciphers值极长,Nginx 默认可能截断(受large_client_header_buffers影响),且仅在 HTTPS 请求中非空。
2. 结合 $ssl_protocol + $ssl_cipher + $http_user_agent 交叉验证
- 若
$ssl_protocol是TLSv1.3,但$ssl_cipher显示TLS_AES_256_GCM_SHA384→ 客户端现代(Chrome/Firefox/Edge 110+) - 若
$ssl_protocol是TLSv1.2,但$ssl_cipher是ECDHE-RSA-RC4-SHA→ 客户端老旧且配置危险(应拦截) - 若
$http_user_agent含Mozilla/5.0 (Windows NT 5.1)且$ssl_ciphers无ECDHE→ 基本锁定为 WinXP + IE6/7
3. 用 $ssl_server_name 和 $scheme 辅助判断客户端是否支持 SNI
- HTTP/1.1 请求中
$scheme为https,但$ssl_server_name为空 → 客户端未发 SNI(如 OpenSSL
替代方案:真正获取 TLS 扩展信息(需外部工具)
若必须分析 ALPN、supported_groups、early_data、psk_key_exchange_modes 等扩展:
- 使用
tshark或tcpdump抓包,配合openssl s_client -debug解析 ClientHello - 部署 Envoy / Traefik / HAProxy(它们部分支持导出扩展字段)
- 在 Nginx 前加一层支持 TLS inspection 的代理(如 mitmproxy,仅限测试环境)
Nginx 本身定位是高性能 Web 服务器/反向代理,不是 TLS 协议分析器——它只做必要协商,不暴露底层握手细节。
不复杂但容易忽略。











