Projekte/v642/IPv4 Support: Unterschied zwischen den Versionen
Runout (Diskussion | Beiträge) (benötigte OpenWRT Pakete) |
|||
(12 dazwischenliegende Versionen von 3 Benutzern werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
Ziel des [[Projekte/v642|v642 Projektes]] ist es das gesamte FunkFeuer Netz auf ein natives IPv6 Netz umzustellen. Genauere Details zu den Beweggründen finden sich auf der | Ziel des [[Projekte/v642|v642-Projektes]] ist es, das gesamte FunkFeuer-Netz auf ein natives IPv6-Netz umzustellen. Genauere Details zu den Beweggründen finden sich auf der Projektseite selbst. Es ist allerdings klar, dass auf absehbare Zeit Endnutzer weiterhin Inhalte über IPv4 abrufen werden und diese eventuell auch bereitstellen wollen. Um dies zu ermöglichen, gibt es eine Vielzahl an sogenannten Transition-Mechanismen. Im Folgenden sollen die Gründe, warum wir uns für ''4in6'' als den Mechanismus für das FunkFeuer-Netz entschieden haben, und auch die technische Implementierung erläutert werden. | ||
== Warum 4in6 == | == Warum 4in6 == | ||
In der Wikipedia gibt es eine ganze Liste von [https://en.wikipedia.org/wiki/Category:IPv6_transition_technologies IPv6 | In der Wikipedia gibt es eine ganze Liste von [https://en.wikipedia.org/wiki/Category:IPv6_transition_technologies IPv6-Transition-Mechanismen]. Warum also für uns ''4in6''? | ||
Als ersten Schritt nahmen wir alle Mechanismen aus dem Rennen welche dem Endnutzer keine IPv4 Adresse in seinem Netzwerk Perimeter zur Verfügung stellen. Wir hielten es für wichtig | Als ersten Schritt nahmen wir alle Mechanismen aus dem Rennen, welche dem Endnutzer keine IPv4-Adresse in seinem Netzwerk-Perimeter zur Verfügung stellen. Wir hielten es für wichtig, dass in einem freien Netz die Nutzer weiterhin auf beiden Netzwerk-Protokollen Inhalte nach ihren eigenen Wünschen verbreiten können. Dies wäre mit NAT-basierten Lösungen, wo Protokollübersetzungen mit State zentral durchgeführt werden, nur schwer möglich. | ||
Am Ende bleiben uns damit noch einige Tunnel | Am Ende bleiben uns damit noch einige Tunnel- und Wrapping-Mechanismen zur Verfügung. Verwaltung ist für uns hier wichtig, da eine große Anzahl von Tunnels schwer zu handhaben sind und wir uns das generell ersparen wollen. Daher wollen wir einen Mechanismus, der pflegeleicht ist. Auch soll State in den Tunnels vermieden werden. Der Unterschied ist hierbei, dass ein Tunnel großteils als konstant gesehen wird -- das heißt er hat eine Verbindung, welche aufrecht erhalten wird (engl. Stateful). Stateful ist generell schwieriger zu skalieren und für unsere Zwecke irrelevant da wir nur zwischen zwei Protokollen übersetzen wollen. Damit begeben wir uns auf das Feld, das besser als Wrapper oder Übersetzer zu bezeichnen ist. Hier kommt dann auch ''4in6'' ins Spiel, welches aufgrund der gut "abgehangenen" Spezifizierung ([https://www.ietf.org/rfc/rfc2473.txt RFC2473] aus dem Jahre 1998!) und dem entsprechend guten Support in Linux gewählt wurde. | ||
== Wie funktioniert 4in6 == | == Wie funktioniert 4in6? == | ||
Wenn du 6in4 bereits kennst brauchst du dir das ganze nur genau umgekehrt vorstellen. Daher auch der Name. :) | Wenn du ''6in4'' bereits kennst, brauchst du dir das ganze nur genau umgekehrt vorstellen. Daher auch der Name. :) | ||
Im ganz einfachen Sinne kann man sich das so vorstellen | Im ganz einfachen Sinne kann man sich das so vorstellen, dass auf einem Router z.B. bei Dir daheim eine ''4in6''-Terminierung konfiguriert wurde. In dieser Konfiguration wird ein virtuelles Interface erstellt, das so konfiguriert ist, dass jedes IPv4-Paket, das in das Interface gerouted wird, in ein IPv6-Paket verpackt wird, und das neue Paket mit einer fixen IPv6-Destination- und -Source-Adresse versehen wird. Danach wird das Paket wie jedes andere IPv6-Paket über das IPv6-Netz geroutet. Am anderen Ende (das ist die Destination-Adresse, die das Paket bekommen hat) steht dann ein Wrapper-Server von uns, der das Paket annimmt und das IPv4-Paket wieder aus der Payload des IPv6-Pakets rausholt. Der Wrapper-Server hat auch eine native IPv4-Anbindung, und dort wird das ausgepackte IPv4-Paket dann ausgegeben. In die Rückrichtung geht das ganze einfach umgekehrt -- es gibt dafür am Wrapper-Server ein entsprechendes Interface, das die IPv4-Pakete in die Richtung von Deinem Router in IPv6-Pakete einpackt; Dein Router packt die IPv4-Pakete wieder aus und schickt sie zum Beispiel in Dein Heimnetz. Es gibt noch ein paar spezifische Sachen, die der Kernel macht (in Bezug auf Fragmentierung, etc.). Die sind im RFC entsprechend beschrieben, aber für die Grundidee irrelevant. | ||
Wenn | Wenn Du noch mehr dazu wissen willst, such am besten nach ''6in4'' (da gibts mehr Content dazu), und denk Dir das ganze einfach im umgekehrten Falle. | ||
== Implementierung == | == Implementierung == | ||
Im Netz werden vom Verein an den Border Punkten (im Moment bei Nessus und in der Krypta) sogennannte Wrapping Server zur Verfügung gestellt. Diese Server werden im IPv6 Mesh die Route <code>2a02: | Im Netz werden vom Verein an den Border-Punkten (im Moment bei Nessus und in der Krypta) sogennannte Wrapping-Server zur Verfügung gestellt. Diese Server werden im IPv6-Mesh die Route <code>2a02:61:0:ee::/80</code> announcieren. Da diese Route von mehreren Punkten ins Netz announciert wird, wird diese als Anycast verstanden. Anycast heißt, dass Traffic von Euch immer zum topologisch nächsten Server geroutet wird. Auch ermöglicht uns diese Art des Routings sofort Redundanzen zu haben. Wenn ein Server kaputt ist, wird die Route im Netz nicht mehr announciert, und ein andere Server übernimmt die Arbeit. Da (anders als bei Tunnellösungen) kein State besteht, ist das Wechseln auf einen anderen Wrapping-Server völlig transparent. | ||
Weiters haben diese Server native IPv4 Anbindung am Backbone Netz. Über diese Anbindung | Weiters haben diese Server native IPv4-Anbindung am Backbone-Netz. Über diese Anbindung werden zu ihnen noch zu fixierende IPv4-Prefixes geroutet. Dort wiederum besteht der Fall, dass mehrere Routen zur selben IPv4-Adresse führen, und diese werden demnach im Backbone-Netz zum nächstgelegenen Server gesandt. Selbes Spiel wie oben im Mesh. | ||
Auf jedem Server werden alle IPv4 Adressen aus den Netzen die wir dorthin | Auf jedem Server werden alle IPv4-Adressen aus den Netzen, die wir dorthin routen, vorkonfiguriert. Dies ist möglich, da wir ein statisches Mapping der IPv4-Adresse in die IPv6-Endpunkt-Adresse machen. Dadurch benötigt es keinerlei neue Konfiguration, um eine IPv4-Adresse in Betrieb zu nehmen, wenn sie Dir zugewiesen wurde. Der Wrap-Server weiß einfach, dass diese IPv4-Adresse an diesen IPv6-Endpunkt geschickt wird. | ||
Auf der anderen Seite bei | Auf der anderen Seite bei Dir wiederum konfigurierst Du nur ein solches Interface für die IPv4-Adresse die Dir zugewiesen wurde. Die IPv6-Adressen, die Du für diese Konfiguration benötigst, ergeben sich wiederum aus der Dir zugewiesenen IPv4-Adresse. Mehr dazu im Beispiel unten. | ||
=== Subnet Plan === | === Subnet-Plan === | ||
Um die Konfiguration dieses Systems einfach zu halten haben wir uns entschlossen eine IPv4 in IPv6 mapped Struktur zu verwenden. Diese sind im [https://www.ietf.org/rfc/rfc4291.txt RFC4291] näher beschrieben. | Um die Konfiguration dieses Systems einfach zu halten, haben wir uns entschlossen, eine IPv4-in-IPv6-mapped-Struktur zu verwenden. Diese sind im [https://www.ietf.org/rfc/rfc4291.txt RFC4291] näher beschrieben. | ||
Für die Wrapper Infrastruktur wurde der folgende Prefix zugewiesen: <code>2a02: | Für die Wrapper-Infrastruktur wurde der folgende Prefix zugewiesen: <code>2a02:61:0:ee::/64</code> | ||
Daraus ergeben sich folgende verwendbare Adressen: | Daraus ergeben sich folgende verwendbare Adressen: | ||
<blockquote> | <blockquote> | ||
<code> | <code> | ||
2a02: | 2a02:0061:0000:00ee:0000:0000:0000:0000 - | ||
2a02: | 2a02:0061:0000:00ee:ffff:ffff:ffff:ffff | ||
</code> | </code> | ||
</blockquote> | </blockquote> | ||
Innerhalb dieses Prefixes haben wir zwei /80 zugewiesen welche einmal in die Richtung nach | Innerhalb dieses Prefixes haben wir zwei /80 zugewiesen, welche einmal in die Richtung nach Außen (also ins Internet aus Sicht vom Mesh-Endknoten bei Dir) und einmal nach Innen routen. | ||
Egress/nach | Egress/nach Außen: <code>2a02:61:0:ee::/80</code> | ||
<blockquote> | <blockquote> | ||
<code> | <code> | ||
2a02: | 2a02:0061:0000:00ee:0000:0000:0000:0000 - | ||
2a02: | 2a02:0061:0000:00ee:0000:ffff:ffff:ffff | ||
</code> | </code> | ||
</blockquote> | </blockquote> | ||
Ingress/nach Innen: <code>2a02: | Ingress/nach Innen: <code>2a02:61:0:ee:1::/80</code> | ||
<blockquote> | <blockquote> | ||
<code> | <code> | ||
2a02: | 2a02:0061:0000:00ee:0001:0000:0000:0000 - | ||
2a02:0060: | 2a02:0060:0000:00ee:0001:ffff:ffff:ffff | ||
</code> | </code> | ||
</blockquote> | </blockquote> | ||
=== | === Beispielkonfiguration === | ||
Im folgenden eine | Im folgenden eine Beispielkonfiguration, mit welcher die IPv4-Adresse <code>185.194.20.123</code> konfiguriert wird. Der Home-Router ist dabei ein Router im Mesh-Netz, welcher dazu gewählt wurde, diese IPv4-Adresse zu terminieren. (Welcher Router das in der Praxis macht, bleibt aber dem Halter der IPv4-Adresse überlassen: Es kann ein Mesh-Router oder ein nachgestellter Router in seinem Netz-Perimeter sein.) | ||
Notiz am Rande. In den meisten Betriebssystemen die IPv6 unterstützen können IPv4 mapped Adressen einfach eingegeben werden indem diese als letzte 32 | Notiz am Rande. In den meisten Betriebssystemen, die IPv6 unterstützen, können IPv4-mapped-Adressen einfach eingegeben werden, indem diese als letzte 32 Bit der Adresse in Dotted-Decimal-Notation eingegeben werden. Zum Beispiel <code>::ffff:123.123.123.123</code>. Um RFC-konform zu sein müssen die vorherigen 16 Bit mit ffff belegt werden. | ||
==== OpenWRT ==== | |||
OpenWRT benötigt folgende Pakete um die Befehle in den nächsten Abschnitten ausführen zu können. | |||
==== Home Router ==== | * ip-full | ||
Basierend auf dem Subnet Plan legen wir am Loopback Interface die | * kmod-ip6-tunnel | ||
==== Home-Router ==== | |||
Basierend auf dem Subnet-Plan legen wir am Loopback-Interface die Endpunktadresse für die ankommenden Pakete an. Diese wird dann von OLSR in das Mesh-Netz announciert und dadurch routebar. | |||
<blockquote> | <blockquote> | ||
<code> | <code> | ||
ip -6 addr add 2a02: | ip -6 addr add 2a02:61:0:ee:1:ffff:185.194.20.123/128 dev lo preferred_lft 0 | ||
</code> | </code> | ||
</blockquote> | </blockquote> | ||
Die Option <code>preferred_lft</code> setzen wir, damit diese Adresse nicht anstatt der Loopback-Adresse für Verbindungen, die von diesem Router ausgehen (und keine spezifische Source-IP haben), verwendet wird. Mehr Details hierzu gibt es [http://www.davidc.net/networking/ipv6-source-address-selection-linux hier] -- leider kann man in Linux keine Primary-IPv6-Adresse für ausgehende Verbindungen setzen. | |||
Als nächstes legen wir ein virtuelles Interface mit 4in6 Konfiguration an und aktivieren dieses. Die IPv6 Adressen geben | Als nächstes legen wir ein virtuelles Interface mit ''4in6''-Konfiguration an und aktivieren dieses. Die IPv6-Adressen geben die Source und Destinations wie oben beschrieben an. | ||
<blockquote> | <blockquote> | ||
<code> | <code> | ||
ip -6 tunnel add wrap1 mode ipip6 remote 2a02: | ip -6 tunnel add wrap1 mode ipip6 remote 2a02:61:0:ee::ffff:185.194.20.123 local 2a02:61:0:ee:1:ffff:185.194.20.123 dev lo<br/> | ||
ip -6 link set dev wrap1 up | ip -6 link set dev wrap1 up | ||
</code> | </code> | ||
</blockquote> | </blockquote> | ||
Danach muss auf diesem Interface noch die IPv4 Adresse konfiguriert werden. | Danach muss auf diesem Interface noch die IPv4-Adresse konfiguriert werden. | ||
<blockquote> | <blockquote> | ||
<code> | <code> | ||
ip -4 addr add | ip -4 addr add 185.194.20.123/32 dev wrap1 | ||
</code> | </code> | ||
</blockquote> | </blockquote> | ||
Dies ist die minimale Konfiguration | Dies ist die minimale Konfiguration. Sie macht diese IPv4-Adresse auf diesem Gerät verfügbar. Jedes Paket, das nun in dieses Interface geschickt wird, wird im Hintergrund verpackt und auf dem IPv6-Transportnetz weitergesendet. Wenn auf unseren Servern ein Paket für diese IPv4-Adresse ankommt, wird das dann umgekehrt gemacht, und wenn es auf der IPv6-Adresse, die am Loopback-Interface konfiguriert wurde, ankommt, wird es ausgepackt und auf dem <code>wrap1</code> Interface ausgegeben. | ||
Da dies nun ein Interface wie alle anderen im Linux Kernel ist, kann es für lokales NAT, Port Forwarding, etc. genutzt werden. Wenn auf diesem Router zum Beispiel noch ein anderes Interface mit | Da dies nun ein Interface wie alle anderen im Linux-Kernel ist, kann es für lokales NAT, Port Forwarding, etc. genutzt werden. Wenn auf diesem Router zum Beispiel noch ein anderes Interface mit Deinem internen IPv4-Netz ist -- sagen wir <code>192.168.0.1/24</code>, könnten wir dieses Netz einfach über öffentliche IPv4-Adresse in das Internet NATen. Das ginge dann zum Beispiel so: | ||
<blockquote> | <blockquote> | ||
<code> | <code> | ||
ip -4 route add 0.0.0.0/0 via | ip -4 route add 0.0.0.0/0 via 185.194.20.123 dev wrap1<br/> | ||
iptables -t nat -A POSTROUTING -o wrap1 -j MASQUERADE | iptables -t nat -A POSTROUTING -o wrap1 -j MASQUERADE | ||
</code> | </code> | ||
</blockquote> | </blockquote> | ||
Wer so ein Setup schon mal mit einer anderen Public IPv4 Adresse gemacht hat wird sehen | Wer so ein Setup schon mal mit einer anderen Public-IPv4-Adresse gemacht hat, wird sehen, dass das alles genau gleich ausschaut. So wollten wir das eben auch -- dass das für den Endnutzer weiterhin gleich verwendbar ist. | ||
==== Wrap Server ==== | ==== Wrap-Server ==== | ||
Die folgende Konfiguration wird für jede IPv4 Adresse die wir für den Transition Mechanismus zuweisen auf unseren Wrap Servern vorhanden sein. Diese muss nicht angelegt werden wenn eine neue IPv4 Adresse zugewiesen wird sondern wird | Die folgende Konfiguration wird für jede IPv4-Adresse, die wir für den Transition-Mechanismus zuweisen, auf unseren Wrap-Servern vorhanden sein. Diese muss nicht angelegt werden, wenn eine neue IPv4-Adresse zugewiesen wird, sondern wird von uns vorprovisioniert. Dies ist hier nur dokumentiert, falls es jemanden interessiert, wie das am anderen Ende ausschaut. Spoiler: sehr ähnlich wie am Home Router. | ||
Adresse für die Terminierung am Loopback Interface - einziger Unterschied | Adresse für die Terminierung am Loopback Interface -- einziger Unterschied, dass diese aus dem anderen /80 Netz stammt. | ||
<blockquote> | <blockquote> | ||
<code> | <code> | ||
ip -6 addr add 2a02: | ip -6 addr add 2a02:61:0:ee::ffff:185.194.20.123/128 dev lo preferred_lft 0 | ||
</code> | </code> | ||
</blockquote> | </blockquote> | ||
Auch wiederum nur die Adressen umgetauscht und der Interface Name enthält die IPv4 Adresse damit das am Server einfacher zu finden ist. | Auch wiederum nur die Adressen umgetauscht, und der Interface-Name enthält die IPv4-Adresse, damit das am Server einfacher zu finden ist. | ||
<blockquote> | <blockquote> | ||
<code> | <code> | ||
ip -6 tunnel add | ip -6 tunnel add wrap185194020123 mode ipip6 remote 2a02:61:0:ee:1:ffff:185.194.20.123 local 2a02:61:0:ee::ffff:185.194.20.123 dev lo | ||
</code> | </code> | ||
</blockquote> | </blockquote> | ||
Zeile 120: | Zeile 126: | ||
<blockquote> | <blockquote> | ||
<code> | <code> | ||
ip -6 link set dev | ip -6 link set dev wrap185194020123 up<br/> | ||
ip -4 route add | ip -4 route add 185.194.20.123/32 dev wrap185194020123 | ||
</code> | </code> | ||
</blockquote> | </blockquote> | ||
Da es leider Systeme gibt die ICMP Nachrichten filtern und daher keine PMTU (Path MTU) Discovery durchführen können, verwenden wir TCP MSS Clamping auf dem Wrap Server. Dadurch werden die initialen TCP SYN Messages angepasst damit sie die korrekte MTU verwenden. | |||
<blockquote> | |||
<code> | |||
iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu | |||
</code> | |||
</blockquote> |
Aktuelle Version vom 14. September 2019, 21:45 Uhr
Ziel des v642-Projektes ist es, das gesamte FunkFeuer-Netz auf ein natives IPv6-Netz umzustellen. Genauere Details zu den Beweggründen finden sich auf der Projektseite selbst. Es ist allerdings klar, dass auf absehbare Zeit Endnutzer weiterhin Inhalte über IPv4 abrufen werden und diese eventuell auch bereitstellen wollen. Um dies zu ermöglichen, gibt es eine Vielzahl an sogenannten Transition-Mechanismen. Im Folgenden sollen die Gründe, warum wir uns für 4in6 als den Mechanismus für das FunkFeuer-Netz entschieden haben, und auch die technische Implementierung erläutert werden.
Warum 4in6
In der Wikipedia gibt es eine ganze Liste von IPv6-Transition-Mechanismen. Warum also für uns 4in6?
Als ersten Schritt nahmen wir alle Mechanismen aus dem Rennen, welche dem Endnutzer keine IPv4-Adresse in seinem Netzwerk-Perimeter zur Verfügung stellen. Wir hielten es für wichtig, dass in einem freien Netz die Nutzer weiterhin auf beiden Netzwerk-Protokollen Inhalte nach ihren eigenen Wünschen verbreiten können. Dies wäre mit NAT-basierten Lösungen, wo Protokollübersetzungen mit State zentral durchgeführt werden, nur schwer möglich.
Am Ende bleiben uns damit noch einige Tunnel- und Wrapping-Mechanismen zur Verfügung. Verwaltung ist für uns hier wichtig, da eine große Anzahl von Tunnels schwer zu handhaben sind und wir uns das generell ersparen wollen. Daher wollen wir einen Mechanismus, der pflegeleicht ist. Auch soll State in den Tunnels vermieden werden. Der Unterschied ist hierbei, dass ein Tunnel großteils als konstant gesehen wird -- das heißt er hat eine Verbindung, welche aufrecht erhalten wird (engl. Stateful). Stateful ist generell schwieriger zu skalieren und für unsere Zwecke irrelevant da wir nur zwischen zwei Protokollen übersetzen wollen. Damit begeben wir uns auf das Feld, das besser als Wrapper oder Übersetzer zu bezeichnen ist. Hier kommt dann auch 4in6 ins Spiel, welches aufgrund der gut "abgehangenen" Spezifizierung (RFC2473 aus dem Jahre 1998!) und dem entsprechend guten Support in Linux gewählt wurde.
Wie funktioniert 4in6?
Wenn du 6in4 bereits kennst, brauchst du dir das ganze nur genau umgekehrt vorstellen. Daher auch der Name. :)
Im ganz einfachen Sinne kann man sich das so vorstellen, dass auf einem Router z.B. bei Dir daheim eine 4in6-Terminierung konfiguriert wurde. In dieser Konfiguration wird ein virtuelles Interface erstellt, das so konfiguriert ist, dass jedes IPv4-Paket, das in das Interface gerouted wird, in ein IPv6-Paket verpackt wird, und das neue Paket mit einer fixen IPv6-Destination- und -Source-Adresse versehen wird. Danach wird das Paket wie jedes andere IPv6-Paket über das IPv6-Netz geroutet. Am anderen Ende (das ist die Destination-Adresse, die das Paket bekommen hat) steht dann ein Wrapper-Server von uns, der das Paket annimmt und das IPv4-Paket wieder aus der Payload des IPv6-Pakets rausholt. Der Wrapper-Server hat auch eine native IPv4-Anbindung, und dort wird das ausgepackte IPv4-Paket dann ausgegeben. In die Rückrichtung geht das ganze einfach umgekehrt -- es gibt dafür am Wrapper-Server ein entsprechendes Interface, das die IPv4-Pakete in die Richtung von Deinem Router in IPv6-Pakete einpackt; Dein Router packt die IPv4-Pakete wieder aus und schickt sie zum Beispiel in Dein Heimnetz. Es gibt noch ein paar spezifische Sachen, die der Kernel macht (in Bezug auf Fragmentierung, etc.). Die sind im RFC entsprechend beschrieben, aber für die Grundidee irrelevant.
Wenn Du noch mehr dazu wissen willst, such am besten nach 6in4 (da gibts mehr Content dazu), und denk Dir das ganze einfach im umgekehrten Falle.
Implementierung
Im Netz werden vom Verein an den Border-Punkten (im Moment bei Nessus und in der Krypta) sogennannte Wrapping-Server zur Verfügung gestellt. Diese Server werden im IPv6-Mesh die Route 2a02:61:0:ee::/80
announcieren. Da diese Route von mehreren Punkten ins Netz announciert wird, wird diese als Anycast verstanden. Anycast heißt, dass Traffic von Euch immer zum topologisch nächsten Server geroutet wird. Auch ermöglicht uns diese Art des Routings sofort Redundanzen zu haben. Wenn ein Server kaputt ist, wird die Route im Netz nicht mehr announciert, und ein andere Server übernimmt die Arbeit. Da (anders als bei Tunnellösungen) kein State besteht, ist das Wechseln auf einen anderen Wrapping-Server völlig transparent.
Weiters haben diese Server native IPv4-Anbindung am Backbone-Netz. Über diese Anbindung werden zu ihnen noch zu fixierende IPv4-Prefixes geroutet. Dort wiederum besteht der Fall, dass mehrere Routen zur selben IPv4-Adresse führen, und diese werden demnach im Backbone-Netz zum nächstgelegenen Server gesandt. Selbes Spiel wie oben im Mesh.
Auf jedem Server werden alle IPv4-Adressen aus den Netzen, die wir dorthin routen, vorkonfiguriert. Dies ist möglich, da wir ein statisches Mapping der IPv4-Adresse in die IPv6-Endpunkt-Adresse machen. Dadurch benötigt es keinerlei neue Konfiguration, um eine IPv4-Adresse in Betrieb zu nehmen, wenn sie Dir zugewiesen wurde. Der Wrap-Server weiß einfach, dass diese IPv4-Adresse an diesen IPv6-Endpunkt geschickt wird.
Auf der anderen Seite bei Dir wiederum konfigurierst Du nur ein solches Interface für die IPv4-Adresse die Dir zugewiesen wurde. Die IPv6-Adressen, die Du für diese Konfiguration benötigst, ergeben sich wiederum aus der Dir zugewiesenen IPv4-Adresse. Mehr dazu im Beispiel unten.
Subnet-Plan
Um die Konfiguration dieses Systems einfach zu halten, haben wir uns entschlossen, eine IPv4-in-IPv6-mapped-Struktur zu verwenden. Diese sind im RFC4291 näher beschrieben.
Für die Wrapper-Infrastruktur wurde der folgende Prefix zugewiesen: 2a02:61:0:ee::/64
Daraus ergeben sich folgende verwendbare Adressen:
2a02:0061:0000:00ee:0000:0000:0000:0000 - 2a02:0061:0000:00ee:ffff:ffff:ffff:ffff
Innerhalb dieses Prefixes haben wir zwei /80 zugewiesen, welche einmal in die Richtung nach Außen (also ins Internet aus Sicht vom Mesh-Endknoten bei Dir) und einmal nach Innen routen.
Egress/nach Außen: 2a02:61:0:ee::/80
2a02:0061:0000:00ee:0000:0000:0000:0000 - 2a02:0061:0000:00ee:0000:ffff:ffff:ffff
Ingress/nach Innen: 2a02:61:0:ee:1::/80
2a02:0061:0000:00ee:0001:0000:0000:0000 - 2a02:0060:0000:00ee:0001:ffff:ffff:ffff
Beispielkonfiguration
Im folgenden eine Beispielkonfiguration, mit welcher die IPv4-Adresse 185.194.20.123
konfiguriert wird. Der Home-Router ist dabei ein Router im Mesh-Netz, welcher dazu gewählt wurde, diese IPv4-Adresse zu terminieren. (Welcher Router das in der Praxis macht, bleibt aber dem Halter der IPv4-Adresse überlassen: Es kann ein Mesh-Router oder ein nachgestellter Router in seinem Netz-Perimeter sein.)
Notiz am Rande. In den meisten Betriebssystemen, die IPv6 unterstützen, können IPv4-mapped-Adressen einfach eingegeben werden, indem diese als letzte 32 Bit der Adresse in Dotted-Decimal-Notation eingegeben werden. Zum Beispiel ::ffff:123.123.123.123
. Um RFC-konform zu sein müssen die vorherigen 16 Bit mit ffff belegt werden.
OpenWRT
OpenWRT benötigt folgende Pakete um die Befehle in den nächsten Abschnitten ausführen zu können.
- ip-full
- kmod-ip6-tunnel
Home-Router
Basierend auf dem Subnet-Plan legen wir am Loopback-Interface die Endpunktadresse für die ankommenden Pakete an. Diese wird dann von OLSR in das Mesh-Netz announciert und dadurch routebar.
ip -6 addr add 2a02:61:0:ee:1:ffff:185.194.20.123/128 dev lo preferred_lft 0
Die Option preferred_lft
setzen wir, damit diese Adresse nicht anstatt der Loopback-Adresse für Verbindungen, die von diesem Router ausgehen (und keine spezifische Source-IP haben), verwendet wird. Mehr Details hierzu gibt es hier -- leider kann man in Linux keine Primary-IPv6-Adresse für ausgehende Verbindungen setzen.
Als nächstes legen wir ein virtuelles Interface mit 4in6-Konfiguration an und aktivieren dieses. Die IPv6-Adressen geben die Source und Destinations wie oben beschrieben an.
ip -6 tunnel add wrap1 mode ipip6 remote 2a02:61:0:ee::ffff:185.194.20.123 local 2a02:61:0:ee:1:ffff:185.194.20.123 dev lo
ip -6 link set dev wrap1 up
Danach muss auf diesem Interface noch die IPv4-Adresse konfiguriert werden.
ip -4 addr add 185.194.20.123/32 dev wrap1
Dies ist die minimale Konfiguration. Sie macht diese IPv4-Adresse auf diesem Gerät verfügbar. Jedes Paket, das nun in dieses Interface geschickt wird, wird im Hintergrund verpackt und auf dem IPv6-Transportnetz weitergesendet. Wenn auf unseren Servern ein Paket für diese IPv4-Adresse ankommt, wird das dann umgekehrt gemacht, und wenn es auf der IPv6-Adresse, die am Loopback-Interface konfiguriert wurde, ankommt, wird es ausgepackt und auf dem wrap1
Interface ausgegeben.
Da dies nun ein Interface wie alle anderen im Linux-Kernel ist, kann es für lokales NAT, Port Forwarding, etc. genutzt werden. Wenn auf diesem Router zum Beispiel noch ein anderes Interface mit Deinem internen IPv4-Netz ist -- sagen wir 192.168.0.1/24
, könnten wir dieses Netz einfach über öffentliche IPv4-Adresse in das Internet NATen. Das ginge dann zum Beispiel so:
ip -4 route add 0.0.0.0/0 via 185.194.20.123 dev wrap1
iptables -t nat -A POSTROUTING -o wrap1 -j MASQUERADE
Wer so ein Setup schon mal mit einer anderen Public-IPv4-Adresse gemacht hat, wird sehen, dass das alles genau gleich ausschaut. So wollten wir das eben auch -- dass das für den Endnutzer weiterhin gleich verwendbar ist.
Wrap-Server
Die folgende Konfiguration wird für jede IPv4-Adresse, die wir für den Transition-Mechanismus zuweisen, auf unseren Wrap-Servern vorhanden sein. Diese muss nicht angelegt werden, wenn eine neue IPv4-Adresse zugewiesen wird, sondern wird von uns vorprovisioniert. Dies ist hier nur dokumentiert, falls es jemanden interessiert, wie das am anderen Ende ausschaut. Spoiler: sehr ähnlich wie am Home Router.
Adresse für die Terminierung am Loopback Interface -- einziger Unterschied, dass diese aus dem anderen /80 Netz stammt.
ip -6 addr add 2a02:61:0:ee::ffff:185.194.20.123/128 dev lo preferred_lft 0
Auch wiederum nur die Adressen umgetauscht, und der Interface-Name enthält die IPv4-Adresse, damit das am Server einfacher zu finden ist.
ip -6 tunnel add wrap185194020123 mode ipip6 remote 2a02:61:0:ee:1:ffff:185.194.20.123 local 2a02:61:0:ee::ffff:185.194.20.123 dev lo
Gleich wie auch oben.
ip -6 link set dev wrap185194020123 up
ip -4 route add 185.194.20.123/32 dev wrap185194020123
Da es leider Systeme gibt die ICMP Nachrichten filtern und daher keine PMTU (Path MTU) Discovery durchführen können, verwenden wir TCP MSS Clamping auf dem Wrap Server. Dadurch werden die initialen TCP SYN Messages angepasst damit sie die korrekte MTU verwenden.
iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu