关键在于统一决策入口+避免本地状态依赖:用geo模块集中定义白名单变量供所有server共享,或下沉至后端服务动态校验Referer,确保集群策略一致。

在多实例 Nginx 集群中保持防盗链白名单策略一致,关键不在“同步配置文件”,而在于**统一决策入口 + 避免本地状态依赖**。防盗链本质是校验 Referer 请求头是否合法,若每个节点各自维护白名单(如用 valid_referers 硬编码),极易因更新不同步、版本差异或漏配导致策略失效。
用 geo 模块集中管理 Referer 白名单
将白名单域名抽象为变量,在 http 块顶层定义,所有 server 实例共享同一套逻辑:
- 在
nginx.conf的http块中统一声明:
default 0;
~*\.example\.com 1;
~*\.admin\.site 1;
localhost 1;
127.0.0.1 1;
}
- 各实例的
location中复用该变量,无需重复写域名列表:
if ($valid_referer = 0) { return 403; }
# 正常提供静态资源
}
这样新增一个白名单域名,只需改一处 geo 定义,reload 所有节点即可生效,无遗漏风险。
通过上游服务动态校验 Referer(推荐用于复杂场景)
当白名单需频繁变更、含业务逻辑(如按用户角色放行)或需与数据库联动时,不建议在 Nginx 层硬编码。可将 Referer 校验下沉到后端统一鉴权服务:
- Nginx 在请求头中透传
$http_referer到后端(如 viaproxy_set_header X-Referer $http_referer;) - 后端服务根据自身规则判断 Referer 是否合法,返回
200或403 - 所有 Nginx 实例配置完全一致,策略完全由后端控制,集群天然一致
避免常见陷阱
-
别用 if + valid_referers 混搭:Nginx 的
valid_referers是独立指令,和if块中的$invalid_referer变量耦合紧密,分散配置易出错;应统一用geo或统一走后端 -
禁用空 Referer 要谨慎:部分合法请求(如直接输入 URL、HTTPS 页面跳转到 HTTP 资源)可能不带 Referer,若白名单中未显式包含
none,会导致误拦 -
CDN 或反向代理后需确认 Referer 可达:若前端有 CDN,确保其未过滤或覆盖
Referer头;必要时用proxy_set_header Referer $http_referer;显式透传


















