Viele Ports <--DNAT--> Viele IPs scripten oder API möglich?

Started by mt, August 31, 2022, 05:45:39 PM

Previous topic - Next topic
Moin zusammen,

ich teste gerade OPNSense auf Tauglichkeit, mein etwas angestaubtes iptables-System zu ersetzen. Soweit ich das beurteilen kann, lässt sich nur eine Aufgabe noch nicht zufriedenstellen lösen:
Ich möchte eine Vielzahl von Servern in meinem LAN mit unterschiedlicher IP und gleichem Port per SSH von außen über eine gemeinsame WAN-IP, dafür mit unterschiedlichen Ports zugänglich machen. Anders gesagt: Jeder Nutzer kann seinen Server über die eine gemeinsame WAN-IP mit einem eigenen SSH-Port erreichen.
Ich muss also regelmäßig einen WAN-Port-Bereich auf einen LAN-IP-Adressbereich per DNAT weiterleiten., z.B
203.0.113.123:{1...255} <----->  172.16.31.{1...255}:22
Ich habe aber keine Zeit, regelmäßig 255 Portweiterleitungen per Weboberfläche anzulegen.
Mit iptables lässt sich so etwas in in bash scripten, z.B.
for(( i=1;i<256;i++))
do
let sshport=$i+31000;
iptables -t nat -A PREROUTING -p tcp -d 203.0.113.123 --dport $sshport -j DNAT --to 172.16.31.$i:22
done

Geht so etwas auch mit OPNSense?
Ich habe bisher folgendes herausgefunden:

  • Die OPNSense API kennt, soweit ich das sehe,  von der Firewall leider nur Aliase und Kategorien, aber nicht NAT. s. https://docs.opnsense.org/development/api/core/firewall.html Steckt das evtl. irgendwo anders?
  • Ein neuer NAT Eintrag wird in der Weboberfläche per PHP erzeugt, s. https://github.com/opnsense/core/blob/master/src/www/firewall_nat_edit.php - da könnte man zur Not was basteln, aber der Code muss dann regelmäßig mit OPNSense zusammengeführt werden und es erscheint mir auch recht umfangreich für das Problem.
  • Händisch in der Weboberfläche angelgte DNAT Einträge landen als rule-Tag in /conf/config.xml. Wenn das alles ist, was man braucht, ließen sich die rule-Tags per Script erzeugen. Ich hätte allerdings Angst, die associated-rule-id-Tags außerhalb des Systems zu erzeugen. Nicht, dass man da Kollisionen erzeugt oder das irgendwie nicht passt. Ich weiß auch nicht, ob die associated-rules nicht irgendwo angelegt werden müssten.
  • HAProxy ist glaube ich nicht das Mittel der Wahl, ich will ja nicht die Last verteilen, sondern eine persistente 1:1 Zuordnung von WAN-Port <----> LAN-IP bekommen.
Fällt euch noch etwas ein? Wie würdet ihr das angehen?
                                                             
Vielen Dank!                                                             

Scheint nicht so eine typische Fragestellung zu sein. Ich probiere es noch kurz, und falls es nicht funktioniert bleibt mir nur bei iptables zu bleiben, zumindest für diese Aufgabe.

> 203.0.113.123:{1...255} <----->  172.16.31.{1...255}:22
> Ich habe aber keine Zeit, regelmäßig 255 Portweiterleitungen per Weboberfläche anzulegen.

Darf ich vielleicht einfach mal nachfragen, warum du das regelmäßig, oft und häufig anlegen musst um 255(!) interne Hosts mit SSH zu bespaßen? Und warum das dann immer neue Mappings sein müssen?

Das klingt eher nach Hosting, aber da hätte man im Regelfall mehr als eine IP. Aber an einem Anschluß mit einer IP mehrere Dutzendmal 255 Hosts intern zu haben verwundert mich jetzt etwas. Vielleicht lässt sich das tatsächlich dann anders als gedacht lösen, aber daher die Frage, wie und warum das so gebaut ist. :)

Cheers
"It doesn't work!" is no valid error description! - Don't forget to [applaud] those offering time & brainpower to help you!
Better have some *sense as no(n)sense! ;)

If you're interested in german-speaking business support, feel free to reach out via PM.

Das ist tatsächlich so etwas wie Hosting, nur mit beschränkten Mitteln aber dafür für einen guten Zweck. Dient der Lehre. Studierende bekommen je Semester eine eigene VM (genauer einen Container...) um sich mit Internettechnologien vertraut zu machen. Es sind auch nicht 255 sondern weniger, ich richte aber immer 255 ein, damit ich nicht später nochmal nachlegen muss. Mir ist klar, dass ein /24 Block die Sache vereinfachen würde, aber ist gerade nicht verfügbar und auch eigentlich nicht nötig. HTTP geht mit einer externen IP per Subdomain über einen Proxy auf die entsprechende VM. Die Proxy-Config erzeuge ich auch per Script.
SSH wird per Port zugeordnet. Da können die gleich mal lernen, ssh -p12345 zu benutzen, dann hat man auch nicht so viele Loginversuche von irgendwelchen Kaspern im auth.log wie bei Port 22.
VPN wäre eine Alternative, aber das macht die Sache komplizierter und das möchte ich ungern supporten müssen ("So, jetzt zeige ich euch mal 3 Stunden auf 37 unterschiedlichen Betriebssystemen, welche Besonderheiten es beim Einrichten eines VPN gibt...").
IPv6 wäre evtl. eine Option.
Doppeltes NAT ginge auch: Portrange auf OPNSense weiterleiten an VM-Nat mit iptables, da dann Port->IP:22 scripten.
Ich bin aber eigentlich gar nicht auf der Suche nach Alternativen, sondern nach einem Verfahren, das mir mit OPNSense erlaubt, was mit iptables eben auch ganz einfach funktioniert. Wäre ja zu schön, wenn man per API an die Portweiterleitung  rankäme, alles andere ist doch irgendwie Gebastel.

Ach ja, es sind neue Mappings, weil einige Ihre Server noch etwas weiterverwenden und ich denen die nicht unterm Hintern abschalten möchte. Ich mag es außerdem übersichtlich und es gibt genügend Ports, so dass ich ein Schema etabliert habe, dass es mir bis ins Jahr 2065 erlaubt, auf den ersten Blick aus IP, Port oder Hostname die anderen Werte zu erzeugen...

> Wäre ja zu schön, wenn man per API an die Portweiterleitung  rankäme, alles andere ist doch irgendwie Gebastel.

Von dem was ich verstanden habe wird das auch nicht ohne weiteres außer es Skript-technisch oder API-mäßig zu bauen.

> 203.0.113.123:{1...255} <----->  172.16.31.{1...255}:22

Problem daran, warum das nicht ohne weiteres in der UI machbar ist (IMHO) dürfte das Problem sein, dass du keinen RegEx auf beliebige Werte legen kannst. Ich meine - sofern ichs richtig im Kopf habe - dass das auch in reiner PF Syntax nicht drin ist, das mit einer Zeile zu definieren, da er keinen Bezug zwischen den beiden Platzhaltern hätte und damit nicht wüsste, welcher Port zu welcher IP gematcht wird. Ich kann mich irren, aber ich meine dem war so.

Somit würde nur bleiben, das als einzelne Regeln zu definieren, was dann sehr wahrscheinlich auch die UI bzw. den Browser zum platzen bringen würde, wenn man mehrfach 255 Einträge untereinander als Tabelle anzeigen würde :)
Vielleicht stehe ich auch wie du im Wald vor lauter Bäumen aber aktuell würde mir keine Syntax einfallen, mit der man das sinnvoll zusammenfassen könnte...

"It doesn't work!" is no valid error description! - Don't forget to [applaud] those offering time & brainpower to help you!
Better have some *sense as no(n)sense! ;)

If you're interested in german-speaking business support, feel free to reach out via PM.