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 sekcjibackendo nazwiestronaana 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