Я бы хотел поставить stunnel перед haproxy 1.4 для обработки HTTPS-трафика. Мне также нужен stunnel, чтобы добавить X-Forwarded-For заголовок. Этого можно добиться с помощью "stunnel-4.xx-xforwarded-for.diff" патчи с сайта haproxy.
Однако в описании упоминается:
Обратите внимание, что этот патч не работает с keep-alive, ...
Мой вопрос: что это будет значить для меня на практике? Я не уверен,
Речь идет о HTTP keep-alive, который позволяет нескольким запросам ресурсов проходить через один сеанс TCP (а с SSL - один сеанс SSL). Это очень важно для производительности SSL-сайта, так как без поддержки активности SSL-подтверждение потребовалось бы для каждого запрошенного ресурса.
Итак, проблема здесь в одном большом сеансе поддержки активности от клиента на всем пути к внутреннему серверу. Это важно для производительности и воспринимается как нечто само собой разумеющееся для современных HTTP-серверов, но в этом патче говорится, что он его не поддерживает. Давайте разберемся, почему ..
Сеанс поддержания активности - это просто несколько запросов, один за другим - как только сервер завершает свой ответ на один запрос, сервер не отправляет FIN
пакет для завершения сеанса TCP; клиент может просто отправить еще одну партию заголовков.
Чтобы понять, что делает этот патч, вот пример диалога keep-alive:
Клиент:
GET / HTTP/1.1
Connection: keep-alive
Host: domain.com
...
Сервер:
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Server: Apache
Content-Length: 34
.... (other headers)
<html><head>content!</head></html>
Вот где остановится несохраняемое соединение. Но keep-alive позволяет клиенту просто запустить другой:
GET /images/some/image.on.the.page.jpg HTTP/1.1
Connection: keep-alive
Host: domain.com
...
Для идентификатора клиента при проксировании некоторые обратные прокси-серверы могут добавлять в X-Forwarded-For
заголовок в каждом клиентском запросе. Это сообщает вышестоящему серверу, откуда исходит запрос (вместо каждого запроса, инициируемого с IP-адреса обратного прокси-сервера), для корректности ведения журнала и других потребностей приложения.
В X-Forwarded-For
заголовок необходимо вводить в каждый запрос клиентского ресурса, отправляемый через соединение keep-alive, поскольку полные заголовки отправляются каждый раз; обработка X-Forwarded-For
заголовок и преобразование в «настоящий» IP-адрес запроса выполняется для каждого запроса, а не для TCP-keep-alive-session. И, может быть, есть отличное программное обеспечение обратного прокси, которое использует один сеанс поддержки активности для обслуживания запросов от нескольких клиентов.
Вот где этот патч терпит неудачу.
Патч на этом сайте следит за буфером сеанса TCP на предмет окончания первого набора заголовков HTTP в потоке и вводит новый заголовок в поток после окончания этого первого набора заголовков. После этого он считает X-Forwarded-For
задание выполнено, и останавливает сканирование на предмет окончания новых наборов заголовков. Этот метод не знает обо всех будущих заголовках, поступающих через последующие запросы.
Не могу их винить; stunnel на самом деле не был построен для обработки и перевода содержимого своих потоков.
Эффект, который это окажет на вашу систему, заключается в том, что первый запрос потока поддержки активности получит X-Forwarded-For
заголовок введен правильно, и все последующие запросы будут работать нормально, но у них не будет заголовка.
Если нет другого патча для инъекции заголовка, который может обрабатывать несколько клиентских запросов на одно соединение (или настроить его с помощью наших друзей в Stack Overflow), вам может потребоваться изучить другие варианты завершения SSL.
STunnel 4.45 исправляет это должным образом, используя некоторые новые возможности (протокол прокси), поставляемые с HAProxy 1.15.
Он также устраняет проблемы с предыдущими патчами и Keep Alive.
Подобно тому, что я опубликовал в другом потоке, HAProxy поддерживает собственный SSL с обеих сторон, начиная с версии 1.5-dev12. Таким образом, наличие X-Forwarded-For, HTTP keep-alive, а также заголовок, сообщающий серверу, что соединение было выполнено через SSL, очень просты:
listen front
bind :80
bind :443 ssl crt /etc/haproxy/haproxy.pem
mode http
option http-server-close
option forwardfor
reqadd X-Forwarded-Proto:\ https if { is_ssl }
server srv1 1.1.1.1:80 check ...
...
Это намного проще, чем исправлять stunnel, и намного лучше, чем сбрасывать keep-alive.
Расширяя отличный ответ от Шейна, вы можете использовать Nginx в качестве терминатора SSL перед HAproxy. Он правильно обрабатывает поддержку активности между клиентом и nginx, которая является наиболее чувствительной к задержке стороной, и устанавливает новое соединение с серверной частью для каждого клиентского запроса, отправляя X-FORWARDED-FOR в каждом из них.