我正在以TLS(基于客户端证书的身份验证)的TCP模式运行HAProxy。我的配置粘贴在下面。我的目标是根据提供的客户端证书将SSH连接重定向到正确的服务器。此示例讨论SSH,但将来我可能需要以这种方式安全地公开各种服务。任何帮助表示赞赏。
请注意,在HTTPS模式下,您可以使用类似方法来提取客户端CN,并针对ACL使用标头中的变量。但是,由于我处于TCP模式,因此不确定如何执行类似操作。
http请求设置标头X-SSL-Client-CN%{+ Q} [ssl_c_s_dn(cn)]
但是,我不确定在TCP模式下运行时如何做类似的事情。
frontend Frontend_server
mode tcp
option tcplog
log global
bind X.X.X.X:8000 ssl crt /etc/certs/server.pem ca-file /etc/certs/ca.crt verify required
acl ACL_SRV1 ??????? -m str -f /etc/SRV1/cn.list
acl ACL_SRV2 ??????? -m str -f /etc/SRV2/cn.list
acl ACL_SRV3 ??????? -m str -f /etc/SRV3/cn.list
log-format %ci:%cp\ [%t]\ %ft\ %b/%s\ %ST\ %B\ %tsc\ %ac/%fc/%bc/%sc\ %sq/%bq\ {%[ssl_c_verify],%{+Q}[ssl_c_s_dn],%{+Q}[ssl_c_i_dn]
use_backend SRV1 if ACL_SRV1
use_backend SRV2 if ACL_SRV2
use_backend SRV3 if ACL_SRV3
backend SRV1
mode tcp
option tcplog
option tcp-check
server MY_SRV1 X.X.X.X:22 check inter 1000 port 22 maxconn 1000
backend SRV2
mode tcp
option tcplog
option tcp-check
server MY_SRV2 X.X.X.X:22 check inter 1000 port 22 maxconn 1000
backend SRV3
mode tcp
option tcplog
option tcp-check
server MY_SRV3 X.X.X.X:22 check inter 1000 port 22 maxconn 1000
答案 0 :(得分:1)
在tcp模式下,TLS不会在HAProxy处终止,但是TLS终止是在haproxy之后的服务器上完成的。在将任何数据发送或转发到服务器之前,必须先知道该服务器。这意味着只能根据TLS握手(ClientHello)中来自客户端的第一个数据来决定选择哪个服务器,而不能决定已经需要服务器回复的以后的数据。
但是,客户端证书仅在服务器明确请求时才由客户端发送。这意味着,为了从客户端获取客户端证书,服务器需要与客户端进行通信,这意味着必须已经建立与服务器的连接。当然,这意味着不能基于客户端证书来决定使用哪个服务器,因为客户端证书在TLS握手中太晚了。
基于客户端证书做出此类决定的唯一方法是已经在负载均衡器上终止TLS。