在 nginx 日志中记录 ja3 指纹是 tls 层反爬审计最轻量可控的方式,需借助 nginx-ssl-ja3 模块或 openresty 提取 $stream_ssl_ja3 变量,结合自定义 log_format 落地日志,并通过日志分析、redis 实时比对及多维度校验实现风控联动。

直接在 Nginx 日志里记录 JA3 指纹,是实现 TLS 层反爬审计最轻量、最可控的方式之一。它不依赖后端解析,也不需要改业务代码,所有识别逻辑集中在接入层,日志本身就能成为风控策略的原始依据。
启用 ssl_preread 并暴露 JA3 变量
Nginx 原生不提供 JA3 字段,必须借助扩展模块或 OpenResty 生态。推荐使用 nginx-ssl-ja3 模块(已适配 OpenSSL 3.x 和 Nginx 1.25+),编译安装后即可通过内置变量获取指纹:
- $http_ssl_ja3:用于 HTTP 上下文(需配合 ssl_preread on + stream 转发)
- $stream_ssl_ja3:用于 stream 上下文,更贴近原始 Client Hello,推荐用于纯 TLS 指纹采集
- 若用 OpenResty,可搭配
lua-resty-ja3在 access_by_lua_block 中提取并写入 log_format 变量
定义含 JA3 的自定义日志格式
在 http 或 stream 块中声明日志格式,把 JA3 指纹作为固定字段嵌入。例如:
注意:$stream_ssl_ja3 在 stream 上下文中才有效;若用在 http 块,需确保请求已由 stream 服务预处理并透传变量(常见于四层代理模式)。
将 JA3 日志落地并用于分析
日志不是记完就完,关键在后续可查、可筛、可联动:
- 用 rsyslog 或 filebeat 实时采集,打标
type: nginx_tls_ja3,便于 Elasticsearch 聚类 - 对
$stream_ssl_ja3值做去重统计,快速发现高频异常指纹(如 requests 默认栈、headless Chrome 固定哈希) - 结合
$remote_addr和$stream_ssl_ja3做联合画像:同一 IP 出现 3 种以上 JA3 指纹,大概率是代理池混用或工具链切换 - 导出 TOP100 异常 JA3 到 Redis,供 Nginx 的 lua-resty-redis 实时比对,触发
return 403
规避浏览器扩展干扰与指纹漂移
真实用户也会用插件、隐私模式或不同终端访问,JA3 并非绝对唯一。部署时需留出合理容错:
- Chrome 124/125/126 的 JA3 差异主要在扩展顺序,启用模块编译参数
--with-cc-opt='-DJA3_SORT_EXT'可强制排序,提升跨版本一致性 - 避免仅靠 JA3 单一维度封禁,建议组合
$http_user_agent(验证是否匹配)、$http_accept(是否含 text/html)、$server_protocol(是否为 HTTP/2)做复合判断 - 对已知合规客户端(如企业内网爬虫、监控探针),可在日志中加
via "internal-bot"标识,方便白名单过滤











