HAProxy仅向本地Apache转发流量时出现SSL握手错误的问题求助
问题描述
我现在在服务器1上运行Apache(Ubuntu系统),它监听80和443端口,配置了多个域名和一张通配符SSL证书,目前所有服务都运行正常。
我想在服务器1上部署HAProxy,把发往domain_name_1的流量转发到服务器2(这台服务器没有配置SSL证书),其他所有域名的流量则通过HAProxy转发回服务器1上的Apache。
我已经做了这些操作:在服务器1上安装HAProxy并让它监听80和443端口,同时把服务器1上的Apache改成监听新端口8888(HTTP)和9999(HTTPS),但现在遇到了问题:
- 发往
domain_name_1的流量能正确转发到服务器2,SSL也正常工作; - 其他应该转发到本地Apache的域名,浏览器返回503错误,查看HAProxy日志发现有大量SSL握手错误。
我之前看到资料说这可能是SSL证书问题或者……
可能的原因及解决办法
结合你的场景,我整理了几个最可能的问题点和对应的解决步骤:
HAProxy与本地Apache的SSL通信逻辑错误
你已经让HAProxy在443端口做了SSL终止(用通配符证书),这时候要注意转发到Apache的方式:- 如果Apache的9999端口没有配置SSL(只是改了监听端口但没配证书),那HAProxy应该用HTTP协议转发到8888端口,而不是用HTTPS连9999——否则两边SSL不匹配就会触发握手错误。
- 如果Apache在9999端口配置了SSL(用同一个通配符证书),那HAProxy的后端配置里要加上
ssl verify none(因为是本地回环通信,不需要严格验证证书),示例配置如下:backend local_apache server apache_local 127.0.0.1:9999 check ssl verify none
域名匹配规则不完整
检查HAProxy的frontend配置,确保所有非domain_name_1的域名都能被正确匹配到本地Apache的后端。比如用通配符ACL来匹配你的所有域名:frontend main bind *:443 ssl crt /path/to/your/wildcard.cert acl is_domain1 hdr(host) -i domain_name_1 acl other_domains hdr(host) -i *.your-base-domain.com # 替换成你的通配符域名 use_backend server2 if is_domain1 use_backend local_apache if other_domains如果ACL规则写得有问题,会导致部分域名的流量没有被正确路由,进而触发503。
Apache新端口的配置验证
- 先确认Apache的
ports.conf已经正确更新:Listen 8888 <IfModule ssl_module> Listen 9999 </IfModule> - 同时检查所有虚拟主机配置,把原来的
*:80和*:443改成对应的*:8888和*:9999。 - 本地测试Apache是否正常:执行
curl http://127.0.0.1:8888和curl https://127.0.0.1:9999 -k(-k跳过证书验证),如果本地都访问失败,那问题出在Apache本身,先修复Apache的配置。
- 先确认Apache的
HAProxy后端健康检查缺失
HAProxy返回503通常是因为它认为后端服务不健康,所以要给本地Apache的后端加上健康检查配置:backend local_apache server apache_local 127.0.0.1:8888 check # HTTP端口的健康检查 # 或者HTTPS端口的健康检查: # server apache_local 127.0.0.1:9999 check ssl verify none这样HAProxy会定期检查Apache的状态,如果健康检查通过,就不会返回503了。
查看更详细的HAProxy日志
把HAProxy的日志级别调高,比如在global段加上log global debug,然后查看日志里的具体错误信息——比如是证书不匹配、SSL协议版本不兼容,还是后端根本没响应SSL请求,这能帮你精准定位问题。
备注:内容来源于stack exchange,提问作者Starstruc8

