1: 1 NAT mit mehreren identischen LANs

12

Ich möchte mehrere LANs verbinden, die sich in entfernten Gebäuden befinden.
Auf der "zentralen" Site befindet sich ein Linux-Computer, auf dem OpenVPN ausgeführt wird. Auf jedem Remote-Standort wird auch OpenVPN ausgeführt.

  1. Der zentrale Standort verfügt über ein LAN mit der Nummer 192.168.0.0/24
  2. Mehrere entfernte Standorte sind ebenfalls mit 192.168.0.0/24 nummeriert
  3. Ich kann / will / will nicht / was auch immer die LAN-Nummerierung ändern
  4. Ich habe keine Kontrolle über die meisten Remote-OpenVPNs

Ich muss dann:
1. virtuelle LANs definieren
2. ein 1: 1-NAT für jeden Standort konfigurieren
3. das 1: 1-NAT auf dem zentralen Router konfigurieren

LAN-Karte .
Jeder Standort verfügt also über ein 10.10.x.0 / 24-LAN.
Wenn ein Computer beispielsweise 192.168.0.44 auf Site 12 erreichen möchte, muss er lediglich ein Paquet an 10.10.12.44 senden

Das Betreiben eines VPN ist für mich kein Problem. Ich verbinde derzeit mehr als 60 Websites. Aber ich finde keinen einfachen Weg, dies 1: 1 NAT zu tun.

Hier ist ein Beispiel für ein Paket, das vom zentralen Standort an einen Remotestandort gesendet wird, und dessen Antwortpaket:

Geben Sie hier die Bildbeschreibung ein

Ich habe einige Tests mit iptables NETMAP durchgeführt, aber ich kann es nicht zum Laufen bringen, da ich nach der Routing-Entscheidung keine Möglichkeit finde, Quelle + Ziel zu ändern.
Ich ziehe es vor, die neue --client-natOpenVPN-Funktion zu vermeiden .
Vielleicht muss ich das Routing erzwingen ip route? Oder zweimal in den Netzwerkstapel mit schleifen veth?

Hinweis: Ich möchte keine Maskerade verwenden. Nur 1/1 NAT.

BEARBEITEN:
Mit einem regulären openVPN-Setup ist dies nicht möglich. Da ein Paket von einem Remote-Standort nicht von einem Paket von einem anderen Standort zu unterscheiden ist: Beide haben ähnliche Quell- und Zieladressen und beide stammen von derselben Tun- (oder Tap-) Schnittstelle. Es ist also nicht möglich, NAT als Quelle zu verwenden.

Lösung 1: Führen Sie das NAT auf den Remote-Standorten aus. In meinem Fall nicht möglich. Ich muss es nur auf der zentralen Seite tun.

Lösung 2: Richten Sie für jeden Remote-Standort ein VPN ein. Also werde ich für jeden eine Tonne haben. Ich denke das kann ok sein. Nicht sehr speichereffizient, aber ok.

Lösung 3: Richten Sie für jeden Standort einen (unverschlüsselten) Tunnel im VPN ein. Dies gibt jeweils eine Schnittstelle. Einfache Tunnel sind nicht plattformübergreifend (zu meinem Vorteil). Zum Beispiel sind GRE oder ipip oder sit für Linux in Ordnung, aber auf einigen entfernten Sites wird nur ein Windows-Computer ausgeführt, sodass openVPN darauf installiert ist. Es ist also unmöglich, einen einfachen Tunnel einzurichten. Eine andere Möglichkeit ist die Verwendung eines komplizierteren Tunnels (welcher?), Aber der Overhead auf dem System und auf dem Systemadministrator kann größer sein als bei mehreren VPNs

Lösung 4: Kompilieren Sie das neueste openVPN, da es eine 1: 1-NAT-Funktion enthält. Ich teste das diese Woche.

Bertrand SCHITS
quelle
1
Für Lösung 4 müssen Sie nicht kompilieren. Die meisten großen Linux-Distributionen haben Pakete auf der offiziellen openVPN-Website zusammengestellt. Dies funktioniert jedoch nicht für Sie, da die Funktion --client-nat eine Push-Option ist. Daher müssen Ihre Kunden auch die neueste RC-Version verwenden (und Sie sagen, Sie haben keine Kontrolle über Remote-Standorte).
Gregory MOUSSAT
1
Nun, ich liege falsch: Die Funktion --client-nat ist zu 100% in OpenVPN enthalten (ich dachte, sie verwendet ipfilter). Ich habe gerade getestet: Es funktioniert auch unter Windows. Siehe meine Lösung unten.
Gregory MOUSSAT
Ich würde gerne wissen, ob Sie das jemals zum Laufen gebracht haben und was Sie getan haben.
Michael Grant

Antworten:

2

Eine sehr grundlegende Lösung ist:
1. Verwenden Sie OpenVPN 2.3 oder höher (derzeit ist die neueste Version 2.3-alpha) für Server + Clients.
2. Verwenden Sie die unten stehende OpenVPN-Konfigurationsoption.
3. Verwenden Sie nichts anderes (kein ipfilter, keine Tricks).

Auf der Serverseite müssen Sie VPN-Adressen manuell verteilen (also keine serverOption, die Sie verwenden müssen ifconfigoder ifconfig-push):

# /etc/openvpn/server.conf
ifconfig 10.99.99.1 10.99.99.2
route 10.99.99.0 255.255.255.0
push "route 10.99.99.0 255.255.255.0"
push "client-nat dnat 10.99.99.11 255.255.255.255 10.10.111.11"
push "client-nat dnat 10.99.99.12 255.255.255.255 10.10.112.12"
push "client-nat dnat 10.99.99.13 255.255.255.255 10.10.113.13"

Die Zeilen routeund push routeund client-natsind erforderlich, wenn Sie direkt zwischen Routern kommunizieren möchten ( ping 10.99.99.1von einem entfernten Standort über das VPN). Sonst können Sie sie wegwerfen.

.

.

Jetzt müssen Sie eine virtuelle Netzwerkadresse auswählen. Ich habe das gleiche beibehalten, das Sie in Ihrem Beispiel verwendet haben: 10.10.0.0/16
Sie erlauben das Routing dafür:

# /etc/openvpn/server.conf
route 10.10.0.0 255.255.0.0
push "route 10.10.0.0   255.255.0.0"

.

.

Sie müssen den Client jetzt anweisen, das 1: 1-NAT zu verwenden:

# /etc/openvpn/ccd/client_11
ifconfig-push 10.99.99.11 10.99.99.1
push "client-nat snat 10.99.99.11 255.255.255.255 10.10.111.11"
push "client-nat snat 192.168.0.0 255.255.255.0 10.10.11.0"
push "client-nat dnat 10.10.10.0 255.255.255.0 192.168.0.0"
iroute 10.10.11.0 255.255.255.0
iroute 10.10.111.0 255.255.255.0

In der ersten Zeile wird die Adresse des Remote-Routers festgelegt. Beachten Sie, dass für Windows-Treiber spezielle Adressen erforderlich sind.
Die zweite und letzte Zeile ermöglichen es dem entfernten Router, über seine 10.99.99.x-Schnittstelle zu kommunizieren.
Die dritte und vierte Zeile übernehmen die Quell- und Ziel-1: 1-NAT
Die fünfte Zeile teilt OpenVPN mit, was mit den entsprechenden Paketen zu tun ist.

Mit dieser Methode können Sites mit identischen (oder nicht) LAN-Adressen ohne beschatteten Host verbunden werden.

Gregory MOUSSAT
quelle
1
Einfach, genial.
Bertrand SCHITS
Ich habe es versucht, konnte es aber nicht zum Laufen bringen. Ich benutze Linux auf beiden Seiten. Etwas ist seltsam oder ich verstehe etwas nicht ganz. Sollte Ihr ifconfig-push in der Datei client_11 (erste Zeile) nicht eine Netzmaske für das zweite Argument anstelle von 10.99.99.1 sein? Zweitens, warum verwenden Sie dieses dritte Netzwerk 10.10.111.0/24? Anscheinend versuchen Sie, das 111-Netzwerk für die Kommunikation zwischen Standorten zu verwenden. Kann das 10.10-Netzwerk nicht direkt dafür verwendet werden? Unabhängig davon, was ich versuche, sehe ich (in tcpdump) nicht, wie sich Snat und Dnat auf Pakete auf dem Client auswirken.
Michael Grant
Nicht wirklich einfach, aber trotzdem brillant.
Neurotransmitter
4

Ich habe etwas Ähnliches mit echten Schnittstellen gemacht, aber ich kann nicht verstehen, warum es mit VPN-Schnittstellen nicht funktioniert.

Die Idee ist, dass das gleiche Subnetz an verschiedenen Schnittstellen auf diesem Router verfügbar ist, was das Routing kompliziert. Wenn ein Paket für 10.10.13.123 in den Router eingeht, wird es grundsätzlich vor dem Weiterleiten an 192.168.0.123 DNATed, sodass Sie dem Routing mitteilen müssen, dass es für 192.168.0.123 auf der Schnittstelle VPN13 bestimmt war .

Dies kann mithilfe von Firewall-Markierungen und Routing-Regeln erfolgen, die diese Markierungen verwenden. SNAT und DNAT müssen mit dem NETMAP-Firewall-Ziel durchgeführt werden. Für SNAT ist es das gleiche Problem. In POSTROUTING haben Sie die Information verloren, dass das Paket von dieser oder jener Schnittstelle stammt und alle die Quelladresse 192.168.0.x haben. Sie benötigen also auch eine Markierung, um diese Informationen von Mangle-PREROUTING zu Nat-POSTROUTING zu übertragen. Sie können dieselbe Markierung verwenden, aber das würde bedeuten, dass diese Pakete diese alternative Routing-Tabelle verwenden würden, sodass Sie die globale Routing-Tabelle für alle duplizieren müssten.

Für jedes Netzwerk würden Sie Folgendes tun:

lnet=192.168.0.0/24
if10=eth0 if11=tun0 if12=tun1 if13=tun2

n=0
for site in 10 11 12 13; do
  table=$site
  net=10.10.$site.0/24
  n=$(($n + 1))
  eval "interface=\$if$site"
  inmark=$(($n * 2)) outmark=$(($n * 2 + 1))

  iptables -t nat -A PREROUTING -d "$net" -j NETMAP --to "$lnet"
  iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -m mark --mark "$inmark"/0xf -j NETMAP --to "$net"
  iptables -t mangle -A PREROUTING -i "$interface" -j MARK --set-mark "$inmark"/0xf
  iptables -t mangle -A PREROUTING -d "$net" -j MARK --set-mark "$outmark"/0xf
  ip rule add fwmark "$outmark"/0xf table "$table"
  ip route add "$lnet" dev "$interface" table "$table"
done

Oben verwenden wir die ersten 4 Bits der Markierung , damit bis zu 7 Netzwerke auf diese Weise geroutet werden können.

Stéphane Chazelas
quelle
1
Danke für deine Antwort. Ich habe es getestet, aber es funktioniert nicht. Ich habe mit nur einem LAN getestet, kein Ergebnis mehr. Ich verwende tcpdump, um die Pakete zu überwachen, und wenn ich ein Paket von einem Remote-Standort an einen zentralen Standort sende, sehe ich nicht einmal etwas (?! Wie ist das möglich?). Mit Ihren Anweisungen versuche ich, meine schrittweise Antwort zu konstruieren. Ich bin mir nicht sicher, ob ich Erfolg haben werde.
Bertrand SCHITS
2
Meine Antwort bezieht sich nur auf das, was auf der zentralen Site zu tun ist. Ich gehe davon aus, dass Sie das Routing auf den anderen Standorten korrekt konfigurieren. Beispielsweise müssen Sie wahrscheinlich eine Route zu 10.10.0.0/16 über den VPN-Tunnel an den Remotestandorten hinzufügen. Möglicherweise müssen Sie openvpn auch anweisen, diese Pakete durchzulassen. Verwenden Sie auf jeden Fall tcpdump, um zu sehen, welche Pakete wo und wie den richtigen Ansatz erhalten. Das iptables LOG-Ziel ist auch dein Freund.
Stéphane Chazelas
2
Wenn Sie keine Pakete sehen, müssen Sie in Ihr openvpn-Protokoll schauen. Sie werden wahrscheinlich verworfene Pakete finden. Wenn dies der Fall ist, verwenden Sie eine "iroute 192.168.0.0 255.255.255.0" für jeden Client in Ihrem Client-Konfigurationsverzeichnis
Gregory MOUSSAT