最近、HAProxyを使用してWebサーバーへのプロキシアクセスを処理する必要がありました。 主な問題は暗号化されたアクセスでした。 誰がこのトピックに関心を持っていますか?
当社には多数のWebサーバーがあります。 アドレスを保存するために、アドレスへのアクセスはHAProxyを介して整理されます。 このようなもの:
同時に、HAProxy自体の構成は非常に簡単です( 例1 )。
フロントエンドhttp_frontend
バインド*:80
モードhttp
オプションhttpclose
acl is_mytest1 hdr_end(ホスト)-i mytest1.loc
is_mytest1の場合はuse_backend mytest1_web
acl is_mytest2 hdr_end(ホスト)-i mytest2.loc
is_mytest2の場合はuse_backend mytest2_web
バックエンドmytest1_web
モードhttp
クッキーSERVERID挿入間接nocache
サーバーmytestweb1 192.168.1.5:80 cookie mytestweb1を確認
バックエンドmytest2_web
モードhttp
クッキーSERVERID挿入間接nocache
サーバーmytestweb2 192.168.1.10:80 cookie mytestweb2を確認
以下では、構成ファイルの完全な例ではなく、興味のある部分のみを示します。
非常にシンプル-ポート80をリッスンし、すべての着信トラフィックを解析します。 mytest1.locが要求された場合、アクセスリストis_mytest1に分類されます。この場合、mytest1_webバックエンドが使用され、このサイトにある内部ホスト192.168.1.5にトラフィックをリダイレクトします。 mytest2.locについても同様です。 すべてが非常にシンプルであると同時に、実際のIPアドレスを保存します。
特に近隣の都市には、これらのWebサイトを作成できるサーバーもあるため、フォールトトレランスの問題が発生しました。 まあ、AmazonクラウドにはLinuxを搭載した仮想マシンがあります。これは同じことを行いますが、クラウドにあるサイト用です。 2つのHAProxyを続けて使用できますか? ほぼこのようなテスト回路を作成して、次のことを確認します。
HAProxy2およびHAProxy3の構成は変更されませんでしたが、HAProxy1にバランシングパラメーターが追加されました( 例No. 2 )。
フロントエンドhttp_frontend
バインド*:80
モードhttp
オプションhttpclose
acl is_mytest1 hdr_end(ホスト)-i mytest1.loc
is_mytest1の場合はuse_backend mytest1_web
acl is_mytest2 hdr_end(ホスト)-i mytest2.loc
is_mytest2の場合はuse_backend mytest2_web
バックエンドmytest1_web
モードhttp
バランスラウンドロビン
クッキーSERVERID挿入間接nocache
サーバーHAProxy1 1.1.1.1:80 cookie haproxy1_1をチェック
サーバーHAProxy2 3.3.3.3:80 Cookieのチェックhaproxy2_1
バックエンドmytest2_web
モードhttp
バランスラウンドロビン
クッキーSERVERID挿入間接nocache
サーバーHAProxy1 1.1.1.1:80 Cookieのチェックhaproxy1_3
サーバーHAProxy2 3.3.3.3:80 Cookieのチェックhaproxy2_3
すべてがうまくいきました。 喜ぶことができるように思えますが、ここではSSLを介して作業用にサイトをやり直すことにしました。 そして問題が始まりました。
最初に戻って、最初からすべてを検討しましょう。 最初の前提は、プロキシサーバーとサイト自体の間のトラフィックを暗号化する必要がないことです。 第二に、証明書をサイトにバインドすることを心配する必要はありません。つまり、どこでも自己署名証明書を使用します。
何をする必要がありますか? HAProxyサーバーに自己署名証明書を生成してインストールすると、クライアントはサイトにアクセスし、プロキシサーバーに移動して証明書を取得し、サーバーへの安全な接続を確立してからWebサイトにリダイレクトします。 さらに、プロキシサーバーの背後にあるすべてのサイトに対して、1つの証明書が使用されます。
それでは始めましょう。 以下を生成します。
openssl req -new -x509 -nodes -out server.crt -keyout server.key
1つのファイルに書き込みます。
cat server.key> /etc/ssl/mytest.loc.pem
cat server.crt >> /etc/ssl/mytest.loc.pem
そして、HAProxy設定を編集します( 例No. 3 ):
フロントエンドhttp_frontend
バインド*:80
モードhttp
オプションhttpclose
acl is_mytest1 hdr_end(ホスト)-i mytest1.loc
is_mytest1の場合はuse_backend mytest1_web
acl is_mytest2 hdr_end(ホスト)-i mytest2.loc
is_mytest2の場合はuse_backend mytest2_web
バックエンドmytest1_web
モードhttp
バランスラウンドロビン
クッキーSERVERID挿入間接nocache
サーバーmytestweb1 192.168.1.5:80 cookie mytestweb1を確認
バックエンドmytest2_web
モードhttp
バランスラウンドロビン
クッキーSERVERID挿入間接nocache
サーバーmytestweb2 192.168.1.10:80 cookie mytestweb2を確認
フロントエンドhttps_frontend
バインド*:443 ssl crt /etc/ssl/mytest.loc.pem
モードhttp
オプションhttpclose
acl is_mytest1 hdr_end(ホスト)-i mytest1.loc
is_mytest1の場合はuse_backend mytest1_web
acl is_mytest2 hdr_end(ホスト)-i mytest2.loc
is_mytest2の場合はuse_backend mytest2_web
ちなみに、再起動する前に構成を確認することは非常に便利な習慣です。
haproxy -c -f /etc/haproxy/haproxy.cfg
構成ファイルは有効です
すべてが正常に機能することを確認します。
それでは、各サイトが自己署名ではなく購入した独自の証明書を持っている場合を考えてみましょう。 また、サイト名に厳密にバインドされています。 この場合、2つの方法で問題を解決できます。HAProxyサーバーまたはHTTPではなくプロキシTCPにサイトの証明書を配置します。 ただし、どちらの場合も、2つのサイトに1つのIPアドレスを使用することはできません。
最初のケースを考えます:
この場合と以前の(自己署名証明書を使用した)場合との唯一の違いは、ここでは個々のインターフェイスをリッスンし、インターフェイスに応じて証明書を発行する必要があることです( 例No. 4 )。
フロントエンドhttp_frontend
バインド*:80
モードhttp
オプションhttpclose
acl is_mytest1 hdr_end(ホスト)-i mytest1.loc
is_mytest1の場合はuse_backend mytest1_web
acl is_mytest2 hdr_end(ホスト)-i mytest2.loc
is_mytest2の場合はuse_backend mytest2_web
バックエンドmytest1_web
モードhttp
バランスラウンドロビン
クッキーSERVERID挿入間接nocache
サーバーmytestweb1 192.168.1.5:80 cookie mytestweb1を確認
バックエンドmytest2_web
モードhttp
バランスラウンドロビン
クッキーSERVERID挿入間接nocache
サーバーmytestweb2 192.168.1.10:80 cookie mytestweb2を確認
フロントエンドhttps_frontend_site1
バインド1.1.1.1-00-0043 ssl crt /etc/ssl/mytest.loc1.pem
モードhttp
オプションhttpclose
acl is_mytest1 hdr_end(ホスト)-i mytest1.loc
is_mytest1の場合はuse_backend mytest1_web
フロントエンドhttps_frontend_site2
バインド9.9.9.9-00-0043 ssl crt /etc/ssl/mytest.loc2.pem
モードhttp
オプションhttpclose
acl is_mytest2 hdr_end(ホスト)-i mytest2.loc
is_mytest2の場合はuse_backend mytest2_web
トラフィックがアドレス1.1.1.1のインターフェイスに到着した場合、クライアントはサイトmytest1.locを要求します。 そこで、このサイトの証明書を彼に発行し、 バックエンドmytest1_webにプロキシします 。
2番目のケースでは、ポート443で到着したすべてのTCPトラフィックを転送します。 これは、たとえば、何らかの理由でサイト証明書をプロキシサーバーに保存したくない場合に行う価値があります。 または、たとえば、プロキシとWebサーバー間の内部ネットワークを信頼しないでください。
HAProxyの構成は、およそ次のようになります( 例5 )。
フロントエンドmytest1_frontend
バインド1.1.1.1-00-0043
モードtcp
use_backend mytest1_webssl
バックエンドmytest1_webssl
モードtcp
オプションssl-hello-chk
サーバーmytestweb 192.168.1.5-00-0043
フロントエンドmytest2_frontend
バインド9.9.9.9-00-0043
モードtcp
use_backend mytest2_webssl
バックエンドmytest2_webssl
モードtcp
オプションssl-hello-chk
サーバーmytestweb 192.168.1.10-00-0043
設定は非常に理解しやすいようです。 おそらく、すべてのTCPトラフィックを転送するため、分析することはできず、したがって、フロントエンド部分にアクセスリストが存在するとエラーがスローされます。
さまざまな都市のWebサイトを分割するというタスクに戻りましょう。 最初に、より単純なケースを考えます。
HAProxy1とHAProxy2の間にインターネットがあるため、自己署名証明書を使用する場合でも、HAProxy1でHTTP PROXY MODEを使用することはできません。そうしないと、そのような接続を暗号化する意味がすべて失われます。 HAProxy1ではtcpモードを使用し、HAProxy2ではhttpモードを使用します。
HAProxy1の構成( 例No. 6 ):
フロントエンドhttps_frontend
バインド*:443
モードtcp
use_backend https_web
バックエンドhttps_web
モードtcp
オプションssl-hello-chk
サーバーhaproxy2 1.1.1.1-00-0043
HAProxy2の構成は、 例3の構成と同じです。
サーバーの2番目の部分を追加します。
HAProxy1の構成( 例No. 7 ):
フロントエンドhttps_frontend
バインド*:443
モードtcp
use_backend https_web
バックエンドhttps_web
モードtcp
バランスラウンドロビン
オプションssl-hello-chk
サーバーhaproxy2 1.1.1.1-00-0043チェック
サーバーhaproxy3 3.3.3.3-00-0043チェック
この例と前の例との違いはすべて、HAProxy2とHAProxy3のバランスとフォールトトレランスの存在です。これは、条件に応じて、異なる都市に存在する必要があります。
最後の例は、自己署名証明書がある場合です。 例4のように、HAProxyサーバーにインストールされているとします:
HAProxy1の構成は前の例のようになり、HAProxy2の構成は例4のようになります。 フロントエンド部分の実際のアドレスにわずかな変更を加えたHAProxy3でも同じです。
また、3つのHAProxyサーバーすべてをTCPモードで構成できることも価値があり、これも実行可能なソリューションになります。
最後に、このタスクの根本的に異なるソリューションを誰かが知っている場合、それらを共有していただければ幸いです。
小さな更新。 ここで、トラフィックを転送する場合、HAProxy2とHAProxy3で異なるIPアドレスのセットを使用する必要はなく、異なるポートを使用する方がはるかに簡単だと思いました。
この図を見てみましょう。
異なる都市に2つの異なるホストサイトがあります。 1つはHAProxy2の背後にあり、2つ目はHAProxy3の背後にあります。 また、バランシングタスクが置かれている中央プロキシサーバー、サイトwww.mytest1.locとwww.mytest2.locのバランスをとる必要があり、サイトwww.mytest3.locは1つのサイトにのみ存在するため、アクセスは経由でのみ転送する必要がありますプロキシサーバー:すべてのサイトは、署名されていない証明書を使用してHTTPおよびHTTPS経由でアクセスできる必要があります。
HAProxy1の構成:
フロントエンドhttp_frontend
バインド*:80
モードhttp
オプションhttpclose
acl is_mytest1 hdr_end(ホスト)-i mytest1.loc
is_mytest1の場合はuse_backend mytest1_web
acl is_mytest2 hdr_end(ホスト)-i mytest2.loc
is_mytest2の場合はuse_backend mytest2_web
acl is_mytest3 hdr_end(ホスト)-i mytest3.loc
is_mytest3の場合はuse_backend mytest3_web
バックエンドmytest1_web
モードhttp
バランスラウンドロビン
クッキーSERVERID挿入間接nocache
サーバーmytestweb1 1.1.1.1:80 cookie mytestweb1をチェック
サーバーmytestweb1 2.2.2.2:80 cookie mytestweb1をチェック
バックエンドmytest2_web
モードhttp
バランスラウンドロビン
クッキーSERVERID挿入間接nocache
サーバーmytestweb2 1.1.1.1:80 cookie mytestweb2をチェック
サーバーmytestweb2 2.2.2.2:80 cookie mytestweb2をチェック
バックエンドmytest3_web
モードhttp
バランスラウンドロビン
クッキーSERVERID挿入間接nocache
サーバーmytestweb3 2.2.2.2:80 cookie mytestweb3をチェック
フロントエンドmytest1_frontend
バインド3.3.3.3-00-0043
モードtcp
use_backend mytest_webssl1
バックエンドmytest_webssl1
モードtcp
バランスラウンドロビン
オプションssl-hello-chk
サーバーmytestweb1 1.1.1.1 ∗ 5551
サーバーmytestweb2 2.2.2.2 ∗ 5551
フロントエンドmytest2_frontend
バインド4.4.4.4-00-0043
モードtcp
use_backend mytest_webssl2
バックエンドmytest_webssl2
モードtcp
バランスラウンドロビン
オプションssl-hello-chk
サーバーmytestweb1 1.1.1.1 ∗ 5552
サーバーmytestweb2 2.2.2.2 ∗ 5552
フロントエンドmytest3_frontend
バインド5.5.5.5-00-0043
モードtcp
use_backend mytest_webssl3
バックエンドmytest_webssl3
モードtcp
バランスラウンドロビン
オプションssl-hello-chk
サーバーmytestweb2 2.2.2.2 ∗ 5553
HAProxy3の構成:
フロントエンドhttp_frontend
バインド*:80
モードhttp
オプションhttpclose
acl is_mytest1 hdr_end(ホスト)-i mytest1.loc
is_mytest1の場合はuse_backend mytest1_web
acl is_mytest2 hdr_end(ホスト)-i mytest2.loc
is_mytest2の場合はuse_backend mytest2_web
acl is_mytest3 hdr_end(ホスト)-i mytest3.loc
is_mytest3の場合はuse_backend mytest3_web
フロントエンドmytest1_frontend
バインド2.2.2.2.2 .5551 ssl crt /etc/ssl/mytest1.loc.pem
モードhttp
オプションhttpclose
オプション
reqadd X-Forwarded-Proto:\ https
use_backend mytest1_web
フロントエンドmytest2_frontend
バインド2.2.2.2.025552 ssl crt /etc/ssl/mytest2.loc.pem
モードhttp
オプションhttpclose
オプション
reqadd X-Forwarded-Proto:\ https
use_backend mytest2_web
フロントエンドmytest3_frontend
バインド2.2.2.2.2 .5553 ssl crt /etc/ssl/mytest3.loc.pem
モードhttp
オプションhttpclose
オプション
reqadd X-Forwarded-Proto:\ https
use_backend mytest3_web
バックエンドmytest1_web
モードhttp
バランスラウンドロビン
統計を有効にする
クッキーSERVERID挿入間接nocache
サーバーmytestweb1 192.168.1.5:80 cookie mytestweb1を確認
バックエンドmytest2_web
モードhttp
バランスラウンドロビン
統計を有効にする
クッキーSERVERID挿入間接nocache
サーバーmytestweb2 192.168.1.10:80 cookie mytestweb2を確認
バックエンドmytest3_web
モードhttp
バランスラウンドロビン
統計を有効にする
クッキーSERVERID挿入間接nocache
サーバーmytestweb3 192.168.1.15:80 cookie mytestweb3を確認