LNMP下防止图片被盗用浪费流量,最直接有效的做法是在Nginx层做referer白名单拦截,再配合CDN签名鉴权或对象存储私有读,基本不用额外付费插件就能把盗链流量压到很低,本文在上海云服务器上实测手动配置和宝塔面板两种方案,结论是手动配置更适合有CDN回源和高防需求的站。
LNMP防止图片盗链怎么设置?先理清盗用路径
图片被盗用通常是指别人的网站直接引用你服务器上的图片URL,用户访问那个网站时,浏览器会向你的服务器发起请求,下载图片并消耗你的带宽,如果对方网站流量不小,你的服务器出口带宽会被白白吃掉。
LNMP环境下,Nginx是所有HTTP请求的第一道关口,所以在Nginx层做防盗链最直接,行业共识认为,referer头是判断请求来源是否合法的基本依据,但它可以被伪造,只能拦住普通盗链,防不住刻意刷流量。
图片盗链浪费流量怎么解决?核心思路分三层:
- 第一层:Nginx用referer白名单拦截大部分外部域名请求。
- 第二层:CDN开启URL鉴权或Referer防盗链,把压力挡在边缘节点。
- 第三层:高价值图片迁移到对象存储并开启私有读,源站不直接对外暴露图片文件。
三层叠加后,即使是上海地域这种带宽单价较高的服务器,也能明显减少流量浪费。
Nginx referer防盗链配置实测
基础版:valid_referers直接拦截
在Nginx的server或location块里配置:
location ~ .(jpg|jpeg|png|gif|webp)$ {
valid_referers none blocked .example.com example.com;
if ($invalid_referer) {
return 403;
}
}
valid_referers后面跟允许的来源。none表示没有referer头的请求,比如直接访问图片地址。blocked表示referer头被浏览器或代理隐藏的情况。.example.com是自己的主域名和子域名。
这个配置的缺点是用了if指令,在Nginx里if和return配合会有一些坑,特别是和try_files、rewrite同时使用时,图片请求量大的站,建议用map模块替代。
优化版:map模块替代if,性能更好
在http块里定义map:
map $http_referer $invalid_referer {
default 1;
"~example.com" 0;
"~.baidu.com" 0;
"~.google.com" 0;
"" 0;
"~.weixin.qq.com" 0;
}
然后在图片location里直接判断:
location ~ .(jpg|jpeg|png|gif|webp)$ {
if ($invalid_referer) {
return 403;
}
}
map在Nginx启动时加载一次,比在每个请求里跑一遍valid_referers效率高,白名单里可以加上百度图片搜索、微信等来源,防止误伤正常收录和分享。
配置后怎么验证
用curl模拟带非法referer的请求:
curl -I -e "http://spam-site.com" https://你的域名/1.jpg
返回403 Forbidden说明拦截生效,再用自己域名测试:
curl -I -e "https://www.example.com" https://你的域名/1.jpg
返回200 OK,空referer测试:
curl -I https://你的域名/1.jpg
如果配置里放行了空referer,应该返回200,这个测试步骤能帮你确认规则没有误伤正常用户。
宝塔面板防盗链和LNMP手动配置哪个好用?
宝塔面板一键防盗链设置路径
在宝塔面板里操作很简单:进入“网站” -> 选择对应站点 -> “设置” -> “防盗链”,填写允许的域名,点击保存,面板会自动生成Nginx配置片段并重载。
宝塔面板的优点:
- 操作路径短,不需要懂Nginx语法。
- 适合只有一个域名、没接CDN的站。
- 修改后自动reload,不怕手滑打错配置。
宝塔面板的缺点:
- 自定义能力弱,比如想放行空referer、按路径区分规则,界面里不够灵活。
- 接CDN后,面板生成的规则容易把回源请求也拦截掉,需要手动改配置。
- 有些版本生成的规则和缓存插件、WebSocket冲突,排查起来比较费劲。
手动Nginx配置的优缺点
手动配置适合对Nginx有一定了解的用户,优点:
- 可以精确控制每个location,针对不同图片类型、不同路径做差异化规则。
- 方便和map、secure_link等模块配合。
- 配置可以直接纳入版本管理,迁移服务器时不用重新在面板里点。
缺点:
- 需要自己测试,改错了可能导致网站大面积403。
- 服务器重启或Nginx升级后要再检查配置是否生效。
方案对比表
| 方案 | 配置难度 | 防盗效果 | 误伤风险 | 适合场景 |
|---|---|---|---|---|
| 宝塔面板一键防盗链 | 低 | 中 | 中 | 单域名、无CDN的小站 |
| Nginx手动referer白名单 | 中 | 中高 | 低 | 有CDN、多子域名的站 |
| referer + secure_link | 高 | 高 | 低 | 图片价值高、易被扒图的站 |
| CDN鉴权 + 对象存储私有读 | 中高 | 高 | 极低 | 流量大、成本敏感型站 |
如果你刚搭建LNMP环境,先用宝塔面板熟悉规则没问题,但一旦接了CDN或者图片目录复杂,手动配Nginx是绕不开的。
进阶方案:签名URL与CDN防盗链联动
为什么referer不够用
referer头可以被伪造,攻击者用脚本直接构造请求,带上你自己域名的referer,就能绕过普通Nginx规则,另外移动端部分网络环境会丢掉referer,导致正常用户被误伤,所以高流量站或者图片被频繁盗用的站,需要签名URL做二次校验。
Nginx secure_link模块实战
secure_link模块用时间戳和密钥生成签名,只有带有效签名的请求才能访问图片,配置示例:
location ~ .(jpg|jpeg|png|gif|webp)$ {
secure_link $arg_st,$arg_e;
secure_link_md5 "$secure_link_expires$uri$remote_addr mysecretkey";
if ($secure_link = "") { return 403; }
if ($secure_link = "0") { return 410; }
}
生成签名URL需要在后端代码里用同样的算法计算md5,这里用mysecretkey举例,实际部署时换成随机字符串,签名过期后返回410 Gone,比403更明确,表示资源已失效。
CDN联动:把压力转移到边缘节点
目前主流CDN都提供URL鉴权功能,开启后,CDN节点会校验请求的签名参数,无效请求直接拒绝,根本不会回源,即使源站Nginx的referer规则被绕过,CDN层也能挡住大部分盗链,CDN按流量计费,但拦截掉盗链后回源量和边缘流量都会下降,总体费用可控,上海地域的源站配合CDN使用,响应速度和带宽成本都能优化。
上海服务器防止图片盗链配置要注意什么?
地域带宽成本压力
上海地域的BGP带宽单价在国内属于较高水平,流量被盗刷后费用上涨会非常明显,如果站点流量主要来自国内用户,把图片放在上海源站是合理的,但一定要把防盗链当成必修项,而不是可选优化。
结合对象存储私有读
图片量大的站,建议把图片迁移到对象存储,开启私有读,只允许应用后端生成签名URL供前端访问,源站LNMP环境只处理页面请求,图片流量不再经过服务器带宽,这样即使有人抓到图片URL,没有签名也无法访问,单个地域的对象存储请求价格通常比服务器带宽便宜,尤其适合图片流量波动大的站点。
地域选择和CDN回源
如果你的源站在上海,CDN节点覆盖全国,回源请求会从上海出口,CDN开启鉴权后,回源请求需要保留referer头,否则源站Nginx会误拦,一般CDN后台有“回源referer”设置,保持默认或填源站域名即可,配置完成后用真实浏览器和curl反复测试不同来源,确认没有误伤。
配置后的监控与故障排查
看日志分析盗链来源
Nginx访问日志里带上$http_referer字段,就能统计哪些外部域名在引用图片,日志格式示例:
log_format main '$remote_addr - $http_referer - $request - $status';
观察日志中$http_referer不是空且不是你白名单域名的记录,基本就是盗链来源,把这些域名加入黑名单或过滤规则,能快速止住流量。
误伤处理
有时候改完配置,自己网站的图片也不显示,常见原因:
- CDN回源请求的referer变成了CDN厂商域名,Nginx拦截了回源。
- 小程序或APP里图片请求没有referer,被
valid_referers规则拦住。 - 浏览器隐私模式或HTTPS跳转导致referer丢失。
处理办法:在小程序端给图片请求加referer头,或者服务端放行空referer,自己网站页面如果有防盗链问题,检查HTML里图片标签是否带了referrerpolicy="no-referrer",改成referrerpolicy="strict-origin-when-cross-origin"即可。
常见错误记录
- 在
location块里用if判断$invalid_referer时,同时写多个return,规则冲突导致所有图片都403。 - 修改完配置后只执行
nginx -t检查语法,忘了systemctl reload nginx,配置没生效。 - 宝塔面板里填了允许域名后,又手动去改Nginx配置文件,面板后续保存把手动配置覆盖掉。
排查命令就两条:nginx -t查语法,tail -f /var/log/nginx/access.log看实时日志,基本能定位大部分问题。
LNMP下所有防盗链动作都围绕Nginx入口展开,手动配置referer白名单是成本最低、见效最快的方案,接CDN和高防站务必做签名URL,把压力从源站剥离,上海地域的服务器带宽不便宜,提前做好这三层,比事后看流量账单补救更省心。
LNMP防止图片盗链常见问题Q&A
问:LNMP防止图片盗链配置后,百度图片搜索还能收录图片吗?
答:可以,百度图片搜索的爬虫通常带baidu.com相关referer,只要在Nginx白名单里加上.baidu.com,就不会拦截,如果百度爬虫被误伤,观察日志里$http_referer字段,找到真实来源域名并加白即可。
问:宝塔面板防盗链和手动Nginx配置能同时用吗?
答:不建议同时使用,两者生成的Nginx规则都作用于图片请求,叠加后容易产生冲突,导致某些正常请求被拦截,要么用面板管理,要么完全手动写配置,选一个层级维护,如果先在面板启用防盗链,后续又需要手动改,最好在面板里关闭该功能再改配置文件。
问:LNMP防止图片盗链后,微信小程序里图片不显示怎么办?
答:微信小程序image组件的请求默认不带referer头,如果Nginx配置里没有放行空referer,图片会被403拦截,多数情况下在服务端配置里允许空referer即可解决,比如valid_referers none blocked保持不变,或者map里给空referer赋值0放行,事实上微信小程序不支持自定义referer头,所以服务端放行空referer是当前通用的处理方式。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/671309.html





