Konfiguracja HAProxy dla HTTP oraz HTTPS
HAProxy jak podaje Wikipedia jest load-balancerem oraz serwerem proxy dla połączeń TCP oraz aplikacji HTTP. Dla mnie jest program, który zrobił robotę jeśli chodzi o hosting aplikacji internetowych na kontenerach. Bez HAProxy, aplikacje WWW na innych fizycznych serwerach musiały mieć odzielny publiczny adres IP. To się zmieniło, właśnie dzięki temu oprogramowaniu. Ten materiał pojawia się na "terminallog", bo jest o stricte jednym programie bez wskazania konkrenej platformy czy systemu operacyjnego.
Ja HAP-a konfigurowałem na Ubuntu 18.04 oraz 20.04. Jednak, tak jak już wspomniałem możemy sobie nawet go skonfigurować na OpenBSD. Mój wybór wtedy padł na Ubuntu, gdyż dopiero co zaznajomiłem się technologią kontenerów LXD.
Przejdźmy może już do konfiguracji. Ten materiał będzie składał się w bardzo dużej części z listingów plików konfiguracyjnych oraz ich opisów. Takie informacje na szybko, bez zbędnej teorii.
Rozpoczniemy od proxy dla HTTP, poniżej znajduje się konfiguracja dostarczana wraz z pakietem.
global log /dev/log local0 log /dev/log local1 notice chroot /var/lib/haproxy stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners stats timeout 30s user haproxy group haproxy daemon # Default SSL material locations ca-base /etc/ssl/certs crt-base /etc/ssl/private # Default ciphers to use on SSL-enabled listening sockets. # For more information, see ciphers(1SSL). This list is from: # https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ # An alternative list with additional directives can be obtained from # https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=haproxy ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256: ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS ssl-default-bind-options no-sslv3 defaults log global mode http option httplog option dontlognull timeout connect 5000 timeout client 50000 timeout server 50000 errorfile 400 /etc/haproxy/errors/400.http errorfile 403 /etc/haproxy/errors/403.http errorfile 408 /etc/haproxy/errors/408.http errorfile 500 /etc/haproxy/errors/500.http errorfile 502 /etc/haproxy/errors/502.http errorfile 503 /etc/haproxy/errors/503.http errorfile 504 /etc/haproxy/errors/504.http
Wartość opcji
ssl-default-bind-ciphers
złamano tylko i wyłączenie
dla celów estetycznych strony.
Kolejny listing przestawia już gotową konfigurację HTTP
global log /dev/log local0 log /dev/log local1 notice chroot /var/lib/haproxy stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners stats timeout 30s user haproxy group haproxy daemon # Default SSL material locations ca-base /etc/ssl/certs crt-base /etc/ssl/private # Default ciphers to use on SSL-enabled listening sockets. # For more information, see ciphers(1SSL). This list is from: # https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ # An alternative list with additional directives can be obtained from # https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=haproxy ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256: ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS ssl-default-bind-options no-sslv3 defaults log global mode http option httplog option dontlognull option forwardfor option http-server-close timeout connect 5000 timeout client 50000 timeout server 50000 errorfile 400 /etc/haproxy/errors/400.http errorfile 403 /etc/haproxy/errors/403.http errorfile 408 /etc/haproxy/errors/408.http errorfile 500 /etc/haproxy/errors/500.http errorfile 502 /etc/haproxy/errors/502.http errorfile 503 /etc/haproxy/errors/503.http errorfile 504 /etc/haproxy/errors/504.http frontend www_front bind *:80 acl host_stronya hdr(host) -i example.edu.pl www.example.edu.pl use_backend stronaa if host_stronya backend stronaa http-request set-header X-Client-IP %[src] server stronaa 192.168.56.2:80 check
Wartość opcji
ssl-default-bind-ciphers
złamano tylko i wyłączenie
dla celów estetycznych strony.
Więc, co się zmieniło względem konfiguracji bazowej? W konfiguracji domyślnej
defaults
zmieniono dwie opcje:
option forwardfor
- dzięki, której włączono wstawianie nagłówka X-Forwarded-For do żądań wysyłanych do serwera. Dzięki temu nagłówku do logów serwera trafi prawdziwy adres IP klienta a nie adres HAP-a,option http-server-close
- włącza zamykanie połączeń przez serwer. Użycie tej opcji ma na celu zmniejszyć zużycie zasobów serwera.
frontend
.
Zawiera ona opcje uruchomieniowe proxy takie jak port, na
którym HAP ma nasłuchiwać oraz reguły, według których należy
traktować spływające do usługi dane. Na przykład do jakiego
serwera przekierować żądanie na konkretny adres. W
przypadku proxy dla HTTP, wystarczą tylko poniższe opcje:
-
acl host_stronya hdr(host) -i example.edu.pl www.example.edu.pl
- ACL-ele są warunkami, które określają kryteria przekazywania danych przez proxy. Te warunki użwane są np. przez polecenia wskazujące na konkretny serwer. Sama reguła ACL składa się w tym przypadku z:- Słowa kluczowego:
acl
, - nazwy:
host_stronya
, - kryterium:
hdr(host)
- To kryterium może być niezrozumiałe. W konteście ACL polega ono na przyrównaniu zawartości nagłówka host żądania z wartościami na końcu reguły, - flagi:
-i
- brak czułości na wielkość znaków, - wartości do przyrównania:
example.edu.pl www.example.edu.pl
- Słowa kluczowego:
-
use_backend stronaa if host_stronya
- polecenie wskazujące na serwer, którego deklaracja znajduje się w sekcjibackend
o nazwiestronaa
na podstawie ACL-kihost_stronya
.
Konfigurację HAProxy możemy przetestować przed uruchomieniem za pomocą poniższego polecenia:
$ sudo haproxy -f <ścieżka_do_pliku_konfiguracyjnego> -c
Użycie HAProxy dla HTTPS, wydaje się być jeszcze prostsze. Poniżej znajduje się listing konfiguracji dla HTTPS jednak w tym przypadku jest TCP/443.
global log /dev/log local0 log /dev/log local1 notice chroot /var/lib/haproxy stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners stats timeout 30s user haproxy group haproxy daemon # Default SSL material locations ca-base /etc/ssl/certs crt-base /etc/ssl/private # Default ciphers to use on SSL-enabled listening sockets. # For more information, see ciphers(1SSL). This list is from: # https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ # An alternative list with additional directives can be obtained from # https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=haproxy ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256: ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS ssl-default-bind-options no-sslv3 defaults log global mode tcp option tcplog option dontlognull timeout connect 5000 timeout client 50000 timeout server 50000 errorfile 400 /etc/haproxy/errors/400.http errorfile 403 /etc/haproxy/errors/403.http errorfile 408 /etc/haproxy/errors/408.http errorfile 500 /etc/haproxy/errors/500.http errorfile 502 /etc/haproxy/errors/502.http errorfile 503 /etc/haproxy/errors/503.http errorfile 504 /etc/haproxy/errors/504.http frontend port443 mode tcp bind *:443 tcp-request inspect-delay 5s tcp-request content accept if { req_ssl_hello_type 1 } use_backend www if { req_ssl_sni -i www.example.edu.pl } use_backend www if { req_ssl_sni -i example.edu.pl } backend www mode tcp server www 192.168.56.2:443
Wartość opcji
ssl-default-bind-ciphers
złamano tylko i wyłączenie
dla celów estetycznych strony.
Jeśli przyrównamy sobie konfiguracje dla HTTP oraz TCP (HTTPS),
to pierwszą rzeczą, która będzie rzucać się nam w oczy będzie
zmiana trybu w sekcji defaults
defaults ... mode tcp option tcplog ...
Z tej sekcji usunięto również opcje
forwardfor
oraz
http-server-close
, ponieważ
są to ustawienia trybu http
W sekcji frontend
nie ma
już ACL-elek są warunki są używane bezpośrednio
przez polecenie use_backend
,
więc po kolei:
mode tcp
- ustawienie trybu TCP,bind *:443
- ustawienie nasłuchiwania na porcie 443 na wszystkich adresach w systemie,tcp-request inpspect-delay 5s
- Maksymalny czas oczekiwania na dane podczas sprawdzania zawartości. Ustawiany w celu oczekiwania na przesłanie przez klienta danych SSL hello,tcp-request content accept if { req_ssl_hello_type 1 }
- Zaakceptowanie zawartości żądania o ile przesłana przez klienta wiadomość SSL hello jest typu nr. 1.
use_backend
, które przekazują żądania do konkretnego
serwera na podstawie warunku. Tym warunkiem jest przypasowanie
wartości SSL SNI do ciągu znaków (w tym przypadku
www.example.edu.pl
) bez
rozróżniania wielkości znaków (flaga -i
).
use_backend www if { req_ssl_sni -i www.example.edu.pl }
Po sekcji frontend
występują
już sekcje backend
, wewnątrz
sekcji znajduje się ustawienie trybu TCP oraz opcja
server
wraz z adresem IP oraz
portem serwera.
backend www mode tcp server www 192.168.56.2:443
To już jest wszystko co trzeba zrobić, aby skonfigurować HAProxy w podstawowy sposób. Te konfiguracje przedstawiają HAP-a jako proxy, które może zastąpić reverse-proxy lokalnie instalowane na serwerach przy pomocy NGINX czy Apache2. Wystarczy tylko skonfigurować aplikacje tak, aby nasłuchiwały na wszystkich interfejsach systemu.
~xf0r3m