Marco Burmeister

  private Homepage



HAProxy

HAProxy ist ein Load Balancer, der TCP und HTTP/HTTPS Datenverkehr als Load Balancer oder Reverse-Proxy behandeln kann. Er ist als OpenSource verfügbar. Es gibt aber auch professionelle Unterstützung bei Bedarf.

Auf dieser Seite wird es um konkrete Anwendungsfälle in dem Umfeld gehen, an denen ich mal gearbeitet hatte.

Hinweis:
Für die Richtigkeit der Daten übernehme ich keine Gewähr!

Die Seite ist in die folgenden Bereiche eingeteilt:




top Allgemeine Hinweise

In diesem Abschnitt werde ich ein paar allgemeine Beschreibungen / Hinweise zum HAProxy zentral erfassen.



top HAProxy als Reverse Proxy für RDP Zugriffe

Beschreibung

Es gibt Situationen, in denen ein Windows System vielleicht nicht von jedem Client oder jedem Server erreichbar sein soll.
Dann kann zum Beispiel ein Zwischensystem mit einem laufenden HAProxy auf Linux dazwischengestellt werden.
Dort wird dann ein (neuer) Port definiert auf den HAProxy dann lauschen soll und eingehenden Datenverkehr an das eigentliche Zielsystem weiterleitet.

Syntax


# Windows Server
frontend [Identifikationsbezeichnung-Frontend]
    bind *:[Port auf Server auf dem HAProxy läuft]
    mode tcp
    option tcplog
    default_backend [Identifikationsbezeichnung-Backend]

backend [Identifikationsbezeichnung-Backend]
    mode tcp
    option tcpka
    balance leastconn
    server [Bezeichner für Servername] [IP-Addresse / DNS Name]:[Port] check weight 1
(Anmerkung: ✂ = Zeilenumbruch nur in Darstellung hier)

# Windows Server
frontend [Identifikationsbezeichnung-Frontend]
  bind *:[Port auf Server auf dem HAProxy läuft]
  mode tcp
  option tcplog
  default_backend [Identifikationsbezeichnung-Backend]

backend [Identifikationsbezeichnung-Backend]
  mode tcp
  option tcpka
  balance leastconn
  server [Bezeichner für Servername] ✂
[IP-Addresse / DNS Name]:[Port] check weight 1

Beispiel

Der HAProxy wird auf den Port 14000 lauschen und dort eingehenden Verkehr an den Server 192.168.10.10 an den Port 3389 weiterleiten.
Die Bezeichnung "meinserver" entspricht nicht dem DNS Namen und dient nur als Bezeichner in der Konfiguration.

# Windows Server
frontend front_msosrdp1
  bind *:14000
  mode tcp
  option tcplog
  default_backend back_msosrdp1

# Windows Server
backend back_msosrdp1
  mode tcp
  option tcpka
  balance leastconn
  server meinserver 192.168.10.10:3389 check weight 1

top HAProxy als Reverse Proxy für MS SQL Server Zugriffe

Beschreibung

Wenn ein SQL Server nur aus bestimmten Netzen erreichbar sein soll, kann das mittels Netzwerkregeln organisiert werden.
Es kann dann aber zum Beispiel auch ein Zwischensystem mit einem laufenden HAProxy auf Linux dazwischengestellt werden, der in dem Zielnetz Zugriff hat.
Für den HAproxy wird dann ein (neuer) Port definiert auf den der HAProxy dann lauschen soll und eingehenden Datenverkehr an das eigentliche Zielsystem weiterleitet.

Hinweis:
Die hier gezeigte Lösung hat im Augenblick noch ein technisches Problem. Wird bei einer laufenden Verbindung zu einem SQL Server aus einem SQL Server Management Studio heraus z.B. der Wizard für die Availability Group Einrichtung gestartet, so wird das entsprechende Fenster leider nicht zurückgesendet.
Diese Funktion muss leider via T-SQL eingerichtet werden.

Syntax


frontend [Identifikationsbezeichnung-Frontend]
  bind :[Port auf Server auf dem HAProxy läuft]
  mode tcp
  # option forwardfor - nur HTTP
  option tcplog
  option tcpka
  use_backend [Identifikationsbezeichnung-Backend]

backend [Identifikationsbezeichnung-Backend]
  mode tcp
  server [Bezeichner für Servername] [IP-Addresse / DNS Name]:[Port] check
(Anmerkung: ✂ = Zeilenumbruch nur in Darstellung hier)

frontend [Identifikationsbezeichnung-Frontend]
  bind :[Port auf Server auf dem HAProxy läuft]
  mode tcp
  # option forwardfor - nur HTTP
  option tcplog
  option tcpka
  use_backend [Identifikationsbezeichnung-Backend]

backend [Identifikationsbezeichnung-Backend]
  mode tcp
  server [Bezeichner für Servername] ✂
[IP-Addresse / DNS Name]:[Port] check

Beispiel

Der HAProxy wird auf den Port 14001 lauschen und dort eingehenden Verkehr an den Server 192.168.10.10 an den Port 1433 (MS SQL Server Standard Port) weiterleiten.
Die Bezeichnung "meinsqlserver1" entspricht nicht dem DNS Namen und dient nur als Bezeichner in der Konfiguration.

frontend front_mssqlsrv1
  bind :14001
  mode tcp
  # option forwardfor - nur HTTP
  option tcplog
  option tcpka
  use_backend back_mssqlsrv1

backend back_mssqlsrv1
  mode tcp
  server meinsqlserver1 192.168.10.10.:1433 check

top HAProxy als Load Balancer für MariaDB/MySQL Zugriffe

Beschreibung

Es gibt vielleicht Situationen in denen zum Endnutzer ein anderer Port und Hostname bekanntgegeben werden soll, als in Realität konfiguriert ist.
Im Umfeld von Cluster Lösungen via Galera Cluster soll vielleicht nur ein Hostname und Port (oder nur wenige) herausgegeben werden und es soll die reale installierte Umgebung nicht allgemein bekanntgegeben werden.
Die Gründe dahinter können vielfältig sein und können begründet sein in einer einfacheren Möglichkeit das Backend auszutauschen oder zu erweitern.
Auf jeden Fall kann hier HAProxy helfen, da er auch als Load Balancer fungieren kann.

Syntax


# MariaDB Galera Cluster
frontend [Identifikationsbezeichnung-Frontend]
    bind *:[Port auf Server auf dem HAProxy läuft]
    mode tcp
    option tcplog
    default_backend [Identifikationsbezeichnung-Backend]

backend [Identifikationsbezeichnung-Backend]
    mode tcp
    option tcpka
    balance leastconn
    server [Bezeichner für Servername] [IP-Addresse / DNS Name]:[Port] check weight 1
    server [Bezeichner für Servername] [IP-Addresse / DNS Name]:[Port] check weight 1
    server [Bezeichner für Servername] [IP-Addresse / DNS Name]:[Port] check weight 1
(Anmerkung: ✂ = Zeilenumbruch nur in Darstellung hier)
			
# MariaDB Galera Cluster
frontend [Identifikationsbezeichnung-Frontend]
  bind *:[Port auf Server auf dem HAProxy läuft]
  mode tcp
  option tcplog
  default_backend [Identifikationsbezeichnung-Backend]

backend [Identifikationsbezeichnung-Backend]
  mode tcp
  option tcpka
  balance leastconn
  server [Bezeichner für Servername] ✂
[IP-Addresse / DNS Name]:[Port] check weight 1
  server [Bezeichner für Servername] ✂
[IP-Addresse / DNS Name]:[Port] check weight 1
  server [Bezeichner für Servername] ✂
[IP-Addresse / DNS Name]:[Port] check weight 1

Beispiel

Der HAProxy wird auf den Port 14002 lauschen und dort eingehenden Verkehr an die Server 192.168.10.11, 192.168.10.12 oder 192.168.10.13 an den Port 3306 weiterleiten.
Die Bezeichnung "dbsrvX" entspricht nicht dem DNS Namen und dient nur als Bezeichner in der Konfiguration.

# MariaDB Galera Cluster
frontend front_mariadbgal1
  bind *:14002
  mode tcp
  option tcplog
  default_backend back_mariadbgal1

backend back_mariadbgal1
  mode tcp
  option tcpka
  balance leastconn
  server dbsrv1 192.168.10.11:3306 check weight 1
  server dbsrv2 192.168.10.12:3306 check weight 1
  server dbsrv3 192.168.10.13:3306 check weight 1

top HAProxy als Reverse Proxy für HTTP und HTTPS Zugriffe

Beschreibung

Wir möchten einen HTTP-Zugriff auf Port 80 auf dem Server auf dem HAProxy läuft auf Protokoll HTTPS umleiten und zusätzlich HTTPS Zugriffe dann an einen anderen Server weiterleiten.

Es muss hierfür für den Server bzw. HAProxy entweder ein Self Signed Zertifikat erstellt oder ein offizielles besorgt werden.
In diesem Beispiel erzeuge ich ein Self Signed Zertifikat, weil das in dem Beispiel ausreichend war.

Self Signed Zertifikat erstellen

Bei der Ablage des Zertifikat-Files muss darauf geachtet werden, ob SELINUX oder AppArmor aktiv sind. Hier muss ggfs. noch etwas konfiguriert werden. Alternativ kann das PEM-File in das Verzeichnis gelegt werden, in dem die Konfigurations-Datei haproxy.cfg vom HAProxy liegt.

In dem Beispiel liegt die Konfigurationsdatei haproxy.cfg vom HAProxy in /etc/haproxy.
  1. User root auf dem Serer mit HAProxy werden
  2. Verzeichnis anlegen, in dem die Zertifikate liegen sollen.
    mkdir /etc/haproxy/mycerts
  3. Wechsel des Verzeichnisses
    cd /etc/haproxy/mycerts
  4. Private Key File mit Bitlänge 2048 erzeugen
    openssl genrsa -out haproxy.key 2048
    oder neuerer Befehl:
    openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out haproxy.key
    (Anmerkung: ✂ = Zeilenumbruch nur in Darstellung hier)
    openssl genrsa -out haproxy.key 2048
    oder neuerer Befehl:
    openssl genpkey -algorithm RSA ✂
    -pkeyopt rsa_keygen_bits:2048 ✂
    -out haproxy.key
  5. Request-File erzeugen
    openssl req -new -key haproxy.key -out haproxy.csr
  6. Zertifikat erzeugen, welches nach 365 Tagen abläuft
    openssl x509 -req -days 365 -in haproxy.csr -signkey haproxy.key -out haproxy.crt
  7. Private Key und Zertifikat in ein File kopieren. Dieses File wird dann im HAProxy in der Konfiguration hinterlegt
    cat haproxy.crt haproxy.key > haproxy.pem

Syntax


frontend [Identifikationsbezeichnung-Frontend]
     bind *:80
     bind *:[Port auf Server auf dem HAProxy läuft] ssl crt [Pfad und Dateiname self signed certificate]
     http-request redirect scheme https if !{ ssl_fc }
     mode http
     default_backend [Identifikationsbezeichnung-Backend]

backend [Identifikationsbezeichnung-Backend]
     mode http
     balance roundrobin
     option forwardfor
     option httpchk HEAD / HTTP/1.1\r\nHost:localhost
     server [Bezeichner für Servername] [IP-Addresse / DNS Name]:[Port] check-ssl ssl verify none
     http-request set-header X-Forwarded-Port %[dst_port]
     http-request add-header X-Forwarded-Proto https if { ssl_fc }
(Anmerkung: ✂ = Zeilenumbruch nur in Darstellung hier)

frontend [Identifikationsbezeichnung-Frontend]
  bind *:80
  bind *:[Port auf Server auf dem HAProxy läuft] ✂
ssl crt [Pfad und Dateiname self signed certificate]
  http-request redirect scheme https ✂
if !{ ssl_fc }
  mode http
  default_backend [Identifikationsbezeichnung-Backend]

backend [Identifikationsbezeichnung-Backend]
  mode http
  balance roundrobin
  option forwardfor
  option httpchk HEAD / HTTP/1.1\r\nHost:localhost
  server [Bezeichner für Servername] ✂
[IP-Addresse / DNS Name]:[Port] check-ssl ✂
ssl verify none
  http-request set-header X-Forwarded-Port %[dst_port]
  http-request add-header X-Forwarded-Proto ✂
https if { ssl_fc }

Beispiel

Der HAProxy wird auf den Port 80 für HTTP und 14005 für HTTPS lauschen, HTTP-Zugriffe auf HTTPS umleiten und eingehenden Verkehr an den Server 192.168.10.14 an den Port 443 (HTTPS) weiterleiten.

Die Bezeichnung "meinwebserver1" entspricht nicht dem DNS Namen und dient nur als Bezeichner in der Konfiguration.

# HTTPS Forward
frontend front_webserver1
     bind *:80
     bind *:14005 ssl crt /etc/haproxy/mycerts/haproxy.pem
     http-request redirect scheme https if !{ ssl_fc }
     mode http
     default_backend back_webserver1

backend back_webserver1
     mode http
     balance roundrobin
     option forwardfor
     option httpchk HEAD / HTTP/1.1\r\nHost:localhost
     server meinwebserver1 192.168.10.14:443 check-ssl ssl verify none
     http-request set-header X-Forwarded-Port %[dst_port]
     http-request add-header X-Forwarded-Proto https if { ssl_fc }
(Anmerkung: ✂ = Zeilenumbruch nur in Darstellung hier)

# HTTPS Forward
frontend front_webserver1
  bind *:80
  bind *:14005 ssl crt /etc/haproxy/mycerts/haproxy.pem
  http-request redirect scheme https ✂
if !{ ssl_fc }
  mode http
  default_backend back_webserver1

backend back_webserver1
  mode http
  balance roundrobin
  option forwardfor
  option httpchk HEAD / HTTP/1.1\r\nHost:localhost
  server meinwebserver1 192.168.10.14:443 check-ssl ✂
ssl verify none
  http-request set-header X-Forwarded-Port ✂
%[dst_port]
  http-request add-header X-Forwarded-Proto ✂
https if { ssl_fc }

top HAProxy als TCP Forwarder für https-Zugriffe

Beschreibung

Wir möchten einen HTTPS-Zugriff auf Port 10443 auf dem Server auf dem HAProxy läuft auf einen anderen Server an einen anderen Port weiterleiten.

Es muss hierfür für den Server bzw. HAProxy entweder ein Self Signed Zertifikat erstellt oder ein offizielles besorgt werden.
In diesem Beispiel erzeuge ich ein Self Signed Zertifikat, weil das in dem Beispiel ausreichend war.

Self Signed Zertifikat erstellen

Bei der Ablage des Zertifikat-Files muss darauf geachtet werden, ob SELINUX oder AppArmor aktiv sind. Hier muss ggfs. noch etwas konfiguriert werden. Alternativ kann das PEM-File in das Verzeichnis gelegt werden, in dem die Konfigurations-Datei haproxy.cfg vom HAProxy liegt.

In dem Beispiel liegt die Konfigurationsdatei haproxy.cfg vom HAProxy in /etc/haproxy.
  1. User root auf dem Serer mit HAProxy werden
  2. Verzeichnis anlegen, in dem die Zertifikate liegen sollen.
    mkdir /etc/haproxy/mycerts
  3. Wechsel des Verzeichnisses
    cd /etc/haproxy/mycerts
  4. Private Key File mit Bitlänge 2048 erzeugen
    openssl genrsa -out haproxy.key 2048
    oder neuerer Befehl:
    openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out haproxy.key
    (Anmerkung: ✂ = Zeilenumbruch nur in Darstellung hier)
    openssl genrsa -out haproxy.key 2048
    oder neuerer Befehl:
    openssl genpkey -algorithm RSA ✂
    -pkeyopt rsa_keygen_bits:2048 ✂
    -out haproxy.key
  5. Request-File erzeugen
    openssl req -new -key haproxy.key -out haproxy.csr
  6. Zertifikat erzeugen, welches nach 365 Tagen abläuft
    openssl x509 -req -days 365 -in haproxy.csr -signkey haproxy.key -out haproxy.crt
  7. Private Key und Zertifikat in ein File kopieren. Dieses File wird dann im HAProxy in der Konfiguration hinterlegt
    cat haproxy.crt haproxy.key > haproxy.pem

Syntax


frontend [Identifikationsbezeichnung-Frontend]
        bind *:10443 ssl crt /etc/haproxy/mycerts/haproxy.pem
        mode tcp
        default_backend [Identifikationsbezeichnung-Backend]

backend [Identifikationsbezeichnung-Backend]
        server [Bezeichner für Servername] [IP-Addresse / DNS Name]:[Port] check ssl verify none
(Anmerkung: ✂ = Zeilenumbruch nur in Darstellung hier)

frontend [Identifikationsbezeichnung-Frontend]
  bind *:10443 ssl crt ✂
/etc/haproxy/mycerts/haproxy.pem
  mode tcp
  default_backend [ID-Backend]

backend [ID-Backend]
  server [Bezeichner für Servername] ✂
[IP-Addresse / DNS Name]:[Port] ✂
check ssl verify none

Beispiel

Der HAProxy wird auf den Port 10443 für HTTPS lauschen und eingehenden Verkehr an den Server 192.168.10.14 an den Port 443 (HTTPS) weiterleiten.

Die Bezeichnung "meinwebserver1" entspricht nicht dem DNS Namen und dient nur als Bezeichner in der Konfiguration.

# HTTPS Forward
frontend front_webserver1
     bind *:10443 ssl crt /etc/haproxy/mycerts/haproxy.pem
     mode tcp
     default_backend back_webserver1

backend back_webserver1
     server meinwebserver1 192.168.10.14:443 check ssl verify none
(Anmerkung: ✂ = Zeilenumbruch nur in Darstellung hier)

# HTTPS Forward
frontend front_webserver1
  bind *:10443 ssl crt ✂
/etc/haproxy/mycerts/haproxy.pem
  mode tcp
  default_backend back_webserver1

backend back_webserver1
  server meinwebserver1 192.168.10.14:443 check ✂
ssl verify none
Wenn die Verbindung fehlschlägt (HAProxy Fehlermeldung: "Server xxx is DOWN, reason: Layer 4 timeout), so sollte die "check" Angabe/Funktion hinter der Kombination <ServerIP>:<Port> entfernt werden.


top HAProxy Fehlerbehebung

In diesem Abschnitt stelle ich aufgetretene Fehler und deren mögliche Lösung zusammen.

Fehlermeldung: "Cannot bind to socket 10443"

Sie ist beim Start des Dienstes zu sehen.
Diese Fehlermeldung kann im Zusammenhang mit SELinux auftauchen. Dann fehlt eine Freischaltung.
Der folgende Befehl behebt das Problem.
sudo semanage port -a -t http_port_t -p tcp 10443
		
(Anmerkung: ✂ = Zeilenumbruch nur in Darstellung hier)

sudo semanage port -a -t http_port_t ✂
-p tcp 10443			  	
		


Fehlermeldung: "Setting tune.ssl.default-dh-param to 1024 by default"

Die komplette Fehlermeldung lautet:
Setting tune.ssl.default-dh-param to 1024 by default, if your workload permits it you should set it to at least 2048. Please set a value >= 1024 to make this warning disappear.
Sie ist beim Start des Dienstes zu sehen.
Um dieses Problem zu lösen ist eine dhparams.pem Datei via openssl zu erstellen und einzubinden.

Anlage Datei dhparams.pem
Die Datei wird wie folgt angelegt:
sudo openssl dhparam -out /etc/haproxy/dhparams.pem 2048
		
(Anmerkung: ✂ = Zeilenumbruch nur in Darstellung hier)

sudo openssl dhparam -out ✂
/etc/haproxy/dhparams.pem 2048			
		

Einbindung Verweise zu Datei dhparams.pem in Konfiguration
Wir öffnen die Konfigurationsdatei mittels vi und ergänzen eine Zeile:
sudo vi /etc/haproxy/haproxy.cfg

Nun ergänzen wir nach der Zeile ssl-default-server-ciphers PROFILE=SYSTEM eine neue Zeile:
ssl-dh-param-file /etc/haproxy/dhparams.pem
		
(Anmerkung: ✂ = Zeilenumbruch nur in Darstellung hier)

ssl-dh-param-file ✂
/etc/haproxy/dhparams.pem			
		

Restart HAProxy

Nun restarten wir den Dienst mittels systemctl.




top Links zum Thema


Hinweis:
Für die Richtigkeit der Daten übernehme ich keine Gewähr!
Für den Inhalt von Internet-Seiten, auf die von dieser Seite verwiesen wird, übernehme ich keine Verantwortung!