纯靠Nginx的valid_referers指令无法实现自动更新白名单,因其不支持动态读取外部文件或变量;但可通过外部脚本定时拉取域名、生成合法valid_referers配置并重载Nginx来实现。

纯靠 Nginx 的 valid_referers 指令无法实现“自动更新白名单”,因为它不支持动态读取外部文件或变量,所有域名必须在配置加载时静态写死。但可以通过外部脚本 + Nginx 重载机制,实现合作域名白名单的定期自动更新。
核心思路:用外部文件托管域名列表,脚本生成配置片段
Nginx 本身不解析变量或执行命令,但支持 include 指令引入外部配置文件。因此可将白名单域名单独存为一个文本文件(如 /etc/nginx/conf.d/trusted-domains.conf),再由脚本定时拉取最新域名、生成合法的 valid_referers 行,最后重载 Nginx。
- 脚本需输出格式严格匹配 Nginx 语法,例如:
valid_referers none blocked example.com *.partner-a.com https://partner-b.net ~\.cdn\-trusted\.org$; - 避免在生成内容中遗漏
none blocked—— 否则会误拦直接访问、微信内嵌页等无 Referer 场景 - 域名含特殊字符(如连字符、点号)需注意正则转义;通配符
*.domain.com不自动包含domain.com,若需主域也得显式列出
脚本示例(bash)与执行逻辑
以下是一个最小可行脚本框架,假设合作方域名通过 HTTP 接口返回纯文本列表(每行一个域名):
- 用
curl -s https://api.example.com/trusted-domains获取最新域名列表 - 过滤空行、注释行,对每个域名做基础校验(如是否含协议、是否为合法域名格式)
- 拼接成一行
valid_referers指令,写入/etc/nginx/conf.d/trusted-domains.conf - 执行
nginx -t && nginx -s reload验证并生效(失败时不重载)
配置中如何引用该白名单
在你的图片资源 location 块里,不再硬编码域名,而是 include 外部文件:
location ~* \.(jpg|jpeg|png|webp|gif|ico)$ {
include /etc/nginx/conf.d/trusted-domains.conf;
if ($invalid_referer) {
return 403;
}
}
注意:include 必须放在 if 之前,且被包含文件里只允许出现 valid_referers 指令(不能含 if 或其他指令)。
安全与稳定性注意事项
- 脚本运行用户需有写入
/etc/nginx/conf.d/和执行nginx -s reload的权限(建议用sudo限定仅这两个命令) - 务必在脚本中加入
nginx -t校验步骤,防止非法域名导致配置错误、服务中断 - 合作方接口不可达时,脚本应保留上一次成功生成的文件,避免清空白名单造成大面积拦截
- 不建议将此机制用于高敏感资源(如付费图片),因 Referer 可伪造,仅作为带宽防护层,关键鉴权仍需后端签名或登录态校验











