OpenWRT würfelt IPv6-Präfixe

Seite 3: Präfix-Schleuder

Inhaltsverzeichnis

Mit IPv6 lassen sich Netzwerke einfach umnummerieren respektive mit neuen Präfixen versorgen. Ein IPv6-Router verteilt dazu neben dem alten Präfix auch ein neues. Das alte bleibt etwa für eingehende Daten weiterhin gültig (valid_lifetime). Gleichzeitig setzt der Router die preferred_lifetime auf 0, sodass die Clients das Präfix nicht mehr für ausgehende Verbindungen einsetzen. Nachdem der Zähler in valid_lifetime abgelaufen ist, verwirft das Betriebssystem bei der Stateless Address Autoconfiguration diese Adresse vollständig und automatisch. Die Grundeinrichtung von IPv6 unter OpenWRT sowie einige Eigenheiten des Router-Linux beschreiben die Artikel IPv6-Zugang fürs LAN nachrüsten und Taschenrouter als IPv6-Verteiler auf heise Netze.

Mit diesem Wissen und mit einem OpenWRT-Router lässt sich schnell ein einfaches Beispiel-Skript zusammenbauen (Download als ZIP-Archiv), das all diese Vorgaben erledigt, einen Präfix auswürfelt und verteilt, die Router-Adressen setzt und sich auch um das Zurückholen abgenutzter Präfixe kümmert. Das in AWK geschriebene Skript greift des Weiteren auf die Jobsteuerung cron sowie OpenWRT-typische Funktionen wie die Konfigurationshilfe uci zurück, die etwa den Linux IPv6 Router Advertisement Daemon (radvd) weitgehend automatisch einrichtet. Auf unserem Testrouter (D-Link DIR-300 Rev. B) läuft ein Sixxs-Tunnel, für den ein /48-Präfix bereitsteht, sowie ein aus den Trunk-Quellen übersetztes OpenWRT mit einem radvd in Version 1.8.2. Ab dieser Version erleichtert eine zusätzliche Funktion das Zurückholen eines benutzten Präfixes – umständliches Setzen von Laufzeiten sowie manuelle Neustarts entfallen. Allerdings muss man die Hilfe zuerst ausdrücklich einschalten.

uci set radvd.@prefix[0].DeprecatePrefix=on
uci set radvd.@prefix[0].DecrementLifetimes=on

Der BEGIN-Block des IPv6-Präfix-Würfel-Skripts setzt den eigenen Präfix (prefix) und ein reserviertes, also vom Skript niemals zu nutzendes Subnetz (reserved). Außerdem finden sich dort die Vorgaben für Gültigkeit, Lebensdauer und die Zeit, nach der das Skript ein einmal genutztes Präfix erneut verwenden darf.

BEGIN {
srand();
prefix="2001:0db8:1";
reserved="affe";
AdvValidLifetime=604800;
AdvPreferredLifeTime=86400;
do {
gensubnet();
} while (find_in_alltime(full_prefix) == 0)
...
exit;
}

function find_in_alltime(full_prefix)
{
FS=";";
erg=1;
while ((getline line < alltime) > 0)
{
split(line, data, ";")
if ( data[1] == full_prefix ) {
if ( data[3] > systime() - (3*AdvValidLifetime)) {
erg=0;
}
}
}
close(alltime);
return erg;
}

function gensubnet() {
do {
subnet=sprintf("%x", int(0xffff*rand()));
} while(subnet == reserved)
full_prefix=prefix ":" subnet "::/64";
router_addr=prefix ":" subnet "::1/64";
gentime=systime();
return;
}

function setgwaddr(addr, ...) {
...
}

function set_newprefix(nprefix,...) {
...
}

Anschließend würfelt die Funktion gensubnet() eine Subnetz-ID und überprüft, ob sie reserviert ist. Falls ja, läuft gensubnet() weiter, bis ein Subnetz-ID gefunden wurde. Zum Abschluss liest das Skript aus einer Logdatei alle bisher verwendeten Präfixe ein und vergleicht sie mit dem gerade erzeugten (find_in_alltime(full_prefix)). Kommt es dabei zu Kollisionen, tritt wieder gensubnet() auf den Plan. Alle anderen Skriptteile kümmern sich über uci um die Einrichtung des Netzes und aktivieren mit ip eine zum Präfix passende und ebenfalls temporäre Gateway- Adresse auf dem Router.

Den täglichen Wechsel des IPv6-Präfixes stößt man über die Jobsteuerung cron an. Die über das Kommando crontab -e eingegebene Zeile

0 5 * * * awk -f /usr/local/bin/mkprefix.awk

rollt allmorgendlich ein neues Präfix aus. Hinterlegt man die Kommandozeile in /etc/rc.local, führt der Router das Skript auch beim Start aus. Das IPv6-Präfix-Würfel-Skript speichert die einmal verwendeten Präfixe in einer Textdatei unter /tmp/prefix.log, die allerdings bei jedem Router-Neustart verloren geht. Zum Schluss muss man noch die IPv6- Firewall des Routers anpassen, die nun ausgehende Daten aller Subnetze unterhalb des eigenen /48-Präfix ins Internet durchreichen soll.

ip6tables -A FORWARD -m state --state NEW \
-i eth0 -o sixxs -s 2001:db8:1234::/48 -j ACCEPT
ip6tables -A FORWARD -m state --state ESTABLISHED,RELATED \
-j ACCEPT

Den hier verwendeten Präfix 2001:db8: 1234::/48 müssen Sie gegen Ihren eigenen austauschen. Anschließend gelangen Sie über den Router mit täglich wechselnden Subnetzen ins Internet. Um den zweiten Teil der IPv6-Adresse (Interface Identifier) muss sich hingegen das Betriebssystem auf den Endgeräten kümmern.

Nach der Veröffentlichung dieses Artikels in c't hat der Autor des Linux IPv6 Howtos, Peter Bieringer, das Skript grundlegend überarbeitet: Denn das oben beschriebene Skript funktioniert so nur auf Routern, die per Sixxs-Tunnel ins Netz gelangen und deren IPv6-Präfix per Hand fest vorgegeben wird. An nativen IPv6-DSL-Zugängen erhält der Router das Netzwerk-Präfix jedoch über DHCPv6 vom Provider zugewiesen, sodass man es im Skript ermitteln muss.