在 Nginx 中,访问域名控制的核心机制是通过 server_name 指令匹配请求的 Host 头部,从而实现虚拟主机隔离与权限管理。当客户端请求到达时,Nginx 根据 $host 或 $http_host 变量选择对应的 server 块,未匹配的请求会被转发到默认 server(通常为 listen 指令中指定的 default_server)。这是最基础的域名控制方式,也是所有高级访问控制的基础。

对于更精细的访问控制,可以利用 allow 与 deny 指令结合 $host 变量实现基于域名的 IP 白名单或黑名单。例如,在 location 块中编写 if ($host !~* ^(example\.com|www\.example\.com)$) { return 403; },可以拒绝非授权域名的所有请求。但需注意,频繁使用 if 可能带来性能隐患,官方文档建议优先使用 map 模块进行变量映射。
更专业且高效的做法是使用 ngx_http_map_module 模块。通过 map $host 创建一个映射变量,将其设置为“allowed”或“denied”,然后在 location 中根据该变量执行 deny all 或 allow all。例如:map $host $domain_access { default 0; example.com 1; www.example.com 1; },随后在 location 中使用 if ($domain_access = 0) { return 403; }。这种方式避免了在请求处理过程中重复进行正则匹配,性能显著优于 if 直接判断。
此外,ngx_http_geo_module 模块也可以与域名控制结合使用。通过 geo $allowed_domain { default no; example.com yes; } 定义地理化(此处为域名)访问策略,再配合 if ($allowed_domain = no) { return 403; }。这种方法适合大规模规则集,因为 geo 模块在启动时预编译哈希表,查找速度极快。
对于跨域请求(CORS)场景下的域名控制,需要处理 Origin 头部而非 Host。通常的做法是在 location 中使用 if ($http_origin ~* ^(https?://(www\.)?example\.com)$) { add_header Access-Control-Allow-Origin "$http_origin"; },并配合 Access-Control-Allow-Credentials 等头部。值得注意的是,if 在 location 中的使用应谨慎,CORS 控制更推荐使用 map 与 add_header 组合:map $http_origin $cors_origin { default ""; ~^https?://(www\.)?example\.com$ $http_origin; } 然后在 location 中 add_header Access-Control-Allow-Origin $cors_origin;,这样对非授权域名不会输出该头部。
在 Nginx 反向代理场景下,域名控制还涉及 proxy_pass 与 proxy_set_header Host $host 的配合。通过修改转发时的 Host 头部,可以实现“域名劫持”或“域名重写”,但此操作属于后端路由控制,而非访问控制。真正的访问控制应始终在 Nginx 的 http、server 或 location 上下文完成。
最佳实践包括:第一,优先使用 map 或 geo 模块替代 if,以保证处理效率与可维护性;第二,所有未匹配的请求应在默认 server 中直接 return 444(关闭连接)或返回 403/404,防止信息泄露;第三,对于敏感域名,建议在 http 块中启用 server_tokens off 隐藏版本号;第四,结合 access_log 记录 $host 变量,便于审计与故障排查。通过以上专业配置,Nginx 能够实现高效、安全的域名级访问控制。

查看详情

查看详情