Referer请求头是浏览器在发起资源请求时自动携带的来源页面地址,服务器可以据此判断图片是被自己的网页加载,还是被外部站点直接引用。Apache本身没有专门的防盗链指令,但借助mod_rewrite模块中的RewriteCond和RewriteRule,可以轻松读取HTTP_REFERER变量并执行条件判断。理解这一机制的关键在于:Referer并非百分百可靠,它可能被客户端禁用、被代理剥离,甚至被伪造,因此防盗链只能作为带宽保护手段,而不是严格的安全边界。

在正式开始配置之前,需要确认Apache已启用mod_rewrite和mod_setenvif模块。大多数Linux发行版默认会加载这两个模块,如果是使用宝塔面板或LNMP一键包,通常也已经启用。如果是在Windows环境下手动配置Apache,则需要检查httpd.conf中是否取消注释了LoadModule rewrite_module modules/mod_rewrite.so和LoadModule setenvif_module modules/mod_setenvif.so。
防盗链规则的基础配置
最常用的做法是在站点根目录的.htaccess文件中写入Rewrite规则,这样无需重启Apache即可生效。如果对性能有较高要求,也可以将规则直接写入虚拟主机配置文件的Directory段落中。下面给出一个典型配置示例,它会阻止jpg、jpeg、png、gif、webp等常见图片格式被非授权域名引用,同时将非法请求重定向到一张提示图片。
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?example\.com [NC]
RewriteCond %{HTTP_REFERER} !^http(s)?://(images\.)?example\.com [NC]
RewriteRule \.(jpg|jpeg|png|gif|webp)$ /images/hotlink-denied.png [L]
</IfModule>
这段代码的逻辑是:当Referer不为空,并且不匹配ipipp.com及其www子域时,图片请求会被重写到/images/hotlink-denied.png。需要注意的是,RewriteCond默认是逻辑与的关系,因此只有当所有条件都满足时,RewriteRule才会执行。如果希望允许多个域名,可以继续追加RewriteCond行,每条条件使用相同的匹配语法即可。
对于不想单独准备提示图片的场景,可以将最后一行换成返回403状态码,例如RewriteRule \.(jpg|jpeg|png|gif|webp)$ - [F]。F标志会让Apache直接返回403 Forbidden,外部站点会看到图片加载失败,而不会消耗额外的图片传输带宽。不过这样做有时会触发浏览器控制台的资源加载错误,如果比较在意用户体验,建议还是使用一张体积很小的提示图。
空Referer与严格策略的取舍
很多站长第一次配置防盗链时,会直接照搬网上的规则,但很快发现直接打开图片地址会返回403,甚至自己站点内的一些图片也被拦截。根本原因在于空Referer的处理。当用户在浏览器地址栏直接输入图片URL、或者某些客户端不发送Referer头时,HTTP_REFERER变量为空。如果规则中没有像上面那样用RewriteCond %{HTTP_REFERER} !^$排除空值,那么空Referer也会被当作非法来源处理。
是否允许空Referer取决于站点的实际需求。对于个人博客或小型展示站点,允许空Referer可以避免误伤直接访问和部分下载工具,损失的是第三方站点可以通过无Referer的代理方式绕过限制。对于图片流量消耗巨大的图床或素材站,可能更倾向于严格策略,将空Referer也一并拒绝,只允许自己域名下的网页引用。严格策略可以在上面的配置基础上去掉第一条空值排除条件,或者使用SetEnvIfNoCase将空Referer标记为非法。
另一种折中方案是只允许特定域名和空Referer,同时屏蔽已知的盗链域名。比如用RewriteCond %{HTTP_REFERER} ^http(s)?://(www\.)?bad-site\.com [NC,OR]配合多个OR条件列出黑名单。这样做维护成本较高,而且盗链域名变化很快,不如白名单方式省心。搜索引擎爬虫在抓取图片时通常不携带Referer,如果图片对SEO有作用,建议保留空Referer放行,否则搜索结果中可能无法展示图片缩略图。
防盗链规则与CDN缓存的冲突排查
如果站点接入了CDN,防盗链配置需要格外小心。CDN节点回源时,Referer头可能被替换成源站域名,也可能保持为空,这取决于CDN服务商的回源策略。如果在源站开启了严格的防盗链规则,CDN节点可能无法正常拉取图片,导致用户访问时出现大量404或403。解决思路有两种:一是在源站放行CDN的回源请求,二是在CDN层面直接配置Referer防盗链,源站只做兜底限制。
对于使用阿里云CDN、腾讯云CDN等国内服务的情况,通常可以在CDN控制台的访问控制中直接设置Referer黑白名单,规则会在边缘节点生效,不再回源。这样做不仅减轻源站压力,也能避免回源请求被源站防盗链误杀。如果必须在源站配置,可以先在日志中查看CDN回源时的Referer值,然后将其加入白名单。比如CDN回源Referer可能是http://your-origin-domain.com,则需要额外添加一条RewriteCond %{HTTP_REFERER} !^http://your-origin-domain\.com [NC]。
另外,浏览器缓存也可能造成误判。当用户从自己站点点击图片后,图片被浏览器缓存,随后用户访问了盗链站点,盗链站点直接引用该图片URL,浏览器可能复用缓存而不发送新的请求,从而绕过服务器检查。这种场景无法通过服务器端防盗链解决,但从实际影响来看,缓存只发生在同一用户设备上,不会造成大规模带宽消耗。真正需要关注的是搜索引擎快照和社交媒体平台的自定义抓取,它们的行为模式差异较大,建议针对主要流量来源单独分析日志再做精细调整。
最后要提醒一句,Referer防盗链并不是万无一失的方案。它无法阻止使用curl、wget等工具直接模拟合法Referer的请求,也无法阻止通过HTTPS到HTTP降级导致的Referer丢失。如果你的图片需要更高的保护级别,可以考虑使用签名URL、短时效Token或者对象存储的私有访问机制。对于大多数普通网站来说,合理配置Rewrite规则已经能够在带宽成本和访问体验之间取得较好的平衡。