1/50
Proxy WWW - Reverse Proxy i Forward Proxy

Rola pośredników w ruchu HTTP

Rola pośredników w ruchu HTTP, buforowanie, Load Balancing z Nginx i HAProxy

  • Proxy (pośrednik) to serwer pośredniczący w komunikacji HTTP między klientem a serwerem docelowym, działający na warstwie L7 (aplikacji) modelu OSI
  • Dwa fundamentalne typy: Forward Proxy (pośrednik wychodzący - maskowanie wyjścia, kontrola pracowników) oraz Reverse Proxy (pośrednik odwrotny - maskowanie wejścia, odciążenie serwerów WWW)
  • Prezentacja obejmuje algorytmy load balancingu (Round Robin, Least Connections, IP Hash), mechanizmy session persistence oraz caching na warstwie proxy
  • Materiał zawiera praktyczne laboratorium: konfiguracja Nginx jako Reverse Proxy, testowanie dystrybucji ruchu, troubleshooting nagłówków X-Forwarded-For oraz diagnostyka martwych serwerów backendu
Proxy WWW - grafika tytułowa
2/50
Cel warsztatu

Praktyczne cele warsztatu proxy

Zarządzanie wejściem aplikacji - inżynierskie podejście do ruchu webowego

  • Zrozumienie, jakie problemy rozwiązują pośrednicy L7: kontrola, bezpieczeństwo, wydajność, niezawodność
  • Praktyczne opanowanie konfiguracji Nginx jako Reverse Proxy z load balancing, buforowaniem i terminacją SSL
  • Opanowanie konfiguracji HAProxy - potężniejszego narzędzia do zarządzania ruchem na L7 z frontend/backend
  • Umiejętność diagnostyki i troubleshooting: sprawdzanie dystrybucji ruchu, nagłówki X-Forwarded-For, wykrywanie martwych backendów
Cel warsztatu
3/50
Agenda spotkania

Plan warsztatu proxy

Plan prezentacji - pięć bloków tematycznych

  • Slajdy 4–12: Podział ról pośredników L7 - Forward Proxy vs Reverse Proxy (Squid, Nginx)
  • Slajdy 13–20: Skalowanie poziome i algorytmy Load Balancingu - Round Robin, Least Connections, IP Hash
  • Slajdy 21–30: Session Persistence (Sticky Sessions), Buforowanie (Caching), nagłówki TTL
  • Slajdy 31–38: Konfiguracja Nginx (upstream, proxy_pass) i HAProxy (frontend, backend)
  • Slajdy 39–50: Laboratorium i troubleshooting: Python HTTP servers, test obciążenia, X-Forwarded-For, cheat sheet
Agenda spotkania
4/50
Model komunikacji bez pośrednika

Bezpośrednie połączenie klient-serwer

Klient łączy się bezpośrednio z serwerem - scenariusz bazowy

  • W tradycyjnym modelu klient (przeglądarka) wysyła żądania HTTP bezpośrednio na adres IP serwera docelowego
  • Żądanie trafia na port 80 (HTTP) lub 443 (HTTPS) serwera, który je bezpośrednio obsługuje
  • Serwer WWW (Apache, Nginx) sam odpowiada za: odbiór połączenia, przetworzenie żądania, obsługę SSL/TLS, wysłanie odpowiedzi
  • Brak pośredników = prosta architektura, ale też brak buforowania, brak rozłożenia obciążenia, brak ochrony
Model komunikacji bez pośrednika
5/50
Czym jest proxy na warstwie 7?

Pośrednik z wglądem w treść HTTP

Pośrednik z pełnym wglądem w treść komunikacji HTTP

  • Proxy to serwer pośredniczący w komunikacji między klientem a serwerem na warstwie aplikacji (L7)
  • W przeciwieństwie do NAT (L3/L4), proxy rozumie protokół HTTP: widzi metodę, URI, nagłówki, ciało żądania i odpowiedzi
  • Może modyfikować żądania i odpowiedzi: wstawiać nagłówki, buforować treść, blokować określone URL-e, przekierowywać
  • Działa jako terminator połączeń TCP: klient łączy się z proxy, a proxy łączy się z serwerem (dwa oddzielne połączenia)
Czym jest proxy na warstwie 7?
6/50
Topologia: Forward Proxy (Pośrednik wychodzący)

Klient maskowany przed serwerem

Klient jest maskowany - serwer widzi adres proxy, nie klienta

  • Forward Proxy pośredniczy w ruchu wychodzącym z sieci wewnętrznej do Internetu
  • Klient konfiguruje przeglądarkę/system, aby używać proxy (ręczne ustawienie: adres IP proxy i port, np. 3128 dla Squid)
  • Serwer w Internecie nie widzi adresu IP klienta - widzi tylko adres proxy (maskowanie wyjścia)
  • Zastosowania: kontrola dostępu pracowników (blokowanie stron), buforowanie pasma, anonimizacja, filtrowanie treści
Topologia: Forward Proxy (Pośrednik wychodzący)
7/50
Forward Proxy w praktyce - Squid jako kontrola pracownika

Squid jako kontrola dostępu

Pakiet serwera Squid, ACL-e, buforowanie

  • Squid: wieloplatformowy serwer proxy z zaawansowanym systemem ACL (Access Control List) do definiowania polityk dostępu
  • Przykładowa reguła: acl banned_sites dstdomain .facebook.com .youtube.com + http_access deny banned_sites
  • Mechanizm buforowania (caching): Squid zapisuje odpowiedzi HTTP i serwuje je z pamięci bez łączenia się z Internetem
  • Narzędzia diagnostyczne: squidclient, logi /var/log/squid/access.log, statystyki w cachemgr.cgi
Forward Proxy w praktyce - Squid jako kontrola pracownika
8/50
Topologia: Reverse Proxy (Pośrednik odwrotny)

Serwer maskowany przed klientem

Serwer jest maskowany - klient widzi tylko proxy, nie zna serwerów backendu

  • Reverse Proxy pośredniczy w ruchu przychodzącym z Internetu do serwerów wewnętrznych
  • Klient (przeglądarka) łączy się z reverse proxy, które przekazuje żądanie do jednego z serwerów backendu
  • Serwery backendu nie są widoczne z Internetu - tylko proxy ma do nich dostęp (maskowanie wejścia do firmy)
  • Zastosowania: load balancing, terminacja SSL/TLS, buforowanie, ochrona przed atakami, odciążenie serwerów aplikacyjnych
Topologia: Reverse Proxy (Pośrednik odwrotny)
9/50
Reverse Proxy jako pierwsza linia obrony

Ochrona backendu przez Reverse Proxy

Ochrona serwerów backendu, terminacja SSL/TLS, odciążenie

  • Pierwsza linia obrony: reverse proxy przyjmuje ruch z Internetu, filtruje go i przekazuje tylko bezpieczne żądania do backendu
  • SSL/TLS termination: proxy obsługuje ciężkie asymetryczne kryptograficzne uzgadnianie (handshake), odciążając serwery aplikacyjne
  • Ukrycie architektury: serwery backendu nie mają publicznych adresów IP - tylko reverse proxy jest widoczne w Internecie
  • Filtrowanie i rate limiting: proxy może ograniczać liczbę zapytań z jednego adresu IP, blokować boty, wykrywać ataki L7
Reverse Proxy jako pierwsza linia obrony
10/50
Forward Proxy vs Reverse Proxy - porównanie

Kontrola wyjścia vs ochrona wejścia

Kontrola wyjścia vs ochrona wejścia

  • CechaForward ProxyReverse Proxy
    Kierunek ruchuWychodzący (LAN → Internet)Przychodzący (Internet → LAN)
    Kto jest maskowanyKlient (serwer nie widzi IP klienta)Serwer (klient nie widzi IP serwera)
    Konfiguracja po stronieKlienta (ręczne ustawienie w przeglądarce)Serwera (DNS kieruje na proxy)
    PrzykładySquid, Privoxy, HAProxy (forward)Nginx, HAProxy, Apache mod_proxy
    Główne zastosowanieKontrola pracowników, oszczędność pasmaLoad balancing, SSL termination, cache
Forward Proxy vs Reverse Proxy - porównanie
11/50
Przepływ ruchu przez Reverse Proxy

Żądanie przez Reverse Proxy do backendu

Ścieżka żądania: klient → Reverse Proxy → Backend → Reverse Proxy → Klient

  • 1. Klient wysyła żądanie HTTP/HTTPS na adres publiczny (DNS wskazuje na reverse proxy)
  • 2. Reverse proxy przyjmuje połączenie, dokonuje terminacji SSL (odszyfrowuje ruch) i analizuje nagłówki
  • 3. Proxy wybiera serwer backendu według algorytmu (Round Robin, Least Connections) i tworzy nowe połączenie TCP
  • 4. Backend przetwarza żądanie i zwraca odpowiedź do proxy; proxy buforuje i przekazuje odpowiedź klientowi
Przepływ ruchu przez Reverse Proxy
12/50
Przepływ ruchu przez Forward Proxy

Żądanie przez Forward Proxy do sieci

Ścieżka żądania: Klient → Forward Proxy → Internet → Forward Proxy → Klient

  • 1. Klient jawnie konfiguruje proxy w przeglądarce lub systemie (adres IP + port proxy, np. 10.0.0.1:3128)
  • 2. Przeglądarka wysyła pełne żądanie HTTP: GET http://www.example.com/ HTTP/1.1 (pełny URL w żądaniu)
  • 3. Forward proxy sprawdza ACL-e, ewentualnie łączy się z Internetem po zasób
  • 4. Proxy buforuje odpowiedź i zwraca ją klientowi; serwer docelowy widzi tylko IP proxy
Przepływ ruchu przez Forward Proxy
13/50
Skalowanie poziome - konieczność w nowoczesnej architekturze

Wielu serwerów za jednym proxy

Jeden serwer to już za mało - jak sprostać rosnącemu ruchowi?

  • Skalowanie pionowe (vertical scaling): dokupienie większej ilości CPU, RAM, szybszych dysków - ma granice fizyczne i ekonomiczne
  • Skalowanie poziome (horizontal scaling): dodawanie kolejnych serwerów (węzłów) do puli, zamiast ulepszania pojedynczej maszyny
  • Load Balancer (LB) to serwer rozdzielający ruch pomiędzy wiele węzłów backendu według zdefiniowanego algorytmu
  • Korzyści: niezawodność (gdy jeden serwer pada, ruch idzie do pozostałych), wydajność (liniowa skalowalność)
Skalowanie poziome - konieczność w nowoczesnej architekturze
14/50
Load Balancer - klasyfikacja L4 vs L7

Równoważenie na transporcie i aplikacji

L4 (transport) vs L7 (aplikacja) - na której warstwie działać?

  • L4 Load Balancer (np. HAProxy w trybie tcp, Linux Virtual Server): działa na warstwie transportowej; decyzje na podstawie adresów IP i portów TCP/UDP; szybki, prosty
  • L7 Load Balancer (np. Nginx, HAProxy w trybie http, Traefik): działa na warstwie aplikacji; widzi metodę, URI, nagłówki, ciasteczka; wolniejszy, ale inteligentniejszy
  • Wybór między L4 a L7 zależy od potrzeb: L4 dla prostego protokołu TCP (bazy danych, gry), L7 dla HTTP (strony WWW, API REST)
  • Nowoczesne load balancery (HAProxy, Nginx) potrafią pracować w obu trybach jednocześnie
Load Balancer - klasyfikacja L4 vs L7
15/50
Algorytm Round Robin

Sprawiedliwa rotacja żądań

Sprawiedliwy zrównoważony obieg - każdy serwer po kolei

  • Round Robin - najprostszy i najbardziej znany algorytm dystrybucji ruchu: każde żądanie trafia do kolejnego serwera w cyklu
  • Działanie: serwery są ułożone w liście [A, B, C]; żądanie 1 -> A, 2 -> B, 3 -> C, 4 -> A, 5 -> B, ...
  • Zalety: idealnie równomierny podział przy założeniu podobnej wydajności serwerów; prostota implementacji
  • Wady: nie uwzględnia aktualnego obciążenia serwera - gdy serwer A jest przeciążony, a B bezczynny, A dostaje tyle samo zadań co B
Algorytm Round Robin
16/50
Ważony Round Robin (Weighted Round Robin)

Dystrybucja wagami mocy serwerów

Dostosowanie dystrybucji do mocy obliczeniowej serwerów

  • Weighted Round Robin - rozszerzenie Round Robin o wagi (współczynniki) przypisane do każdego serwera
  • Serwer z wagą 5 otrzymuje 5 razy więcej zadań niż serwer z wagą 1 (proporcjonalnie do mocy obliczeniowej)
  • Przykład: backend A (weight=3), B (weight=2), C (weight=1) -> na 6 zadań: A = 3, B = 2, C = 1
  • Idealny dla heterogenicznych środowisk, gdzie serwery mają różną moc (np. starsze serwery otrzymują mniej ruchu)
Ważony Round Robin (Weighted Round Robin)
17/50
Algorytm Least Connections

Najmniej obciążony serwer wygrywa

Inteligentny wybór najmniej obciążonego serwera

  • Least Connections - algorytm, który kieruje nowe zadanie do serwera z najmniejszą liczbą aktywnych połączeń
  • Load balancer śledzi liczbę otwartych połączeń do każdego serwera backendu, wybierając ten z najmniejszą wartością
  • Zalety: adaptuje się do różnej wydajności serwerów - serwery szybciej przetwarzające zadania mają mniej aktywnych połączeń
  • Wady: wymaga utrzymywania stanu (stateful) - load balancer musi śledzić liczbę połączeń dla każdego backendu
Algorytm Least Connections
18/50
Algorytm IP Hash

Stałe przypisanie klienta do serwera

Rygorystyczne i niezmienne przypięcie za pomocą funkcji skrótu

  • IP Hash - algorytm, który na podstawie adresu IP klienta oblicza skrót (hash) i przypisuje go na stałe do serwera
  • Ten sam klient (to samo IP) zawsze trafia do tego samego serwera, o ile pula backendu się nie zmienia
  • Idealny dla aplikacji stanowych, które nie obsługują sticky sessions - sesja użytkownika jest na stałe na jednym serwerze
  • Wady: nierównomierny rozkład przy małej liczbie klientów; zmiana puli (dodanie/usunięcie serwera) zmienia przypisania
Algorytm IP Hash
19/50
Porównanie algorytmów load balancingu

Wybór algorytmu do scenariusza

Round Robin vs Least Connections vs IP Hash

  • AlgorytmZaletyWadyKiedy używać
    Round RobinProsty, równomierny podziałNie uwzględnia obciążeniaJednorodne serwery, znany czas zadania
    Least ConnectionsAdaptacyjny, sprawiedliwyStateful, większy narzutZadania o zmiennym czasie (HTTP dynamiczny)
    IP HashStałe przypisanie klientaNierównomierny przy małej liczbie klientówAplikacje stanowe bez sticky sessions
Porównanie algorytmów load balancingu
20/50
System decyzyjny silnika load balancera

Podejmowanie decyzji routingowej

Jak load balancer podejmuje decyzje o wyborze serwera?

  • 1. Health check: load balancer okresowo wysyła zapytania do backendu, aby sprawdzić, czy serwer żyje
  • 2. Filtrowanie: usunięcie z puli serwerów martwych (DOWN), przeciążonych (draining) lub w konserwacji
  • 3. Wybór algorytmu: spośród żywych serwerów, load balancer stosuje skonfigurowany algorytm
  • 4. Forward: przekazanie zadania do wybranego serwera z modyfikacją nagłówków (X-Forwarded-For)
System decyzyjny silnika load balancera
21/50
Problem stanu sesji w systemach rozproszonych

Sesja użytkownika na wielu serwerach

Gdy użytkownik loguje się na jednym serwerze, a następne zadanie trafia na inny

  • Aplikacje webowe często przechowują stan sesji lokalnie w pamięci serwera (np. $_SESSION w PHP, sesja w Python Flask)
  • Przy bezstanowym load balancingu (Round Robin), użytkownik może zostać przekierowany do innego serwera - jego sesja jest tam nieznana
  • Efekt: użytkownik jest wylogowywany, koszyk zakupowy pusty, dane formularza utracone
  • Rozwiązanie: Session Persistence (lepkość sesji) zapewnia, że wszystkie zadania od jednego klienta trafiają do tego samego serwera
Problem stanu sesji w systemach rozproszonych
22/50
Session Persistence (Sticky Sessions)

Lepkie sesje dla spójności

Sztuczna niezmienna sesja - przypięcie klienta do serwera

  • Session Persistence (lepkość sesji): load balancer zapamiętuje, który serwer obsłużył pierwsze żądanie klienta
  • Mechanizmy: ciasteczko klienta (cookie insert), IP hash, URL hash
  • W Nginx: brak natywnego sticky sessions - wymaga modułu komercyjnego lub użycia ip_hash; w HAProxy: cookie SRVNAME insert
  • Zalety: prostota implementacji; Wady: problem z awarią serwera (utrata sesji), nierównomierne obciążenie
Session Persistence (Sticky Sessions)
23/50
Ciasteczko klienta na balancerze - jak działa cookie insert?

Ciasteczko identyfikujące serwer

HAProxy wstrzykuje ciasteczko z nazwą serwera

  • 1. Klient wysyła pierwsze zadanie do load balancera (np. HAProxy) - nie ma jeszcze ciasteczka
  • 2. HAProxy wybiera serwer backendu (np. web02), przekazuje zadanie i otrzymuje odpowiedź
  • 3. HAProxy dodaje do odpowiedzi nagłówek Set-Cookie: SRVNAME=web02 i zwraca klientowi
  • 4. Przy kolejnych zadaniach klient wysyła Cookie: SRVNAME=web02 i HAProxy kieruje do web02
Ciasteczko klienta na balancerze - jak działa cookie insert?
24/50
Buforowanie na warstwie Proxy (Caching)

Caching dla odciążenia backendu

Problem spowolnień witryn z ogromnym narzutem plików statycznych

  • Aplikacje webowe często serwują dużo plików statycznych: obrazy, CSS, JavaScript, czcionki
  • Każde zadanie o plik statyczny obciąża serwer aplikacyjny (I/O dyskowe, interpreter PHP) - marnotrawstwo
  • Rozwiązanie: buforowanie na warstwie proxy - reverse proxy przechowuje kopię i serwuje bez łączenia z backendem
  • Efekt: zmniejszenie obciążenia serwerów nawet o 90% dla zasobów statycznych; szybsze odpowiedzi dla klientów
Buforowanie na warstwie Proxy (Caching)
25/50
Mechanizm Cachingu w Nginx

Zapisywanie zasobów na linii frontu

Zapisywanie zasobów na linii frontowej - konfiguracja

  • Główne dyrektywy: proxy_cache_path (raz, w kontekście http) i proxy_cache (dla lokalizacji)
  • Przykład: proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=mycache:10m max_size=1g inactive=60m;
  • Klucz bufora domyślnie: $scheme$proxy_host$request_uri; można modyfikować przez proxy_cache_key
  • Włączenie: proxy_cache mycache; + proxy_cache_valid 200 302 60m; (buforuj odpowiedzi 200/302 przez 60 minut)
Mechanizm Cachingu w Nginx
26/50
Nagłówki TTL - sterowanie czasem życia w buforze

Czas życia zasobu w buforze

Logika zapisywania zasobów z Cache-Control i Expires

  • Serwer backendu kontroluje buforowanie przez nagłówki HTTP: Cache-Control i Expires
  • Cache-Control: public, max-age=3600 - buforuj przez 1 godzinę; private - tylko dla jednego użytkownika
  • Cache-Control: no-cache, no-store - zakaz buforowania (dane osobowe, sesje)
  • Nginx respektuje nagłówki backendu - jeśli backend ustawi no-cache, Nginx nie zbuforuje odpowiedzi
Nagłówki TTL - sterowanie czasem życia w buforze
27/50
Modyfikatory czasu - praktyczne TTL patterns

Wzorce TTL dla różnych treści

Jak ustawiać TTL w zależności od typu zasobu?

  • Pliki statyczne z fingerprintem (style.a1b2c3.css): max-age=31536000, immutable - rok, nigdy nie sprawdzaj
  • Obrazy, fonty, media: max-age=86400 - 1 dzień; public dla ogólnodostępnych
  • Strony HTML dynamiczne: no-cache, must-revalidate - sprawdzaj przy każdym zadaniu
  • API z danymi użytkownika: private, no-cache - tylko dla jednego użytkownika
Modyfikatory czasu - praktyczne TTL patterns
28/50
Cache Invalidation - jak unieważnić bufor?

Unieważnienie bufora po zmianie treści

Gdy zmieniasz treść, ale w buforze wciąż jest stara

  • Cache invalidation to jeden z najtrudniejszych problemów w informatyce
  • Metoda 1: purge - zadanie HTTP z metodą PURGE usuwa dany klucz z bufora (wymaga konfiguracji w Nginx)
  • Metoda 2: wersjonowanie - zmiana nazwy pliku (fingerprint) lub parametru ?v=2 powoduje pominięcie starego wpisu
  • Metoda 3: krótki TTL - ustawienie krótkiego czasu życia (np. 5 minut) dla zasobów, które mogą się zmieniać
Cache Invalidation - jak unieważnić bufor?
29/50
SSL/TLS termination na reverse proxy

Terminacja SSL na proxy

Terminacja ciężkiego asymetrycznego obciążenia na proxy

  • Protokół TLS wymaga kosztownych obliczeniowo operacji kryptograficznych podczas handshake (RSA/ECDHE)
  • SSL termination: reverse proxy przejmuje te operacje; klient łączy się przez HTTPS, a do backendu idzie czysty HTTP
  • Zalety: backend nie marnuje CPU na kryptografię; jeden certyfikat SSL na proxy zamiast na każdym serwerze
  • Wady: ruch między proxy a backendem jest niezaszyfrowany - wymaga zaufanej sieci wewnętrznej lub TLS re-encrypt
SSL/TLS termination na reverse proxy
30/50
Porównanie: L4 vs L7 proxy w kontekście load balancingu

TCP vs HTTP w równoważeniu

HAProxy w trybie tcp vs http - kiedy który wybrać?

  • CechaL4 (TCP mode)L7 (HTTP mode)
    WidziAdresy IP, porty TCPMetoda, URI, nagłówki, cookie
    RoutingRound Robin, Least ConnectionsTo samo + content-based (URI, header)
    SSL terminationNieTak
    CachingNieTak
    WydajnośćBardzo wysokaWysoka
    PrzykładyHAProxy mode tcp, LVSHAProxy mode http, Nginx
Porównanie: L4 vs L7 proxy w kontekście load balancingu
31/50
Nginx jako Reverse Proxy - architektura i kompilacja

Nginx jako serwer proxy i balanser

Demon szybkiego dostępu, wydajny i bezlitosny

  • Nginx oparty na asynchronicznej pętli zdarzeń (event-driven, non-blocking I/O) - jeden proces może obsłużyć tysiące połączeń
  • W przeciwieństwie do Apache (MPM prefork = jeden proces na połączenie), Nginx nie tworzy nowego procesu dla każdego klienta
  • Model master-worker: proces master czyta konfigurację i zarządza workerami; procesy worker obsługują połączenia
  • Kompilacja z modułami: --with-http_ssl_module (SSL), moduł upstream wbudowany domyślnie
Nginx jako Reverse Proxy - architektura i kompilacja
32/50
Blok upstream - definiowanie grupy zapleczowej

Definiowanie grupy serwerów backendu

Dyrektywa upstream: serwery backendu, wagi, algorytmy

  • Blok upstream definiuje grupę serwerów backendu, do której proxy będzie przekazywać zadania
  • Składnia: upstream nazwa { server adres:port; server adres:port; ... }
  • Modyfikatory serwera: weight=5 (waga), max_fails=3 (ile błędów = DOWN), fail_timeout=30s
  • Algorytmy: least_conn (Least Connections), ip_hash (IP Hash), domyślnie Round Robin
Blok upstream - definiowanie grupy zapleczowej
33/50
proxy_pass - przekazanie zadania do backendu

Przekazanie żądania do backendu

Praktyczna konfiguracja: proxy_pass http://upstream;

  • Dyrektywa proxy_pass w bloku location wskazuje, dokąd ma być przekazane odebrane zadanie HTTP
  • Składnia: proxy_pass http://nazwa_upstream; - nazwa_upstream to nazwa bloku upstream
  • Ważne: proxy_pass http://backend; przekazuje oryginalny URI; proxy_pass http://backend/; (z kreską) obcina część URI
  • Dodatkowe dyrektywy: proxy_set_header Host $host;, proxy_set_header X-Real-IP $remote_addr;
proxy_pass - przekazanie zadania do backendu
34/50
Pełna konfiguracja Nginx Reverse Proxy z load balancing

Kompleksowa konfiguracja Nginx proxy

Przykład kompleksowej konfiguracji z listingiem

  • # /etc/nginx/nginx.conf (fragment)
    http {
        upstream backend {
            least_conn;
            server 192.168.1.10:8080 weight=3;
            server 192.168.1.11:8080 weight=2;
            server 192.168.1.12:8080 backup;
        }
        server {
            listen 80;
            server_name example.com;
            location / {
                proxy_pass http://backend;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            }
        }
    }
Pełna konfiguracja Nginx Reverse Proxy z load balancing
35/50
HAProxy - potężniejszy brat z wyższego rzędu

HAProxy jako specjalizowany balanser

HAProxy: specjalizowany load balancer L7 z zaawansowanymi możliwościami

  • HAProxy (High Availability Proxy) - darmowy, otwarty, niezwykle wydajny load balancer L4/L7
  • Specjalizacja: HAProxy tylko reverse proxy i load balancing - nie serwuje plików statycznych
  • Rekordowa wydajność: miliony jednoczesnych połączeń na pojedynczym serwerze
  • Zaawansowane funkcje: stick tables, ACL, health checki HTTP, statystyki w czasie rzeczywistym na porcie 8404
HAProxy - potężniejszy brat z wyższego rzędu
36/50
Architektura HAProxy: frontend i backend

Wydzielenie struktur blokowych HAProxy

Wydzielenie struktur blokowych: sekcje frontend i backend

  • HAProxy dzieli konfigurację na dwa wyraźne bloki: frontend (strona przychodząca) i backend (strona wychodząca)
  • frontend - definiuje adres IP i port nasłuchu, tryb (http/tcp), reguły ACL
  • backend - definiuje serwery docelowe, algorytm load balancingu, stick tables, health checki
  • Rozdzielenie umożliwia wielokrotne użycie tego samego backendu przez różne frontendy
Architektura HAProxy: frontend i backend
37/50
Konfiguracja HAProxy Reverse Proxy z load balancing

Przykład konfiguracji HAProxy

Przykład konfiguracji: frontend HTTP -> backend z Round Robin

  • # /etc/haproxy/haproxy.cfg
    global
        log /dev/log local0
        maxconn 4096
    
    defaults
        mode http
        timeout connect 5s
        timeout client 30s
        timeout server 30s
    
    frontend http-in
        bind *:80
        default_backend web_servers
    
    backend web_servers
        balance roundrobin
        option httpchk GET /health
        server web1 192.168.1.10:80 check fall 3 rise 2
        server web2 192.168.1.11:80 check fall 3 rise 2
        server web3 192.168.1.12:80 check backup
Konfiguracja HAProxy Reverse Proxy z load balancing
38/50
HAProxy statystyki i monitoring

Wbudowany monitoring HAProxy

Wbudowany interfejs statystyk - podgląd na żywo każdego serwera

  • HAProxy oferuje wbudowany interfejs statystyk dostępny przez HTTP na porcie 8404
  • Konfiguracja:
    listen stats
        bind *:8404
        stats enable
        stats uri /
        stats refresh 10s
        stats auth admin:haslo
  • Interfejs pokazuje: status (UP/DOWN), liczbę aktywnych połączeń, błędy, czas odpowiedzi, przesłane bajty
  • Dostępne również: REST API (od HAProxy 2.0) oraz narzędzia typu haproxyctl
HAProxy statystyki i monitoring
39/50
LAB: Przygotowanie środowiska testowego

Budowa grupy testowych serwerów

Budowa grupy testowych serwerów HTTP z Pythonem

  • Cel: symulacja prostego środowiska produkcyjnego z trzema serwerami backendu i jednym reverse proxy
  • Wykorzystamy wbudowany serwer HTTP Pythona na portach 8081, 8082, 8083
  • Każdy serwer zwróci inną nazwę w odpowiedzi, abyśmy widzieli, który serwer obsłużył zadanie
  • Środowisko: Linux (Debian/Ubuntu) lub WSL na Windows; wymagany Python 3 i Nginx/HAProxy
LAB: Przygotowanie środowiska testowego
40/50
LAB: Uruchomienie serwerów testowych

Polecenia dla trzech serwerów HTTP

Polecenia krok po kroku dla trzech serwerów Python HTTP

  • 1. Utwórz katalogi: mkdir -p /tmp/srv{1,2,3}; echo 'Server 1' > /tmp/srv1/index.html; echo 'Server 2' > /tmp/srv2/index.html; echo 'Server 3' > /tmp/srv3/index.html
  • 2. Uruchom serwery Python: cd /tmp/srv1 && python3 -m http.server 8081 & (analogicznie 8082, 8083)
  • 3. Sprawdź: curl http://localhost:8081 powinien zwrócić 'Server 1'
  • 4. Opcjonalnie: przygotuj /health: mkdir -p /tmp/srv{1,2,3}/health; echo 'OK' | tee /tmp/srv{1,2,3}/health/index.html
LAB: Uruchomienie serwerów testowych
41/50
LAB: Konfiguracja Nginx Reverse Proxy

Konfiguracja odwrotnego proxy Nginx

Praktyczna konfiguracja odwrotnego proxy z Nginx na porcie 80

  • 1. Utwórz plik konfiguracyjny: /etc/nginx/sites-available/proxy-lab
  • 2. Zdefiniuj upstream: upstream backend { server 127.0.0.1:8081; server 127.0.0.1:8082; server 127.0.0.1:8083; }
  • 3. Zdefiniuj server: server { listen 80; location / { proxy_pass http://backend; proxy_set_header X-Real-IP $remote_addr; } }
  • 4. Włącz: ln -s ...; nginx -t; systemctl reload nginx
LAB: Konfiguracja Nginx Reverse Proxy
42/50
LAB: Test obciążeniowy Round Robin

Test dystrybucji z pętlą curl

Test dystrybucji ruchu z pętlą w BASH + curl

  • Test dystrybucji: for i in {1..15}; do curl -s http://localhost; sleep 0.5; done
  • Spodziewany wynik: Server 1, Server 2, Server 3, Server 1, Server 2, ...
  • Wariant z numeracją: for i in {1..15}; do echo -n "Req $i: "; curl -s http://localhost; echo; sleep 0.5; done
  • Dla testu Least Connections: dodaj least_conn; w bloku upstream i przeładuj Nginx
LAB: Test obciążeniowy Round Robin
43/50
LAB: Test z ciasteczkiem sesyjnym i sticky sessions

Sprawdzenie lepkości sesji

Sprawdzenie mechanizmu lepkości sesji w HAProxy

  • 1. Skonfiguruj HAProxy zamiast Nginx z cookie SRVNAME insert indirect nocache
  • 2. W backend: serwery z atrybutem cookie srv1, cookie srv2, cookie srv3
  • 3. Przeładuj HAProxy, testuj: curl -c /tmp/cookies.txt -b /tmp/cookies.txt -L http://localhost
  • 4. Wszystkie zadania powinny trafiać do tego samego serwera (sticky session)
LAB: Test z ciasteczkiem sesyjnym i sticky sessions
44/50
LAB: Test z symulacją awarii serwera

Awaria backendu i reakcja proxy

Wyłączenie serwera backendu i obserwacja reakcji load balancera

  • 1. W trakcie działania pętli testowej, zatrzymaj jeden z serwerów Python
  • 2. Nginx/HAProxy powinien automatycznie wykluczyć martwy serwer
  • 3. W interfejsie HAProxy stats zobaczysz status DOWN na czerwono
  • 4. Po przywróceniu serwera, load balancer automatycznie przywróci go do puli
LAB: Test z symulacją awarii serwera
45/50
Sesja troubleshooting: Zagubione adresy IP klienta

Backend widzi IP proxy zamiast klienta

Problem: backend loguje IP proxy zamiast IP klienta

  • Problem: serwer backendu loguje adres IP load balancera zamiast IP klienta
  • Przyczyna: bez odpowiednich nagłówków, backend widzi tylko adres IP proxy
  • Skutek: logi serwera są bezużyteczne; blokowanie IP atakujących nie działa; geolokalizacja fałszywa
  • Rozwiązanie: przekazywanie nagłówka X-Forwarded-For z reverse proxy do backendu
Sesja troubleshooting: Zagubione adresy IP klienta
46/50
Troubleshooting: X-Forwarded-For w Nginx

Dyrektywa proxy_set_header

Naprawa przez dyrektywę proxy_set_header dla backendu

  • W bloku location dodaj: proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  • Dodatkowo: proxy_set_header X-Real-IP $remote_addr; (prostszy nagłówek z jednym IP)
  • Po stronie backendu (Nginx jako serwer WWW): log_format main '$http_x_forwarded_for - $remote_user ...';
  • Ważne: nigdy nie ufaj ślepo X-Forwarded-For - klient może go fałszować
Troubleshooting: X-Forwarded-For w Nginx
47/50
Troubleshooting: X-Forwarded-For w HAProxy

Opcja forwardfor w HAProxy

Dyrektywa option forwardfor w HAProxy

  • W HAProxy: option forwardfor w bloku backend lub defaults
  • HAProxy domyślnie dodaje X-Forwarded-For ze źródłowym IP klienta
  • Opcjonalnie: option originalto - nagłówek X-Original-To z oryginalnym adresem docelowym
  • Po stronie backendu bez zmian - zmień logi na X-Forwarded-For
Troubleshooting: X-Forwarded-For w HAProxy
48/50
Troubleshooting: Diagnostyka martwych serwerów backendu

Health checki i logi błędów

Health checki, logi błędów, interfejs statystyk

  • Objaw: klienci otrzymują błędy 502 Bad Gateway, 503 Service Unavailable
  • 1. Sprawdź status serwerów: systemctl status serwer-aplikacji
  • 2. Sprawdź logi Nginx: tail -f /var/log/nginx/error.log - szukaj "upstream timed out"
  • 3. Sprawdź health checki: curl -I http://backend:8080/health z poziomu proxy
  • 4. W HAProxy: sprawdź interfejs stats (port 8404) - kolor serwera wskazuje status
Troubleshooting: Diagnostyka martwych serwerów backendu
49/50
Troubleshooting: Zaawansowana diagnostyka proxy

Analiza logów i timeouty

Analiza logów, nagłówki, timeouty, testy obciążeniowe

  • Sprawdź rozkład ruchu: tail -f /var/log/nginx/access.log | awk '{print $1}'
  • Debug nagłówków proxy: curl -v http://localhost - sprawdź czy X-Forwarded-For jest poprawny
  • Test timeoutu: time curl -v --max-time 5 http://localhost
  • Symuluj przeciążenie: ab -n 1000 -c 100 http://localhost/ (Apache Bench) i obserwuj rozkład
Troubleshooting: Zaawansowana diagnostyka proxy
50/50
Finał: Cheat Sheet administratora proxy

Przydatne polecenia proxy

Przydatne zestawienie poleceń dla administratora

  • Nginx Reverse Proxy: nginx -t (test), systemctl reload nginx (przeładowanie), tail -f /var/log/nginx/access.log (logi)
  • HAProxy: haproxy -f /etc/haproxy/haproxy.cfg -c (test), systemctl reload haproxy (przeładowanie), port 8404 (statystyki)
  • Testowanie dystrybucji: for i in {1..10}; do curl -s http://localhost; done
  • Nagłówki proxy: X-Forwarded-For (Nginx: proxy_set_header, HAProxy: option forwardfor), X-Cache-Status (debug cache)
Finał: Cheat Sheet administratora proxy