Das Ende naht… nicht nur das Ende der Welt (2012 und so) sondern auch das Ende der verfügbaren IPv4-Adressen. Nicht, dass das für mich persönlich morgen bedrohliche Konsequenzen nach sich zieht, aber dennoch der richtige Zeitpunkt, sich mal ein wenig mit IPv6 zu beschäftigen. Da mein DSL-Provider keine direkte v6-Anbindung anbietet und das letztendlich auch ein wenig langweilig wäre, habe ich mich für eine Tunnellösung mittels SixXS entscheiden. Wer oder was SixXS ist und wie man dort an IPv6-Anbindung kommt, ist auf ihrer Website schön erklärt und wird an dieser Stelle deshalb ausgespart.
Ich möchte den Tunnel nicht auf einer meiner Workstations betreiben, da dieser zum Sammeln von ISKs 24/7 online sein soll. Mein Router würde sich dafür natürlich anbieten, das ist jedoch nicht ganz unproblematisch. Der WRT54G v2.2 von Linksys hat leider einen Broadcom-Chipsatz, der sich nicht mit Linux 2.6 versteht, weshalb dort ein OpenWRT mit 2.4er-Kernel läuft. In Linux 2.4 gibt es zwar auch schon IPv6 aber leider fehlt dem dortigem ip6tables das Connection-Tracking, was den ganzen Firewall-Aufbau quasi unmöglich macht. Es bleiben also die Alternativen „2.4-Kernel mit WLAN aber ohne IPv6“ oder „2.6-Kernel mit IPv6 aber ohne WLAN“. Dumme Sache… Zum Glück greift hier jedoch wieder die altbewährte Regel „Warum eins kaufen, wenn man für das doppelte Geld zwei haben kann“ und wie es der Zufall will habe ich aus alten Internet-über-den-Innenhof-Zeiten sogar noch ein 2. Gerät hier stehen.
Der Plan ist also wie folgt: Der bisherige Router bleibt auf Linux 2.4, übernimmt WLAN und DSL-Anbindung. Der zweite WRT54G wird mit 2.6er-Firmware bespielt und fungiert als Tunnel-Endpoint und Gateway für den IPv6-Traffic. Anleitungen zur Installation der notwendigen Programme sind im Wiki von SixXS zu finden (für OpenWRT z.B. hier). Deshalb möchte ich hier nur kurz auf die größten Fallen hinweisen.
Die korrekte Systemzeit ist das A und O da die Tunnel-Endpoints auf den PoPs keine Verbindung annehmen, wenn die Zeitdifferenz zu groß ist. Es ist also wichtig die Startreihenfolge von Diensten und Hotplug-Scripten so zu ändern, dass Zeitdienste wie ntpdate oder rdate VOR aiccu liegen. Beim Backfire RC4 musste dazu das Script /etc/hotplug.d/40-rdate in 30-rdate umbenannt werden. Im Gegenstück wird das AICCU-Script von 30-aiccu in 40-aiccu unbenannt, um den Start nach hinten zu schieben.
In Verbindung mit radvd und aiccu kann es zu Problemen mit dem Routing kommen, wenn die Startreihenfolge nicht richtig ist. Radvd sollte vor aiccu gestartet werden. Dazu wird in den jeweiligen init-Scripten der Wert der START-Variable auf 50 (radvd) bzw. 51 (aiccu) gestellt.
Damit der IPv6-Router auch Pakete weiterleitet, muss in der Datei /etc/sysctl.conf eine Zeile mit „net.ipv6.conf.all.forwarding=1“ eingefügt werden, wenn nicht bereits passiert. Die Einstellung wird nach einem Neustart wirksam bzw. kann auch mittels folgendem Befehl on-the-fly aktivert werden:
echo 1 > /proc/sys/net/ipv6/conf/all/forwarding |
echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
Der Router sollte nun das eingestellte Subnetz in das LAN publizieren und die Pakete durch den Tunnel routen. An dieser Stelle sei nun nochmal darauf hingewiesen, dass wir beim IPv6 kein NAT mehr haben. Diese bisher damit einhergehende bequeme Abschottung des LANs nach außen ist somit nicht mehr existent. Ohne entsprechende Firewall kann nun jeder IPv6-Nutzer jeden Rechner innerhalb unseres LANs problemlos anpingen und auf entsprechende Services connecten. Es ist daher dringends anzuraten, entsprechende Firewall-Einstellungen vorzunehmen. Meine /etc/firewall.user sieht in etwa so aus:
# First, delete all:
ip6tables -F
ip6tables -X
# Allow anything on the local link
ip6tables -A INPUT -i lo -j ACCEPT
ip6tables -A OUTPUT -o lo -j ACCEPT
# Allow anything out on the internet
ip6tables -A OUTPUT -o sixxs -j ACCEPT
# Allow the localnet access us:
ip6tables -A INPUT -i br-lan -j ACCEPT
ip6tables -A OUTPUT -o br-lan -j ACCEPT
# Filter all packets that have RH0 headers:
ip6tables -A INPUT -m rt --rt-type 0 -j DROP
ip6tables -A FORWARD -m rt --rt-type 0 -j DROP
ip6tables -A OUTPUT -m rt --rt-type 0 -j DROP
# Allow Link-Local addresses
ip6tables -A INPUT -s fe80::/10 -j ACCEPT
ip6tables -A OUTPUT -s fe80::/10 -j ACCEPT
# Allow multicast
ip6tables -A INPUT -s ff00::/8 -j ACCEPT
ip6tables -A OUTPUT -s ff00::/8 -j ACCEPT
# Allow ICMPv6 everywhere
ip6tables -I INPUT -p icmpv6 -j ACCEPT
ip6tables -I OUTPUT -p icmpv6 -j ACCEPT
ip6tables -I FORWARD -p icmpv6 -j ACCEPT
# Allow forwarding
ip6tables -A FORWARD -m state --state NEW -i br-lan -o sixxs -s <subnet-prefix>::/48 -j ACCEPT
ip6tables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
# Set the default policy
ip6tables -P INPUT DROP
ip6tables -P FORWARD DROP
ip6tables -P OUTPUT DROP |
# First, delete all:
ip6tables -F
ip6tables -X
# Allow anything on the local link
ip6tables -A INPUT -i lo -j ACCEPT
ip6tables -A OUTPUT -o lo -j ACCEPT
# Allow anything out on the internet
ip6tables -A OUTPUT -o sixxs -j ACCEPT
# Allow the localnet access us:
ip6tables -A INPUT -i br-lan -j ACCEPT
ip6tables -A OUTPUT -o br-lan -j ACCEPT
# Filter all packets that have RH0 headers:
ip6tables -A INPUT -m rt --rt-type 0 -j DROP
ip6tables -A FORWARD -m rt --rt-type 0 -j DROP
ip6tables -A OUTPUT -m rt --rt-type 0 -j DROP
# Allow Link-Local addresses
ip6tables -A INPUT -s fe80::/10 -j ACCEPT
ip6tables -A OUTPUT -s fe80::/10 -j ACCEPT
# Allow multicast
ip6tables -A INPUT -s ff00::/8 -j ACCEPT
ip6tables -A OUTPUT -s ff00::/8 -j ACCEPT
# Allow ICMPv6 everywhere
ip6tables -I INPUT -p icmpv6 -j ACCEPT
ip6tables -I OUTPUT -p icmpv6 -j ACCEPT
ip6tables -I FORWARD -p icmpv6 -j ACCEPT
# Allow forwarding
ip6tables -A FORWARD -m state --state NEW -i br-lan -o sixxs -s <subnet-prefix>::/48 -j ACCEPT
ip6tables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
# Set the default policy
ip6tables -P INPUT DROP
ip6tables -P FORWARD DROP
ip6tables -P OUTPUT DROP
Nachdem der Tunnel nun aufgebaut ist und die anderen IPv6-Geräte über diesen brav ihren Traffic leiten, kommen wir zum letzten Problem, bedingt durch die Position des Tunnel-Endpoints nicht direkt auf dem IPv4-Gateway sondern im LAN hinter dem IPv4-NAT. Die Firewall auf dem IPv4-Router knippst nämlich nach einer gewissen Zeit den Durchgang durch die Firewall für den Tunnel-Traffic zu, wenn dort nicht regelmäßig Pakete durchgehen. Um dies zu umgehen legen wir auf dem IPv4-Router eine Firewall-Einstellung (in /etc/firewall.user) an, die den 6in4-Traffic (genau das ist nämlich der Tunnel-Traffic) pauschal an den IPv6-Gateway umleitet und das Connection-Tracking umgeht:
# send 6in4 traffic to ipv6 endpoint
iptables -t nat -A PREROUTING -i ppp0 -p 41 -j DNAT --to $IPv6GATEWAY
iptables -t filter -A FORWARD -i ppp0 -p 41 -d $IPv6GATEWAY -j ACCEPT |
# send 6in4 traffic to ipv6 endpoint
iptables -t nat -A PREROUTING -i ppp0 -p 41 -j DNAT --to $IPv6GATEWAY
iptables -t filter -A FORWARD -i ppp0 -p 41 -d $IPv6GATEWAY -j ACCEPT
Mit diesen Einstellungen sollte nun IPv6-Konnektivität für jeden im LAN möglich sein, der Lust darauf hat. Die IP-Adressen werden per Autokonfiguration vergeben. Da diese Adressen per-default von der MAC-Adresse des jeweiligen Endgerätes abhängen kann dies zu dem unschönen Effekt führen, dass ein Gerät ständig mit der gleichen IP-Adresse online ist und sich für weiteren Überwachnungsbedarf sogar regelmäßig anpingen lässt. Um dem entgegen zu laufen, sei auf die Privacy-Extension verwiesen. Betriebssysteme, die diese beherrschen, generieren die IP-Adressen jedesmal zufällig neu. Eine Überwachnung ist somit in einem 64er-Netz mit seinen 1.8 x 10^19 möglichen Adressen schonmal eine Stufe aufwändiger.
Das hier beschriebene Setup läuft bei mir jetzt seit guten 3 Wochen stabil vor sich hin. Ich bin noch dabei herauszufinden, wie ich DHCP-Server für IPv4-Adressen, lokalen DNS-Server und DNS-Forwarder richtig auf die beiden Router verteile. Sicher ist nur, dass der DNS-Forwarder möglichst auf einer Kiste mit IPv6-Konnektivität sitzen sollte, da einige DNS-Server im Netz so konfiguriert werden, dass sie AAAA-Records (also IPv6-Adressen für Hostnames) nur rausgeben, wenn die Anfrage von einer IPv6-Adresse kommt. Darüber hinaus ist das bei mir alles noch ein wenig im Fluss.