Apache2虚拟主机HTTPS重定向过多问题排查求助
Apache2虚拟主机重定向循环问题排查与解决
问题背景
- 服务器基于microk8s部署多站点,Apache2作为反向代理将流量转发至对应Pod端口
- 某Django站点出现重定向过多循环,同服务器上的PHP站点、另一Django站点运行正常
- 尝试多种HTTPS强制跳转Rewrite规则无效,日志显示重定向持续触发;将80端口虚拟主机改为直接Redirect到HTTPS仍出现循环
- HTTPS请求被错误转发至80端口,无法到达Django Pod,但本地执行
curl localhost:30102可正常获取页面
可能原因
- Apache未识别真实请求协议:若前端存在代理(如microk8s Ingress),Apache接收的是代理转发的HTTP请求,
%{HTTPS}变量始终为off,导致强制HTTPS规则反复触发形成循环。 - HTTPS虚拟主机转发配置错误:443端口虚拟主机的反向代理规则可能错误将请求转回80端口,或未正确传递协议标识给Django。
- Django未信任代理头部:Django的
SECURE_SSL_REDIRECT开启后,若未识别到代理传递的HTTPS标识,会再次重定向到HTTPS,引发循环。
解决方案
1. 修正Apache的HTTPS识别逻辑
启用mod_remoteip和mod_headers模块:
a2enmod remoteip headers
在全局配置(如/etc/apache2/apache2.conf)或对应虚拟主机配置中添加:
# 信任microk8s代理的IP段(根据实际环境调整) RemoteIPTrustedProxy 127.0.0.1/32 10.1.0.0/16 # 传递真实协议到后端 RequestHeader set X-Forwarded-Proto "https" if "%{HTTPS}s" == "on" RequestHeader set X-Forwarded-Proto "http" if "%{HTTPS}s" == "off"
修改80端口虚拟主机的Rewrite规则,改用X-Forwarded-Proto判断协议:
<VirtualHost *:80> ServerName stage.example.com ServerAlias www.stage.example.com RewriteCond %{SERVER_NAME} =www.stage.example.com [OR] RewriteCond %{SERVER_NAME} =stage.example.com RewriteCond %{HTTP:X-Forwarded-Proto} !=https RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent] </VirtualHost>
2. 检查并修正HTTPS虚拟主机配置
确保443端口虚拟主机正确反向代理到Django Pod端口,且传递必要头部:
<VirtualHost *:443> ServerName stage.example.com ServerAlias www.stage.example.com # SSL证书配置 SSLEngine on SSLCertificateFile /path/to/your/cert.pem SSLCertificateKeyFile /path/to/your/key.pem # 反向代理到Django Pod端口 ProxyPass / http://localhost:30102/ ProxyPassReverse / http://localhost:30102/ # 传递真实协议和主机头给Django RequestHeader set X-Forwarded-Proto "https" RequestHeader set X-Forwarded-Host %{SERVER_NAME}e </VirtualHost>
3. 调整Django站点配置
在settings.py中添加代理信任配置:
ALLOWED_HOSTS = ['stage.example.com', 'www.stage.example.com'] # 信任代理传递的HTTPS标识 SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') # 保持SSL重定向开启(若之前已配置) SECURE_SSL_REDIRECT = True
4. 验证并重启服务
- 检查Apache配置语法:
apache2ctl configtest - 重启Apache:
systemctl restart apache2 - 测试访问:执行
curl -v https://stage.example.com,确认无重定向循环且页面正常返回
内容的提问来源于stack exchange,提问作者bbg
相关产品推荐
相关产品推荐

