Apache2.4配置.htaccess:仅允许test2子域访问test1禁止直接访问
原有规则失效原因
你写的规则存在三个明显缺陷,导致无法达到预期效果:
- 匹配逻辑没有做域名边界校验,规则里仅判断referer字符串是否包含
test2.domain.com,类似test2.domain.com.evil.com这种仿冒域名的请求会被直接误放行。 - 没有考虑referer为空的场景:用户直接在地址栏输入地址、开启浏览器隐私模式、安装了拦截referer上报的安全插件时,请求头里不会携带referer字段,原有规则会把这类请求全部拦截,同时也没有预留特殊路径(比如服务健康检查接口)的白名单配置位。
- Apache 2.4提供了原生的访问控制指令,相比mod_rewrite实现的拦截逻辑性能更高、匹配精度更好,不需要额外用rewrite做判断。
正确配置
将test1子域名对应站点根目录下的.htaccess文件内容替换为以下配置即可,两种方案二选一:
方案1:Apache 2.4原生访问控制(推荐,性能最优)
<IfModule mod_authz_core.c> # 默认拦截所有请求 Require all denied # 仅允许来源为test2.domain.com的请求,正则做了边界校验防止仿冒域名绕过 Require expr "%{HTTP_REFERER} =~ m#^https?://test2\.domain\.com(/|$)#i" # 可选配置:如果有不需要拦截的公开路径(比如健康检查接口),可以按下面格式加白名单,不需要就删除 # Require expr "%{REQUEST_URI} == '/healthcheck'" </IfModule>
方案2:修正后的mod_rewrite规则
如果你更习惯用rewrite写法,可以用以下修正后的规则:
RewriteEngine On # 排除不需要拦截的公开路径,不需要就删除下一行 RewriteCond %{REQUEST_URI} !^/healthcheck$ [NC] # 校验referer是否为合法的test2.domain.com来源,NC标识不区分大小写 RewriteCond %{HTTP_REFERER} !^https?://test2\.domain\.com(/|$) [NC] # 命中规则直接返回403禁止访问,L标识停止后续规则处理 RewriteRule .* - [F,L]
注意事项
HTTP_REFERER字段可以被客户端随意篡改,仅适合做防普通用户直接访问的软拦截,如果需要高安全级别的访问控制,必须叠加请求签名、身份鉴权等逻辑。- 如果你实际使用的是.de后缀的域名,把配置里的
.com替换为.de即可。 - 配置生效前请确认Apache已经开启对应模块(原生方案需要开
mod_authz_core,rewrite方案需要开mod_rewrite),重载Apache配置后清空浏览器缓存再测试,避免缓存导致规则不生效。 - 如果需要放行部分公开资源路径,在拦截判断前新增对应路径的排除条件即可。
内容的提问来源于stack exchange,提问作者user7206180
相关产品推荐
相关产品推荐

