侧边栏壁纸
博主头像
いちごみるく

行动起来,活在当下

  • 累计撰写 69 篇文章
  • 累计创建 47 个标签
  • 累计收到 55 条评论

目 录CONTENT

文章目录

Nginx 拒绝 IP 直接访问:default_server、444 与 TLS 握手拒绝

为网站配置域名后,直接访问服务器 IP 有时仍会显示网站内容。这通常是因为请求没有匹配任何 server_name,最终落到了该监听地址的默认虚拟主机上。

可以单独设置默认虚拟主机接住这类请求:HTTP 关闭连接,HTTPS 则在未匹配域名的 TLS 握手阶段拒绝。下面的配置适用于支持 ssl_reject_handshake 的 Nginx,最低版本为 1.19.4。

一、默认虚拟主机由 listen 决定

server_name _; 只是一个通常不会被正常域名匹配的名字,并不自动代表“所有域名”。负责兜底的是 listen 上的 default_server。

同一监听地址和端口只能设置一个默认虚拟主机。添加前先检查现有配置;Debian/Ubuntu 的默认站点文件、面板生成的站点配置都可能已经设置了它。相关选择顺序见 Nginx 请求处理文档。

二、添加 HTTP 和 HTTPS 兜底配置

把下面两个 server 块放在 Nginx 的 http 上下文中,例如已由 nginx.conf 引入的站点配置文件:

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;

    return 444;
}

server {
    listen 443 ssl default_server;
    listen [::]:443 ssl default_server;
    server_name _;

    ssl_reject_handshake on;
    return 444;
}

如果系统没有启用 IPv6,去掉两个 [::] 监听。若实际网站只监听某个指定 IP,需要为对应的地址、端口设置默认虚拟主机,而不是只复制通配地址配置。

HTTP 部分应使用 return 444,不是 return 0。444 是 Nginx 的特殊处理:关闭连接而不向客户端发送 HTTP 响应头。浏览器或 curl 因此可能显示空响应,而不是一个内容为“444”的网页。return 指令说明对此有明确规定。

HTTPS 部分使用 ssl_reject_handshake on,无需给这个拒绝握手的默认块随意配置一张证书。TLS 握手发生在 HTTP 请求之前,单纯的 return 444 无法替代握手拒绝。ssl_reject_handshake 文档给出了同样的默认主机用法。

正常域名站点继续保留自己的 server_name、证书、静态目录或反向代理配置。不要把 ssl_reject_handshake on 加到需要正常访问的域名站点里。

三、检查并重新加载

sudo nginx -t

确认检查成功后,再重新加载:

sudo systemctl reload nginx

如果报 duplicate default server,先处理同一监听地址上的重复配置;如果报不认识 ssl_reject_handshake,检查实际运行的 Nginx 版本,而不是继续添加证书来掩盖问题。

四、同时验证拒绝与正常访问

以下 203.0.113.10 和 www.example.com 均为占位值,替换成自己的服务器 IP 与正常站点域名。

直接请求 IP:

curl -v http://203.0.113.10/
curl -vk https://203.0.113.10/

预期前者连接关闭、不返回网站页面,后者 TLS 握手失败。第二条命令的 -k 仅用于排查证书校验因素,它不会让被服务端拒绝的握手成功。

再验证正常域名。使用 --resolve 可以绕过 DNS 解析,仍以正确域名发送 Host 和 TLS SNI:

curl -I --resolve www.example.com:80:203.0.113.10 http://www.example.com/
curl -I --resolve www.example.com:443:203.0.113.10 https://www.example.com/

此时应进入正常网站,得到站点原本的响应或跳转。只测“IP 打不开”不够,还要确认正常域名没有一起被拒绝。

五、这项配置的边界

它处理的是未匹配的 Host/SNI,不是按来源 IP 做访问控制。知道正确域名的客户端仍能连接服务器 IP,并携带正确的 Host/SNI 访问网站,前面的 --resolve 测试正好展示了这一点。

如果目标是让源站只接受 CDN 或特定客户端的连接,还需要单独设置网络访问策略。这里的默认虚拟主机只负责避免把普通 IP 访问和未匹配域名请求交给真实站点。

0

评论区