在 Nginx 中,如果客户端请求的域名未在 server_name 指定的配置中匹配,Nginx 仍然会将请求转发到默认的 server 块。为了防止非 server_name 配置的域名访问,可以使用以下几种方法:
方法 1:使用默认 server 块拦截未匹配的域名
在 Nginx 配置文件中(通常是 /etc/nginx/nginx.conf 或 /etc/nginx/conf.d/default.conf),添加一个默认的 server 块,只允许 server_name 明确配置的域名访问,其他所有未匹配的域名都返回 444(直接断开连接)。
| |
解释
listen 80 default_server;:表示该server块是默认的服务器,所有未匹配的请求都会进入这里。server_name _;:这个_是一个通配符,表示未匹配的任何域名都会进入该server块。return 444;:返回 444 状态码,直接断开连接,不给客户端任何响应,提高安全性。
方法 2:使用 if 语句在特定 server 块中拦截
如果不想使用默认 server 块,也可以在你的业务 server 块中检查 Host 头,拒绝非指定域名的访问。
| |
解释
if ($host !~* ^(example\.com|www\.example\.com)$):检查Host头,如果不符合example.com或www.example.com,则返回403 Forbidden。return 403;:拒绝访问。
⚠️ 注意:Nginx 官方不推荐 if 语句用于控制访问,但在简单场景下可以使用。
方法 3:监听特定 IP,限制非指定域名访问
如果服务器有多个 IP,可以让 Nginx 只监听特定 IP,并通过 server_name 控制。
| |
方法 4:针对 HTTPS 限制非 server_name 访问
如果使用 HTTPS,并且不希望未配置的域名访问你的服务器,可以使用以下方式:
| |
解释
- 让
default_server处理所有未匹配的域名。 - 使用一个默认的 SSL 证书(可以是一个无效或自签名证书)。
- 直接返回
444,防止服务器暴露给未授权的访问者。
如何生成自签名 SSL 证书?
| |
总结
如果希望完全禁止未配置 server_name 的域名访问,推荐使用 方法 1(默认 server 块拦截)或 方法 3(监听特定 IP),它们是 Nginx 官方推荐的方式,性能最好,配置最清晰。
如果有更复杂的需求(如某些域名返回 403,其他域名正常访问),可以使用 方法 2(if 语句检查 $host)。对于 HTTPS,使用 方法 4 结合默认 server 块。