HAProxy:无法在未经验证的情况下转发标头中的客户端证书

问题描述

我有一个双向 TLS 设置,HAProxy 会终止传入的 SSL 连接。我需要在后端执行客户端证书验证,而不是在 haproxy 端,因为我们有一个动态信任库,我不能只设置一个 ca 文件并将所有验证逻辑委托给 haproxy。 常规设置工作正常(haproxy 根据 CA 证书验证客户端证书):

bind *:443 ssl crt /etc/certs/haproxy.pem verify required ca-file /etc/certs/ca.crt
http-request redirect scheme https unless { ssl_fc }
http-request set-header X-SSL-ClientCert          %{+Q}[ssl_c_der,base64]

后端正确接收 X-SSL-ClientCert,但这还不够。 如果去掉 verify required ca-file /etc/certs/ca.crt 跳过 haproxy 验证,在后端读取时 X-SSL-ClientCert 为空,即 HAProxy 不再使用客户端证书设置 header。有关如何解决此问题的任何想法?

解决方法

好吧,经过一番修补后,我偶然发现了以下内容:

HAProxy 文档 https://cbonte.github.io/haproxy-dconv/2.3/configuration.html#5.2-verify 说明了 verify 的两个选项:[none|required],但似乎有一个未记录的选项,即 optional 似乎可以解决问题:

bind *:443 ssl crt /etc/certs/haproxy.pem verify optional ca-file /etc/certs/ca.crt
http-request set-header X-SSL-Client-Cert          %{+Q}[ssl_c_der,base64]
http-request set-header X-SSL-Client-CN            %{+Q}[ssl_c_s_dn(cn)]
http-request set-header X-SSL-Client-Verify        %[ssl_c_verify]
,

你的想法是正确的。

另一方面,我认为有一个更具可读性的文字。

在你的 /etc/hapee/hapee-lb.cfg

bind :443 ssl crt-list /etc/hapee/certs-file

在您的 /etc/hapee/certs-file 中

cert_example1.pem [verify optional ca-file /etc/hapee/certs/ca.crt]
cert_example2.pem

因此您可以根据您的 SNI 轻松列出所有证书以及可能的验证选项。

匹配的后端

backend
        http-request set-header X-SSL-Client-DN            %[ssl_c_s_dn]
        http-request set-header X-SSL-Client-Cert          %{+Q}[ssl_c_der,base64]
        http-request set-header X-SSL-Client-CN            %{+Q}[ssl_c_s_dn(cn)]
        http-request set-header X-SSL-Client-Verify        %[ssl_c_verify]