Referer 校验可以作为“静态资源防盗链”的轻量方案,但需了解其局限:Referer 可能不存在、被部分浏览器/代理隐藏或被伪造,因此仅适合作为“门槛”,不可作为安全逻辑的唯一依据。
关键指令
valid_referers: 定义哪些来源的 Referer 视为合法。可使用关键字:none:无 Referer(用户直接访问)blocked:Referer 头存在但被客户端或代理屏蔽server_names:当前服务自身的域名(来自server_name)具体主机名或通配:如
img.abc.com、*.trusted.com$invalid_referer: 由valid_referers计算的结果,非法为1。
推荐写法一:仅在静态资源上做防盗链
只针对图片/媒体资源做 Referer 校验,避免影响接口与页面。
非法Referer请求过来时, invalid_referer 值为1,就return 403。
server {
listen 80;
server_name img.abc.com;
# 静态资源根目录
root /var/www/img;
# 图片等资源防盗链
location ~* \.(png|jpg|jpeg|gif|webp|svg)$ {
# 允许:无/被屏蔽的 Referer、自身域名与指定白名单
valid_referers none blocked server_names *.baidu.com *.360.cn;
if ($invalid_referer) {
return 403;
# 或者返回占位图(外部重定向)
# return 302 https://cdn.abc.com/403.jpg;
# 或者内部改写到占位图(不改变浏览器地址)
# rewrite ^ /403.jpg last;
}
# 静态文件正常返回
try_files $uri =404;
}
}说明:
将校验放在资源型
location里,减少误伤。server_names自动兼容你的站点域名(含别名),无需手写本域名。白名单可用通配
*.domain或正则~*domain\.com。
推荐写法二:仅允许特定外站引用(白名单)
如果业务只允许指定外站引用你的资源,扩展白名单即可。
非法Referer请求过来时, invalid_referer 值为1,就return 403。
location ~* \.(mp4|mp3|m3u8)$ {
valid_referers none blocked server_names *.trustedpartner.com *.baidu.com *.360.cn;
if ($invalid_referer) { return 403; }
try_files $uri =404;
}推荐写法三:黑名单拦截特定来源(用 map 避免多层 if)
不建议同时维护白名单和黑名单,容易冲突。若确需黑名单,推荐在 http 级用 map。
当Referer为map范围内的值时, invalid_referer 值为1,就return 403。
http {
map $http_referer $is_bad_ref {
default 0;
~*baidu\.com 1; # 正则匹配
~*evil\.partner 1;
}
server {
server_name img.abc.com;
location ~* \.(png|jpg|jpeg|gif|webp|svg)$ {
if ($is_bad_ref) { return 403; }
# 仅黑名单拦截,不做白名单校验
# 如需白名单,请添加:
# valid_referers none blocked server_names;
# if ($invalid_referer) { return 403; }
try_files $uri =404;
}
}
}参考
官方文档:
valid_referers指令说明(允许none、blocked、server_names、通配域与正则)