Nginx 防盗链中允许特定 IP 访问如何写

作者:袖梨 2026-08-17

Nginx中实现“防盗链+允许特定IP直连”的关键在于:用$allow_access变量综合判断referer合法性或IP是否在白名单,再通过return 403拦截未授权请求;需配合geo预处理IP、valid_referers设内置变量,并仅对静态资源location生效。

在 Nginx 中实现“防盗链 + 允许特定 IP 直接访问”,本质是:对 referer 做限制,但对指定 IP 地址豁免该限制。不能只靠 valid_referers,必须结合 if$remote_addr 判断,再用变量控制是否放行。

核心思路:用变量标记“是否允许”

先定义一个默认为拒绝的变量(如 $allow_access),然后根据条件(referer 合法 或 IP 在白名单)将其设为 1;最后在 location 中用 deny/allow 或返回状态码控制访问。

配置示例(推荐方式)

以下配置放在 serverlocation 块中:

# 定义白名单 IP(支持多个,用空格分隔)geo $white_ip {default 0;192.168.1.100 1;203.0.113.45 1;2001:db8::1 1; # 支持 IPv6}初始化访问权限变量

set $allow_access 0;

如果是白名单 IP,直接允许

if ($white_ip) { set $allow_access 1; }

如果 referer 合法(例如本站域名或空 referer),也允许

valid_referers none blocked server_names *.example.com example.com; if ($valid_referers) { set $allow_access 1; }

拒绝未被允许的请求(例如返回 403)

if ($allow_access = 0) { return 403; }

关键细节说明

  1. 不要在 if 中直接写 allow/deny:Nginx 的 allow/deny 不能放在 if 块里,否则会报错或行为异常;改用 return 403rewrite ... break 更可靠。
  2. valid_referers 必须在 if 之前声明:它本身不拦截请求,只是设置内置变量 $valid_referers,后续才能在 if 中判断。
  3. geo 指令比多次 if 判断 IP 更高效:尤其当白名单 IP 较多时,用 geo 预处理可避免重复字符串匹配。
  4. 注意空 referer 的处理:浏览器直接地址栏输入、HTTPS 页面引用 HTTP 资源等场景可能触发空 referer,若需允许,确保 valid_referers 包含 none

补充:仅对特定文件类型启用防盗链

把上述逻辑放在针对静态资源的 location 中,避免影响 API 或后台接口:

location ~* .(jpg|jpeg|png|gif|webp|pdf|zip|mp4)$ {# 上述 $allow_access 判断逻辑放在这里geo $white_ip { ... }set $allow_access 0;if (...) { ... }if ($allow_access = 0) {return 403;}}

相关文章

精彩推荐