Nginx防盗链通过valid_referers指令结合正则匹配多域名白名单,支持子域、多顶级域、端口及DNS规范校验,并推荐精确匹配与正则组合提升安全与性能。

Nginx 防盗链中用正则表达式匹配多域名白名单,核心是通过 valid_referers 指令结合正则语法,精准放行指定来源域名,同时拦截非法引用。这不是简单“允许几个域名”,而是要让 Nginx 正确识别并信任一组结构各异的合法 Referer(比如 example.com、shop.example.org、blog-v2.test.cn),同时拒绝其他所有来源。
以下分三类实用场景说明:
正则匹配多级子域与不同顶级域(推荐写法)
适用于白名单含多个主域或复杂子域结构,例如允许 a.com、b.net、api.x.org、docs.y.co.uk:
location ~ \.(jpg|jpeg|png|gif|webp)$ {
valid_referers none blocked ~^https?://([a-zA-Z0-9.-]+\.)?(a\.com|b\.net|x\.org|y\.co\.uk)(:[0-9]+)?(/|$);
if ($invalid_referer) {
return 403;
# 或返回自定义图片:rewrite ^(.*)$ /static/forbidden.png break;
}
}说明:
-
~^https?://匹配http://或https://开头 -
([a-zA-Z0-9.-]+\.)?可选匹配任意一级或多级子域(如api.、cdn.static.) -
(a\.com|b\.net|x\.org|y\.co\.uk)是白名单主域列表,需转义点号 -
(:[0-9]+)?允许带端口(如测试环境:8080) -
(/|$)确保域名后接/或结尾,防误匹配(如避免bad.comx.org被x.org错误命中)
正则提取并校验子域名前缀(用于动态授权)
适合 SaaS 多租户场景,只允许 tenant1.app.io、demo2.app.io 这类固定主域下的子域:
location ~ \.(mp4|pdf|zip)$ {
valid_referers ~^https?://([a-z0-9][a-z0-9\-]{1,61}[a-z0-9]\.)+app\.io($|/);
if ($invalid_referer) {
return 403;
}
}说明:
-
([a-z0-9][a-z0-9\-]{1,61}[a-z0-9]\.)+严格匹配符合 DNS 规范的子域名段(支持连字符、长度限制) -
app\.io是固定主域,确保不会匹配到evil-app.io - 不捕获变量也可,若后续需记录来源,可加命名捕获组:
~^https?://(?<tenant>[^.]+)\.app\.io($|/)
组合精确 + 正则提升可靠性(生产建议)
避免纯正则覆盖过宽,把高频、确定的域名优先用精确或通配符声明:
valid_referers
none
blocked
example.com www.example.com
*.myshop.cn
~^https?://([a-z0-9]+\.)?service-(dev|staging)\.com($|/)
~^https?://(admin|portal)\.cloud-[0-9]{2}\.org($|/);说明:
-
none:允许空 Referer(直接访问图片) -
blocked:拦截被篡改或无效协议的 Referer(如ftp://) - 显式列出
example.com和www.example.com,比正则更快更安全 -
*.myshop.cn覆盖所有一级子域,比等效正则性能更好 - 后续正则专注处理带数字/环境标识的特殊模式
注意要点:
-
valid_referers必须写在location块内,且仅对当前 location 生效 - 正则必须以
~(区分大小写)或~*(忽略大小写)开头,后者更稳妥 - 测试时用 curl 模拟 Referer:
curl -H "Referer: https://test.example.com" https://yoursite.com/photo.jpg - 若开启日志,可加
log_format referer_log '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"';辅助排查
不复杂但容易忽略。


















