Aktionen

Apache2 als Reverse Proxy und Loadbalancer Beispiel Proxmox

Aus znilwiki

Changelog:

  • 22.03.2025 erste Version
  • 23.05.2025 Version mit Websockets überarbeitet

Vorwort

Ein Arbeitskollege hat vor seinen Proxmox-Cluster einen Loadbalancer geschaltet. Dadurch landet er immer auf einen aktiven Knoten, auch bei einem Ausfall.
Das fand ich eine prima Idee - und die Gelegenheit mal zu prüfen ob so etwas auch mit einem Apache Reverse Proxy geht - Jupp, kann dieser auch!
Wie immer läuft das ganze bei mir unter Ubuntu, in diesem Fall 24.04 LTS, es sollte aber mit allen Apache2 Installationen funktionieren.



Schritt 1: Verschlüsselte Webseite

Ich baue immer erst die Webseite inklusive SSL Zertifikat und Umleitung auf https. Erst wenn diese funktioniert baue ich das Reverse Proxy ein.
Ich nutze eine Apache .vhost Konfiguration bei der jede Webseite seine eigene Konfigurationsdatei hat; https://httpd.apache.org/docs/2.4/vhosts/examples.html
Da ich faul bin nutze ich einen Host mit installiertem ISPConfig: https://znil.net/index.php?title=IONOS_Mietserver_Ubuntu_24.04_-_Einrichtung_ISPConfig#ISPConfig_Installieren Über die GUI von ISPConfig kann ich leicht die Subdomain erstellen und auch gleich ein passendes Zertifikat anfordern lassen.
Das erneuern der Zertifikate funktioniert aber nicht mehr wenn der Reverse Proxy eingebaut ist, deshalb läuft dafür noch ein Cronjob: https://znil.net/index.php?title=IONOS_Mietserver_Ubuntu_24.04_-_Einrichtung_ISPConfig#CronJob_f%C3%BCr_Reverse-Proxy_Seiten Nach wenigen Minuten steht die Webseite:


Wenn eure Webseite so funktioniert, könnte Ihr die Proxy-Geschichte einbauen.


Apache 2 benötigte Module aktivieren

a2enmod proxy_http proxy_balancer lbmethod_byrequests proxy_wstunnel
systemctl restart apache2.service

Das aktiviert neben dem Proxy-Modul auch das für das Loadbalancing und für die Prüfung ob ein Host erreichbar ist.
Zusätzlich mit proxy_wstunnel auch das Modul für das Proxing von Websockets.



Proxy konfigurierten

Dazu bearbeite ich die entsprechende .vhost Datei auf meinem Webserver:

nano /etc/apache2/sites-available/proxmox.znil.net.vhost

Im Abschnitt für Port 443 füge ich folgendes hinzu:

<IfModule mod_proxy_balancer.c>
    <Proxy balancer://proxmox>
        BalancerMember https://192.168.0.231:8006
        BalancerMember https://192.168.0.229:8006 status=+H
        BalancerMember https://192.168.0.230:8006 status=+H
        BalancerMember https://192.168.0.228:8006 status=+H
        ProxySet lbmethod=byrequests
    </Proxy>
</IfModule>
<IfModule mod_proxy.c>
    ProxyPreserveHost On
    ProxyRequests Off
    ProxyErrorOverride On

    SSLProxyEngine On

    SetEnv force-proxy-request-1.0 1
    SetEnv proxy-nokeepalive 1

    SSLProxyVerify none
    SSLProxyCheckPeerCN off
    SSLProxyCheckPeerName off
    SSLProxyCheckPeerExpire off

    ProxyPass "/" "balancer://proxmox/"
    ProxyPassReverse "/" "balancer://proxmox/"
</IfModule>


Erklärung der Parameter:

<Proxy balancer://proxmox>                               Erstellt eine Loadbalancing Gruppe
BalancerMember https://192.168.0.231:8006                Das erste Mitglied der Gruppe, wird per Default genommen
BalancerMember https://192.168.0.229:8006 status=+H      jedes weitere Mitglied bekommt status=+H = wird nur genommen wenn die anderen davor nicht erreichbar sind.
ProxySet lbmethod=byrequests                             Die Verfügbarkeitsprüfung erfolgt über den Aufruf der BalanceMember URL

SSLProxyVerify none                                      Keine Prüfung des internen Zertifikates, es kann also 
SSLProxyCheckPeerCN off                                  extern ein Zertifikat, z.B. von Lets Encrypt für alle
SSLProxyCheckPeerName off                                4 internen Server genommen werden.
SSLProxyCheckPeerExpire off

ProxyPass "/" "balancer://proxmox/"                      Reverse Proxy auf die Loadbalancergruppe "proxmox"
ProxyPassReverse "/" "balancer://proxmox/"


Das ganze ist dann eine Failover-Konfiguration, es wird der nächste Server aus der Liste genommen wenn der der davor nicht verfügbar ist.
Wenn Ihr das {{{1}}} weglasst, macht er ein echtes Loadbalancing was aber wegen der Anmeldung bei Proxmox blöd sein kann.


Falls Ihr wie ich ISPConfig einsetzt, könnt Ihr das auch einfach in die Einstellungen der Webseite kopieren:



Proxmox Cluster mit Loadbalancing und Websockets für VNC-Konsole

Hinweis: Es funktioniert, zickt aber manchmal. Also nur die Konsole der VMs. In dem Fall einfach mal per F5 neu laden und es noch mal versuche. Achtung, wenn man schnell zwischen den Konsolen wechselt, kann es auch mal sein das man die falsche bekommt, nämlich noch die vorherige.

Ich musste das obige Beispiel - welches für viele normale Webseiten problemlos funktionieren würde - noch mal speziell für Proxmox anpassen damit auch die Remote-Console zu den VMs funktioniert.
Und zwar mussten die Websockets auch mit hinein, was mit dem Loadbalancing nicht ganz so einfach war.
upgrade=websocket funktioniert erst ab Apache Version 2.4.47!

<Proxy balancer://proxmox>
    BalancerMember https://192.168.0.231:8006 upgrade=websocket
    BalancerMember https://192.168.0.229:8006 upgrade=websocket status=+H
    BalancerMember https://192.168.0.230:8006 upgrade=websocket status=+H
    BalancerMember https://192.168.0.228:8006 upgrade=websocket status=+H
    ProxySet lbmethod=byrequests
</Proxy>

SSLProxyEngine on
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
ProxyRequests off
ProxyPreserveHost on

<Location />
    ProxyPass "balancer://proxmox/"
    ProxyPassReverse "balancer://proxmox/"
</Location>




Proxmox ohne Cluster

Ein Reverse Proxy ohne Loadbalancing sähe so aus:

        SSLProxyEngine on
        SSLProxyVerify none
        SSLProxyCheckPeerCN off
        SSLProxyCheckPeerName off

        ProxyRequests off
        ProxyPreserveHost on

        <Location />
            ProxyPass https://192.168.0.228:8006/
            ProxyPassReverse https://192.168.0.228:8006/
        </Location>

        <LocationMatch ^/(api2/json/nodes/[^\/]+/[^\/]+/[^\/]+/vncwebsocket.*)$>
            ProxyPass wss://192.168.0.228:8006/$1 retry=0
        </LocationMatch>

        <Location /websockify>
            ProxyPass ws://192.168.0.228:8006
            ProxyPassReverse ws://192.168.0.228:8006
        </Location>

oder als Kurzform:

        SSLProxyEngine on
        SSLProxyVerify none
        SSLProxyCheckPeerCN off
        SSLProxyCheckPeerName off

        ProxyRequests off
        ProxyPreserveHost on

        <Location />
            ProxyPass https://192.168.0.228:8006/ upgrade=websocket
            ProxyPassReverse https://192.168.0.228:8006/
        </Location>




Quellen




Konfiguration überprüfen

apache2ctl -t

prüft ob alle Dateien in Ordnung sind und zeigt eventuelle Fehler an.


Kommentare

Loading comments...