web-dev-qa-db-ja.com

SSLパススルートラフィックを処理するHAProxyを使用したTCPスティッキーセッションの実装

SSLがバックエンドサーバーで終了する必要がある場合、HAProxyでセッションスティッキをどのように実装できますか?バックエンドはセッションを共有できないため、スティッキネスが必要です。

これは私の元の構成です:

# SSL passthrough
listen https_handler
    bind 1.2.3.4:443
    mode tcp
    balance leastconn
    stick match src
    stick-table type ip size 200k expire 30m
    server s1 1.1.1.1:443
    server s2 1.1.1.2:443

# haproxy logs (not sticking)
10.x.x.2:xxxxx [17/Dec/2014:19:29:41.396] fe BACKEND_Website/s1 37/0/1/3/41 200 8364
10.x.x.2:xxxxx [17/Dec/2014:19:29:41.456] fe BACKEND_Website/s1 36/0/1/1/39 200 9082
10.x.x.2:xxxxx [17/Dec/2014:19:29:41.456] fe BACKEND_Website/s2 35/0/1/3/39 200 2529
10.x.x.2:xxxxx [17/Dec/2014:19:29:41.545] fe BACKEND_Website/s1 35/0/0/3/38 200 1460
10.x.x.2:xxxxx [17/Dec/2014:19:29:41.501] fe BACKEND_Website/s2 36/0/1/1/109 200 376
10.x.x.2:xxxxx [17/Dec/2014:19:29:41.545] fe BACKEND_Website/s1 36/0/1/1/74 200 2298
10.x.x.2:xxxxx [17/Dec/2014:19:29:41.604] fe BACKEND_Website/s1 35/0/1/2/38 200 5542

以下の構成は、srcを読み取るための私の試みです

これにより、502 Bad Gatewayエラーが発生します。それは、トラフィックがバックエンドに到達するまでにすでに復号化されているためだと思います。

# terminate SSL at HAProxy 
listen https_handler
    bind 1.2.3.4:443 ssl crt /etc/ssl/certs/certs.pem
    mode tcp
    balance leastconn
    stick match src
    stick-table type ip size 200k expire 30m
    server s1 1.1.1.1:443
    server s2 1.1.1.2:443

証明書をバインディングに接続したことに注意してください。これは、HAProxyがsrcを読み取ってスティックテーブルをセットアップできるようにするためです。 (これが正しいかどうかはわかりません。)そして、この時点で、トラフィックはすでに復号化されています。

この暗号化されたトラフィックが暗号化されたトラフィックを期待するバックエンドサーバーに渡されるときに問題があると思います...

私はこれらの提案を見てきました:

  1. HAProxy 1.5でSSLを終了します-私の場合は不可能です。 SSLはバックエンドサーバーで処理する必要があります。
  2. スティッキーを維持するためにSSLセッションIDを使用します。-完全に理解していないため、これを試すのは懐疑的ですまだ。そして、それはhaproxyの変更(?)バージョンを使用しているようです。
  3. send-proxyディレクティブとX-Forward-Proto headerを使用します。 -しかし、これにはHTTPのみのバックエンドも必要です。

アドバイスをいただければ幸いです。

最も簡単な解決策は、balance source、ただし、多くのクライアントが同じIPからのものである場合、バックエンドサーバー上でそれほど公平ではない可能性があります。

これを実現する方法の詳細については、 http://blog.haproxy.com/2013/04/22/client-ip-persistence-or-source-ip-hash-load-balancing/ を参照してください。

2
Jim G.

問題の原因が、バックエンドサーバーがトラフィックをHTTPではなくHTTPSであると想定しているという事実である場合は、 encrypting HTTPを試して、通常のLayer7ロードバランシングを実行します。

listen https_handler
    bind 1.2.3.4:443 ssl crt /etc/ssl/certs/certs.pem
    mode http
    balance leastconn
    # any stick rules you need
    server s1 1.1.1.1:443 ssl
    server s2 1.1.1.2:443 ssl

さらに簡単です-どうせsrcに固執しようとしているようですが、なぜ最初にTCPトラフィックを復号化するのですか?

listen https
    bind 1.2.3.4:443 # <- NO ssl setting
    mode tcp
    balance leastconn
    stick match src
    stick-table type ip size 200k expire 30m
    server s1 1.1.1.1:443 ssl
    server s2 1.1.1.2:443 ssl

TCP=モードでは、ペイロードは気になりません。具体的には、暗号化されているかどうかとその方法は気にしません。

0
Felix Frank