最实用的防盗链方式是在Nginx中配置valid_referers并启用含$invalid_referer和$http_referer的自定义日志格式,结合set_real_ip_from获取真实IP,再通过awk分析theft_access.log筛选高频盗链IP,最后用fail2ban自动封禁。

直接在 Nginx 中配置防盗链并同步记录可疑请求的完整 IP 信息,是定位盗链源头最实用的方式。关键不在于只拦住盗链,而在于“拦得清楚、记得到位、查得明白”。
防盗链配置要带日志标记
默认的 valid_referers + if ($invalid_referer) 只会拦截,但不会区分哪些是真实盗链、哪些是误触发(比如微信内嵌浏览器、某些 RSS 阅读器会清空 Referer)。你需要让日志明确标出这类请求:
- 在
http块中定义一个自定义日志格式,加入$invalid_referer和$http_referer字段:
log_format theft '$remote_addr - $remote_user [$time_local] "$request" '
'"$status" $body_bytes_sent "$http_referer" "$http_user_agent" '
'"$invalid_referer"'; - 在对应
server或location块中启用该格式,并确保access_log指向独立文件(避免和主日志混在一起):
access_log /var/log/nginx/theft_access.log theft; - 保留原
valid_referers规则,但建议显式允许空 Referer(none)和自身域名:
valid_referers none blocked *.example.com example.com;
重点:让盗链请求可追溯到真实 IP
很多盗链来自代理、CDN 或微信/QQ 内置浏览器,它们可能把真实用户 IP 藏在 X-Forwarded-For 或 X-Real-IP 头里。如果 Nginx 前面有反向代理(如 Cloudflare、SLB),必须提前获取真实 IP,否则日志里全是代理节点地址:
- 在
http块顶部添加:
set_real_ip_from 103.21.244.0/22; # Cloudflare IPv4 段示例
set_real_ip_from 2405:b500::/32; # Cloudflare IPv6 段
real_ip_header X-Forwarded-For;
real_ip_recursive on; - 确认后,日志中的
$remote_addr就是真实访客 IP,不是中间代理 IP。
用日志快速筛出高频盗链 IP
盗链行为往往具有明显特征:大量 403 请求、Referer 是陌生域名、User-Agent 异常(如空、含 bot、或固定爬虫标识)。用一条命令就能揪出可疑源头:
- 统计最近一小时访问被拒但 Referer 非空且非本站的前 10 个 IP:
awk '$9 ~ /https?:\/\// && $9 !~ /example\.com/ {print $1}' /var/log/nginx/theft_access.log |
awk '{count[$1]++} END{for (ip in count) if (count[ip]>5) print count[ip], ip}' |
sort -nr | head -10 - 查看某 IP 的全部请求详情(含 Referer 和 UA):
grep "^1.2.3.4 " /var/log/nginx/theft_access.log | tail -20
配合 fail2ban 自动封禁高频盗链者
识别出恶意 IP 后,手动加防火墙规则效率低。推荐用 fail2ban 把高频盗链行为自动转为 iptables 或 nftables 封禁:
- 新建 jail 配置
/etc/fail2ban/jail.d/nginx-theft.conf:
[nginx-theft]
enabled = true
filter = nginx-theft
logpath = /var/log/nginx/theft_access.log
maxretry = 10
findtime = 300
bantime = 3600 - 对应 filter 定义在
/etc/fail2ban/filter.d/nginx-theft.conf中,匹配盗链特征行:
failregex = ^<HOST>.*"GET .*.(jpg|png|mp4|pdf).*HTTP.*" 403.*".*https?://(?!.*example.com).*"


















