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
для определенной страницы / логина / идентификатора мне нужно потребовать сертификат клиента и отправить его на бэкэнд (IIS), который будет использовать его для аутентификации, я не могу найти способ запросить сертификат по определенному пути, и пересылка сертификата на бэкэнд также не работает, предыдущий config использовал «режим tcp», который перенаправляет все в IIS, и он работал, но мне нужно использовать «acl» для пересылки запроса с определенным путем на другой сервер, но «acl» не работает в https, поэтому он должен быть http
Вы не можете запросить сертификат для определенного пути, потому что согласование 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 }
... это сделает сертификат необязательным, но отклонит запросы с этим префиксом пути, если сертификат еще не был представлен.
Опять же, технически корректно, но не обязательно то, что вам действительно нужно.