Ankommenden Datenverkehr zu OpenVPN umleiten

Mardor

Well-Known Member
Hallo,

ich habe vor auf meinem FreeBSD einen Tunnel zum OpenVPN Provider ipredator aufzubauen. Dies sollte soweit kein Problem sein.

Was ich im Endeffekt erreichen möchte ist, dass alle Rechner meines Netzwerks die über diesen Router (dieses FreeBSD) bisher ins Internet gegangen sind nun stattdessen über den OpenVPN tunnel geleitet werden ohne die Möglichkeit zu haben dieses zu umgehen.

Hat jemand einen Tipp wie ich dies erreichen kann.

Gruß Mardor
 
man pf.conf
/route-to

Edit: Wenn es OpenBSD wäre, würde ich das OpenVPN in eine separate virtuelle Routingtabelle packen, damit man keine 0/1+128/1 Spielereien braucht, um die default route zu überlagern.
 
Zuletzt bearbeitet:
Hallo TCM,

ich habe jetzt wirklich Stunde um Stunde verbracht um dies mit route-to hinzubekommen ohne irgendwelchen Erfolg.

Vielleicht könntest du mir nochmals helfen.

Mein Netzwerkumgebung


Client ---> (rl0) FreeBSD mit OpenVPN client (rl1) --> internet gateway --> inet
rl0: 192.168.10.254
rl1: 192.168.5.252
tun0: wird dynamisch von IPredator vergeben
Internet Gateway: LAN 192.168.5.254
Internet Gateway: WAN PPPOE
Client: 192.168.10.100/24 GW 192.168.10.254

Was ohne Probleme funktioniert ist das Pingen vom FreeBSD über tun0. Ich sehe auf einem Testserver die IP Adresse des OpenVPN Gateways

Code:
netstat -nrfinet
Routing tables

Internet:
Destination        Gateway            Flags    Refs      Use  Netif Expire
0.0.0.0/1          46.246.38.1        UGS         0        9   tun0 =>
default            192.168.5.254      UGS         0  1110466    rl1
46.246.38.0/24     46.246.38.215      UGS         0        0   tun0
46.246.38.130/32   192.168.5.254      UGS         0       47    rl1
46.246.38.215      link#8             UH          0        0   tun0
127.0.0.1          link#7             UH          0     3310    lo0
128.0.0.0/1        46.246.38.1        UGS         0       25   tun0
192.168.5.0/24     link#4             U           0     2027    rl1
192.168.5.252      link#4             UHS         0        0    lo0
192.168.10.0/24    link#3             U           0  1977062    rl0
192.168.10.254     link#3             UHS         0        0    lo0
Code:
rl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=2008<VLAN_MTU,WOL_MAGIC>
        ether 00:40:f4:89:d8:e1
        inet 192.168.10.254 netmask 0xffffff00 broadcast 192.168.10.255
        inet6 fe80::240:f4ff:fe89:d8e1%rl0 prefixlen 64 scopeid 0x3
        nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active
rl1: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=2008<VLAN_MTU,WOL_MAGIC>
        ether 00:40:f4:89:d8:e0
        inet 192.168.5.252 netmask 0xffffff00 broadcast 192.168.5.255
        inet6 fe80::240:f4ff:fe89:d8e0%rl1 prefixlen 64 scopeid 0x4
        nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active
rl2: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
...
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
...
tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> metric 0 mtu 1500
        options=80000<LINKSTATE>
        inet6 fe80::240:f4ff:fe89:d8e1%tun0 prefixlen 64 scopeid 0x8
        inet 46.246.33.190 --> 46.246.33.190 netmask 0xffffff00
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
        Opened by PID 2783n5
Ich habe per pf fogende Konfigurationen ohne Erfolg versucht:

Code:
#pass in on rl0 route-to tun0 all
#pass out from rl0 route-to tun0 all
#pass out on rl0 route-to tun0 all

#pass out on rl1 from rl0 route-to tun0
#pass in on rl0 route-to tun0 to any keep state
#pass out quick on tun0 route-to rl1 inet proto tcp from any to any
Vielleicht hast du oder irgendjemand einen weiteren Tipp für mich ?

Gruß Mardor
 
Also, route-to must du nur "in on rl0" machen. Alles andere ist unnötig.

Desweiteren musst du bedenken, dass du auf tun0 NAT machen musst. Die VPN-Gegenstelle wird sicher nicht dein LAN kennen und Routen dafür haben.
 
Hallo TCM,

vielen dank für deine superschnelle Antwort.

Also, route-to must du nur "in on rl0" machen. Alles andere ist unnötig.

Wäre das dann nicht die Zeile 1 die ich getestet habe:
Code:
pass in on rl0 route-to tun0
Desweiteren musst du bedenken, dass du auf tun0 NAT machen musst. Die VPN-Gegenstelle wird sicher nicht dein LAN kennen und Routen dafür haben.
Du meinst die LAN IP Adresse die während des OpenVPN Aufbaus verwendet wurde oder ?

Ok mit NAT habe ich noch nichts bei pf gemacht, da werde ich mich noch einlesen.
 
Der OpenVPN-Tunnel besteht aus der Adresse, die du vom Peer kriegst und dessen Adresse. Das ist das "Innere" des VPN. Das Äußere ist deine LAN-Adresse der FreeBSD-Box und die öffentliche Adresse vom Peer, wobei deine LAN-Adresse von deinem "internet gateway" per NAT in deine öffentliche Adresse umgesetzt wird.

Was das VPN angeht, existieren für den Peer keine LAN-Adressen. Für den FreeBSD host ist das einfach wie eine Internetverbindung, auf der du natürlich NATen musst, wenn mehrere Rechner dranhängen; genau wie dein internet gateway NATen muss.

pass in on rl0 route-to tun0 war zwar schon richtig, aber ohne NAT kriegt der VPN-Peer LAN-Adressen als Absender und kann keine Antworten zurückschicken.
 
Hallo TCM,

ich habe mir deine Antwort jetzt mehrfach durchgelesen bin aber nicht sicher ob ich Dich richtig verstanden habe.

Der OpenVPN-Tunnel besteht aus der Adresse, die du vom Peer kriegst und dessen Adresse. Das ist das "Innere" des VPN.

In meinem Fall wären dies dann IP Adressen aus dem 46.246.38.0.

Das Äußere ist deine LAN-Adresse und die öffentliche Adresse vom Peer, wobei deine LAN-Adresse von deinem "internet gateway" per NAT in deine öffentliche Adresse umgesetzt wird.

Ok dies wäre dann die IP der Telekom (da genattet wurde) und die IP Adresse von der ich mich auf versch. Internetserver verbinde.

Für den FreeBSD host ist das einfach wie eine Internetverbindung, auf der du natürlich NATen musst, wenn mehrere Rechner dranhängen; genau wie dein internet gateway NATen muss.

Hier hänge ich gerade fest, von welcher auf welche Adresse müsste ich hier natten ?
Sorry für die nochmalige Nachfrage.
 
Ich sehe gerade, dass die FreeBSD-Kiste ja besagte überlagerte "default routen" hat, d.h. du brauchst route-to gar nicht.

Ansonsten mal der Ablauf:

1. Client aus 192.168.10/24 schickt Paket mit src: 192.168.10.x dst: a.b.c.d. Laut seiner default route sucht er sich dafür die MAC-Adresse von 192.168.10.254 und schickt das Paket dahin.
2. 10.254 nimmt das Paket an und guckt entweder in seine Routen, um rauszukriegen, über welches Interface das Paket geht oder kriegt das von pf per route-to direkt eingetrichtert. Paket geht also über tun0. src: 192.168.10.x dst: a.b.c.d
3. FreeBSD-Kiste macht NAT und ersetzt die Quell-Adresse 192.168.10.x durch die IP-Adresse des tun0-Interface. src: <tun0-Adresse FreeBSD-Kiste> dst: a.b.c.d
4. Paket kommt beim OpenVPN daemon an und wird eingekapselt in ein Paket mit src: 192.168.5.252 dst: 46.246.38.130
5. Gemäß Routing-Tabelle auf FreeBSD-Kiste geht diese spezielle Ziel-Adresse über rl1 an das internet gateway
6. internet gateway macht NAT und ersetzt 192.168.5.252 durch deine aktuelle öffentliche Adresse. src: <pub addr> dst: 46.246.38.130
7. Der VPN-Peer kriegt das Paket auf seiner öffentlichen Adresse und entkapselt es und findet darin ein Paket mit src: <tun0-Adresse der FreeBSD-Kiste> dst: a.b.c.d

Würde der Peer also bei 7 ein Paket mit src: 192.168.10.x finden, wüsste er damit nichts anzufangen. Deswegen ist Schritt 3 wichtig. Edit: "nichts anzufangen" im Sinne von "die Antworten kommen nicht an". Entweder verwirft er das Paket wegen 192.168-Adresse sofort oder schickt es doch nach draußen, wo spätestens dann aber keine Anworten zurückkommen können.

Versuche also Folgendes: Das mit route-to vergiss einfach mal vorläufig. Wichtig ist nur, dass du auf der FreeBSD-Kiste auf tun0 NAT machst. Ich kenne leider nur die Syntax von OpenBSD. FreeBSD hat ein älteres pf. Kann also sein, dass ich mich hier vertue:

Code:
nat on tun0 inet all -> (tun0)
 
Zuletzt bearbeitet:
Hallo TCM,

vielen dank für deine ausführliche und verständliche Erklärung.
Der NAT Befehl funktioniert einwandfrei.

Gruß Mardor
 
Hallo TCM,

ich hätte doch noch eine Frage. Du hast beschrieben, dass nun in FreeBSD automatisiert die route über tun0 priorisiert wird. Kannst du noch etwas genau beschreiben wie dies funktioniert oder wo ich mehr Informationen hierzu erhalten kann ?

Ich möchte nämlich von meinem internen LAN und meiner DMZ direkt on tun Device arbeiten:
Client ---> (rl0) FreeBSD mit OpenVPN client (rl1) --> DMZ --> (5.254)internet gateway --> inet

rl0: 192.168.10.254
rl1: 192.168.5.252
tun0: wird dynamisch vom OpenVPN Provider vergeben
Internet Gateway: LAN 192.168.5.254
Internet Gateway: WAN PPPOE
Client: 192.168.10.100/24 GW 192.168.10.254
Da aktuell jeder Traffic in den Tunnel weitergeleitet wird, kann ich leider meine devices in der DMZ nicht erreichen.

Aktuell sieht meine pf.conf so aus:

Code:
# Interface
int_if="rl0"
ext_if="rl1"
tunnel_if="tun0"

int_net="192.168.10.0/24"
dmz_net="192.168.5.0/24"

set optimization aggressive
set block-policy return

# Skip all loopback traffic
set skip on lo

# Scrub all traffic
scrub in

# Perform NAT on external interface
nat on $tunnel_if all -> ($tunnel_if)
no nat on $tunnel_if from $int_net to $dmz_net

# Allow inbound traffic on internal interface
pass in quick on $int_if from $int_net keep state


# Define default behavior
block in on $ext_if from $dmz_net to $int_net
block in on $int_if from any to any
Code:
Internet:
Destination        Gateway            Flags    Refs      Use  Netif Expire
0.0.0.0/1          yyyy-xx-x.vpn.xxx UGS         0  1702787   tun0 =>
default            192.168.5.254      UGS         0    64153    rl1
46.15.15.0         yyyy-xx-x.vpn.x UGS         0        0   tun0
46.15.15.15/32     192.168.5.254      UGS         0  1681449    rl1
yyyy-xx-x.vpn.x    link#8             UH          0        0   tun0
localhost          link#7             UH          0       14    lo0
128.0.0.0/1        yyyy-xx-x.vpn.xxx UGS         0    88551   tun0
192.168.5.0        link#4             U           0     6999    rl1
192.168.5.252      link#4             UHS         0        0    lo0
192.168.10.0       link#3             U           0  3245476    rl0
192.168.10.254     link#3             UHS         0        0    lo0
Gruß Mardor
 
Das funktioniert durch die beiden Routen 0.0.0.0/1 und 128.0.0.0/1, welche zusammen sinngemäß der default route 0.0.0.0/0 entsprechen, diese aber dadurch "überlagern", dass in der Routingtabelle spezifischere Routen immer vor allgemeineren Routen zählen. Spezifischer heißt dabei einfach größere netmask.

Wenn man sich die Routen binär anschaut, sieht man das auch auf Anhieb:

Code:
128/1:
10000000.00000000.00000000.00000000 =128.0.0.0
10000000.00000000.00000000.00000000 = Maske /1

0/1:
00000000.00000000.00000000.00000000 = 0.0.0.0
10000000.00000000.00000000.00000000 = /1

deckt exakt das gleiche ab wie:

0/0:
00000000.00000000.00000000.00000000 = 0.0.0.0
00000000.00000000.00000000.00000000 = /0

Wenn deine DMZ direkt an einem Interface der FreeBSD-Kiste hängt, dann existiert automatisch eine spezifischere Route als die default route und du brauchst eigtl. nichts tun.

no nat on $tunnel_if from $int_net to $dmz_net kannst du rausnehmen, weil Traffic für $dmz_net nicht über tun0 gehen sollte. Wenn was nicht funktioniert, dürfte hier pf schuld sein. Ergänze die block-Regeln durch ein "log" und schau mit tcpdump -nei pflog0, was hängenbleibt.
 
Zuletzt bearbeitet:
Hello TCM,

danke wiedermal für deine tolle Erklärung und Hilfe.

Sobald ich die blocking rule wegnehme kann ich von LAN in die DMZ. Allerdings auch umgekehrt, dies wollte ich verhindern. Deshalb habe ich gehofft das die "pass in .. keep state" des Hin- und Rückweg abdecke (LAN->DMZ, DMZ-LAN) und dann mit dem block nur den Weg von DMZ zu LAN verhindere.

Somit wäre dann der Weg (Hin und zurück) von LAN zu DMZ erlaubt aber der Weg von DMZ zu LAN verboten.


Code:
# Allow inbound traffic on internal interface
pass in quick on $int_if from $int_net keep state


# Define default behavior
block in on $ext_if from $dmz_net to $int_net

Im Moment weis ich allerdings nicht wo mein Denkfehler liegt.


Gruß Mardor
 
Hallo TCM,

ich wollte nochmals nachfragen ob du schon Zeit hattest Dir meine Frage mal anzuschauen.

Gruß Mardor
 
man pf.conf
/route-to

Edit: Wenn es OpenBSD wäre, würde ich das OpenVPN in eine separate virtuelle Routingtabelle packen, damit man keine 0/1+128/1 Spielereien braucht, um die default route zu überlagern.

Auch FreeBSD unterstützt alternative Routingtabellen. Statt route exec muss man nur setfib verwenden. IPFW kann auch die Routingtabelle pro Paket noch mal umschreiben.
 
Zurück
Oben