HAProxy作为反向代理的SSL透传问题及需求咨询
我来帮你逐个梳理并解决这三个HAProxy配置问题,都是SSL透传(TCP模式)下很容易踩的坑:
1. 证书匹配异常:访问Amazon时加载Intel证书
这个问题的核心是HAProxy没有根据客户端SNI(Server Name Indication)请求正确匹配对应域名的证书,导致返回了错误的证书触发浏览器的域名不匹配错误。
解决方案:
确保你的HAProxy配置里,证书是按SNI动态匹配的,而不是全局绑定一个证书。推荐两种方式:
方式1:使用证书目录自动匹配
把所有域名的证书文件(命名格式为域名.pem,比如www.amazon.com.pem、www.intel.com.pem)放到同一个目录下,然后在frontend的bind指令里指定这个目录:frontend ssl_proxy bind *:443 ssl crt /etc/haproxy/certs/ mode tcp # 其他配置...HAProxy会自动根据客户端SNI请求,从目录里找到对应域名的证书返回。
方式2:用ACL+指定证书
如果需要更精准的控制,可以通过ACL匹配SNI,然后指定对应证书:frontend ssl_proxy bind *:443 ssl mode tcp acl sni_amazon req.ssl_sni -i www.amazon.com acl sni_intel req.ssl_sni -i www.intel.com use_backend amazon_backend if sni_amazon use_backend intel_backend if sni_intel # 绑定对应证书到backend backend amazon_backend mode tcp server amazon www.amazon.com:443 ssl crt /etc/haproxy/certs/www.amazon.com.pem backend intel_backend mode tcp server intel www.intel.com:443 ssl crt /etc/haproxy/certs/www.intel.com.pem这种方式适合需要单独配置后端的场景。
2. 通配子域名的SSL透传配置
要实现*.oracle.com、*.lenovo.com这类通配子域名的透传,关键是用正则匹配SNI,然后统一转发到对应主域名的后端,不用逐个注册子域名。
解决方案:
在TCP模式的frontend里,用正则ACL匹配SNI,然后将请求转发到对应后端:
frontend tcp_ssl_proxy bind *:443 mode tcp # 正则匹配所有oracle子域名 acl sni_oracle req.ssl_sni -m reg ^.*\.oracle\.com$ # 正则匹配所有lenovo子域名(包括主域名) acl sni_lenovo req.ssl_sni -m reg ^(.*\.lenovo\.com|lenovo\.com)$ # 匹配后转发到对应后端 use_backend oracle_backend if sni_oracle use_backend lenovo_backend if sni_lenovo # 默认后端处理其他请求 default_backend default_backend backend oracle_backend mode tcp # 直接透传到oracle的官方HTTPS端口,支持动态DNS解析需要配置resolvers server oracle oracle.com:443 resolvers dns_resolvers backend lenovo_backend mode tcp server lenovo lenovo.com:443 resolvers dns_resolvers # 配置DNS解析器,让HAProxy能动态解析后端域名 resolvers dns_resolvers nameserver dns1 8.8.8.8:53 nameserver dns2 8.8.4.4:53 resolve_retries 3 timeout resolve 5s timeout retry 2s hold valid 30s
这样所有xxx.oracle.com、yyy.lenovo.com的请求都会被自动匹配并透传,无需逐个配置子域名。
3. HTTP转HTTPS重定向偶发失效
偶发失效通常和请求不匹配ACL规则、客户端缓存或者HAProxy配置遗漏有关,我们可以从这几个方向排查:
解决方案:
优化HTTP前端的重定向配置
确保你的HTTP前端配置能覆盖所有可能的请求场景,比如忽略Host头大小写、包含主域名和子域名:frontend http_proxy bind *:80 mode http # 匹配所有lenovo和oracle相关域名(包括子域名) acl target_domains hdr(host) -i lenovo.com *.lenovo.com oracle.com *.oracle.com # 对非HTTPS请求强制重定向到HTTPS redirect scheme https code 301 if target_domains !{ ssl_fc } # 可选:对所有HTTP请求都重定向(如果不需要区分域名) # redirect scheme https code 301 if !{ ssl_fc }这里用
-i忽略大小写,避免因为Host头大小写不一致导致ACL不匹配。排查偶发失效的具体场景
- 查看HAProxy的访问日志,添加
capture request header Host len 64到HTTP前端,记录失效请求的Host头,确认是否符合ACL规则; - 检查客户端是否缓存了旧的HTTP响应:301是永久重定向,客户端会长期缓存,如果之前配置有误,可能需要用户清除浏览器缓存,或者临时改用302临时重定向测试;
- 确认所有HTTP请求都到达了HAProxy:检查网络拓扑,确保客户端的80端口请求没有被其他设备拦截。
- 查看HAProxy的访问日志,添加
内容的提问来源于stack exchange,提问作者user7416378

