最有效防盗链方式是在图片 location 块中配置 valid_referers 白名单并用 if($invalid_referer) 返回 403;需精准匹配后缀、正确设置 root/alias、覆盖 none/blocked/域名白名单,避免误伤合法访问。

直接在匹配图片资源的 location 块里配置 valid_referers 白名单 + if ($invalid_referer) 拦截,是最有效、最常用的方式。关键不是“能不能拦”,而是“拦得准不准、误不误伤”。
只对图片资源启用防盗链
避免影响 HTML、API 或字体等非盗链高发资源。用正则精准匹配常见图片后缀:
location ~* \.(jpg|jpeg|png|gif|webp|svg)$ {- 这个块内必须有
root或alias,否则文件根本找不到,防盗链就形同虚设 - 不要写成
location /images/后再靠内部路径判断——容易漏掉根目录或 CDN 回源的图片请求
设置合理的 Referer 白名单
白名单要覆盖真实合法访问场景,否则用户点开链接看不到图,会以为网站坏了:
valid_referers none blocked *.yourdomain.com yourdomain.com;-
none:允许直接输入 URL 访问(比如收藏夹打开、微信内嵌浏览器) -
blocked:覆盖 HTTPS 页面加载 HTTP 图片、某些代理/防火墙清空 Referer 的情况 - 显式列出
www.yourdomain.com和yourdomain.com——它们是两个不同字符串,缺一不可 - 如需支持合作站点,加
partner-site.com或正则~\.cdn\.(com|net)$
拦截动作要明确且可追踪
返回 403 是最推荐的做法,语义清晰、日志好查、CDN 和爬虫能正确识别:
if ($invalid_referer) { return 403; }- 避免用
rewrite ... break跳转到提示图——状态码还是 200,掩盖了盗链行为,还可能因路径错乱导致循环或 404 - 如需展示友好提示,改用:
error_page 403 =200 /images/forbidden.png;,既保持 403 日志记录,又返回一张小图 - 可选加日志格式,方便排查误拦:
log_format referer_deny '$remote_addr - $remote_user [$time_local] "$request" $status $invalid_referer';
注意几个易踩的坑
这些细节不处理,防盗链可能完全失效或大面积误拦:
- HTTPS 页面引用 HTTP 图片时,浏览器会主动清空 Referer,
blocked必须保留 - 使用
alias时,路径末尾斜杠要和 location 一致(如location /img/ { alias /data/images/; }) - 不要把
valid_referers放在http或upstream块里——它只在server或location内生效 - Referer 可被伪造,仅适合防普通盗链;高敏感资源(如会员图片、下载包)建议叠加
secure_link签名验证











