haproxy + stunnel + utrzymywać przy życiu?

10

Chciałbym umieścić stunnel przed haproxy 1.4 do obsługi ruchu HTTPS. Potrzebuję również stunnela, aby dodać nagłówek X-Forwarded-For . Można to osiągnąć za pomocą łatek „stunnel-4.xx-xforwarded-for.diff” ze strony internetowej haproxy.

Jednak w opisie wspomniano:

Pamiętaj, że ta łatka nie działa z utrzymywaniem przy życiu, ...

Moje pytanie brzmi: co to dla mnie oznacza w praktyce? Nie jestem pewien

  1. jeśli chodzi o zachowanie między
    • klient i stunnel
    • stunnel i haproxy
    • lub haproxy i serwer zaplecza?
  2. co to oznacza dla wydajności: jeśli mam 100 ikon na stronie, czy przeglądarka będzie musiała negocjować 100 pełnych połączeń SSL, czy może ponownie użyć połączenia SSL, tworząc nowe połączenia TCP?
Chris Lercher
źródło

Odpowiedzi:

12

Chodzi o utrzymywanie aktywności HTTP, które pozwala na przesyłanie wielu żądań zasobów przez jedną sesję TCP (a przy SSL - przez jedną sesję SSL). Ma to ogromne znaczenie dla wydajności witryny SSL, ponieważ bez podtrzymania połączenia dla każdego żądanego zasobu potrzebny byłby uścisk dłoni SSL.

Tak więc problemem jest jedna duża sesja podtrzymywania aktywności od klienta aż do serwera zaplecza. Jest to ważna kwestia dla wydajności i jest oczywista dla współczesnych serwerów HTTP, ale ta poprawka mówi, że nie obsługuje tego. Zobaczmy, dlaczego ...


Sesja podtrzymywania aktywności to tylko kolejne żądania jeden po drugim - gdy serwer zakończy odpowiedź na jedno żądanie, serwer nie wysyła FINpakietu, aby zakończyć sesję TCP; klient może po prostu wysłać kolejną partię nagłówków.

Aby zrozumieć, co robi ta łatka, oto przykład rozmowy podtrzymującej życie:

Klient:

GET / HTTP/1.1
Connection: keep-alive
Host: domain.com
...

Serwer:

HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Server: Apache
Content-Length: 34
.... (other headers)
<html><head>content!</head></html>

Tutaj kończy się połączenie, które nie pozwala utrzymać się przy życiu. Ale utrzymanie przy życiu pozwala klientowi po prostu odpalić następną:

GET /images/some/image.on.the.page.jpg HTTP/1.1
Connection: keep-alive
Host: domain.com
...

W przypadku identyfikatora klienta w proxy, niektóre zwrotne proxy mogą dodać X-Forwarded-Fornagłówek w każdym żądaniu klienta. To informuje serwer nadrzędny, z którego pochodzi żądanie (zamiast każdego żądania inicjowanego z adresu IP zwrotnego serwera proxy), dla zachowania bezpieczeństwa w logowaniu i innych potrzebach aplikacji.

X-Forwarded-ForNagłówek musi być wstrzykiwany do każdego klienta żądanie zasobu wysłanego przez połączenie podtrzymania, jak pełne nagłówki są wysyłane za każdym razem; obsługa X-Forwarded-Fornagłówka i tłumaczenie na „prawdziwy” adres IP żądania odbywa się na podstawie sesji, a nie sesji TCP. I hej, może jest tam jakieś niesamowite oprogramowanie odwrotnego proxy, które wykorzystuje pojedynczą sesję podtrzymywania życia do obsługi żądań od wielu klientów.

To jest miejsce, w którym ta łatka zawiedzie.


Łatka w tej witrynie obserwuje bufor sesji TCP dla końca pierwszego zestawu nagłówków HTTP w strumieniu i wstrzykuje nowy nagłówek do strumienia po zakończeniu tego pierwszego zestawu nagłówków. Po wykonaniu tej czynności uznaje X-Forwarded-Forpracę za wykonaną i zatrzymuje skanowanie w poszukiwaniu końca nowych zestawów nagłówków. Ta metoda nie ma wiedzy o wszystkich przyszłych nagłówkach przychodzących za pośrednictwem kolejnych żądań.

Naprawdę nie mogę ich winić; stunnel nie był tak naprawdę zbudowany do obsługi i tłumaczenia zawartości jego strumieni.

Efektem tego będzie to, że pierwsze żądanie strumienia podtrzymującego spowoduje X-Forwarded-Forprawidłowe wstrzyknięcie nagłówka, a wszystkie kolejne żądania będą działać poprawnie - ale nagłówek nie będzie miał.

O ile nie istnieje kolejna łatka do wstrzykiwania nagłówków, która może obsłużyć wiele żądań klientów na połączenie (lub dostosować tę z pomocą naszych przyjaciół w Stack Overflow), być może będziesz musiał spojrzeć na inne opcje zakończenia SSL.

Shane Madden
źródło
1
Doskonała odpowiedź, dzięki. Przypomina mi, dlaczego warto zadawać tutaj pytania.
Chris Lercher,
1
Aby mieć możliwość wstrzykiwania nagłówka w stunnel, trzeba będzie mówić prawie cały HTTP, co byłoby ogromnym nakładem pracy. Mimo to, można również użyć protokołu PROXY HAProxy (która wymaga łaty dla stunnel lub alternatywnie stud ) wstrzyknąć nagłówka HAProxy. Zobacz dokumentację, aby uzyskać więcej informacji (z pamięci podręcznej Google, ponieważ witryna HAproxy wydaje się być częściowo zepsuta w bankomatach)
Holger Tylko
3

Podobnie do tego, co napisałem w innym wątku, HAProxy obsługuje natywne SSL po obu stronach od 1.5-dev12. Posiadanie X-Forwarded-For, HTTP keep-alive, a także nagłówek informujący serwer, że połączenie zostało nawiązane przez SSL, jest tak proste jak to:

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 ...
    ...

Jest to o wiele łatwiejsze niż łatanie stunnela i znacznie lepsze niż zrzucanie na utrzymanie.

Willy Tarreau
źródło
Możesz użyć ssl_fc zamiast is_ssl
josch
2

Rozszerzając doskonałą odpowiedź Shane'a, możesz użyć Nginx jako terminatora SSL przed HAproxy. Prawidłowo obsługuje utrzymywanie aktywności między klientem a nginx, która jest stroną najbardziej wrażliwą na opóźnienia, i tworzy nowe połączenie z zapleczem dla każdego żądania klienta, wysyłając X-FORWARDED-FOR w każdym z nich.

Ochoto
źródło
1
Jeśli jednak potrzebujesz websockets, nginx nie będzie działać.
w00t
Ponadto obsługuje pamięć podręczną sesji ssl.
3molo