Nginx→Varnish负载均衡→Apache SSL连接报400错误求助
400错误排查与解决方案(针对你的HTTPS代理架构)
嘿Greg,咱们结合你的部署链路来拆解这个400错误——这几乎肯定是代理层之间HTTP/HTTPS处理不匹配导致的,先再明确下你的架构:
- 服务器1:Nginx(443端口,HTTPS接收请求)→ 反向代理到本机Varnish 5(80端口,HTTP)
- Varnish 5 → 负载均衡转发请求到服务器2/3的Apache(443端口,HTTPS)
- 服务器2/3:Apache处理HTTPS请求并返回应用内容
核心问题推测与修复步骤
1. 最可能的根源:Varnish直接发HTTP请求到后端HTTPS端口
Varnish本身是HTTP缓存服务,默认只会发送明文HTTP请求,但你后端的Apache监听的是443端口(期望TLS握手的HTTPS连接)。如果Varnish直接把HTTP请求扔到HTTPS端口,Apache完全无法解析这种“非TLS”的请求,自然会返回400错误。
解决办法:给Varnish加TLS代理来对接后端HTTPS
推荐用Hitch(Varnish官方推荐的TLS代理工具)来处理Varnish到后端的HTTPS连接:
- 步骤1:在服务器1安装Hitch
- 步骤2:配置Hitch(示例配置文件
/etc/hitch/hitch.conf):
# 监听Varnish转发过来的本地端口 frontend = "[127.0.0.1]:6082" # 指向后端服务器2和3的443端口 backend = "[服务器2IP]:443,[服务器3IP]:443" # 服务器1的SSL证书,用于和后端建立TLS连接 pem-file = "/path/to/your/server1-ssl-cert.pem"
- 步骤3:修改Varnish的VCL配置,把后端指向Hitch的监听端口,而不是直接指向服务器2/3的443:
# 定义后端(通过Hitch中转) backend server2 { .host = "127.0.0.1"; .port = "6082"; } backend server3 { .host = "127.0.0.1"; .port = "6082"; } # 配置轮询负载均衡 director lb round_robin { { .backend = server2; } { .backend = server3; } } sub vcl_recv { # 把请求转发到负载均衡器 set req.backend_hint = lb; }
2. Nginx到Varnish的转发需正确传递HTTPS头信息
即使解决了Varnish到后端的问题,如果Nginx转发到Varnish时没传递必要的HTTPS标识,后端Apache可能会因为请求头缺失而无法正确处理。
修复Nginx配置:
在Nginx的反向代理location块里添加这些头:
location / { proxy_pass http://127.0.0.1:80; # 转发到Varnish的80端口 # 传递必要的请求头 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 告诉后端这是HTTPS请求 }
3. Apache端的配置验证
最后确认后端Apache的配置是否兼容代理请求:
- 确保虚拟主机的
ServerName/ServerAlias和你访问的域名完全匹配 - 启用
mod_remoteip模块,让Apache识别来自Varnish的真实IP,并正确处理X-Forwarded-Proto头:
RemoteIPHeader X-Forwarded-For RemoteIPTrustedProxy 服务器1IP # 信任服务器1的IP RequestHeader set X-Forwarded-Proto "https" env=HTTPS
快速验证步骤
- 先直接访问服务器2/3的443端口,确认Apache本身能正常响应HTTPS请求,排除后端问题
- 在服务器1上执行
curl -H "Host: yourdomain.com" http://127.0.0.1:80,如果返回400,说明Nginx到Varnish的转发有问题 - 执行
curl http://服务器2IP:443,如果返回400,就坐实了“HTTP请求发到HTTPS端口”的问题,这时候必须用Hitch或Varnish的TLS模块来解决
内容的提问来源于stack exchange,提问作者GregOs
相关产品推荐
相关产品推荐

