web-dev-qa-db-ja.com

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)に送信する必要があります。特定のパスで証明書を要求する方法が見つからず、バックエンドへの証明書転送も機能しません。 configはすべてをIISに転送する「modetcp」を使用していましたが、機能していましたが、特定のパスでリクエストを別のサーバーに転送するには「acl」を使用する必要がありますが、「acl」はそうではありませんhttpsで作業しているので、httpである必要があります

1
jetcarq q

パスがわかる前にTLSネゴシエーションがすでに完了しているため、特定のパスの証明書を要求することはできません。パスがわかったら、手遅れです。

同様に、クライアント証明書を「転送」することはできません。このプロキシがmode httpにある場合、2つのTLSセッションがあります。1つはクライアントとプロキシの間、もう1つはプロキシとバックエンドサーバーの間です。プロキシにはクライアント証明書の秘密鍵がないため、クライアントの証明書を使用してバックエンドとTLSをネゴシエートすることはできません。秘密鍵を所有せずに誰かのクライアント証明書を使用できる場合、クライアント証明書は役に立ちません。証明書は公開鍵でもあり、公開鍵はそれ自体では表されないため、「公開」されます。価値のあるものなら何でも。

レイヤー5)を使用してプロキシでHTTP要求ヘッダーとして設定することにより、クライアントによって提示された証明書の属性を転送することができます。 fetches しかし、実際の証明書を確認する必要があるバックエンドを満足させることはできないでしょう。

クライアント証明書全体をバックエンドのリクエストヘッダーに挿入することも可能です...

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

...しかし、これがあなたが説明するシナリオで役立つ可能性は低いです。

同様に、requiredの代わりにbind ... ssl ... verify optionalを使用して、証明書がすでに提示されていない限り、特定のパスのリクエストをブロックできます。

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

...これにより、証明書はオプションになりますが、証明書がまだ提示されていない場合は、このパスプレフィックスが付いた要求を拒否します。

繰り返しますが、技術的には有効ですが、必ずしも本当に必要なものとは限りません。

5