haproxy + stunnel + keep-alive?

10

Я хотел бы поставить stunnel перед haproxy 1.4 для обработки трафика HTTPS. Мне также нужен stunnel для добавления заголовка X-Forwarded-For . Это может быть достигнуто с помощью «Stunnel-4.xx-xforwarded-for.diff» пластырей с HAproxy сайта.

Тем не менее, описание упоминает:

Обратите внимание, что этот патч не работает с keep-alive, ...

Мой вопрос: что это будет означать на практике для меня? Я не уверен,

  1. если речь идет о поддержании жизни между
    • клиент и stunnel
    • Stunnel и haproxy
    • или хакрокси и бэкэнд сервер?
  2. что это означает для производительности: если у меня есть 100 значков на веб-странице, придется ли браузеру договариваться о 100 полных соединениях SSL или он может повторно использовать соединение SSL, просто создавая новые соединения TCP?
Крис Лерчер
источник

Ответы:

12

Это касается поддержки активности HTTP, которая позволяет нескольким запросам ресурсов проходить через один сеанс TCP (и, с SSL, один сеанс SSL). Это имеет большое значение для производительности сайта SSL, так как без поддержки активности SSL рукопожатие будет необходимо для каждого запрашиваемого ресурса.

Таким образом, проблема заключается в одном большом сеансе поддержки активности от клиента до внутреннего сервера. Это важно для производительности, и, разумеется, для современных HTTP-серверов, но этот патч говорит, что не поддерживает его. Давайте посмотрим, почему ..


Сеанс keep-alive - это просто большее количество запросов один за другим - как только сервер заканчивает свой ответ на один запрос, сервер не отправляет FINпакет для завершения сеанса TCP; клиент может просто отправить другую партию заголовков.

Чтобы понять, что делает этот патч, вот пример поддерживающего разговора:

Клиент:

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-сеанса. И, может быть, есть какое-то отличное программное обеспечение обратного прокси, которое использует один сеанс keep-alive для обслуживания запросов от нескольких клиентов.

Вот где этот патч не работает.


Патч на этом сайте отслеживает буфер сеанса TCP для конца первого набора заголовков HTTP в потоке и вставляет новый заголовок в поток после окончания этого первого набора заголовков. После того, как это сделано, он считает выполненную X-Forwarded-Forработу и останавливает сканирование для конца новых наборов заголовков. Этот метод не знает о всех будущих заголовках, поступающих через последующие запросы.

Не могу их винить; Stunnel на самом деле не был создан для обработки и перевода содержимого своих потоков.

Эффект, который это будет иметь в вашей системе, состоит в том, что первый запрос потока keep-alive получит X-Forwarded-Forправильно введенный заголовок, и все последующие запросы будут работать нормально, но у них не будет заголовка.

Если нет другого патча для внедрения заголовка, который может обрабатывать несколько клиентских запросов на соединение (или его можно настроить с помощью наших друзей в Stack Overflow), вам, возможно, придется поискать другие варианты для завершения SSL.

Шейн Мэдден
источник
1
Отличный ответ, спасибо. Напоминает мне, почему это хорошая идея, чтобы задавать вопросы здесь.
Крис Лерчер
1
Чтобы иметь возможность поддерживать инъекцию заголовка keep-alive в stunnel, он должен иметь возможность говорить почти по всему HTTP, что потребует огромных усилий. Тем не менее, вы можете также использовать протокол ПРОКСИТЕ HAproxy (который требует патча для Stunnel или альтернативно шпильки ) инъекционным заголовка в HAproxy. См. Документацию для получения дополнительной информации (из кеша Google, так как сайт HAproxy, кажется, частично отключен от банкомата)
Holger Just
3

Подобно тому, что я опубликовал в другой теме, 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, и намного лучше, чем отказ от поддержки.

Вилли Тарро
источник
Возможно, вы захотите использовать ssl_fc вместо is_ssl
josch
2

Расширяя превосходный ответ от Шейна, вы можете использовать Nginx в качестве терминатора SSL перед HAproxy. Он правильно обрабатывает keep-alive между клиентом и nginx, который является наиболее чувствительной к задержке стороной, и создает новое соединение с бэкендом для каждого клиентского запроса, отправляя X-FORWARDED-FOR в каждом из них.

Ochoto
источник
1
Однако если вам нужны websockets, то nginx не будет работать.
w00t
Плюс, он поддерживает кеш сессии ssl.
3моло