阻止恶意引用的核心是用nginx基于referer头做白名单校验并返回403,推荐配置valid_referers+return 403;可配合error_page返回友好提示图但保持403语义;高价值资源应叠加secure_link签名验证。

阻止恶意引用的核心是让 Nginx 拒绝非法来源的静态资源请求,最常用、最直接的方式就是基于 Referer 头做白名单校验,并返回明确的拒绝响应。
用 valid_referers + return 403 拦截非法请求
这是生产环境最推荐的基础写法。它语义清晰、日志可读、CDN 和浏览器都能正确识别被拒绝状态。
- 把配置放在能匹配目标资源的
location块中,例如:location ~* \.(jpg|png|gif|js|css|mp4|pdf)$ { ... } - 用
valid_referers列出所有允许的来源,比如:valid_referers none blocked example.com *.example.com www.example.com;
其中none允许直接输入地址访问,blocked允许被代理清空 Referer 的请求,example.com和通配符支持子域名 - 紧接着加判断和拦截:
if ($invalid_referer) { return 403; }
注意:不要用rewrite跳转,否则状态码仍是 200,掩盖了盗链行为
返回友好提示图(保持 403 语义)
如果希望用户看到一张“禁止盗链”的图片,又不想破坏 HTTP 状态码,可以用 error_page:
- 先定义一个内部 location 提供提示图:
location = /static/forbidden.png { internal; alias /var/www/html/static/forbidden.png; } - 在资源 location 中添加:
error_page 403 =200 /static/forbidden.png;
这样外部看到的是图片,Nginx 日志和爬虫仍记录为 403,逻辑不混淆
增强防护:加一层 URL 签名(secure_link)
单纯靠 Referer 容易被伪造,对高价值资源(如付费视频、下载链接),建议叠加签名验证:
- 启用
ngx_http_secure_link_module(通常已内置) - 生成带过期时间与哈希的签名链接,例如:
https://example.com/video.mp4?md5=abc123&expires=1720000000 - 在 location 中配置:
secure_link $arg_md5,$arg_expires;<br>secure_link_md5 "$secure_link_expires$uri$remote_addr your_secret_key";<br>if ($secure_link = "") { return 403; }<br>if ($secure_link = "0") { return 410; }
注意事项与避坑点
这些细节常被忽略,但直接影响防盗链是否生效:
-
valid_referers只能在server或location块里用,不能写在http或upstream中 - 多个域名之间用空格分隔,不是逗号;通配符
*.example.com匹配子域名,但不匹配根域,要单独写example.com - 测试时注意浏览器缓存和 Referer 策略(如从 HTTPS 页面请求 HTTP 资源可能不带 Referer)
- 移动端 WebView、部分小程序或 Electron 应用可能不发 Referer,需结合业务实际调整白名单(如加 IP 或允许
blocked)











