启用 ssl_reject_handshake on 可在 tls 握手阶段拒绝未知 sni 请求,需置于 http 块顶层,配合精确 server_name 列表生效,不发证书、不留痕迹。

直接在 http 块中启用 ssl_reject_handshake on,配合严格限定的 server_name 列表,就能在 TLS 握手阶段拒绝未知 SNI 的连接,不发证书、不建连接、不留痕迹。
必须放在 http 上下文中全局开启
该指令不能写在单个 server 块里,也不支持用 if 条件判断。正确位置是 http 块顶层:
- 添加
ssl_reject_handshake on;一行即可生效,无需额外参数 - 它只对启用了 SSL 的
listen 443 sslserver 生效,不影响 HTTP 请求 - 一旦开启,所有未被
server_name显式匹配的 SNI 请求,都会收到unrecognized_nameTLS 告警并断连
每个 HTTPS server 必须明确列出合法域名
避免使用通配符或模糊匹配,否则会削弱防护效果:
- 写死生产使用的精确域名,例如
server_name example.com www.example.com; - 禁用
*.example.com这类泛域名,它会让所有子域都通过握手,失去拦截意义 - 不要保留“兜底 default_server”,Nginx 不再需要靠它响应未知请求
验证是否真正生效
用 OpenSSL 模拟探测,观察服务器是否拒绝握手而非返回证书:
- 执行:
openssl s_client -connect your.ip:443 -servername fake.test.com -tls1_2 - 成功防护时,输出中会出现
SSL routines::UNRECOGNIZED_NAME,且无Certificate:段 - 若仍看到证书信息或返回 200/444,说明配置未加载、未生效,或指令位置错误
搭配日志与防火墙增强可观测性
虽然握手被拒,但部分 SNI 信息仍可记录,便于分析攻击特征:
- 在
log_format中加入$ssl_server_name,能捕获客户端声称的域名 - 结合
limit_req对高频失败握手 IP 限速,防暴力枚举 - 不依赖 UA 或 IP 黑名单,从协议层切断信息泄露路径,更稳定可靠











