最有效阻断域名嗅探的方式是在TLS握手阶段拦截非法请求,通过在http块顶层配置ssl_reject_handshake on,严格限定server_name并禁用通配符和default_server,使未匹配SNI的请求立即断连并触发UNRECOGNIZED_NAME告警。

直接在 TLS 握手阶段拦截非法请求,是阻断域名嗅探最有效的方式。关键不是等请求进入 HTTP 层再返回 444,而是在客户端刚发起 HTTPS 连接、还没发任何 HTTP 数据时就切断——ssl_reject_handshake 就是为此设计的指令。
明确配置位置:必须放在 http 块顶层
该指令不支持写在 server 块里,也不能用 if 判断或放在 stream 上下文。正确做法是在 nginx.conf 的 http { ... } 区域最上方添加:
ssl_reject_handshake on;- 它只对启用了
listen 443 ssl的 server 生效,不影响 HTTP 流量 - 启用后,所有未被
server_name显式匹配的 SNI 请求(比如 IP 直连、伪造域名、扫描器探测)都会触发UNRECOGNIZED_NAME告警并立即断连
每个 HTTPS 站点必须精确声明合法域名
防护效果取决于你是否严格限定可接受的 SNI 名称:
- 写死生产使用的完整域名,例如:
server_name example.com www.example.com api.example.com; - 禁用通配符:
*.example.com会让所有子域通过握手,等于主动开放探测面 - 不要保留“兜底 default_server”——它会覆盖 ssl_reject_handshake 的全局拦截逻辑
验证是否真正生效
别依赖浏览器访问 IP 看是否打不开,要观察 TLS 层行为:
- 执行:
openssl s_client -connect 1.2.3.4:443 -servername fake.test.com -tls1_2 - 成功拦截时,输出中应出现
SSL routines::UNRECOGNIZED_NAME,且无Certificate:段 - 若仍看到证书信息或返回 HTTP 状态码,说明配置未加载、指令位置错误,或存在带证书的 default_server 干扰
搭配日志增强可观测性
虽然握手被拒,但客户端声明的 SNI 仍可记录用于分析:
- 在
log_format中加入$ssl_server_name变量 - 配合
limit_req对高频失败握手的 IP 限速,防暴力枚举 - 注意:这不是靠 UA 或 IP 黑名单,而是从协议层切断信息泄露路径,更稳定可靠


















