在 nginx 中避免多站点串站的核心做法是确保每个 server 块拥有唯一且精确的 server_name,并配置一个无匹配条件的默认 server 块来拦截非法请求。当客户端请求的 host 头与任何配置的 server_name 都不匹配时,nginx 会将请求路由到该默认块,从而防止其落入其他站点的配置中。此外,必须显式设置 return 444 或 return 404 以拒绝这些未授权访问,而不是让它们静默失败或返回错误页面。

如何验证 server_name 的匹配优先级
Nginx 处理 server_name 遵循严格的优先级顺序:精确匹配最高,通配符次之,正则表达式最低。如果多个规则可能匹配同一个域名,Nginx 会选择优先级最高的那个。理解这一机制有助于排查为什么某个请求没有进入预期的站点。例如,如果同时存在 server_name www.example.com 和 server_name *.example.com,前者将优先被选中。这种确定性确保了只要配置得当,就不会出现因模糊匹配导致的串站。

server {
listen 80;
server_name exact.example.com;
return 200 'Exact Match';
}
server {
listen 80;
server_name *.example.com;
return 200 'Wildcard Match';
}
在上述配置中,请求 exact.example.com 会返回 'Exact Match',而 sub.example.com 会返回 'Wildcard Match'。这证明了精确匹配优于通配符。开发者应利用这一点,为关键域名设置精确匹配,以避免被更宽泛的通配符规则捕获。
如何处理未匹配的 Host 头以防止串站
为了防止 IP 直接访问或未知域名解析到服务器后暴露主站点内容,必须配置一个默认的 server 块。这个块通常监听所有端口(如 listen 80 default_server)且不包含任何 server_name 或包含 _。它的作用是作为“黑洞”,接收所有无法匹配到其他 server 块的请求。在这个块中,应返回 444 状态码(Nginx 特有,连接关闭)或 403/404,以明确拒绝访问。这样即使攻击者尝试通过 IP 或其他域名访问,也无法获取任何有效内容,从而彻底杜绝串站风险。

server {
listen 80 default_server;
server_name _;
return 444;
}
此配置确保所有非预期域名的请求都被立即断开连接。这是防御串站的最重要防线。在实际部署中,务必将此块放在配置文件的最前面或确保其优先级最高,因为 Nginx 按文件加载顺序处理 default_server 标记。结合精确的 server_name 配置,可以构建一个安全的多站点环境。
基于 server_name 冲突时的具体排查步骤
当出现串站问题时,最常见的原因是 server_name 配置重叠或默认块缺失。排查时应首先检查是否有多个 server 块定义了相同的域名。其次,确认是否存在 default_server 块来处理未匹配请求。可以使用 nginx -T 命令输出完整配置,然后使用 grep 搜索 server_name 和 default_server。如果发现重复定义,需合并或移除冗余配置。若缺少默认块,则添加上述 return 444 的配置。最后,重启 Nginx 并测试各个域名的访问情况,确保只有配置的域名能正常访问,其他均被拒绝。











