Administrator
发布于 2025-11-05 / 5 阅读
0
0

Nginx Referer 校验与防盗链最佳实践

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;
    }
  }
}

参考


评论