nginx防盗链最实用方式是valid_referers+$invalid_referer+if+return 403,仅防懒盗链;防伪造需用secure_link模块,但多数发行版默认不带,且须编译启用;valid_referers仅在server或location块生效,不可写在http顶层。

云原生边缘节点中,Nginx 配置防盗链(如 valid_referers)时若发现规则失效、日志里所有请求都显示为同一个内网 IP,大概率不是防盗链写错了,而是真实客户端 IP 在转发链路中被覆盖或未透传——这会直接导致 $http_referer 虽然可用,但 $remote_addr 已失真,进而让基于 IP 的限流、白名单、甚至某些 referer 校验逻辑(比如限制“仅允许来自某 IP 段的 referer”)误判。
确认是否真丢了真实 IP
先别改配置,快速验证问题根源:
- 在 Nginx 日志格式中临时加入
$http_x_forwarded_for和$http_x_real_ip字段,例如:
log_format debug '$remote_addr - $http_x_real_ip - $http_x_forwarded_for - "$request" $status'; - 触发一次请求,查看 access.log 输出。如果
$remote_addr是 10.x.x.x 或 127.0.0.1,而$http_x_forwarded_for有类似203.208.60.1, 10.10.20.5的多段值,说明上游已传 XFF,但 Nginx 自身没识别;如果连 XFF 都为空,则问题出在更前端(如 Service Mesh Sidecar、Ingress Controller 或 CDN 回源配置)。
检查边缘节点特有的代理层级
云原生边缘常含多级代理:CDN → Kubernetes Ingress(如 Nginx Ingress Controller)→ 边缘 Pod 内 Nginx → 后端服务。每一跳都可能覆盖或清空头信息:
- 确认 Ingress Controller 是否已启用
use-forwarded-headers: "true"(Helm values 或 ConfigMap),否则它不会把 XFF/X-Real-IP 透给下游 Pod; - 检查边缘 Nginx 所在 Pod 的入口流量是否经过云厂商 SLB 或 WAF,这些组件默认只传 XFF,不传 X-Real-IP,且可能伪造或截断头字段;
- 用
curl -H "X-Forwarded-For: 1.1.1.1" http://your-edge-ip手动测试,看日志中是否能捕获该值——若能,说明 Nginx 接收头没问题,问题在上游未加;若不能,检查是否有underscores_in_headers on;缺失(某些云环境 header 含下划线会被丢弃)。
修复 Nginx 本层的 realip 解析
仅设置 proxy_set_header 不够,边缘节点必须主动“信任并解析”传入的头,否则 $remote_addr 永远是连接发起方(如 kube-proxy 或 sidecar 的 IP):
- 在
http块中启用 realip 模块(确认已编译:nginx -V 2>&1 | grep -o http_realip); - 明确声明可信代理段,例如:
set_real_ip_from 10.0.0.0/8;
set_real_ip_from 192.168.0.0/16;
set_real_ip_from 172.16.0.0/12;
real_ip_header X-Real-IP;
real_ip_recursive on;
注意:若上游用的是 X-Forwarded-For,就把real_ip_header改成X-Forwarded-For,但务必配合real_ip_recursive on,否则多级代理下会取到倒数第二个 IP; - 确保这些指令放在
http或server块顶层,不在某个location内——realip 是连接建立阶段解析的,location 级无效。
防盗链配置需适配 IP 来源变更
修复真实 IP 后,原有防盗链逻辑可能仍异常,因为 valid_referers 本身不依赖 IP,但你很可能在配套规则中混用了 IP 判断:
- 避免在
if ($remote_addr = xxx) { ... }中硬编码判断——现在$remote_addr已是真实 IP,但若未启用 realip,它还是代理 IP; - 若需结合 referer 和 IP 做双重校验(如“仅允许来自 A 域名且 B 地区的请求”),应统一读
$http_x_real_ip或启用 realip 后的$remote_addr,不要混用; - 检查
valid_referers是否用了none或blocked,某些边缘网关会主动过滤空 referer,导致合法请求被拒,此时应加none并配合 UA 或 IP 白名单兜底。











