如何正确为禁止访问文件配置RewriteRule实现HTTPS跳转?
目标
针对 http://站点域名/.htaccess 的请求,需要实现的效果:
- 不泄露
.htaccess文件本身的内容 - 仅把请求地址的
http://前缀替换为https://,不修改原请求路径 - 协议升级完成后,对该请求返回403权限错误提示
最终预期地址栏显示为https://站点域名/.htaccess,页面展示403提示内容。
当前存在的问题
请求处理完成后,地址栏最终显示为 https://站点域名/403.shtml,和预期路径不符。
前置说明
- 站点的
.htaccess文件访问拦截逻辑、全局403错误跳转规则,都是网站托管服务商预先配置的,无权限直接修改服务器层面的这部分规则 - 当前站点自定义的HTTPS强制跳转规则,写在站点根目录的
.htaccess文件中,现有代码如下:
RewriteEngine on RewriteCond %{HTTPS} !on RewriteRule .* https://%{HTTP_HOST}/$0 [L,QSA,R=301]
问题原因
现有规则执行链路存在两个错位:
- 现有HTTPS跳转规则没有优先匹配对
.htaccess这类受保护文件的请求,导致这类请求先触发了服务商的403拦截逻辑 - 服务商配置的403错误跳转是外部重定向模式,也就是触发403时会直接把地址栏跳转到指定的403.shtml路径,而不是在原路径下内部返回403提示内容,最终导致路径被篡改。
修复方法
调整.htaccess里的规则优先级,确保对.htaccess的请求先完成HTTPS协议跳转,再内部处理403返回,不触发服务商的外部重定向逻辑:
- 把HTTPS跳转规则放在
.htaccess文件最顶部,确保所有未走HTTPS的请求,不管请求的是什么资源,都先完成协议升级,再走后续的访问判断 - 针对
.htaccess的请求,自定义本地的403错误返回规则,使用内部包含的方式加载403提示页面,避免跳转到独立的403.shtml路径。
调整后的参考配置:
RewriteEngine on # 优先完成所有请求的HTTPS协议升级 RewriteCond %{HTTPS} !=on RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L] # 对已升级到HTTPS的/.htaccess请求,直接返回403 RewriteCond %{REQUEST_URI} ^/\.htaccess$ RewriteRule ^\.htaccess$ - [R=403,L] # 自定义403错误的处理方式:内部读取/403.shtml内容返回,不做外部跳转 ErrorDocument 403 /403.shtml
配置生效后,请求处理链路为:http下的/.htaccess → 301跳转至https下的/.htaccess → 返回403状态码,内部加载403.shtml的内容在当前路径展示,地址栏始终保持预期的https://站点域名/.htaccess,不会跳转到独立的403.shtml地址。
内容的提问来源于stack exchange,提问作者Tamás Bolvári
相关产品推荐
相关产品推荐

