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

Реализация липких сессий TCP с HAProxy для обработки сквозного трафика SSL

Как мы можем реализовать закрепление сеанса в HAProxy, когда SSL должен завершиться на внутренних серверах? Нам нужна липкость, потому что серверные части не могут совместно использовать сеансы.

Это моя первоначальная конфигурация:

# SSL passthrough
listen https_handler
    bind 1.2.3.4:443
    mode tcp
    balance leastconn
    stick match src
    stick-table type ip size 200k expire 30m
    server s1 1.1.1.1:443
    server s2 1.1.1.2:443

# haproxy logs (not sticking)
10.x.x.2:xxxxx [17/Dec/2014:19:29:41.396] fe BACKEND_Website/s1 37/0/1/3/41 200 8364
10.x.x.2:xxxxx [17/Dec/2014:19:29:41.456] fe BACKEND_Website/s1 36/0/1/1/39 200 9082
10.x.x.2:xxxxx [17/Dec/2014:19:29:41.456] fe BACKEND_Website/s2 35/0/1/3/39 200 2529
10.x.x.2:xxxxx [17/Dec/2014:19:29:41.545] fe BACKEND_Website/s1 35/0/0/3/38 200 1460
10.x.x.2:xxxxx [17/Dec/2014:19:29:41.501] fe BACKEND_Website/s2 36/0/1/1/109 200 376
10.x.x.2:xxxxx [17/Dec/2014:19:29:41.545] fe BACKEND_Website/s1 36/0/1/1/74 200 2298
10.x.x.2:xxxxx [17/Dec/2014:19:29:41.604] fe BACKEND_Website/s1 35/0/1/2/38 200 5542

Конфигурация ниже - это моя попытка прочитать src:

Это приводит к ошибке 502 Bad Gateway. Я предполагаю, что это потому, что трафик уже расшифрован к тому моменту, когда он достигает бэкэнда.

# terminate SSL at HAProxy 
listen https_handler
    bind 1.2.3.4:443 ssl crt /etc/ssl/certs/certs.pem
    mode tcp
    balance leastconn
    stick match src
    stick-table type ip size 200k expire 30m
    server s1 1.1.1.1:443
    server s2 1.1.1.2:443

Обратите внимание, что я подключил сертификат к привязке. Это нужно для того, чтобы HAProxy мог читать src и настраивать stick-table. (Не уверен, что это правильно.) И на этом этапе трафик уже расшифрован.

Я думаю, проблема заключается в том, что этот расшифрованный трафик передается на внутренние серверы, которые ожидают зашифрованный трафик ...

Я видел эти предложения:

  1. Завершить SSL на HAProxy 1.5 - в моем случае это невозможно. SSL должен обрабатываться внутренними серверами.
  2. Используйте идентификатор сеанса SSL для сохранения устойчивости. - Я скептически отношусь к этому, потому что еще не совсем понимаю. И, похоже, использует модифицированную (?) Версию haproxy.
  3. Использовать send-proxy директива и X-Forward-Proto заголовок. - но понял, что для этого также нужен бэкэнд только для HTTP.

Был бы признателен за любой совет.

Самое простое решение - использовать balance source, но если многие клиенты приходят с одного и того же IP-адреса, это может быть не очень справедливо для ваших внутренних серверов.

Видеть http://blog.haproxy.com/2013/04/22/client-ip-persistence-or-source-ip-hash-load-balancing/ для более подробного обсуждения методов достижения этой цели.

Если корень вашей проблемы заключается в том, что внутренние серверы ожидают, что трафик будет HTTPS, а не HTTP, попробуйте шифрование HTTP и выполните обычную балансировку нагрузки Layer7.

listen https_handler
    bind 1.2.3.4:443 ssl crt /etc/ssl/certs/certs.pem
    mode http
    balance leastconn
    # any stick rules you need
    server s1 1.1.1.1:443 ssl
    server s2 1.1.1.2:443 ssl

Еще проще - поскольку вы, очевидно, пытаетесь придерживаться src в любом случае, почему вы вообще вообще расшифровываете TCP-трафик?

listen https
    bind 1.2.3.4:443 # <- NO ssl setting
    mode tcp
    balance leastconn
    stick match src
    stick-table type ip size 200k expire 30m
    server s1 1.1.1.1:443 ssl
    server s2 1.1.1.2:443 ssl

В режиме TCP вам не важны полезные данные. В частности, вам все равно, зашифровано ли оно и как.