我有一台 HAProxy 1.5.9 服务器,它将提供由自签名 CA 签名的证书或 Let's Encrypt 证书,具体取决于提供的“服务器名称”。这是我的配置文件:
defaults
mode tcp
option clitcpka
listen ft_app
bind *:5000 ssl crt /certs/private.pem ca-file /app/certs/self-signed-ca.pem crt /certs/self-signed.pem crt /app/certs/lets-encrypt.pem ciphers AES:ALL:!aNULL:!eNULL:!3DES:!DES:!RC4:!DHE:!EDH:!MD5:!PSK:!aECDH:@STRENGTH no-sslv3 no-tlsv10 no-tlsv11
mode tcp
option tcplog
tcp-request inspect-delay 10s
use_backend app_http if HTTP
default_backend app_tcp
backend app_http
mode http
option httplog
balance roundrobin
reqadd X-Forwarded-Proto:\ https
cookie SRVID insert indirect nocache
http-check expect status 200
server app_4 10.10.10.4:15672 cookie app_4 check inter 10s rise 2 fall 2
server app_3 10.10.10.3:15672 cookie app_3 check inter 10s rise 2 fall 2
server app_2 10.10.10.2:15672 cookie app_2 check inter 10s rise 2 fall 2
backend app_tcp
option tcp-check
server app_4 10.10.10.4:5672 check inter 10s rise 2 fall 2
server app_3 10.10.10.3:5672 check inter 10s rise 2 fall 2
server app_2 10.10.10.2:5672 check inter 10s rise 2 fall 2
它有效。我不明白的是 HAProxy 究竟如何选择要提供的证书。我认为这是从证书元数据中获取“服务器名称”。如果是这样,那么究竟是哪个字段,我该如何检查它,openssl x509 -in ca.pem -text -noout
似乎没有任何可能的嫌疑人。
答案1
我明白了。请阅读原文。来自 HAProxy 文档:
https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#5.1-crt
证书将颁发给提供有效 TLS 服务器名称指示字段且该字段与其 CN 或 alt 主题之一匹配的客户端。支持通配符,即使用通配符“*”代替第一个主机名组件(例如:*.example.org 匹配 www.example.org 但不匹配 www.sub.example.org)。
如果客户端未提供 SNI,或者 SSL 库不支持 TLS 扩展,或者客户端提供的 SNI 主机名与任何证书均不匹配,则将显示第一个加载的证书。这意味着,当从目录加载证书时,强烈建议首先将默认证书作为文件加载,或确保它始终是目录中的第一个证书。
因此,它使用了 CN 或替代名称,或者默认为第一个提供的证书。我检查了 CN,结果不匹配,但后来我找到了替代名称:
X509v3 Subject Alternative Name:
DNS:myhost.example.com
这与我获得该证书时连接的域相匹配!因此,在我的情况下,Haproxy 使用替代名称选择证书,因为 CN 不是 FQDN。
答案2
TLS 证书中的服务器名称首先是显示为“通用名称”Subject: ... CN=www.example.com
当你拥有包含多个服务器名称的证书时,它被称为 SAN 证书https://en.m.wikipedia.org/wiki/Subject_Alternative_Name
并且与该证书有效的其他服务器名称是
DNS Name: example.com
DNS Name: www.example.om
DNS Name: ...
条目。
通过来自客户端的服务器名称指示,HAProxy 可以将请求的 URL 与可用的证书进行匹配。
如果客户端没有使用 sni 或者没有匹配的证书,HAProxy 可能会使用第一个证书作为默认证书(并且客户端会收到证书不匹配错误