Apache防盗链核心是通过Referer字段匹配白名单,但Referer可伪造,仅适合轻量防护;推荐mod_setenvif替代mod_rewrite提升高并发性能,并需结合CDN透传、签名URL等多层策略。

Apache 的 mod_rewrite 如何判断 Referer 是否合法
防盗链的核心是拦截非白名单来源的图片请求,依赖的是 HTTP 请求头中的 Referer 字段。但要注意:Referer 可被客户端伪造或完全不发送(比如 HTTPS 页面引用 HTTP 资源时浏览器会清空它),所以它只适合做轻量级防护,不能替代权限控制。
实际配置中,用 RewriteCond 匹配 %{HTTP_REFERER} 是最常用方式:
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?yourdomain\.com/ [NC]
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?another-trusted-site\.com/ [NC]
RewriteRule \.(jpg|jpeg|png|gif|webp)$ - [F]
-
!^$排除空 Referer(直接访问、书签、某些隐私模式)——若你希望这些也禁止,就删掉这行 -
[NC]必须加,否则大小写敏感会导致匹配失败 - 正则末尾的
/很关键,不加可能误拦yourdomain.com.hacker.site这类域名 - 如果站点支持 HTTPS 和 HTTP,
https?://比硬写https://更稳妥
为什么 mod_setenvif 比纯 mod_rewrite 更适合高并发图床
当图片目录每秒承载数百请求时,mod_rewrite 的正则引擎开销明显。而 mod_setenvif 是基于字符串前缀/后缀的快速匹配,性能更好,且能和 FilesMatch 配合做细粒度控制。
典型组合用法:
SetEnvIfNoCase Referer "^https?://(www\.)?yourdomain\.com/" good_referrer SetEnvIfNoCase Referer "^https?://(www\.)?cdn\.yourdomain\.com/" good_referrer <filesmatch> Order Deny,Allow Deny from all Allow from env=good_referrer </filesmatch>
-
SetEnvIfNoCase不触发重写流程,CPU 占用低,Apache 2.4 下尤其推荐 -
Order Deny,Allow在 Apache 2.4 中已过时,如用新版请改用Require env good_referrer+Require all denied - 注意:该方案对空 Referer 默认放行(因未设 env),如需拦截,得额外加
SetEnvIfNoCase Referer "^$" bad_referrer并在Require中排除
Header set Content-Disposition "attachment; filename=\"blocked.jpg\"' 能防右键另存为吗
不能。这个响应头只会让浏览器把图片当作附件下载,并不会阻止用户查看源码、复制 URL 或用开发者工具抓包。更糟的是,它会让合法用户也无法直接浏览图片——所有请求都变成下载行为。
真正有用的策略是混合手段:
- 对敏感图集,用带时效签名的临时 URL(如
/img/xxx.jpg?token=abc123&exp=1717028400),后端校验后再输出内容 - 用
Header set X-Content-Type-Options "nosniff"防止 MIME 类型嗅探绕过 - 禁用目录索引:
Options -Indexes,避免用户通过/images/列出全部文件 - 对高频异常请求(如 1 秒内多个不同图片请求),用
mod_evasive或 fail2ban 封 IP
CDN 场景下 Apache 配置为何经常失效
如果你的图片走 CDN(比如 Cloudflare、阿里云 CDN),那么用户请求根本不会到达你的 Apache,Referer 也可能是 CDN 节点发来的(如 https://your-cdn-domain.net),导致规则全不生效。
此时必须分两层处理:
- CDN 后台开启「跟随源站 Referer 策略」或「透传原始 Referer」(Cloudflare 叫
Origin Header,阿里云叫「回源请求头」) - Apache 改用
%{HTTP:X-Forwarded-For}或%{HTTP:X-Real-Referer}(取决于 CDN 设置的实际 header 名)来判断,例如:RewriteCond %{HTTP:X-Real-Referer} !^https?://yourdomain\.com/ [NC] - 务必确认 CDN 是否缓存了 403 响应——如果缓存了,真实用户也会被永久拦住;应在 CDN 规则里设置
Cache-Control: private, no-store对 403 响应
防盗链不是开关式功能,而是要贴着你的流量路径(直连 / CDN / 多级代理)一层层对齐 Referer 传递链,漏一环就形同虚设。










