web-dev-qa-db-ja.com

同じIP上のHAProxyとvhostsを使用したパススルーSSL

HAProxyでSSLを他の仮想ホストとIPを共有する仮想ホストにパススルーできますか?

やってみる

frontend https
bind *:443 #ssl
mode tcp
default_backend port_443

backend port_443
mode tcp
server web42 www.example.com

しかし、www.example.comではなく、デフォルトのWebサーバーが表示されます

フロントエンドでSNIを実行できますが、バックエンドにどのように言うか-これはドメインwww.example.com用ですか?

server web1 www.example.com:443 sni str(www.example.com) verify none

どちらも機能しません。

明確にするために、ウェブサーバーwww.default.com、www.example.com、www.example.netはすべて同じIPとポートを持っています。 10.0.1.10:443 Apache/ngixは、SNIを使用して適切なvhostを選択します。

問題はまだ解決されていません。ここにいくつかのグラフィック

                                   --------------------
                                  |(All 10.0.1.10:443)
www2.example.com:443 -> HaProxy ->|www.default.com <- Apache vhost default
                                  |www.example.com
                                  |www.example.net 
                                   --------------------

Www.example.comにアクセスしたい(モードtcp)

Www.example.comとwww.example.netの秘密鍵がある場合。セキュリティの問題なしにwww.example.net(ユーザー入力がwww.example.comの場合)にアクセスできますか?

2
Ralf Viellieber

接続は任意のバックエンドサーバー/ポートに渡すことができます。

しかし、私はあなたのセットアップから欠けているものがたくさんあるのを見ます。

したがって、これは、グローバルIPv4アドレスを共有する必要があるhttps接続を独自のグローバルIPv6(および固有のプライベートIPv4)を持つバックエンドサーバーに転送する私のHAProxyセットアップからのものです。

frontend https
    bind :443
    mode tcp
    option tcplog
    tcp-request inspect-delay 5s
    tcp-request content accept if { req.ssl_hello_type 1 }

    use_backend goren_example_com if { req_ssl_sni -i awx.example.com }
    use_backend goren_example_com if { req_ssl_sni -i goren.example.com }
    use_backend goren_example_com if { req_ssl_sni -i tower.example.com }

backend goren_example_com
    server goren 192.168.101.182:443 send-proxy-v2

ここではSNI検査を行っており、SNIホスト名を照合して、接続を送信するバックエンドを決定していることに注意してください。

次に、send-proxy-v2を使用して、バックエンド接続で PROXYプロトコル を有効にします。これにより、接続が開始されたIPアドレスをバックエンドに通知できます。この設定ではX-Forwarded-Forを使用できないため、このプロトコルを使用します。

ただし、PROXYプロトコルでは、バックエンドサーバーがそれを認識する必要があります。これを実現するには、nginxの設定を少し変更する必要がありました。

listen 443 ssl http2 proxy_protocol;
listen [::]:443 ssl http2;
set_real_ip_from 192.168.101.1;
real_ip_header proxy_protocol;

listenおよびproxy_protocolreal_ip_headerを指定することにより、nginxはPROXYプロトコルを介してクライアントの実際のIPアドレスを取得することを認識します。 (そして、私はhaproxy経由でIPv4接続をプロキシするだけなので、IPv6リスナーではそれを使用しないことに注意してください。IPv6接続は直接着信し、プロキシは必要ありません。これはIPv6の大きな利点の1つです。)

最後に、古いバージョンのnginxスポークバージョン1のPROXYプロトコルなので、send-proxy-v2haproxy.cfgが機能しない場合は、send-proxyに変更する必要があります。

(そして、もしあなたがまだApacheを使っている人なら、 RemoteIPProxyProtocol on を設定してください。)

4
Michael Hampton

これは不可能です。 HAProxyは、tcpモードのすべてのsni str(www.example.com)を無視します。 (sni str()は終了用で、SSLを再度暗号化すると思います)しかし、tcpモードでは、クライアントがwww.example.comを呼び出したときに、www.example.comに到達し、デフォルトのサーバーには到達しません。私の本当の問題は、www2.example.comでのテストが不可能だったということです。 (そしてこれは本番環境だったので、テストできません)

0
Ralf Viellieber