nginx通过valid_referers预设白名单并结合$invalid_referer变量,在if中对图片请求做判断,非法referer时用rewrite重定向至提示图;推荐使用break+internal方式内部重写,并配置internal location托管提示图,确保安全且不暴露路径。

Nginx 通过 rewrite 实现防盗链图片重定向,核心是判断请求头中的 Referer 是否来自合法域名,不合法则用 rewrite 将图片请求重定向到指定提示图(如“禁止盗链”水印图)或返回 403。这不是单纯屏蔽,而是“重定向替代”,用户体验更友好。
1. 判断 Referer 并匹配非法来源
Nginx 不支持直接在 rewrite 中写正则判断 referer,需先用 valid_referers 指令预设白名单,再通过内置变量 $invalid_referer(值为 "1" 表示非法)做条件分支:
-
valid_referers none blocked server_names *.example.com;→ 允许无 referer(直接访问)、合法域名(含子域)、以及被防火墙清空 referer 的情况;blocked指 referer 被中间代理篡改或加密导致无法解析的场景也纳入放行范围(可选) -
$invalid_referer是布尔型变量:合法时为空字符串,非法时为 "1"
2. 使用 if + rewrite 实现图片重定向
在 location 块中针对图片后缀(如 .jpg/.png/.gif)做判断,仅对非法 referer 的图片请求执行重定向:
location ~* \.(jpg|jpeg|png|gif|webp)$ {
valid_referers none blocked *.example.com;
if ($invalid_referer) {
rewrite ^/.*$ /images/hotlink-denied.png redirect;
# 或用 break + internal 重写为内部路径(推荐,避免暴露真实路径)
# rewrite ^/.*$ /images/hotlink-denied.png break;
# internal;
}
}
-
redirect:返回 302 临时重定向,浏览器地址栏会跳转到提示图 URL —— 简单但暴露提示图路径 -
break+internal:内部重写,不改变浏览器 URL,且只允许 internal location 访问该提示图,更安全 - 务必把
valid_referers放在if外层,否则每次请求都重复校验,影响性能
3. 配置 internal 提示图 location(推荐方式)
配合上一步的 break,定义一个仅限内部访问的 location,托管防盗链提示图:
location /images/hotlink-denied.png {
internal; # 禁止外部直接访问
alias /var/www/static/images/hotlink-denied.png;
}
-
alias必须指向真实文件路径,注意末尾斜杠与root的区别 - 若用
root,写法为:root /var/www/static;,则请求/images/xxx会映射到/var/www/static/images/xxx - 确保该图片已存在、Nginx 有读取权限,且 MIME 类型能被正确识别(通常无需额外配置)
4. 注意事项与常见问题
实际部署时容易忽略的关键点:
-
HTTPS 站点 referer 可能被浏览器策略清空:部分浏览器在 HTTPS→HTTP 跳转时丢弃 referer,建议全站 HTTPS,并在
valid_referers中保留none -
if在 location 中使用是安全的,但在 server 级别慎用(可能引发非预期行为) - 移动端 App 或某些客户端可能不带 referer,若业务允许直接访问图片,应加入
none白名单 - 测试时用 curl 模拟非法 referer:
curl -H "Referer: https://evil.com" https://yoursite.com/photo.jpg











