NetzwerktechnikMakeLinuxHTTPCHTTP/2HTTP3 QUICReverse Proxy

Reverse Proxy in nerdisch.

Der Server auf dem dieser Blog läuft ist ein recht gut ausgestattet Root Server, der in einem Rechenzentrum von Hetzner steht. Es läuft ein Debian 12 basiertes Proxmox-VE zum einfachen Management verschiedener Container und virtueller Maschinen.

Demzufolge gibt es eine ganze Reihe an Web Services die in einem virtuellen Netzwerk in den Tiefen des Systems ganz gerne nach Außen kommunizieren würden. Hierzu hatte ich bisher auf Nginx als Reverse Proxy gesetzt. Das funktionierte auch sehr gut auch wenn mir der administrative Aufwand zum neu einrichten von Diensten mich langsam nervte.

Nach einer Recherche bezüglich Web Technologien. Nicht nur HTTP Server sondern vor allem mit welchen Programmiersprachen ich mich zukünftig auseinandersetze, staunte ich nicht schlecht als ich feststellte wie sehr sich die Technologie in den vergangenen zwei Jahren weiterentwickelt haben.

Zusammenreißen, nicht abschweifen... Man; ist das schwer nicht zu sehr zum Programmieren abzuschweifen.

Nein! Dieser Artikel richtet sich an den geneigten Systemintegrator und jedem mit Interesse an Linux Konfiguration.


image

Hey, Julian. Durchhalten das hier ist wirklich interessant.

Alternativen zu Nginx

Ja, die gibt es. Sogar recht zahlreich. Ich für meinen Teil habe mir zwei genauer angeschaut. Erwähnenswert ist Traefik, ein in Go geschriebener, der sich neben der erstaunlichen Performance vor allem durch seinem Zero-Conf Ansatz interessant macht. Wie bei den meisten Unternehmen gibt es eine Open Source sowie eine Version mit zusätzlicher Funktionalität, die dann aber unter einer proprietären Lizenz erworben werben muss. Das nächste Major Release soll dann auch native Unterstützung für QUIC aka HTTP3 bieten.

image

Dann wäre da noch HAProxy, der auf der Programmiersprache C basiert , die eine hohe Leistung und Portabilität gewährleistet. HAProxy folgt einem Event-Driven Programmierparadigma, das es ihm ermöglicht, Tausende von gleichzeitigen Verbindungen mit geringem Ressourcenverbrauch zu verarbeiten. Mittlerweile das am meist verwendete Verfahren zur Implementierung von Hochleistung Netzwerkdiensten. Zumindest meiner bescheidenen Beobachtung nach.

HAProxy besteht aus zwei Hauptkomponenten: dem Prozessmanager (haproxy) und dem Worker-Prozess (haproxy-systemd-wrapper). Der Prozessmanager ist verantwortlich für das Laden der Konfigurationsdatei, das Starten des Worker-Prozesses und das Überwachen seiner Aktivität. Der Worker-Prozess ist verantwortlich für das Akzeptieren von Anfragen von Clients, das Weiterleiten von Anfragen an Backend-Server und das Zurückgeben von Antworten an Clients.


HAProxy

HAProxy ist ein Open-Source-Softwareprodukt, das als Load Balancer oder Reverse Proxy für TCP- und HTTP-basierte Anwendungen eingesetzt wird. Ein Reverse Proxy ist ein Server, der Anfragen von Clients entgegennimmt und sie an einen oder mehrere Backend-Server weiterleitet, die die eigentliche Verarbeitung durchführen. Der Reverse Proxy gibt dann die Antwort des Backend-Servers an den Client zurück. Ein Reverse Proxy kann verschiedene Vorteile bieten, wie z.B.:

  • Verbesserung der Leistung und Skalierbarkeit der Anwendung durch Lastverteilung auf mehrere Backend-Server
  • Verbesserung der Sicherheit und Zuverlässigkeit der Anwendung durch Verschlüsselung, Authentifizierung, Caching, Komprimierung und Filterung von Anfragen
  • Vereinfachung der Anwendungskonfiguration und -Wartung durch Abstraktion von Netzwerkdetails und Bereitstellung einer einheitlichen Schnittstelle für Clients
image

HAProxy ist einer der beliebtesten Reverse Proxies auf dem Markt und wird von vielen großen Unternehmen wie GitHub, Stack Overflow, Reddit und Twitter verwendet. Es zeichnet sich durch seine hohe Leistung, Stabilität, Flexibilität und Vielseitigkeit aus, unterstützt verschiedene Protokolle, Algorithmen und Funktionen für die Lastverteilung, die Anpassung an unterschiedliche Anforderungen ermöglichen. Zusätzlich bietet es auch eine umfangreiche Statistik- und Überwachungsfunktion.

Die Zusammenarbeit mit den unterschiedlichsten Webservern ist unproblematisch, aber einer der häufigsten ist Nginx, der ebenfalls ein Open-Source-Softwareprodukt, das sowohl als Webserver als auch als Reverse Proxy fungieren kann. Er ist bekannt für seine hohe Leistung, Skalierbarkeit und Effizienz bei der Verarbeitung von statischen und dynamischen Inhalten und kann auch verschiedene Funktionen wie Caching, Komprimierung, Verschlüsselung und Authentifizierung bereitstellen.

Die Kombination von HAProxy und Nginx als Reverse Proxy bietet einige Vorteile gegenüber der alleinigen Verwendung von Nginx als Reverse Proxy. Einige davon sind:

  • Eine bessere Lastverteilung auf mehrere Backend-Server, da HAProxy mehr Algorithmen und Optionen unterstützt als Nginx
  • Höhere Verfügbarkeit und Fehlertoleranz, da eine integrierte Gesundheitsprüfung verfügbar ist, die automatisch fehlerhafte Backend-Server erkennt und isoliert
  • Bessere Kontrolle über den Datenverkehr, da mit einer leistungsfähigen Konfigurationssprache komplexe Regeln für die Weiterleitung und Filterung von Anfragen definiert werden können
  • Eine sehr hohe Transparenz über den Systemzustand, da HAProxy über eine detaillierte Statistik- und Überwachungsfunktionen verfügt, die in Echtzeit aktualisiert wird

Wieder Standardmäßig kein QUIC integriert

Allerdings habe ich in den Entwicklerdokumentation eine ausführliche Anleitung finden können, die wirklich gut nachzuvollziehen war und erläutert wie man HAProxy aus dem Quellcode und einem speziellem Forks von OpenSSL, die eine vollständige Kompatibilität zu den QUIC APIs bietet, kompilieren und linken lassen kann. Seit dem vorletzten Release gilt die QUIC Implementation von HAProxy als "Production Ready".

Vermutliche erwische ich den einen oder anderen System Integrator außerhalb seiner Komfortzone. Nur Mut, ich gebe eine Schrittweise Anleitung.

Aber auch, wenn du das nicht machen magst. Ich bin mir ziemlich sicher das innerhalb der nächsten Patch-Zyklen es direkt vom Entwicklerteam mit QUIC erstellte Binärpakete geben wird. Genauso wie es auch bei Traefik sein wird.

HAProxy aus dem Source erstellen

Zur nächst richten wir uns die Entwicklerumgebung zum Erstellen von Anwendungen ein. Dafür wird neben den Betriebssystemabhängigen Standardprogrammierbibliotheken auch ein Compiler gebraucht. Dem Projektaufbau nach zur Urteilen besteht kein direkter Support für Windows. GCC oder Clang Toolchain benötigen wir daher. Die Shell Befehle sind Kompatibel zu allen Debian artigen Distributionen. Mit ein wenig Transferleistung wird das sicher aber auch in deiner liebsten Distribution funktionieren.

Build Environment vorbereiten

$ sudo apt-get update
$ sudo apt-get install build-essential

Das build-essential Paket enthält alle nötigen Standard-Libaries, einen C sowie C++ Compiler, Linker und Tools zum Erstellen und Ausführen von Scripts zur Konfiguration einer Build-Pipeline.

Danach erstellen wir die Dependency QUICTLS

QUICTLS erstellen

$ cd /opt
$ # Repository von QUICTLS klonen 
$ git clone https://github.com/quictls/openssl
$ cd openssl
$ # Die Build-Pipeline konfigurieren
$ ./config --libdir=lib [--prefix=/opt/quictls]
$ ./Configure
$ # Kompilieren und Linken
$ make
$ # Installieren
$ make install

Nur noch einmal und dann ist es getan

HAProxy aus dem Quellcode erstellen

$ cd /opt
$ # Repository wieder klonen. Nur diesmal die von HAProxy
$ git clone https://github.com/haproxy/haproxy.git
$ cd haproxy
# Diesmal übergeben wir die Parameter direkt an Make
$ make -j $(nproc) TARGET=generic \
    USE_QUIC=1 \
    USE_OPENSSL=1 SSL_INC=/opt/quictls/include SSL_LIB=/opt/quictls/lib \
    LDFLAGS="-Wl,-rpath,/opt/quictls/lib"
Argument Option Eigenschaft
j [n] Anzahl der zu verwendenen CPU Kernen. Der Befehl nproc gibt die Anzahl der verfügbaren Kerne zurück.
USE_QUIC <0|1> Berücksichtigt beim Erstellen die Codeabschnitte, die QUIC implementieren.
USE_OPENSSL <0|1> SSL bzw. TLS wird auf Basis der auf dem System zur Verfügung stehenden SLL-Lib erstellt und kann zur Laufzeit verwendet werden
SSL_INC <path> Pfad zu den C Header, die die Funktions Definitionen beinhalten
SSL_LIB <path> Pfad zu den Bibliotheken, die die Funktionalitäten implementieren
LDFLAGS "-Wl,-rpath,/opt/quictls/lib" Die Zeichenkette wird gegen Ende des Build-Prozesses and den Linker übergeben. -Wl Flagged die darauf folgende Liste an Paramter explizit für den Linker bestimmt. Durch rpath schreibt der Linker den Pfad zur Laufzeitbibliothek hardcoded in die Binärdatei. Dadurch wird nicht versehentlich eine falsche Version geladen.

Jetzt muss nur noch obligatorisch installiert werden und zack, fertig ist dein personalisierter HAProxy Build.

$ make install

In der Entwicklerdokumentation sind noch weitere Optionen und Funktionen erläutert, die durchaus intreressant sein könnten für den einen oder anderen.


Konfiguration

Abschließend möchte ich ganz schnell nochmal eine grundlegende Konfiguration erläutern. Leider kein Zero-Conf aber im Gegensatz zu Nginx ist das wirklich nicht kompliziert. Dafür ist HAProxy aber auch weniger flexibel einsetzbar.

/etc/haproxy/haproxy.cfg

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

  # Default SSL material locations
  #ca-base /etc/ssl/certs
  #crt-base /etc/ssl/private
  ca-base /opt/cert
  crt-base /opt/cert

  # See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
  ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA38>        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

Neben einem Globalen-Blocks gibt es noch einen Default und ein oder mehrere Frontend sowie ein oder mehrere Backend Blöcke.

/etc/haproxy/haproxy.cfg

frontend fe
  # mode definiert den Übertragungsmodus (alterrnativ: TCP)
  mode http
  bind 0.0.0.0:80
  # ssl aktiviert die Verschlüsselung
  # Ich habe symbolische Links aller benötigten Zertifikate
  # in /opt/cert erstellt. Das gilt dann für jeden Host
  # alpn aktiviert Application-Layer-Protocol Negotiation
  # h2 = HTTP2
  # h3 = HTTP3 (Der verwendete Port ist nebensächlich)
  bind 0.0.0.0:443 ssl crt /opt/cert alpn h2
  bind quic4@:443 ssl crt /opt/cert alpn h3
  # Dass leitet alle nicht HTTPS Anfragen auf HTTPS um
  http-request redirect scheme https unless { ssl_fc }
  # Das ist nun wichtiger als der genutzte UDP Port:
  # Man fügt den Response ein Headerfelds zu mit folgendem
  # Key Value Pair - alt-svc: h3=":443";ma=900
  # Dadurch wird der Client über den alternativen Dienst
  # in Kenntniss gesetzt.
  http-response set-header alt-svc "h3=\":443\";ma=900;"

Den letzten Teil der Konfiguration spare ich mir. Ich denke wer es soweit geschafft hat, findet auch selbstständig herraus wie der Rest funktioniert.


Quellen

haproxy/INSTALL at master · haproxy/haproxy
HAProxy Load Balancer’s development branch (mirror of git.haproxy.org) - haproxy/haproxy
image
How to Configure and Use HAProxy as a Reverse Proxy | Linux Tutorials for Beginners
As a server administrator or webmaster, you may find yourself in a situation where you need to distribute network or web traffic across multiple servers. Th…
image
What are the Differences between HAProxy and Ngnix in reverse proxy mode?
What are the differences between HAProxy and Nginx when it comes to their abilities as a reverse proxy?
image
NGINX and HAProxy: Testing User Experience in the Cloud - NGINX
We compare the reverse proxying performance of HAProxy and NGINX. Performance is similar until the request rate is large enough for HAProxy to hit 100% CPU utilization. At that point, its performance degrades significantly while NGINX continues to experience almost no latency.
image
Wie man einen Reverse Proxy einrichtet (Schritt-für-Schritt für Nginx und Apache)
Umfassende Anleitung für Reverse Proxy für WordPress. Erfahre, wie du eine andere WordPress Seite aus einem Unterverzeichnis per Reverse Proxy laden kannst.
image