Nginx无法直接检测MITM,但可通过分析TLS握手失败、非标准密码套件、异常请求行为及证书透明度联动等日志指纹间接识别MITM尝试。

Nginx 本身不参与 TLS 证书信任链校验,无法直接确认客户端是否连到了真实服务器,因此不能“检测到正在发生的 MITM”。但它能记录 TLS 握手和请求过程中的大量可观察信号——这些信号一旦出现系统性异常,就是 MITM 尝试留下的关键指纹。
关注 TLS 握手失败的集中模式
MITM 工具(如 Evilginx、mitmproxy)在模拟目标站点时,常因证书配置不全、协议支持不一致或签名算法缺失,导致 TLS 握手中断。Nginx error_log 中高频出现以下错误需重点筛查:
- SSL routines::sslv3 alert bad certificate(客户端拒绝伪造证书)
- SSL routines::unknown protocol(ClientHello 协议版本/扩展不匹配)
- no suitable signature algorithm(服务端与中间代理支持的签名算法无交集)
若同一 IP 或 UA 在 1 分钟内对多个不同域名(如 login.example.com、api.example.com)反复触发同类错误,且这些域名本不该被同一终端并发访问,则高度提示该客户端正被中间代理劫持并尝试泛化转发。
提取并分析 TLS 协议与密码套件指纹
在 log_format 中加入 $ssl_protocol 和 $ssl_cipher 变量,构建带加密特征的日志格式:
log_format mitm '$remote_addr [$time_local] "$request" $status "$http_user_agent" "$ssl_protocol/$ssl_cipher" $request_time';
MITM 工具往往使用默认或老旧 TLS 配置,例如:
- 大量请求固定使用 TLSv1.2/ECDHE-RSA-AES128-GCM-SHA256(而真实用户流量中密码套件分布更离散)
- 缺失 ALPN 扩展或强制禁用 HTTP/2($http2 值恒为空)
- JA3 指纹(需 nginx-ssl-fingerprint 模块)集中于已知恶意工具哈希库(如 Evilginx v2 的 JA3 值为 771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513,0)
识别异常的请求行为组合
MITM 流量不是单纯“加密异常”,它常伴随 HTTP 层逻辑矛盾:
- 同一 IP 短时间内发起大量 400 Bad Request,且请求路径覆盖多个子域的登录页(如 /login、/auth、/sso),但无静态资源请求(CSS/JS/图片)
- User-Agent 显示现代浏览器(如 Chrome/124),却始终不携带 Sec-Fetch-* 头,或 Accept-Language 固定为 en-US(真实用户语言偏好有自然波动)
- 请求中 Host 头与 SNI 不一致(需通过 $ssl_server_name 和 $host 对比),或 $ssl_client_hello 中存在非标准扩展字段
联动 HSTS 与证书透明度做交叉验证
日志本身是被动证据,需配合主动机制提升可信度:
- 开启 HSTS(Strict-Transport-Security):若某客户端反复访问 HTTP 版本或忽略 HSTS 策略重定向,可能已被中间代理降级
- 启用 OCSP 装订:MITM 工具常无法正确响应 OCSP 查询,导致 $ssl_stapling 变量值为 “off” 或握手延迟显著升高
- 将 Nginx 日志接入证书透明度(CT)监控平台:若发现某 IP 频繁触发证书签发告警(如新证书匹配你的域名但 CA 非你授权),说明攻击者可能正在准备伪造证书











