Mit Hilfe dieser Installationsanleitung für den HAProxy Version 3 stable (LTS) können Sie beispielsweise zwei verschiedene Cloud-Anwendungen parallel betreiben und diese mit LetsEncrypt Zertifikaten versorgen. Wir nutzen dafür einen Mixed Mode, also Layer 6 (http) und Layer 4 (tcp) in der HAProxy-Konfiguration. Der HAProxy agiert dabei als klassischer ReverseProxy und kann auf Wunsch auch als Loadbalancer fungieren.
Nachfolgend stellen wir dafür unsere HAProxy-Konfiguration aus dem Labor bereit. Diese nutzen wir bspw. für unsere Cloud-Testinstanzen (bspw. Nextcloud und OpenCloud) auf einem dedizierten Server. Die SSL-Terminierung übernimmt dabei das jeweilige Backend, also Nextcloud und OpenCloud und nicht der HAProxy selbst. Der HAProxy reicht die https-Anfragen an die Anwendung durch und agiert im tcp-Mode (Layer 4) quasi transparent.
Um den aktuellen HAProxy zu installieren müssen die Repos eingebunden werden:
sudo -s
DEBIAN
curl https://haproxy.debian.net/bernat.debian.org.gpg \
| gpg --dearmor > /usr/share/keyrings/haproxy.debian.net.gpg
echo deb "[signed-by=/usr/share/keyrings/haproxy.debian.net.gpg]" \
http://haproxy.debian.net bookworm-backports-3.0 main \
> /etc/apt/sources.list.d/haproxy.list
Ubuntu
apt-get install --no-install-recommends software-properties-common
add-apt-repository ppa:vbernat/haproxy-3.0
Ab hier geht es für beide Betriebssysteme weiter
Installieren Sie den HAProxy und das Tool hatop:
apt update
apt install -y haproxy=3.0.\* hatop
Wir betreiben in diesem Szenario eine Nextcloud neben einer OpenCloud. Um das nachzustellen öffnen Sie die Datei haproxy.cfg:
mv /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak
touch /etc/haproxy/haproxy.cfg && nano /etc/haproxy/haproxy.cfg
Fügen Sie den gesamten Inhalt in die leere Datei ein und passen die rot markierten Werte an Ihre Umgebung an:
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
user haproxy
group haproxy
daemon
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
defaults
log global
mode tcp
option tcplog
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 ACME
bind :80 v4v6
mode http
maxconn 200
acl acmerequest path_beg /.well-known/acme-challenge/
acl nextcloud_host hdr(host) -i nextcloud.domain.org
acl opencloud_host hdr(host) -i opencloud.domain.org opencloud-collabora.domain.org opencloud-wopiserver.domain.org
redirect scheme https code 301 if !acmerequest
use_backend ACME_NEXTCLOUD if acmerequest nextcloud_host
use_backend ACME_OPENCLOUD if acmerequest opencloud_host
backend ACME_NEXTCLOUD
mode http
fullconn 100
balance source
server nextcloud 127.0.0.1:82 check maxconn 100
backend ACME_OPENCLOUD
mode http
fullconn 100
balance source
server opencloud 127.0.0.1:81 check maxconn 100
frontend CLOUDS
bind :443 v4v6
mode tcp
maxconn 20000
option tcplog
log global
tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }
acl acl_nextcloud req.ssl_sni -i nextcloud.domain.org
acl acl_opencloud req.ssl_sni -i opencloud.domain.org opencloud-collabora.domain.org opencloud-wopiserver.domain.org
use_backend NEXTCLOUD_HTTPS if acl_nextcloud
use_backend OPENCLOUD_HTTPS if acl_opencloud
default_backend NEXTCLOUD_HTTPS
backend OPENCLOUD_HTTPS
description OPENCLOUD
mode tcp
fullconn 10000
balance source
stick-table type binary len 32 size 1m expire 600m
option ssl-hello-chk
server opencloud 127.0.0.1:444 check maxconn 10000
backend NEXTCLOUD_HTTPS
description NEXTCLOUD
mode tcp
fullconn 10000
balance source
stick-table type binary len 32 size 1m expire 600m
option ssl-hello-chk
server nextcloud 127.0.0.1:445 check send-proxy-v2 maxconn 10000
Wenn Sie im Nextcloud_HTTPS-Backend den Parameter send-proxy-v2 verwenden, so muss auch nginx angepasst werden.
nano /etc/nginx/nginx.conf
set_real_ip_from <ext-ip oder 127.0.0.1>;
# real_ip_header X-Forwarded-For;
real_ip_header proxy_protocol;
nano /etc/nginx/conf.d/nextcloud.conf
[...]
server {
listen 443 ssl proxy_protocol;
listen [::]:443 ssl proxy_protocol;
http2 on;
[...]
Testen Sie die neue HAProxy-Konfiguration
haproxy -c -f /etc/haproxy/

Ist diese gültig, so starten Sie den HAProxy-Dienst neu, um die Konfiguration zu aktivieren.
systemctl restart nginx.service haproxy.service
systemctl status haproxy.service

HTTP-Request werden automatisch zu https-Requests umgeschrieben. Nur Anfragen die für Lets Encrypt relevant sind können Port 80 nutzen.
Ob und wie der HAProxy arbeitet, das können Sie mit Hilfe dieses Skripts visualisieren:
touch hat.sh
Fügen Sie diese Zeilen hinzu
#!/bin/bash
hatop -s /run/haproxy/admin.sock
exit 0
Markieren Sie das Skrtipt als ausführbar und starten es dann:
./hat.sh

Sie sehen nun in Echtzeit, wie der HAProxy als Reverse Proxy arbeitet.
Das war’s schon – wir wünschen Ihnen viel Spaß beim Erkunden des HAProxys. Über Ihre Unterstützung (diese wird ordnungsgemäß versteuert!) würden wir uns sehr freuen.