HAProxy 需要特定 url 上的客户端证书并将其转发到后端

jet*_*q q 2 certificate https haproxy

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
Run Code Online (Sandbox Code Playgroud)

对于某些页面/登录名/身份证,我需要要求客户端证书并将其发送到后端(IIS),后者将使用它进行身份验证,我找不到在某些路径上询问证书的方法,并且证书转发到后端也不起作用,以前config 正在使用“mode tcp”,它将所有内容转发到 IIS 并且它正在工作,但我需要使用“acl”将具有特定路径的请求转发到另一台服务器,但“acl”在 https 中不起作用,因此它应该是 http

Mic*_*bot 6

不能要求某条路径的证书,因为在知道路径之前TLS协商已经完成,所以一旦知道路径就为时已晚。

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

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

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

http-request set-header X-Client-Certificate %[ssl_c_der,base64]
Run Code Online (Sandbox Code Playgroud)

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

同样,您可以使用bind ... ssl ... verify optional代替required,然后阻止对特定路径的请求,除非已提供证书...

http-request deny if { path_beg /login/idcard } !{ ssl_fc_has_crt }
Run Code Online (Sandbox Code Playgroud)

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

同样,技术上有效,但不一定是您真正需要的。