Eigentlich habe ich in meinem letzten Blog-Post angekündigt, diesmal „den abgebissenen Apfel bis auf den Kern“ zu schälen. Aber gerade als ich alle Vorbereitungen dafür abgeschlossen hatte, erinnerte mich ein außergewöhnlich religiöser Kollege (der an dieser Stelle nicht namentlich genannt werden möchte) daran, was Adam und Eva damals widerfahren ist, nachdem sie vom selbigen Apfel „nur“ abgebissen hatten. Ein Risiko von solchem Kaliber für einen einzigen Blogpost einzugehen, wäre einfach nur unverhältnismäßig. Deshalb beschränke ich mich in diesem Beitrag darauf, dem Skript vom letzten mal IPv6-Unterstützung zu verleihen.
Bestandsaufnahme
Weder die Topologien der Netzwerke, noch die damit einhergehenden Probleme haben sich seit dem letzten Beitrag geändert. Das Setup wurde „lediglich“ auf IPv6 umgestellt – schließlich wird man in Zukunft über die Nutzung von IPv4 wahrscheinlich ähnlich wertend reden wie heute über die Nutzung von Schreibmaschinen. Das Problem besteht darin, dass eine VM im Netz 2001:db8::192.0.2.16/124
nicht ohne weiteres mit Containern im Netz 2001:db8::192.0.2.32/124
kommunizieren kann, da sie nicht weiß, dass letztgenanntes Netz hinter der VM 2001:db8::192.0.2.18
liegt. Um dieses Problem zu beheben, kann man entweder jeder einzelner betroffener VM diesen Weg beizubringen – oder man nutzt…
Statische IPv6-Routen auf Mac OS X
Leider ist dies etwas schwieriger, als die Einrichtung von IPv4-Routen – zumindest wenn die VMs mit Parallels betrieben werden. Dem Host wird nämlich die IP 2001:db8::192.0.2.17
nicht automatisch zugewiesen. Und es gibt anscheinend keine Möglichkeit, dies über die Netzwerkeinstellungen dauerhaft zu ändern.
Dann eben durch die Hintertür…
Das zuletzt bereits angelegte Skript /usr/local/sbin/add-static-routes.sh
, das beim Systemstart automatisch ausgeführt wird (siehe letzten Blogbeitrag), kann für diesen Zweck mitgenutzt werden, indem man am Ende folgende Zeile hinzufügt:
/usr/local/sbin/assign-inet6-address.pl "$(/usr/local/sbin/get-iface-by-inet-address.pl 192.0.2.17)" 2001:db8::192.0.2.17/124
Alle Skripte, die nicht im letzten Blogpost auftauchen stehen am Ende dieses Blogposts. Die konkreten Daten sind nicht aus der Luft gegriffen, sondern müssen mit den Parallels-Netzwerkeinstellungen übereinstimmen – wobei die Adresse der Netzwerk-Schnittstelle „Subnetz + 1“ sein sollte:
2001:db8::c000:210 + 1 = 2001:db8::c000:211 = 2001:db8::192.0.2.17
Zurück zu der Route
Nach der eben vollendeten Überwindung der Parallels-Hürde steht der Eigentlichen statischen Route nichts mehr im Wege. Diese wird einfach in /usr/local/sbin/add-static-routes.sh
mit aufgenommen:
/usr/local/sbin/add-static-route6.pl 2001:db8::192.0.2.32/124 2001:db8::192.0.2.18
Diese Route tritt spätestens nach einem Neustart in Kraft. Mangels Geduld kann man auch die zwei hinzugefügten Zeilen direkt auf der Kommandozeile ausführen:
# bash bash-3.2# /usr/local/sbin/assign-inet6-address.pl "$(/usr/local/sbin/get-iface-by-inet-address.pl 192.0.2.17)" 2001:db8::192.0.2.17/124 bash-3.2# /usr/local/sbin/add-static-route6.pl 2001:db8::192.0.2.32/124 2001:db8::192.0.2.18
Fazit
„Warum extrem einfach wenn es auch unnötig kompliziert geht?“ Diesem Motto werde ich auch weiterhin treu bleiben – also stay tuned!
Skripte
/usr/local/sbin/get-iface-by-inet-address.pl
#!/usr/bin/perl # (C) 2017 NETWAYS GmbH | GPLv2+ # Author: Alexander A. Klimov my $inet_addr = shift; exit 2 if ! defined $inet_addr; # RTFM at https://wp.me/pgR2o-rur my $iface; $inet_addr = quotemeta($inet_addr); POLL: for (;;) { for (`/sbin/ifconfig`) { if (/^(\S+?): /) { $iface = $1 } elsif (defined($iface) && /^\tinet $inet_addr /) { print $iface; last POLL } } sleep 1 }
/usr/local/sbin/assign-inet6-address.pl
#!/usr/bin/perl # (C) 2017 NETWAYS GmbH | GPLv2+ # Author: Alexander A. Klimov my $iface = shift; my $inet6_addr = shift; exit 2 if !(defined($iface) && defined($inet6_addr) && $inet6_addr =~ m~^(.+)/(\d+)$~); # RTFM at https://wp.me/pgR2o-rur my $status = system("/sbin/ifconfig", $iface, "inet6", $1, "prefixlen", $2) >> 8; die "/sbin/ifconfig: $status" if ($status != 0)
/usr/local/sbin/add-static-route6.pl
#!/usr/bin/perl # (C) 2017 NETWAYS GmbH | GPLv2+ # Author: Alexander A. Klimov my $destination = shift; my $gateway = shift; exit 2 if !(defined($destination) && defined($gateway) && $destination =~ m~^(.+)/(\d+)$~); # RTFM at https://wp.me/pgR2o-rur $destination = $1; my $destination_prefixlen = $2; my $gatewayBin = ip6adr2bin($gateway); POLL: for (;;) { for (`/sbin/ifconfig`) { if (/^\tinet6 (.+?)(?:%\S+)? prefixlen (\d+)/) { if (ip6bin2prefix($gatewayBin, $2) eq ip6bin2prefix(ip6adr2bin($1), $2)) { my $status = system("/sbin/route", "add", "-inet6", "-prefixlen", $destination_prefixlen, "-net", $destination, $gateway) >> 8; die "/sbin/route: $status" if ($status != 0); last POLL } } } sleep 1 } sub ip6adr2bin { my $raw = shift; if ($raw =~ /::/) { my ($head, $tail) = split(/::/, $raw); $head = ip6part2bin($head); $tail = ip6part2bin($tail); return $head . ("0" x (128 - (length($head) + length($tail)))) . $tail } ip6part2bin($raw) } sub ip6bin2prefix { my $addr = shift; my $prefixlen = shift; substr($addr, 0, $prefixlen) . ("0" x (128 - $prefixlen)) } sub ip6part2bin { join("", map({ /\./ ? join("", map({ sprintf("%08b", $_) } split(/\./, $_))) : sprintf("%016b", hex($_)) } split(/:/, shift()))) }

0 Kommentare
Trackbacks/Pingbacks