为什么即使在 HAProxy 中配置了多个证书,浏览器也始终只显示一个服务器的证书?

为什么即使在 HAProxy 中配置了多个证书,浏览器也始终只显示一个服务器的证书?

我是 HAProxy 的新手。我有四台虚拟机,其中一台装有 HAProxy,另外三台装有 Apache httpd。我想要实现的是,当用户使用 https 连接到 HAProxy IP 时,连接应该重定向到其他三台服务器中的任何一台。请参阅下面的配置;

global
    maxconn 50000
    log /dev/log local0
    log /dev/log local1 notice
    user root
    group root
    stats timeout 30s
    nbproc 2
    cpu-map auto:1/1-4 0-3
    ssl-default-bind-ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
    ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
    daemon

defaults
    mode http
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms

frontend ft_http
    bind :80
    mode http
    default_backend bk_http

frontend ft_https
    bind :443 ssl crt-list /etc/haproxy/crt-list.txt
    mode tcp
    default_backend bk_https

backend bk_http
    mode http
    balance roundrobin
    default-server inter 1s
    server testserver1 192.168.0.1:80 check
    server testserver2 192.168.0.2:80 check
    server testserver3 192.168.0.3:80 check

backend bk_https
    mode tcp
    balance roundrobin
    stick-table type ip size 200k expire 1m
    default-server inter 1s
    server testserver1 192.168.0.1:443 check
    server testserver2 192.168.0.2:443 check
    server testserver3 192.168.0.3:443 check

下面是它的样子crt-list.txt

/etc/haproxy/testserver1.pem testserver1
/etc/haproxy/testserver2.pem testserver2
/etc/haproxy/testserver3.pem testserver3

我已经通过引用这些网址生成了证书https://www.techrepublic.com/article/how-to-enable-https-on-apache-centos/https://www.suse.com/support/kb/doc/?id=000018152

现在,每当我在浏览器中点击 https://haproxy_ip 时,浏览器都会提示未签名的证书,并且它始终属于testserver1。其他两台服务器的证书未被获取。

并且,当我接受证书并继续时,我得到一个包含以下内容的页面;

# Bad Request

Your browser sent a request that this server could not understand.
Reason: You're speaking plain HTTP to an SSL-enabled server port.
Instead use the HTTPS scheme to access this URL, please.

Apache/2.2.34 (Amazon) Server at testserver1.localdomain Port 443

每当我重新加载页面时,消息的最后一行都会像Apache/2.2.34 (Amazon) Server at testserver2.localdomain Port 443和一样发生变化Apache/2.2.34 (Amazon) Server at testserver2.localdomain Port 443(但是当我获取证书时,它是我为其创建的证书testserver1

现在,我的问题是,为什么我总是获得证书testserver1

提前致谢。

答案1

HAproxy 提供的证书没有负载平衡。

前端始终为 SNI 握手中使用的主机名提供最佳证书。最佳证书是证书CNSAN证书中的条目与请求中使用的 URI 匹配的证书,如果无法找到匹配项,则使用默认证书。

选项crt-list使用第一个条目作为默认证书。

此外,前端提供的证书与 HAProxy 连接的后端服务器无关。
除非您的负载均衡器在 TCP/IP 级别运行并且仅转发连接,否则负载均衡器就是中间人;客户端连接到负载均衡器,负载均衡器与后端建立自己的新连接以转发请求

来自手册:

绑定行中第一个声明的证书用作默认证书(来自crtcrt-list选项),如果没有其他证书匹配,haproxy 应在 TLS 握手中使用该证书。如果提供的 SNI 与其 CN 或 SAN 匹配,即使在任何 crt-list 上找到匹配的 SNI 过滤器,也将使用此证书。SNI 过滤器 !* 可在第一个声明的证书之后使用,以不将其 CN 和 SAN 包含在 SNI 树中,因此除非没有其他证书匹配,否则它永远不会匹配。这样,第一个声明的证书就可以作为后备

相关内容