FreeBSD-Äquivalent zu "Source Hints" unter Linux?

MH1962

Member
Unter Linux gibt es die Möglichkeit, einer Route einen sogenannten Source Hint beizugeben, also eine IP-Source-Adresse, die für ausgehende Pakete benutzt werden soll, für die diese Route zutrifft. Dies kann sinnvoll sein, wenn (Verschlüsselungs-)Tunnel auf dem Rechner enden

Das geht ungefähr so:

ip route add 1.2.3.0/24 ... src 4.5.6.7

Unter FreeBSD finde ich leider weder etwas äquivalentes noch überhaupt einen Ansatz, die Problematik zu lösen. Selbst NAT (per ipfw) funktioniert im Falle eines IPSEC-Tunnels für lokal erzeugte Pakete NICHT, da das "Eintüten" in den Tunnel anscheinend vor dem NAT erfolgt und somit die Pakete bei "unpassender" Source-Adresse eben gar nicht im Tunnel landen (ipfw scheint nur auf Interfaces zu wirken, aber lokal erzeugte Pakete laufen nicht über ein Interface...).

Übersehe ich irgendwas offensichtliches?
 
Leider nein, denn der Autor will Pakete von unterschiedlichen Quellen unterschiedlich routen.

Ich will eigentlich genau das umgekehrte, ich will die Source-IP in Abhängigkeit von der Route setzen.

Die Source-IP kann (wenn das System mehrere IPs hat) über ein bind() von der Applikation bestimmt werden, wenn die das nicht tut, bestimmt das Betriebssystem die Source-IP.

Ich will hier halt nachhelfen und wüsste gerne, ob und wenn ja wie das auch unter FreeBSD geht. Unter Linux kenne ich zwei mögliche Lösungen, der Source-Hint bei der Route oder NAT. Unter FreeBSD scheint es den Source-Hint nicht zu geben und NAT für lokal erzeugte und sofort getunnelte Pakete nicht zu greifen.
 
Ist mein Anliegen wirklich so ungewöhnlich, dass noch niemand vor der gleichen Frage gestanden hat oder - wahrscheinlicher - habe ich noch nicht rübergebracht, was ich eigentlich genau will? Ich vermag es im Moment allerdings nicht in andere Worte zu fassen, daher im Zweifelsfall bitte fragen, was unverständlich war.

Dass man unter FreeBSD anscheinend nicht in den Source-Adress-Selection-Algorithmus für das Routing eingreifen kann, habe ich mir mittlerweile ergooglet. Also bleibt nur die Möglichkeit mit dem NAT. Ich kenne mich zwar mit NAT einigermaßen gut aus, aber nicht unter FreeBSD.

Ich habe grundsätzlich folgendes probiert:

Code:
ipfw nat 1 config ip a.b.c.d
ipfw add 10 nat 1 all from any to e.f.g.0/24

Das funktioniert auch "normalerweise"! Es wird dann in allen Paketen, deren Ziel im Subnet e.f.g.0/24 liegen, die Source-Adresse a.b.c.d gesetzt!

Es funktioniert aber nicht (so wie gewollt) in Verbindung mit (z.B.) Strongswan, wenn Strongswan so aufgesetzt ist, dass die Source-Adresse a.b.c.d in den Tunnel gehen soll. Denn offensichtlich wird die NAT-Regel eben nicht ausgeführt, bevor entschieden wird, dass das Paket in den Tunnel gehen soll. Ergebnis: Das Paket wird zwar geNATet, geht aber am Tunnel vorbei. Und das ist nicht das, was ich will.

Unter Linux kann ich das Gewünschte mit einer iptables-Regel erreichen:

Code:
iptables -t nat -A POSTROUTING -d e.f.g.0/24 -j SNAT --to a.b.c.d

(selbe IP-Adressen wie im obigen ipfw-Beispiel.

und schon habe ich das gewünschte Verhalten, sprich, das NAT wird vor der Entscheidung, ob das Paket in den Tunnel geht, ausgeführt.

Wenn man nach der Problematik unter FreeBSD googlet, ergibt sich kein einheitliches Bild, es schwankt (subjektiv betrachtet) zwischen "müsste eigentlich gehen", "geht nur mit ipfw", "geht nur mit pf" und "hab's ausprobiert und krieg's nicht hin". Einen Thread, der in einer Lösung der Frage endet, konnte ich nicht finden, daher meine Anfrage hier.
 
Hm, zumindest mal nicht ohne weiteres. Wenn ich das richtig verstehe, kann man mit "setfib" einem Programm eine komplett andere Routing-Table "unterjubeln". Aber ich hab ja noch die selben Interfaces. Und die Routing-Engine versucht ja immer noch anhand der Interface-IPs zu "erraten", welche Source-IP sie den lokal erzeugten Paketen gibt. Und da fehlt mir die Phantasie, wie ein möglicher Lösungs-Ansatz, beginnend mit setfib, weiter gehen sollte.
 
So, jetzt habe ich doch noch eine Lösung gefunden, mit Hilfe von "jail":

Code:
jail -c allow.raw_sockets ip4.addr=a.b.c.d command=ping e.f.g.h

Außerdem muss man noch die IP-Adresse a.b.c.d einem lokalen Interface als Alias zuweisen, damit auch die Antwort-Pakete ankommen (und nicht etwa an das Default-Gateway weiter geroutet werden).

Nicht so schön wie erhofft, aber funktioniert.
 
Hi @MH1962,

hast Du Dir mal die pf mit route-to and reply-to angeschaut?
https://www.openbsd.org/faq/pf/pools.html
Ja, habe ich. Nach meinem Verständnis - man korrigiere mich, wenn dieses falsch ist - kann ich damit aber doch noch "nur" eine "Ausnahme" für das Routing definieren, für die Pakete, die auf die Regel matchen.

Da passt eher schon nat-to, aber hier würde ich annehmen, dass das genau wie bei ipfw nicht bei lokal erzeugten und dann gleich eingetunnelten Paketen matcht, weil das eigentliche NATing ja vom Kernel gemacht wird. Werde ich in einem ruhigen Moment vielleicht noch mal probieren.

Wohlgemerkt, das gilt für FreeBSD, bei OpenBSD mag das anders sein.
 
Die PF kann auch filtern und regeln matchen anhand von UserID's / Groups. Pooling von ausgehenden IP's macht die PF aber auch.
Wenn Du nat vor einem Tunnel brauchst, dann geht das mit Strongswan.
Sonst sollte das mit if_ipsec auch gehen.
 
Zurück
Oben