OpenVPN hinter HAProxy Reverse Proxy - wie?
-
Hallo,
ich betreibe auf meiner pfSense (2.5.2) über die entsprechenden Packages (Addons) sowohl einen HAProxy als Reverse Proxy, als auch OpenVPN Server. Alles aktuellste Versionen des Package Centers.
Hinter dem HAProxy befinden sich derzeit 3 Backends, auf die ich über ein HTTPS-Frontend entsprechend zugreifen kann.
Er lauscht also auf Port 443 (und 80, was aber umgeleitet wird zu 443). Jedes Backend erreiche ich extern per HTTPS über eine eigene Subdomain (LE Zertifikat). Das ist ja auch irgendwo das Ziel des Ganzen.Der OVPN Server nutzte bisher immer Port 443 TCP extern (intern 59999).
Jetzt, seitdem ich den HAProxy am laufen habe, habe ich für den OVPN auf Port 8080 gewechselt und per NAT Regel wirds entsprechend umgeleitet.
Funktioniert ja auch alles soweit, jedoch wollte ich fragen ob es möglich ist auch den OVPN Server hinter dem HAProxy zu betreiben.
Sprich, sodass ich per VPN Client einfach zu vpn.meinedomain.de verbinde und das über Port 443 und nicht 8080.
Damit würde die entsprechende NAT und Inbound Regel wegfallen.Ich denke es bedarf einem weiteren Frontend (Typ TCP?) für OpenVPN, zusätzlich zum HTTPS Frontend für die anderen 3 Backends.
Nur ist mir nicht ganz klar wie die Konfig dann insgesamt in der GUI zu machen ist, sodass die Dienste (Backends) auch dementsprechend erreichbar sind und es nicht kollidiert bzw. kollabiertVielleicht hat ja jemand eine Konfig dieser Art bereits am Laufen und kann helfen.
Vielen Dank vorab.
-
@ihaveastream
Ich glaube schon mal gelesen zu haben, dass jemand so etwas umgesetzt hat. Selbst habe ich aber keine Erfahrung.
Aber du könntest es mit der Port-Sharing Funktion von OpenVPN versuchen, ist vielleicht einfacher einzurichten: Sharing a Port with OpenVPN and a Web ServerDamit leitet OpenVPN alles weiter, was es nicht als OpenVPN Paket interpretiert.
Als IP kannst du bspw. auch 127.0.0.1 angeben und HAProxy auf diese lauschen lassen.Sollte noch hinzufügen, dass auch dies in Verbindung mit HAProxy von Leuten hier schon erfolgreich umgesetzt wurde.
-
wow, nice - danke für den Tipp! Das sieht mal richtig gut aus und hat auch auf Anhieb und ohne bisher erkennbare Nebeneffekte geklappt
Bin begeistert!
-
@ihaveastream Umleitung via OpenVPNs Passthrough kann man machen, ist aber normalerweise nicht schön, lahmt und laggt. Kann man via HAproxy mit Paketunterscheidung realisieren oder direkt einen Demultiplexer wie SSLH einsetzen, der den Kram auseinanderdröselt. Wenns aber jetzt erstmal so genügt - auch schön :)
-
Ich bin immer für Vorschläge offen... mit SSLH hatte ich in der Vergangenheit schon mal experimentiert, damals aber nur auf meinem NAS, was performance-technisch nicht brauchbar war.
Ich suche nach einer möglichst eleganten Lösung, die zentral auf der pfSense laufen kann, deren Performance sollte ausreichend sein (läuft in einer Proxmox VM auf einem i5-6400 und genügend RAM).
Kannst du das mit der Paketunterscheidung etwas erklären oder gibt es da irgendwo einen Guide?
Ich bin noch nicht ganz dahintergestiegen, aber ich glaube das Portsharing mittels OVPN und dem damit verbundenen HAProxy auf localhost stellt mich an einer anderen Stelle gerade vor ein Problem, was ich vorher so nicht hatte...
Danke.
-
bei HAproxy kann man im Frontend via ACL einiges rausfiltern. Beispielsweise wenn man SSH demultiplexen möchte (es gibt Leute, die tcp/22 auf 443 umbiegen und via DNS dann rausfiltern :)) kann man das via bspw. mit
acl foo_proto_ssh payload(1,7) -m bin 5353482d322e30 tcp-request content accept if foo_proto_ssh
und später selektieren mit
use_backend foo_bk_ssh if foo_proto_ssh
OpenVPN könnte man rausfischen nach den HTTPS/SNI Sachen mit
use_backend openvpn if !{ req.ssl_hello_type 1 } !{ req.len 0 }
Da OpenVPN keinen Hello Type hat (kein HTTPS) aber die Request Länge größer 0 hat.
Oder man kann es sich noch einfacher machen und einfach alles als Default Backend zu OpenVPN schicken, was man nicht vorher mit ACLs abgegriffen und auf ein HTTP(S) Backend abgeworfen hat. Kommt ganz drauf an. Und klappt natürlich nur für OpenVPN Server mit TCP mode, nicht mit UDP ;)Auf dem "braucht dringend Zeit um sich damit zu beschäftigen" Zettel steht immer noch, aus SSLH ein simples kleines pfSense Paket zu machen. Komme aber aktuell kaum zu was - man bräuchte einfach mehr Hände und mehr Zeit.
Das Package selbst ist aber extrem simpel und es wäre kein großer Aufwand, das manuell auf der pfSense zu installieren, sich eine Config zu schreiben und es zu starten. Konfiguration sieht ebenfalls nicht wirklich schwierig aus:# Once configuration ready, you *must* set RUN to yes here # and try to start sslh (standalone mode only) RUN=yes # binary to use: forked (sslh) or single-thread (sslh-select) version DAEMON=/usr/sbin/sslh DAEMON_OPTS="-u sslh -p MYPUBLICIP:443 --ssh 127.0.0.1:22 --openvpn 127.0.0.1:1194 --ssl 127.0.0.1:443 -P /var/run/sslh/sslh.pid"
Also effektiv 3-4 Zeilen Config, MYPUBLICIP ist die IP auf WAN Seite auf die gehört wird, die 127er sind dann eben die Dienst-IPs. OpenVPN wäre dann wahrscheinlich auf localhost gebunden, also 127.0.0.1:1194 (für tcp1194 local aber von extern via 443), SSH wird wahrscheinlich nicht gebraucht und SSL kann man auf localhost (oder eine IP der pfSense) mit 443 setzen, da kann dann der HAproxy drauf lauschen - hauptsache er kommt dem SSLH Agent nicht in die Quere.
Somit bspw. auf WAN:443 SSLH aufsetzen, HAproxy lauscht auf LAN:443 und OpenVPN auf localhost:1194DAEMON_OPTS="-u sslh -p WANIP:443 --openvpn 127.0.0.1:1194 --ssl LANIP:443 -P /var/run/sslh/sslh.pid"
Das wäre dann so ein Beispiel.
Nur als Ideen und Vorschläge :)
Cheers
-
Das klingt sehr interessant!
Ursprünglich war ja mein Vorhaben OVPN als Backend laufen zu lassen, aber ich kam da (bisher) nicht weiter.
Am besten gefällt mir tatsächlich die Idee mit dem SSLH Paket, aber ich habe leider nicht die Skills das zu coden. Vielleicht ist das also mal was für später, wenn du die Zeit dazu finden konntest :)Also zurück zum OVPN mit dem SSL Hello.
Wäre das dann auf Localhost als IP und Port 443?Reicht es (in der GUI) beim Backend unter "Health Check Method" lediglich SSL auszuwählen oder müssen weitere Dinge konfiguriert werden, bzw. geht es nur über die Konsole?
Thx
-
@ihaveastream said in OpenVPN hinter HAProxy Reverse Proxy - wie?:
Am besten gefällt mir tatsächlich die Idee mit dem SSLH Paket, aber ich habe leider nicht die Skills das zu coden. Vielleicht ist das also mal was für später, wenn du die Zeit dazu finden konntest :)
Muss man für quick'n'dirty nichts coden. Nur das entsprechende Package per SCP/SFTP auf die Sense kopieren, installieren, Config erstellen, fertig. Also so wie bspw. beim Wireguard Package auch bevor es fertig war.
-
Wenn du mit dem Paket mal spielen willst:
auf der Konsole
curl https://pkg.freebsd.org/FreeBSD:12:amd64/latest/All/sslh-1.21c.txz --output sslh-1.21c.txz
Dann hast du das Paket vom offiziellen Mirror. Hat keine Abhängigkeiten.
pkg install sslh-1.21c.txz
installiert das dann. sslh Binary selbst liegt in
/usr/local/sbin
und die Config in/usr/local/etc
.
Examples gibt es in/usr/local/share/examples/sslh/example.cfg
-
danke dafür noch.
Angenommen die Sense würde sich ein Update ziehen, würde das Paket nebst Konfig dann danach noch vorhanden sein wenn man es auf diesem Wege installiert? -
@ihaveastream Das kommt auf das Update an. Das nächste "große" Update (wenn das Base OS aktualisiert wird auf FreeBSD !=12.2) wäre wahrscheinlich schwierig. Aber solang das Paket nicht durch eine Änderung von was anderem deinstalliert wird, würde auch ein Update via Paketaktualisierung das Paket eigentlich nicht ohne Grund löschen.
Die Config kann man sicherstellen, indem man diese bspw. nicht selbst manuell anlegt, sondern das Filer Package dazu benutzt und die Config darin ablegt. Das ist dann auch komplett Update-safe.
-
@jegr said in OpenVPN hinter HAProxy Reverse Proxy - wie?:
[...]OpenVPN könnte man rausfischen nach den HTTPS/SNI Sachen mit
use_backend openvpn if !{ req.ssl_hello_type 1 } !{ req.len 0 }
Da OpenVPN keinen Hello Type hat (kein HTTPS) aber die Request Länge größer 0 hat.
Oder man kann es sich noch einfacher machen und einfach alles als Default Backend zu OpenVPN schicken, was man nicht vorher mit ACLs abgegriffen und auf ein HTTP(S) Backend abgeworfen hat. Kommt ganz drauf an. Und klappt natürlich nur für OpenVPN Server mit TCP mode, nicht mit UDP ;)[...]
ich glaube ich würde mich aktuell dann doch lieber erst mal mit diesem Thema befassen.
Leider ist mir noch nicht ganz klar wie ich...-
Hierbei einerseits das OpenVPN Backend zu konfigurieren habe (lauscht ja dann vermutlich auf 127.0.0.1 und einem definierten Port, z.B. default 1194?)...
-
Wie ich die ACLs entsprechend konfiguriere...
-
Ob ich ein weiteres Frontend zusätzlich zum allgem. HTTPS Frontend benötige?..
Würde da die GUI bevorzugen, wenn hierüber entsprechend konfigurierbar.
Danke.
-
-
@viragomann Das ganze funktioniert sehr gut und ist einfach umzusetzen, leider ist dann auf den Webservern und auch Matomo kein vernünftiges loggen möglich. Als IP-Adresse steht dann immer die angegebene 127.0.0.1 drin, da der OpenVPN Server die eigentliche Verbindung annimmt.
Gibt es eine Möglichkeit das die anfragende IP-Adresse zum HAProxy durchgereicht wird?
-
@nonick
Ich verwende das nicht selbst. Ich hatte es mal entdeckt und auf meine Todo Liste fürs Heimnetz mit dem Präfix "vielleicht" gesetzt.
Mein Heim OpenVPN lauscht auf TCP 587, damit hatte ich bislang noch keine Probleme. Der Port sollte heutzutage zumeist erlaubt sein und zuhause brauche ich ihn nicht.Gibt es eine Möglichkeit das die anfragende IP-Adresse zum HAProxy durchgereicht wird?
Das ist by-design von OpenVPN und muss so sein, damit das bedenkenlos funktioniert, wenngleich es sich auf der pfSense theoretisch auch anders lösen ließe.
Es gäbe nur die Möglichkeit, noch ein Verzeichnis mit anzugeben, in das OpenVPN dann temporäre Verbindungs-Logs mit den Quell-IPs u. -ports und Ziel-IPs u. -ports schreibt.
Diese müssten aber weggesichert werden, solange die Proxy-Verbindung besteht, weil sie beim Trennen gelöscht werden.
Siehe dazu: https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage -
@viragomann Dachte ich mir schon, ist aber ist trotzdem schade. Irgendwas ist immer, vor allem wenn etwas einfach umzusetzen ist. Das ganze funktioniert ja überraschend gut, nur das die IP-Adressen von der anfragenden Quelle nicht an den HAProxy weitergereicht werden.