nginx 默认证书实为兜底配置,核心是安全拦截而非提供服务;应优先用 default_server + return 444 或 ssl_reject_handshake on 实现零信任防护,禁用泛域名与默认证书响应。

在 Nginx 中,所谓“默认证书”并不是一个官方术语,而是指为 未匹配任何显式 server_name 的 HTTPS 请求 提供响应的兜底配置。它的核心目的不是提供服务,而是安全拦截——比如拒绝非法域名探测、防止证书信息泄露、阻断恶意 SNI 扫描。真正有效的做法不是“配一个能用的默认证书”,而是用协议层控制 + 精确匹配 + 主动拒绝来实现零信任防护。
明确拒绝未匹配域名:用 default_server + return 444
这是最常用且兼容性最好的方式,适用于所有 Nginx 版本(包括不支持 ssl_reject_handshake 的旧版):
- 在
http块中,单独定义一个监听 443 的 default_server,放在所有其他server块之前或之后均可,但必须显式声明default_server -
server_name _;表示匹配任意未声明的域名 -
ssl_certificate和ssl_certificate_key必须填写(哪怕用自签临时证书),否则 Nginx 启动会报错或导致全部 HTTPS 失效 - 使用
return 444;—— 这是 Nginx 特有状态码,表示直接关闭连接,不返回任何 HTTP 响应体,比 403/443 更隐蔽
示例配置:
server {
listen 443 ssl default_server;
server_name _;
ssl_certificate /etc/nginx/ssl/fallback.crt;
ssl_certificate_key /etc/nginx/ssl/fallback.key;
return 444;
}
更彻底的协议层拦截:启用 ssl_reject_handshake(推荐新环境)
如果你使用的是 Nginx 1.19.4+(2026 年主流版本均已支持),这才是真正意义上的“零握手暴露”方案:
- 只需在
http块顶层添加一行:ssl_reject_handshake on; - 它不依赖任何证书,也不建立 TLS 连接,而是在 Client Hello 阶段就检查 SNI 域名是否在任一
server的server_name列表中 - 未匹配时,直接发送
unrecognized_nameTLS 警告并断连,客户端看不到证书、收不到 HTTP 响应,日志里也无完整请求记录 - 每个合法 HTTPS server 必须写死精确域名,例如
server_name example.com www.example.com;,禁用*.example.com - 不要保留任何
default_server,否则会绕过该机制
辅助验证与可观测性:确认拦截是否真生效
光配对不行,得验证它真的在起作用:
- 用 OpenSSL 模拟非法 SNI 请求:
openssl s_client -connect your.ip:443 -servername fake.test.com -tls1_2 - 成功拦截时,输出中应出现
SSL routines::UNRECOGNIZED_NAME,且没有Certificate:段落 - 若看到证书内容、或返回 403/444/200,说明配置未加载、位置错误(如写在 server 块里)、或被泛域名/默认 server 覆盖
- 在
log_format中加入$ssl_server_name,可记录每次 TLS 握手声称的域名,便于分析扫描特征
别踩这些坑
常见配置失误会直接让防护失效:
- 把
ssl_reject_handshake on写进某个server块里 → 无效,必须在http块顶层 - HTTPS server 使用
server_name *.example.com→ 所有子域都通过握手,失去拦截意义 - 留着一个带证书的
default_server→ 它会响应所有未匹配域名,等于主动“认领”非法请求 - 只在 80 端口做
return 301或if ($host != ...)→ 对 HTTPS 探测完全无效,攻击者直连 443 - 忽略证书路径权限或格式错误 → 导致 Nginx 启动失败,整个 HTTPS 服务瘫痪











