HAProxy ist eine kostenlose Open-Source-Software, die einen Hochverfügbarkeits-Load-Balancer (Layer 4 im [[osi|OSI]] Modell) und Reverse-[[proxy|Proxy]] für TCP- und HTTP-basierte Anwendungen bereitstellt, die Anforderungen auf mehrere Server verteilen.
=====Installation=====
* Service Ubuntu: /lib/systemd/system/haproxy.service
* Service RHEL: /etc/systemd/system/haproxy.service
In den meissten Distributionen installiert der Paketmanager eine veraltete Version (1.8)
[[SELinux]] deaktivieren oder den Dienst freigeben
apt install haproxy
Hauptconfig unter:
/etc/haproxy/haproxy.cfg
Konfiguration prüfen (vor einem Restart/Reload)
sudo haproxy -c -f /etc/haproxy/haproxy.cfg
====Kompilieren====
Von der [[https://www.haproxy.org/download/|offiziellen Homepage]] kann man aktuellere Pakete herunterladen.
sudo dnf install gcc pcre-devel tar make wget openssl-devel systemd-devel -y
wget http://www.haproxy.org/download/2.8/src/haproxy-2.8.3.tar.gz
tar -xvzf haproxy-2.8.3.tar.gz
cd haproxy-2.8.3
make TARGET=linux-glibc USE_OPENSSL=1 USE_PCRE=1 USE_ZLIB=1 USE_SYSTEMD=1
sudo make install
sudo cp haproxy /usr/sbin/haproxy
sudo mkdir -p /etc/haproxy
# Wahrscheinlich nicht funktional, besser from scratch erstellen
# cp examples/basic-config-edge.cfg /etc/haproxy/haproxy.cfg
Create a service file /etc/systemd/system/haproxy.service
[Unit]
Description=HAProxy Load Balancer
After=network.target
[Service]
ExecStart=/usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -Ws
ExecReload=/usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -c -q
ExecReload=/bin/kill -USR2 $MAINPID
Restart=always
User=root
Group=root
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reexec
sudo systemctl daemon-reload
sudo systemctl enable haproxy
sudo systemctl start haproxy
# Fix not needed
setcap 'cap_net_bind_service=+ep' /usr/sbin/haproxy
====Manueller Start====
haproxy -f /etc/haproxy/haproxy.cfg [-Ws]
haproxy -db -f /etc/haproxy/haproxy.cfg
=====Konfiguration=====
See also [[https://www.haproxy.com/documentation/haproxy-configuration-tutorials/|HAProxy configuration tutorials]]
====Global====
* [[https://www.haproxy.com/documentation/haproxy-configuration-tutorials/proxying-essentials/configuration-basics/global/|HAProxy Globals]]
* [[https://www.haproxy.com/documentation/haproxy-configuration-manual/latest/#3|Keywords in global section]]
Der globale Abschnitt befindet sich oben in Ihrer Konfigurationsdatei. Er definiert Anweisungen auf Prozessebene, beispielsweise die maximale Anzahl zulässiger Verbindungen, den Speicherort der Protokolle und den Benutzer und die Gruppe, unter der der Prozess ausgeführt werden soll. Das folgende Beispiel zeigt nur einige der verfügbaren Optionen:
global
maxconn 60000
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
user haproxy
group haproxy
chroot /var/empty
====Defaults====
* [[https://www.haproxy.com/documentation/haproxy-configuration-tutorials/proxying-essentials/configuration-basics/defaults/|HAProxy Defaults]]
In einem Abschnitt "defaults" werden allgemeine Einstellungen gespeichert, die von den nachfolgenden Frontend- und Backend-Abschnitten übernommen werden. Er kann auch lange Konfigurationen durch Reduzierung doppelter Zeilen verkürzen. Beispiel für eine Standardkonfiguration: Durch Hinzufügen von Standardeinstellungen zur Konfiguration können Sie Einstellungen definieren, die gegebenenfalls von allen darunter liegenden Abschnitten übernommen werden. Beispielsweise ist "mode" sowohl auf ein Frontend als auch auf ein Backend anwendbar, "balance" hingegen nur auf Backends. Nicht alle Anweisungen können in "defaults" aufgenommen werden, z.B. die Zeilen "bind" und "server".
defaults
mode http
balance roundrobin
# Inherits mode
frontend website
bind *:80
default_backend web_servers
# Inherits mode and balance
backend web_servers
server s1 192.168.1.25:80
server s2 192.168.1.26:80
====Frontend====
Ein "frontend" Abschnitt ([[https://www.haproxy.com/documentation/haproxy-configuration-tutorials/proxying-essentials/configuration-basics/frontends/|HAProxy Frontend]]) definiert die IP-Adressen und Ports, mit denen Clients eine Verbindung herstellen können. Sie können beliebig viele Frontend-Abschnitte hinzufügen, um verschiedene Websites oder Anwendungen im Internet verfügbar zu machen.
frontend foo.com
mode http
bind 192.168.1.5:80
default_backend foo_servers
frontend db.foo.com
mode tcp
bind 192.168.1.15:3306
default_backend db_servers
===HTTPS Termination===
Das Pem Zertifikat muss Cert und Privkey beinhalten!
certbot certonly --standalone -d vpn.zarat.at
certbot certonly --standalone -d sip.zarat.at
bash -c 'cat /etc/letsencrypt/live/vpn.zarat.at/fullchain.pem /etc/letsencrypt/live/vpn.zarat.at/privkey.pem > /etc/ssl/private/vpn.zarat.at.pem'
bash -c 'cat /etc/letsencrypt/live/sip.zarat.at/fullchain.pem /etc/letsencrypt/live/sip.zarat.at/privkey.pem > /etc/ssl/private/sip.zarat.at.pem'
frontend https_termination
mode tcp
bind *:443 ssl crt /etc/ssl/private/
use_backend vpn if { req.hdr(host) -i vpn.zarat.at }
use_backend sip if { req.ssl_sni -i sip.zarat.at }
===Redirect HTTP to HTTPS===
frontend mywebsite
mode http
bind :80
bind :443 ssl crt /etc/ssl/certs/ssl.pem
http-request redirect scheme https if !{ ssl_fc }
default_backend servers
====Backend====
Ein "backend" Abschnitt ([[https://www.haproxy.com/documentation/haproxy-configuration-tutorials/proxying-essentials/configuration-basics/backends/|HAProxy Backend]]) definiert einen Serverpool, an den der Load Balancer Anfragen weiterleitet. Sie können beliebig viele Backend-Abschnitte hinzufügen. Jedes Backend-Schlüsselwort wird durch eine Bezeichnung, z. B. "web_servers", von anderen unterschieden.
frontend foo_and_bar
mode http
bind *:80
use_backend foo_servers if { req.hdr(host) -i foo.com }
use_backend bar_servers if { req.hdr(host) -i bar.com }
backend foo_servers
mode http
balance roundrobin
server foo1 192.168.1.25:80 check
server foo2 192.168.1.26:80 check
server foo3 192.168.1.27:80 check
backend bar_servers
mode http
balance roundrobin
server bar1 192.168.1.35:80 check
server bar2 192.168.1.36:80 check
server bar3 192.168.1.37:80 check
=====Stats=====
HAProxy hat ein Web Frontend zum Überwachen der Statistiken.
frontend stats
mode http
bind *:8404
stats enable
stats refresh 10s
stats uri /stats
stats show-modules
http://:8404/stats
=====High Availability=====
HAProxy bietet das High Availability Modul nur in der kostenpflichtigen Enterprise Version. Alternativ kann man [[keepalived]] verwenden. Keepalived implementiert [[VRRP]], das selbe Protokoll das vom HA Modul verwendet wird.
=====Health Check=====
frontend smtp-frontend
bind *:25
mode tcp
default_backend smtp-backend
backend smtp-backend
mode tcp
description Das Mailrelay Backend
option tcp-check
tcp-check connect port 25
tcp-check send string "helo test.domain"
tcp-check expect rstring ^220
balance roundrobin
server vtsv-postfix4 172.21.0.187:25 check
Health Check mit Custom Script
frontend smtp-frontend
bind *:25
mode tcp
default_backend smtp-backend
backend smtp-backend
mode tcp
description Das Mailrelay Backend
option tcp-check
tcp-check connect port 12345
tcp-check expect rstring "^200"
balance roundrobin
server vtsv-postfix4 172.21.0.187:25 check
Und ein Script am Backend
#!/bin/bash
if ss -tulpn | grep -q "0.0.0.0:25"; then
echo "200"
else
echo "500"
fi
=====Agent Check=====
Untested
frontend smtp-frontend
bind *:25
mode tcp
default_backend smtp-backend
backend smtp-backend
mode tcp
description Das Mailrelay Backend
balance roundrobin
server vtsv-postfix4 172.21.0.187:25 check agent-check agent-port 12345 inter 1000
Auf dem Backend ein kleines Bash Script.
#!/bin/bash
if ss -tulpn | grep -q "0.0.0.0:25"; then
echo "200"
else
echo "500"
fi
As a Service
sudo nano /etc/systemd/system/agent-check.service
[Unit]
Description=HAProxy Agent Check Listener
After=network.target
[Service]
ExecStart=/usr/bin/socat TCP-LISTEN:12345,reuseaddr,fork EXEC:/home/manuel/agent.sh
Restart=always
User=manuel
WorkingDirectory=/home/manuel
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reexec
sudo systemctl daemon-reload
sudo systemctl enable agent-check.service
sudo systemctl start agent-check.service
=====Proxy Protocol=====
HAProxy implementiert das [[https://www.haproxy.com/blog/use-the-proxy-protocol-to-preserve-a-clients-ip-address|Proxy-Protocol]] womit die originale Client-IP an das Backend weitergereicht werden kann. [[https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt|Spezifikation]].
Möchte man das proxy-protocol im Frontend empfangen verwendet man die Option accept-proxy, möchte man es an das Backend sendet verwendet man send-proxy.
Siehe [[https://serverfault.com/questions/1193486/how-to-configure-health-check-for-postfix-behind-haproxy-when-using-the-proxy-pr]]
=====ACL=====
ACL geben true oder false zurück. Die ACL kann dann in jeder Zeile angewendet werden die ein conditional if or unless statement abfragt. Siehe [[https://www.haproxy.com/documentation/haproxy-configuration-tutorials/proxying-essentials/custom-rules/acls/|ACL Dokumentation]]
frontend www
bind :80
acl images_url path_beg -i /images/
use_backend static_assets if images_url
=====Fetches=====
[[https://www.haproxy.com/documentation/haproxy-configuration-tutorials/proxying-essentials/custom-rules/fetches/|Fetch Dokumentation]]
Eine Funktion, die Informationen über die aktuelle Anfrage, die aktuelle Antwort, die Verbindung oder den internen Zustand des Load Balancers zurückgibt.
frontend www
bind :80
http-request deny if { path /api/bad/ }
frontend www
bind :80
http-request set-var(txn.http_version) req.ver
http-response add-header Via "%[var(txn.http_version)] %[hostname]"
=====Persistence=====
====Stick Table====
Siehe [[https://www.haproxy.com/documentation/haproxy-configuration-tutorials/proxying-essentials/custom-rules/stick-tables/|Stick Table Dokumentation]]
# Track src IP, max 1Mill entries expire after 30m
backend app_servers
stick-table type ip size 1m expire 30m
stick on src
server app1 192.168.1.10:80 check
server app2 192.168.1.11:80 check
=====Links=====
* [[https://docs.haproxy.org/|Offizielle Dokumentation]]
* [[https://discourse.haproxy.org/t/haproxy-email-preserve-client-ip/5699/4]]
* [[https://www.haproxy.com/documentation/haproxy-configuration-tutorials/proxying-essentials/client-ip-preservation/transparent-proxying/]]
* [[https://www.linuxbabe.com/mail-server/smtp-imap-proxy-with-haproxy-debian-ubuntu-centos]]
* [[https://www.haproxy.com/blog/efficient-smtp-relay-infrastructure-with-postfix-and-load-balancers|Untested]]