Apache ProxyPass跳转而非正常反向代理 隐藏容器端口配置问题排查
问题根因分析
- 反向代理后跳转到
example.com:8014的原因
你代理侧虽然开启了ProxyPreserveHost On,把原始Host头subdomain.example.com传给了容器内的Apache,但容器内的443虚拟主机ServerName仅配置了example.com,无法匹配subdomain.example.com的请求,会触发Apache默认虚拟主机匹配逻辑,返回指向自身配置的ServerName的301跳转。同时你代理侧的ProxyPassReverse仅替换路径前缀,没有替换跳转目标中的域名和端口,直接将容器返回的example.com:8014跳转地址透传给客户端,最终导致地址栏URL发生变化。 - 访问
example.com:8012没有跳转到8014端口HTTPS服务的原因
容器内80端口的重写规则判断条件为%{SERVER_NAME} =example.com:8014,和实际请求完全不匹配:8012端口映射的是容器内的80端口,此时SERVER_NAME是example.com、端口为80,不会命中该重写条件,自然不会触发跳转。
解决方案
第一步:修改容器内的Apache配置
<VirtualHost *:80> ServerName example.com # 新增subdomain别名,适配代理传递的Host头 ServerAlias subdomain.example.com RewriteEngine on # 修正重写规则:只要是80端口访问就跳转到同域名的HTTPS RewriteCond %{SERVER_PORT} =80 # 跳转地址用%{HTTP_HOST}动态获取,不要写死域名端口,适配不同访问来源 RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [END,NE,R=permanent] </VirtualHost> <VirtualHost *:443> ServerAdmin admin@example.com ServerName example.com # 新增subdomain别名,匹配代理传递的Host头 ServerAlias subdomain.example.com <Directory /var/www/html> AllowOverride All </Directory> SSLEngine On SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 SSLHonorCipherOrder off SSLSessionTickets off SSLOptions +StrictRequire SSLCertificateFile /etc/apache2/fullchain.pem SSLCertificateKeyFile /etc/apache2/privkey.pem # 新增配置:告知Apache当前请求是前端代理传递的HTTPS请求,避免内部逻辑重复跳转 SetEnvIf X-Forwarded-Proto "https" HTTPS=on </VirtualHost>
修改完成后重启容器内的Apache服务。
第二步:优化代理侧配置(可选)
你当前代理通过HTTPS访问容器的8014端口,需要确保代理侧信任容器内的证书,否则可能出现502错误。如果容器使用自签证书,可以在代理侧443虚拟主机配置中添加一行:
SSLProxyVerify none
如果不需要容器侧再做HTTPS处理,也可以直接将代理目标改为容器的80端口对应映射地址,性能更高且无需处理证书兼容问题:
# 替换原有ProxyPass和ProxyPassReverse配置 ProxyPass / http://example.com:8012/ ProxyPassReverse / http://example.com:8012/ # 新增传递协议头的配置 RequestHeader set X-Forwarded-Proto "https"
修改完成后重启代理侧的Apache服务,清理浏览器缓存(301为永久重定向,会被浏览器缓存)后再测试即可。
内容的提问来源于stack exchange,提问作者Tito Tigi
相关产品推荐
相关产品推荐

