Öffentliche IP-Adresse mit Tinc-VPN von einem Server auf einen anderen Tunneln

Für einen Server-Umzug sollte das neue System übergangsweise mit IP-Adressen des alten Systems betrieben werden. Da das neue System bei einem anderen Anbieter gehostet wird als das alte, war eine Übernahme der IP-Adressen via Routing nicht möglich. Daher habe ich ein Routing über einen verschlüsselten Tunnel via Tinc-VPN eingerichtet.

Der Prozess war nicht ganz so einfach wie ich dachte. Wie ich es zum Laufen bekommen habe, dokumentiere ich in diesem Artikel.

Die Theorie

Mein Plan war wir folgt. Via Tinc baue ich einen Tunnel zwischen beiden Maschinen im „switch“-Modus auf. In diesem Modus habe ich an beiden Enden ein Netzwerk-Device, welches sich so verhält, als wäre es eine Netzwerkkarte, die mit dem anderen Ende via Kabel oder Switch verbunden ist. Nun kann ich darüber die gewünschten IPs routen.

Die Praxis

Für das Beispiel verwende ich die folgenden IP-Adressen:

1.1.1.1 – öffentliche IP-Adresse des alten Systems
2.2.2.2 – öffentliche IP-Adresse des neuen Systems
3.3.3.3 – öffentliche IP-Adresse des alten Systems, welche auf das neue System geroutet werden soll
9.9.9.9 – externe öffentliche IP-Adresse, von der aus ich die Erreichbarkeit der zu routenden Adresse prüfe

Auf dem alten System

Zunächst ist Tinc (via apt) zu installieren. Anschließend wird auf dem alten System eine Konfiguration erstellt:

mkdir /etc/tinc/altzuneu
mkdir /etc/tinc/altzuneu/hosts

Datei /etc/tinc/altzuneu/tinc.conf:

Name = alt
Mode = switch
ConnectTo = neu

Datei /etc/tinc/altzuneu/tinc-up

#!/bin/sh
ifconfig $INTERFACE 0.0.0.0 up

Datei /etc/tinc/altzuneu/hosts/alt

Address = 1.1.1.1

Datei /etc/tinc/altzuneu/hosts/neu

Address = 2.2.2.2

Nun werden die Keys für den alten Host erzeugt:

tincd -n altzuneu -K

 

Auf dem neuen System

Das Setup des neuen Systems erfolgt exakt wie beim alten System. Allerdings sind in tinc.conf Name und ConnectTo zu vertauschen:

Name = neu
Mode = switch
ConnectTo = alt

Nachdem die Keys hier generiert sind, müssen noch die Public-Keys der beiden Systeme ausgetauscht werden. Das geschieht, indem /etc/tinc/altzuneu/hosts/alt vom alten auf das neue System und /etc/tinc/altzuneu/hosts/neu vom neuen auf das alte System kopiert werden.

Erster Test

Sind beide Seiten konfiguriert, wird das VPN zur Liste der zu startenden VPNs hnzugefügt und tinc gestartet

echo "altzuneu" >> /etc/tinc/nets.boot
service tinc restart

Der Befehl ifconfig zeigt nun auf beiden Seiten ein Device „altzuneu“ ohne IP-Adresse an. Ich vergebe beiden Enden eine IP-Adresse in einem nicht verwendeten internen Subnetz:

auf "alt":
ifconfig altzuneu 192.168.1.1 up
auf "neu":
ifconfig altzuneu 192.168.1.2 up

Beide Enden sollten sich nun gegenseitg auf dieser IP anpingen können.

Mit echter IP

Auf dem neuen System soll natürlich kein internes Netz sondern die öffentliche IP geroutet werden. Da ich hier kein Gegenstück aus dem gleichen Subnetz habe, verwende ich auf der Seite „alt“ eine einzelne interne IP und auf der Seite „neu“ die zu routende öffentliche IP. Damit das Funktioniert, müssen entsprechende Routen gesetzt werden:

auf "alt":
ifconfig altzuneu 192.168.1.1/32 up
ip route add 3.3.3.3/32 via 192.168.1.1 scope link
auf "neu":
ifconfig altzuneu 3.3.3.3/32 up
ip route add 192.168.1.1/32 via 3.3.3.3 scope link

Und schon kann ich von alt auf 3.3.3.3 pingen. Damit das auch von extern geht, muss auf „alt“ noch ip forwarding aktiviert werden:

echo "1" > /proc/sys/net/ipv4/ip_forward

Leider klappt aus irgend einem Grund der Ping von meiner externen IP auf 3.3.3.3 noch nicht.

Rückfahrschein

Mittels TCPDUMP auf „neu“ ist das Problem schnell gefunden:

tcpdump -n -i altzuneu icmp
[...] 9.9.9.9 > 3.3.3.3: ICMP echo request [...]

Auf dem VPN-Interfaces sind nur Echo-Requests zu sehen. Die Antworten fehlen jedoch.

tcpdump -n -i eth0 icmp
[...] 3.3.3.3 > 9.9.9.9: ICMP echo reply [...]

Die Antworten finden sich auf dem öffentlichen Interface wieder. Der Grund ist, dass das System eingehende Anfragen aus dem Internet sieht. Die Antworten darauf werden über das Default-Gateway gesendet. Nun könnte ich das Default-Gateway zwar ändern, dann habe ich das selbe Problem aber für Traffic, der über die neue IP des neuen Systems (2.2.2.2) reinkommt.

Die Lösung lautet Source Policy Routing. Dieses Kernel-Feature erlaubt es, IP-Paketen aufgrund Ihrer Eigenschaften eine eigene Routing-Tabelle zuzuweisen. Diese kann dann ein eigenes Default-Gateway haben, welches keinen Einfluss auf andere Pakete haben. Die „spezielle Eigenschaft“ der entsprechenden Pakete ist hier, dass sie die IP 3.3.3.3 als Quelle haben.

auf "neu":
ip rule add from 3.3.3.3 table 2
ip route add default via 192.168.1.1 table 2

Und schon kennt das neue System die Rückroute für Pakete der gerouteten IP.

Paketgrößen

Die Path-MTU zwischen unterschiedlichen Rechenzentren ist in der Regel 1500 byte. Dies kann ermittelt werden, indem mit

ping -s 1472 -c 10 -M do EXTERNE-IP

auf das jeweils andere System gepingt wird. Durch den VPN-Overhead reduziert sich die MTU auf 1445 bytes (Ping mit -s 1417 von neu auf 192.168.1.1). Tinc fragmentiert intern die Pakete entsprechend, sauberer ist es jedoch, dem VPN-Device gleichd ie richtige MTU zu geben:

ifconfig altzuneu mtu 1445

Alles zusammen fügen

Damit man obige Einstellungen nicht bei jedem Neustart neu machen muss, können die Befehle in das tinc-up-Script aufgenommen werden.

tinc-up auf „alt“:

#!/bin/sh
ifconfig $INTERFACE 192.168.1.1/32 mtu 1445 up
ip route add 3.3.3.3/32 via 192.168.1.1 scope link
echo "1" > /proc/sys/net/ipv4/ip_forward

tinc-up auf „neu“:

#!/bin/sh
ifconfig $INTERFACE 3.3.3.3/32 mtu 1445 up
ip route add 192.168.1.1/32 via 3.3.3.3 scope link
ip rule add from 3.3.3.3 table 2
ip route add default via 192.168.1.1 table 2

Nach dem Neustart der beiden Tinc-Daemons sollte 3.3.3.3 weiterhin extern erreichbar sein. Ein tracepath von extern auf die IP sollte zwar den Bruch in der MTU zeigen, die intern verwendete 192.168.1.1 sollte jedoch nicht auftauchen.

Fazit

Mittels Routing über ein VPN kann eine öffentliche IP von einem Server zu einem anderen getunnelt werden. Die Übertragung erfolgt dabei verschlüsselt. Im Gegensatz zu Port-Weiterleitungen (z.b. mit rinetd oder NAT) bleibt Original-IP des Anfragenden erhalten und wird in Logfiles korrekt angezeigt. Damit alles korrekt funktioniert, muss besonderes Augenmerk auf das Source-Policy-Routing-Setup gelegt werden.

Veröffentlicht unter Linux

1 Gedanke zu „Öffentliche IP-Adresse mit Tinc-VPN von einem Server auf einen anderen Tunneln

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert