HAProxy 要求客户端在特定 URL 上提供证书并将其转发到后端

HAProxy 要求客户端在特定 URL 上提供证书并将其转发到后端
frontend  front
bind *:80
bind *:443 ssl crt /etc/haproxy/certs/server.pem ca-file /etc/haproxy/certs/id.crt verify required 
option tcplog
mode http    
default_backend app

backend app    
balance roundrobin
cookie SERVERID insert
option ssl-hello-chk
mode http
option httpclose
option forwardfor     
option httpchk get /WebApi/help
server  app1 1.1.1.1:443 check ssl fall 1 rise 3 verify none cookie webA
server  app2 1.1.1.2:443 check ssl fall 1 rise 3 verify none cookie webB

对于某个页面 /login/idcard 我需要客户端证书并将其发送到后端(IIS),后端将使用它进行身份验证,我找不到在特定路径上请求证书的方法,证书转发到后端也不起作用,以前的配置是使用“模式 tcp”,它将所有内容转发到 IIS 并且它可以工作,但我需要使用“acl”将具有特定路径的请求转发到另一台服务器,但“acl”在 https 中不起作用,所以它应该是 http

答案1

您无法为某个路径请求证书,因为 TLS 协商在知道该路径之前就已经完成,因此一旦您知道该路径,就太晚了。

类似地,不可能“转发”客户端证书——如果此代理处于启用状态,mode http则有两个 TLS 会话——一个在客户端和代理之间,另一个在代理和后端服务器之间。代理没有客户端证书的私钥,因此它无法使用客户端证书与后端协商 TLS。如果可以在不拥有私钥的情况下使用某人的客户端证书,则客户端证书将毫无用处——证书也是公钥,而公钥是“公开的”,因为它们本身并不代表任何有价值的东西。

可以转发属性客户端提供的证书,通过在代理中将它们设置为 HTTP 请求标头来使用第 5 层获取但这可能无法满足需要查看实际证书的后端。

甚至可以将整个客户端证书注入到后端的请求标头中……

http-request set-header X-Client-Certificate %[ssl_c_der,base64]

...但这不太可能在您描述的场景中有用。

类似地,您可以使用bind ... ssl ... verify optional而不是required,然后阻止对特定路径的请求,除非已经出示了证书......

http-request deny if { path_beg /login/idcard } !{ ssl_fc_has_crt }

...这将使证书成为可选的,但如果尚未提供证书,则拒绝带有此路径前缀的请求。

再次强调,从技术上来说,这是有效的,但不一定是你真正需要的。

相关内容