我们有一个带有 HAProxy(pfSense)和多个 Web 服务器的防火墙。每个 Web 服务器都配置了 HTTPS。HAProxy 前端规则已定义Server Name Indication TLS extension matches
,Web 服务器已定义为后端(都非常相似)。
摘录 HAProxy 配置(域/ip 已替换)
frontend HAProxy_443-merged
bind 1.2.3.4:443 name 1.2.3.4:443
mode tcp
log global
option log-separate-errors
timeout client 45000
tcp-request inspect-delay 5s
acl sub1example req.ssl_sni -m end -i sub1.example.com
acl sub2example req.ssl_sni -m end -i sub2.example.com
...
tcp-request content accept if { req.ssl_hello_type 1 }
use_backend sub1.example.com_ipvANY if sub1example
use_backend sub2.example.com_ipvANY if sub2example
...
backend sub1.example.com_ipvANY
mode tcp
id 159
log global
timeout connect 30000
timeout server 30000
retries 3
server sub1.example.com 192.168.1.80:443 id 160 check inter 1000
...
所有域名本身都运行正常,但同一浏览器中的某些子域名(同一根域名,例如 *.example.com)存在问题。
描述:
如果您在 30 秒内在同一浏览器会话中访问不同的子域,则流量将路由到第一个 Web 服务器/后端。如果您重新加载页面,它将更新此未知会议. 约 30 秒后,会议已关闭,您可以访问正确的页面。
但有些子域名没有这些问题。
顺便说一句:它无法通过 Postman 之类的工具重现。
我调查了前端和后端的 HAProxy 设置,检查了响应标头并尝试调试 ssl 握手,但我找不到问题的相似之处或正常工作和有问题的 Web 服务器/后端之间的差异。
有人意识到这个问题吗?提前致谢。
答案1
如果多个内部服务器具有多域证书(或通配符证书),其中证书涵盖的不同域由不同的内部服务器处理,则可能会发生这种情况。
假设一个证书同时具有 A.example.com 和 B.example.com 的主题备用名称。如果客户端通过 haproxy 创建与 A.example.com 的 HTTP/2 连接,它将嗅探初始 TLS ClientHello 并将流量转发到负责 A.example.com 的服务器 A。如果客户端访问 B.example.com,浏览器可能会决定使用相同的 TCP 连接,因为根据证书,它对 A.example.com 和 B.example.com 都有效。请参阅RFC 7540 第 9.1.1 节。连接重用HTTP/2 标准中允许这样做的相关部分。
现在,服务器 A 可能无法处理 B.example.com 的请求。在这种情况下,服务器应发出代码为 421“错误定向请求”的响应,在这种情况下,客户端(浏览器)可能会使用新的 HTTP/2 连接重复该请求。如果服务器没有创建这样的响应,客户端就不知道问题所在,也无法采取相应的措施。
在 haproxy 中无法修复此问题,因为 haproxy 只会根据初始 ClientHello 决定将数据转发到何处。相反,必须通过让服务器回复 421 或确保证书仅涵盖服务器实际服务的域来修复此问题。
也可以看看421 错误请求和HTTP/2 连接池破坏了 SNI 主机。