HAProxy 1.6と 巧妙なハック を使用して、ブラウザーがSNIに対応しているかどうかを検出するHAProxy tcpモードフロントエンドを取得し、それに基づいて、強力に暗号化されたSSL終了バックエンドまたは弱いもの。これにより、SSLラボでのA +グレーディングが保証され、IE6を除くすべてのブラウザーでSSLを使用できます。
これが私の設定です。いくつかのテンプレート変数が含まれていますが、それは一目瞭然のはずですが、私の質問に関連する領域にはありません。
frontend https_incoming
bind 0.0.0.0:443
mode tcp
option tcplog
tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }
use_backend https_strong if { req.ssl_sni -m end .transloadit.com }
default_backend https_weak
backend https_strong
mode tcp
option tcplog
server https_strong 127.0.0.1:1665
frontend https_strong
bind 127.0.0.1:1665 ssl crt ${DM_ROOT_DIR}/envs/ssl/haproxy-dh2048.pem no-sslv3 no-tls-tickets ciphers ${strongCiphers}
mode http
option httplog
option httpclose
option forwardfor if-none except 127.0.0.1
http-response add-header Strict-Transport-Security max-age=31536000
reqadd X-Forwarded-Proto:\ https
reqadd FRONT_END_HTTPS:\ on
use_backend http_incoming
backend https_weak
mode tcp
option tcplog
server https_weak 127.0.0.1:1667
frontend https_weak
bind 127.0.0.1:1667 ssl crt ${DM_ROOT_DIR}/envs/ssl/haproxy.pem no-sslv3 ciphers ${weakCiphers}
mode http
option httplog
option httpclose
option forwardfor if-none except 127.0.0.1
http-response add-header Strict-Transport-Security max-age=31536000
reqadd X-Forwarded-Proto:\ https
reqadd FRONT_END_HTTPS:\ on
use_backend http_incoming
問題:https_incoming
フロントエンドはクライアントIPを認識していますが、mode tcp
にあるため、この情報をmode http
X-Forwarded-For
ヘッダーに保存できません。 option forwardfor
はTCPモードでは無効です。
From serverfaultに関する別の質問 使用できることがすでにわかっています:
だから私が理解しているように、X-Forwarded-For
ヘッダーはもう必要ありません。LVSの場合:パケットはスプーフィングされてソースがクライアントIPになり、PROXYの場合:パケットはカプセル化されて運ばれますクライアントIP。
これらはどちらも機能するようです。しかし、LVSは副作用をもたらす可能性のある心臓外科のようですが、PROXYには、プロキシ/アプリケーションの上流/下流に完全な互換性がない可能性があるという欠点があります。
私はもっと軽量なものを本当に望んでいました、そしてそれが私が言及したように私がHAProxy 1.6の新しい "Capture"機能 を見つけたときです:
キャプチャスロットを宣言してデータを格納し、セッション中いつでも使用できます。
さらに、次の例を示します。
defaults
mode http
frontend f_myapp
bind :9001
declare capture request len 32 # id=0 to store Host header
declare capture request len 64 # id=1 to store User-Agent header
http-request capture req.hdr(Host) id 0
http-request capture req.hdr(User-Agent) id 1
default_backend b_myapp
backend b_myapp
http-response set-header Your-Host %[capture.req.hdr(0)]
http-response set-header Your-User-Agent %[capture.req.hdr(1)]
server s1 10.0.0.3:4444 check
それは私には見え、情報はフロントエンドに保存され、後でバックエンドで使用されるので、おそらくクライアントIPをTCPモードで取得し、保存して、後でそれを使用できます。行、たぶんそう:
http-response set-header X-Forwarded-For %[capture.req.hdr(0)]
私は capture docs を見てきましたが、httpモードヘッダーでキャプチャの方が向いているようですが、- メーリングリストカンバセーション の使用も正常に示しています。 tcp-request capture
。
私はいくつかのことを試しましたが、その中で:
tcp-request capture req.hdr(RemoteAddr) id 0
# or
tcp-request content capture req.hdr(RemoteHost) id 0
しかし、あなたが見ることができるように、私は構文がどうあるべきか、そしてどのキーの下でこの情報が利用可能であるのか手がかりを持っていません、そして私はそれを (私は)関連するドキュメント で見つけることができません。
質問:TCP=モードでクライアントIPをキャプチャし、後でこの情報をHTTPモードのX-Forwarded-For
ヘッダーに書き込むことができますか?可能であれば、どうしますか?この構文ですか?
私の質問に答えるために、トラフィックはここでHAProxyを「去る」ので、これは可能ではないようです:
TCP HTTP
frontend->backend (->leaving->) frontend->backend
そのため、コンテキストが失われ、キャプチャを保持できません。代わりに、「PiBa-NL」がIRC= Freenodeの#haproxyで昨日提案したように:
[5:29pm] PiBa-NL: kvz, use proxy-protocol between back and front
[5:54pm] kvz: PiBa-NL: Thanks, does this mean my app also needs to understand
the proxy protocol, or will it be 'stripped' once it reaches the
backend. I don't think my node.js server could handle it without
significant changes to its stack
[6:07pm] kvz: Or let me rephrase: could I enable the proxy protocol on the first
frontend, then 'unwrap' it in the second frontend, taking the client ip
and putting it into the http header - so that my app would not have to
be proxy protocol compatible, and it would just be means to carry the
client ip from first frontend to the second?
[6:49pm] PiBa-NL: kvz, the last part you can still use the x-forwarded-for header
[6:50pm] PiBa-NL: but between haproxy backend and frontend you would use the
proxyprotocol to make the second frontent 'know' the original client ip
[6:50pm] PiBa-NL: server https_strong 127.0.0.1:1665 send-proxy
[6:50pm] PiBa-NL: bind 127.0.0.1:1665 ssl crt .... accept-proxy
[6:52pm] PiBa-NL: the second frontend can then still use the
'option forwardfor', and it should insert the wanted header
[6:53pm] PiBa-NL: so basically 'yes'
つまり、PROXYプロトコルは、2つのフロントエンドを接着してCient IPをカプセル化するためにのみ使用されますが、2番目のフロントエンドはラップを解除し、X-Forwarded-For
を介してoption forwardfor
ヘッダーに保存するため、バックエンドが送信できます。アプリサーバーへのプロキシプロトコルを使用しないリクエスト。つまり、上流/下流の互換性の問題を心配する必要はありません。
HAProxyはすでにX-Forwarded-Forヘッダーを追加しているはずです。これらのいずれかが非標準である場合は、プロトコルまたはポート、あるいはその両方を追加することができます。
私は通常、このような動作を、リクエストヘッダーをエコーするページでテストします。これにより、使用可能なヘッダーとその内容を簡単に確認できます。
X-Forward-Forがアドレスのリストを含むことは珍しいことではありません。これは、リクエストが複数のプロキシを通過したか、誰かがヘッダーをスプーフィングしていることを示しています。右端のアドレスは、要求を処理した最後のプロキシ(ha-proxy)によって追加されたアドレスになります。
一部のWebサーバーは、接続ではなくヘッダーからIPアドレスを記録するように構成できます。これは、アクセスログや、着信接続のIPアドレスに基づいてヘッダーを生成する場合に役立ちます。
2つの異なるスタックを使用せずに、IE 6を除くすべてのリストされたブラウザーをサポートしながら、A +レーティングを達成することは可能です。
WinXP/IE8とJava 6は安全なプロトコルを使用したForward Secrecyをサポートしていないので、テストはその失敗に対して不利になりません。他のすべてのブラウザーはサーバーの順序付けを強制する場合にForward Secrecyを使用します。(成功しない場合、Win Phoneは失敗します。)
A +の評価では、少なくとも180日間の期間でStrict-Transport-Securityを設定する必要があります。