web-dev-qa-db-ja.com

https実サーバーとクライアント証明書を備えたApacheロードバランサー

ネットワーク要件では、すべてのネットワークトラフィックを暗号化する必要があると規定されています。

ネットワーク構成は次のようになります。

                                                              ------------
                                                /-- https --> | server 1 | 
                                               /              ------------
|------------|               |---------------|/               ------------
|   Client   | --- https --> | Load Balancer | ---- https --> | server 2 |
|------------|               |---------------|\               ------------
                                               \              ------------
                                                \-- https --> | server 3 |
                                                              ------------

また、クライアント証明書を渡す必要があります。

私は透明な実サーバーで負荷分散を行うことができる設定を持っています:

<VirtualHost *:8666>

    DocumentRoot "/usr/local/Apache/ssl_html"
    ServerName vmbigip1
    ServerAdmin [email protected]
    DirectoryIndex index.html


   <Proxy *>
        Order deny,allow
        Allow from all
   </Proxy>

    SSLEngine on
    SSLProxyEngine On
    SSLCertificateFile /usr/local/Apache/conf/server.crt
    SSLCertificateKeyFile /usr/local/Apache/conf/server.key


   <Proxy balancer://mycluster>
       BalancerMember http://1.2.3.1:80
       BalancerMember http://1.2.3.2:80
       # technically we aren't blocking anyone, but could here
       Order Deny,Allow
       Deny from none
       Allow from all
       # Load Balancer Settings
       # A simple Round Robin load balancer.
       ProxySet lbmethod=byrequests
   </Proxy>

   # balancer-manager
   # This tool is built into the mod_proxy_balancer module allows you
   # to do simple mods to the balanced group via a gui web interface.
   <Location /balancer-manager>
       SetHandler balancer-manager
       Order deny,allow
       Allow from all
   </Location>

    ProxyRequests Off
    ProxyPreserveHost On

    # Point of Balance
    # Allows you to explicitly name the location in the site to be
    # balanced, here we will balance "/" or everything in the site.
    ProxyPass /balancer-manager !
    ProxyPass / balancer://mycluster/ stickysession=JSESSIONID
</VirtualHost>

ロードバランサーのサーバーが

       BalancerMember https://1.2.3.1:443
       BalancerMember https://1.2.3.2:443

しかし、それはうまくいきません。 SSLネゴシエーションエラーが発生します。

これを機能させる場合でも、クライアント証明書を渡す必要があります。

任意の助けいただければ幸いです。

6
Jack Scheible

単にできないユーザー証明書を要求するバックエンドノードでクライアント証明書を直接使用し、ロードバランサーがSSLを「終了」する場所エンドユーザーからの/ TLS接続。

クライアント証明書を使用したSSL/TLSハンドシェイクでは、クライアントとサーバー間で交換されるすべてのハンドシェイクメッセージに最後に署名する必要があります。つまり、クライアントは、クライアント証明書を要求する実際のSSL/TLSサーバーに直接接続する必要があります。ブラウザーのSSL/TLS接続がロードバランサーまでしか行かない場合、バックエンドノードへのクライアントはロードバランサーです。バックエンドノードには別のハンドシェイクが表示され、これは失敗します。

これを回避するには2つの方法があります。

  • DNSまたはTCPベースのロードバランサー(例:ipchains)を使用します。この場合、ブラウザーからのSSL/TLS接続はバックエンドノードに直接接続されます。直接クライアント証明書認証が可能になります。

  • ロードバランサーにクライアント証明書認証を実行させ、その情報をバックエンドノードに伝達するだけです。これには、バックエンドノードが検証を正しく行うためにロードバランサーを信頼する必要がありますが、バックエンドノードがロードバランサーを信頼できない場合、それを使用しても意味がありません。

    mod_proxy_ajp(またはmod_jk)は、クライアント証明書をAJPプロトコルの一部として転送できますが、これは主にJavaコンテナ用であり、AJPトラフィックは暗号化されていません。

    mod_proxy_httpを使用している場合は、mod_headerなどのヘッダーを追加して、RequestHeader set X-ClientCert %{SSL_CLIENT_CERT}sなどのHTTPヘッダーを介して証明書を渡すことができます。正確な詳細を思い出すことはできませんが、このヘッダーがクリアされていることを確認して、クライアントのブラウザー(他のユーザーが偽造する可能性があるブラウザー)から送信されないようにすることが重要です。バックエンドノードで実行しているどのアプリケーションでも、そのヘッダーから認証情報を取得できる必要があります(そして、ロードバランサーによって既に検証されていると信頼できる)。

    SSLCACertificateFile/Pathを使用してApache Httpdで通常のクライアント証明書認証を構成する必要があるSSLVerifyClientおよびmod_sslディレクティブに加えて、バックエンドへのSSL/TLSクライアントとしてApache Httpdを構成するためにSSLProxyCheckPeerCN onおよびSSLProxyCACertificateFile/Pathも構成する必要があります。ノード(mod_proxyディレクティブについては SSLProxy*ドキュメントの紹介を参照 を参照)。

    バックエンドサーバーで、リクエストが別のクライアントではなくロードバランサーからのものであることを確認したい場合(直接接続を作成できる)、ロードバランサーにクライアント証明書も使用させることができます(SSLProxyMachineCertificateFileを使用) )、バックエンドのメモに対して認証します。これにより、バックエンドの認証システムがそれほど複雑にならないことに注意してください。実際に取得するクライアント証明書の認証は、プロキシ(通常どおり確認する必要がある)の認証ですが、それらのアプリケーションアプリケーションユーザーに関する限り、サーバーはヘッダーベースのクライアント証明書を使用するように構成する必要があります。

8
Bruno

SSL構成が不完全に見えます。クライアント証明書を要求するには、追加する必要があります

SSLVerifyClient require
SSLVerifyDepth  1
SSLCACertificateFile <your CA cert file>

詳細は クライアントに証明書を使用して強制的に認証させる方法 を参照してください。

必須かどうかはわかりませんが、 SSLCipherSuite ディレクティブもありません。このようにすると、弱い暗号を整理して、 [〜#〜] beast [〜#〜] 攻撃に対してできることを実行できます。

SSLHonorCipherOrder On
SSLCipherSuite RC4-SHA:ALL:!ADH:!EXPORT:!LOW:!MD5:!SSLV2:!NULL
2
f_puras