tcp - HAProxy - TCP 模式下基于 Client CN 的 ACL
问题描述
我在 TCP 模式下使用 TLS(基于客户端证书的身份验证)运行 HAProxy。我的配置粘贴在下面。我的目标是根据提供的客户端证书将 SSH 连接重定向到正确的服务器。此示例讨论 SSH,但将来我可能必须以这种方式安全地公开各种服务。任何帮助表示赞赏。
请注意,在 HTTPS 模式下,您可以使用类似的方法提取客户端 CN,并将标头中的变量用于 ACL。但是,由于我处于 TCP 模式,我不确定如何做类似的事情。
http-request set-header 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
解决方案
在 tcp 模式下,TLS 不会在 HAProxy 处终止,但 TLS 终止是在 haproxy 后面的服务器上完成的。在将任何数据发送或转发到服务器之前,当然必须知道该服务器。这意味着只能根据 TLS 握手 (ClientHello) 中来自客户端的第一个数据来决定选择哪个服务器,而不能在需要服务器回复的后续数据上进行。
但是,客户端证书只有在服务器明确请求时才由客户端发送。这意味着,为了从客户端获取客户端证书,服务器需要与客户端通信,这意味着必须已经建立与服务器的连接。这当然意味着不能基于客户端证书来决定使用哪个服务器,因为客户端证书在 TLS 握手中为时已晚。
根据客户端证书做出此类决定的唯一方法是已经在负载均衡器处终止 TLS。
推荐阅读
- symfony - 未触发 executeQuery 的教义事件
- excel - 为什么我不能将 Worksheets 对象变量初始化为 Worksheets 集合?
- android - 通过亚马逊应用商店在中国部署应用
- angular - 角度 6 中复杂对象的字符串插值
- ssh - SSH 卡在 client_input_global_request:rtype hostkeys-00@openssh.com want_reply 0
- eclipse - 如何将“ear”项目从 Eclipse 或 JBoss Studio 部署到 JBoss 或 Wildfly 应用服务器
- javascript - 使用 $near 和 $maxDistance 一起查询 MongoDB 不返回任何结果
- java - 如何通过给出月份中的星期和星期几来获取日期
- corda - generateSpend 源自另一个节点
- maven - IntelliJ IDEA 和 kendo 无法解析 taglib