web-dev-qa-db-ja.com

haproxy + stunnel + keep-alive?

HTTPSトラフィックを処理するためにhaproxy 1.4の前にstunnelを配置したいと思います。 X-Forwarded-Forヘッダーを追加するためのstunnelも必要です。これは、haproxyウェブサイトの "stunnel-4.xx-xforwarded-for.diff" patches によって実現できます。

ただし、説明では次のように述べています。

このパッチはキープアライブでは機能しないことに注意してください...

私の質問は、これは実際に私にとって何を意味するのでしょうか?わからない

  1. これがキープアライブに関するものである場合
    • クライアントとstunnel
    • stunnelとhaproxy
    • またはhaproxyとバックエンドサーバー?
  2. これがパフォーマンスに与える意味:Webページに100個のアイコンがある場合、ブラウザーは100個の完全なSSL接続をネゴシエートする必要がありますか、または新しいTCP接続?
10
Chris Lercher

これは、単一のTCP=セッション(およびSSLの場合、単一のSSLセッション)を介して複数のリソース要求を受信できるようにするHTTPキープアライブに関するものです。これはパフォーマンスにとって非常に重要ですSSLサイトの場合、キープアライブがないため、要求された各リソースに対してSSLハンドシェイクが必要になります。

したがって、ここでの懸念は、クライアントからバックエンドサーバーまでの1つの大きなキープアライブセッションです。これはパフォーマンスにとって重要なことであり、最近のHTTPサーバーでは当然のことと考えられていますが、このパッチはそれをサポートしていないと言っています。その理由を見てみましょう。


キープアライブセッションは、次々と要求が増えるだけです。サーバーが1つの要求に対する応答を完了すると、サーバーはFINパケットを送信してTCPを終了しませんセッション;クライアントは単にヘッダーの別のバッチを送信できます。

このパッチの機能を理解するために、キープアライブの会話の例を次に示します。

クライアント:

GET / HTTP/1.1
Connection: keep-alive
Host: domain.com
...

サーバ:

HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Server: Apache
Content-Length: 34
.... (other headers)
<html><head>content!</head></html>

ここで、非キープアライブ接続が停止します。ただし、キープアライブを使用すると、クライアントは別のクライアントを起動できます。

GET /images/some/image.on.the.page.jpg HTTP/1.1
Connection: keep-alive
Host: domain.com
...

プロキシのクライアントIDの場合、一部のリバースプロキシは、各クライアント要求のX-Forwarded-Forヘッダーに追加できます。これにより、ロギングやその他のアプリケーションのニーズの健全性のために、要求が(リバースプロキシのIPから開始されるすべての要求の代わりに)どこから来ているかを上流のサーバーに伝えます。

X-Forwarded-Forヘッダーは、ヘッダー全体が毎回送信されるため、キープアライブ接続を介して送信されるすべてのクライアントリソース要求に挿入する必要があります。 X-Forwarded-Forヘッダーの処理と「実際の」要求IPへの変換は、TCPキープアライブセッションごとではなく、要求ごとに行われます。そして、ねえ、単一のキープアライブセッションを使用して複数のクライアントからの要求にサービスを提供する素晴らしいリバースプロキシソフトウェアがあるかもしれません。

これは、このパッチが失敗する場所です。


そのサイトのパッチは、TCPセッションのバッファーでストリームの最初のHTTPヘッダーセットの終わりを監視し、その最初のヘッダーセットの終わりの後に新しいヘッダーをストリームに挿入します。 。これが完了すると、X-Forwarded-Forジョブが完了したと見なされ、新しいヘッダーセットの終わりのスキャンが停止されます。このメソッドは、後続のリクエストを介して受信する将来のヘッダーをすべて認識しません。

それらを実際に非難することはできません。 stunnelは、ストリームのコンテンツの処理と変換を行うために実際に構築されたのではありません。

これがシステムに与える影響は、キープアライブストリームのfirstリクエストがX-Forwarded-Forヘッダーを適切に挿入し、後続のリクエストはすべて正常に機能することです。ただし、ヘッダーはありません。

接続ごとに複数のクライアント要求を処理できる別のヘッダーインジェクションパッチがない場合(または、スタックオーバーフローで友人の助けを借りてこれを調整できる場合)を除き、SSL終了の他のオプションを確認する必要があります。

12
Shane Madden

STunnel 4.45は、HAProxy 1.15に付属するいくつかの新機能(プロキシプロトコル)を使用してこれを適切に修正します

以前のパッチとキープアライブの問題も修正します

5
Ben Walding

別のスレッドで投稿したのと同様に、HAProxyは1.5-dev12以降、ネイティブSSLを両側でサポートしています。したがって、X-Forwarded-For、HTTPキープアライブ、および接続がSSLを介して行われたことをサーバーに通知するヘッダーを持つことは、次のように簡単です。

listen front
    bind :80
    bind :443 ssl crt /etc/haproxy/haproxy.pem
    mode http
    option http-server-close
    option forwardfor
    reqadd X-Forwarded-Proto:\ https if { is_ssl }
    server srv1 1.1.1.1:80 check ...
    ...

Stunnelにパッチを適用するよりもはるかに簡単で、キープアライブをドロップする必要があるよりもはるかに優れています。

3
Willy Tarreau

Shaneの優れた回答を拡張して、HAproxyの前でSSLターミネーターとしてNginxを使用できます。クライアントとnginxの間のキープアライブを正しく処理します。これは、最もレイテンシの影響を受けやすい側面であり、各クライアント要求に対してバックエンドへの新しい接続を作成し、それぞれにX-FORWARDED-FORを送信します。

2
Ochoto