Назад | Перейти на главную страницу

Сквозной SSL с HAProxy и vhosts на одном IP

Могу ли я передать SSL с HAProxy на виртуальный хост, который имеет общий 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

Я мог бы сделать 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.

Проблема до сих пор не решена. Вот немного графики

                                   --------------------
                                  |(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) без проблем с безопасностью?

Вы можете передавать соединения на любой внутренний сервер / порт, который хотите.

Но я вижу, что в вашей настройке отсутствует множество вещей.

Итак, это из моей собственной настройки HAProxy, с которой я перенаправляю https-соединения, которые должны иметь общий глобальный адрес IPv4, на внутренние серверы, у которых все имеют уникальный глобальный IPv6 (и уникальный частный IPv4).

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 что позволяет ПРОКСИ протокол на внутреннем соединении. Это позволит мне сообщить серверу 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;

Указав proxy_protocol в listen и real_ip_header, теперь nginx знает, как получить реальный IP-адрес клиента по протоколу PROXY. (И обратите внимание, что я не использую его в прослушивателе IPv6, потому что я проксирую IPv4-соединения только через haproxy. IPv6-соединения поступают напрямую, и прокси-сервер не требуется. Это одно из больших преимуществ IPv6.)

Наконец, более старые версии nginx говорили о версии 1 протокола PROXY, поэтому, если send-proxy-v2 в haproxy.cfg не работает, вам нужно изменить его на send-proxy.

(И если вы один из тех, кто все еще использует Apache, установите RemoteIPProxyProtocol on.)

Это невозможно. HAProxy игнорирует каждую строку sni (www.example.com) в режиме tcp. (Я думаю, что sni str () предназначен для завершения и снова зашифрует SSL) Но в режиме tcp вы ДОЙДЕТЕ достичь www.example.com, а не сервера по умолчанию, когда клиент вызовет www.example.com. Моя настоящая проблема заключалась в том, что тестирование с www2.example.com невозможно. (И это была производственная среда, поэтому я не могу ее протестировать)