EdgeRouter mit IPv6
Seit ein paar Jahren habe ich nun einen EdgeRouter X, der mein Heimnetzwerk mit dem Internet verbindet, in Kombination mit DSL-Modem und UniFi-WLAN-Zugangspunkten. Prinzipiell bin ich mit der Anschaffung zufrieden, die eine defekte FritzBox ersetzte, weil der EdgeRouter mehr Flexibilität bietet, allerdings ist er leider eher was für Bastler, denn für normale Anwender. Das betrifft auch IPv6, das von Ubiquity über alle Produktreihen hinweg recht stiefmütterlich behandelt wird, nicht nur beim EdgeRouter, sondern auch beispielsweise bei der UniFi-Serie. Hier also meine Notizen, wie ich IPv6 zum Laufen gebracht habe.
Setup
- EdgeRouter X mit eigenem DSL-Modem an
eth0
- EdgeOS-Version 2.0.9
- Zugang über PPPoE (1&1)
- Der Internetzugang ist schon eingerichtet
Ich habe den Wizard WLAN+2LAN2 ausgeführt und hier schonmal die IPv6-Unterstützung und Prefix Delegation aktiviert. Dadurch entsteht schon mal ein Teil der Konfiguration, aber man kann auch einfach alles wie unten angegeben eintragen.
Basics
Nur nochmal die Grundlagen von IPv6 zum Verständnis:
IPv6-Adressen gibt es für verschiedene Bereiche. Die globalen Adressen sind weltweit gültig, es gibt kein NAT wie bei IPv4. Das bedeutet, dass jedes Gerät eine IPv6-Adresse hat, die es überall verwendet. Webserver im Internet sehen z.B. die IPv6-Adresse eures Handys und nicht die eures Routers. Das ist ein wichtiger Unterschied zu IPv4, weil man z.B. auch bei dynamischem DNS nicht den Router und seine Adresse verwendet.
Ihr erhaltet von eurem Provider beim Verbinden einen Präfix, d.h. eine bestimmte Anzahl von Stellen am Anfang der IPv6-Adresse wird vom Provider vorgegeben. Der Rest wird durch das Gerät selbst festgelegt: Er wird in der Regel aus der MAC-Adresse erzeugt und bleibt auch über verschiedene Präfixe gleich.
Geräte haben oft mehrere IPv6-Adressen, die einen unterschiedlichen Scope
haben. Neben den o.g. globalen Adressen, die quasi weltweit eindeutig sind,
gibt es noch Link-Local-Adressen, die zur Kommunikation im eigenen
Netzwerk dienen und von Routern nicht geroutet werden. Diese beginnen immer
mit fe80
und sind nur innerhalb des Netzwerks eindeutig.
Wenn die Privacy Extensions aktiviert sind, wird noch eine weitere, globale Adresse mit dem gleichen Präfix generiert, deren hinterer Teil aber zufällig ist und nicht aus der MAC-Adresse abgeleitet wird. Diese Adresse hat nur einen begrenzten Gültigkeitszeitraum, bevor sie wieder neu erzeugt wird, und verhindert, dass anhand des hinteren Teils immer die gleichen Geräte wiedererkannt werden. Für ausgehende Verbindungen wird dann diese Adresse verwendet, das Gerät ist aber auch unter der „normalen“ IPv6-Adresse erreichbar. Daher sind unter der IPv6-Netzwerkkonfiguration meistens gleich mehrere Adressen aufgelistet.
Verbindet sich eure Internetverbindung neu, bekommen alle Netzwerkgeräte neue (globale) IPv6-Adressen, da sich der Präfix ändert. Der hintere Teil der Adresse bleibt gleich. Das schafft eine zusätzliche Problematik, auf die am Ende des Dokuments eingegangen und die auch gelöst wird.
Konfiguration
Die Konfiguration nehme ich über das Webinterface unter dem Menüpunkt Config Tree vor. Scheinbar ist in der Ubiquity-Community es sehr beliebt, das direkt über die Konsole zu machen, aber so kann man auch gut die Einstellungsmöglichkeiten sehen.
Wenn der Router bereits mit dem WLAN+2LAN2-Wizard konfiguriert wurde, können einige Einstellungen schon da sein.
Internetverbindung
Die grundsätzliche Konfiguration erfolgt unter der PPPoE-Schnittstelle unter interfaces / ethernet / eth0 / pppoe / 0.
ipv6
Grundsätzliche IPv6-Unterstützung aktivierenaddress
autoconf
aktivieren
enable
aktivierendup-addr-detect-transmits
auf1
setzen
dhcpv6-pd
Prefix Delegation aktivieren (Weitergabe des IPv6-Präfix an das internet Netzwerk)rapid-commit
aufenable
setzenno-dns
aktivieren: IPv6-DNS deaktivieren (falls ihr eigene DNS-Server nutzt)pd
0
hinzufügenprefix-length
auf56
setzen (abhängig von eurem Provider)interface
switch0
hinzufügenhost-address
auf::1
setzen (Ende der internen IPv6-Adresse für den Router)prefix-id
auf:1
setzenservice
aufslaac
setzenno-dns
aktivieren
- Wenn mehrere virtuelle Switches verwendet werden, die auch IPv6 unterstützen
sollen, müssen diese mit ihrem entsprechenden Namen (z.B.
switch0.2
) hinzugefügt werden und je eine eigenehost-address
undprefix-id
erhalten.
Firewall
Die Firewall muss so konfiguriert werden, dass sie IPv6 zulässt. Hier kann ungefähr den Standardkonfiguration des Wizard verwendet werden. Die Konfiguration erfolgt unter firewall / ipv6-name.
WANv6_IN
hinzufügendefault-action
:drop
description
:WAN inbound traffic forwarded to LAN
enable-default-log
aktivierenrule
10
hinzufügenaction
:accept
description
:Allow established/related sessions
state
established
:enable
related
:enable
20
hinzufügenaction
:drop
description
:Drop invalid state
state
invalid
:enable
30
hinzufügenaction
:accept
description
:allow ICMPv6
protocol
:ipv6-icmp
WANv6_LOCAL
hinzufügendefault-action
:drop
description
:WAN inbound traffic to the router
enable-default-log
aktivierenrule
10
hinzufügenaction
:accept
description
:Allow established/related sessions
state
established
:enable
related
:enable
20
hinzufügenaction
:drop
description
:Drop invalid state
state
invalid
:enable
30
hinzufügenaction
:accept
description
:allow IPv6 icmp
protocol
:ipv6-icmp
40
hinzufügen
Diese Regel war bei mir erforderlich, damit ich auch intern IPv6-Adressen bekomme.action
:accept
description
:Allow IPv6 DHCP
protocol
:udp
destination
port
:546
source
port
:547
Anschließend müssen die Regeln noch unter interfaces / ethernet / eth0 / pppoe / 0 / firewall hinzugefügt werden:
in
ipv6-name
:WANv6_IN
- unter
name
sollte bereits die IPv4-RegelWAN_IN
stehen
local
ipv6-name
:WANv6_LOCAL
- unter
name
sollte bereits die IPv4-RegelWAN_LOCAL
stehen
Portfreigaben
Wie oben erwähnt, funktionieren Adressen bei IPv6 anders: Der Zugriff von außen erfolgt direkt über die globale IPv6-Adresse des Geräts, mit dem verbunden werden soll, z.B. dem Webserver. Daher gibt es keine Portweiterleitungen wie bei IPv4, man muss lediglich in der Firewall die Ports für die entsprechenden IPv6-Adressen aufmachen, damit der Traffic durchgelassen wird.
Das erfolgt in der WANv6_IN-Regel unter firewall / ipv6-name / WANv6_IN. Hier einfach noch zusätzliche Regeln unter rule am Ende hinzufügen, die wie folgt aufgebaut sind:
action
:accept
description
: z.B.HTTP für Webserver
destination
address
Hier die IPv6-Adresse ohne den Präfix angeben und mit Präfix-Maske, ansonsten muss die Adresse nach jedem Reconnect wieder aktualisiert werden, z.B.::aaaa:bbbb:cccc:dddd/::ffff:ffff:ffff:ffff
Switch
Unter interfaces / switch / switch0 / ipv6 müssen die IPv6-Einstellungen getroffen werden. Wenn ein virtueller Switch genutzt wird, müssen die Einstellungen auch für die entsprechenden virtuellen Switches unter dem Unterpunkt vif getroffen werden.
dup-addr-detect-transmits
:1
address
autoconf
aktivieren
router-advert
Verteilt den Präfix im Netzwerkmanaged-flag
:true
Notwendig, damit neue Präfixes sofort von den Clients übernommen werdenother-config-flag
:true
prefix
::/64
hinzufügen
Nach diesen Schritten solltet ihr im Idealfall nun IPv6-Adressen mit euren
Netzwerkgeräten erhalten. Das könnt ihr mit diversen
IPv6-Testseiten prüfen oder einfach mal mit
ping6
oder ping -6
irgendeine Domain anpingen, die IPv6 unterstützt.
Adressen-Problematik
Leider ist die Freude von kurzer Dauer. Wie im Abschnitt Basics beschrieben, erhaltet ihr mit jedem Reconnect einen neuen Präfix und damit eure Netzwerkgeräte neue IPv6-Adressen. Und da entsteht das Problem: Die alten IPv6-Adressen fallen nicht weg und die Netzwerkgeräte versuchen immer noch, die erste erhaltene IPv6-Adresse für die Kommunikation zu nutzen. IPv6-Verbindungen sind dann nicht mehr möglich.
Das Problem ist hier beschrieben und ein Lösungsvorschlag wird gemacht, der jedoch inzwischen nicht mehr so funktioniert.
Router konfigurieren
Von diesem Problem ist zunächst mal euer switch0-Interface bzw. auch die virtuellen Switches am Router betroffen. Daher muss dieser erstmal in der Funktionalität etwas erweitert werden, damit dort die alten IPv6-Adressen gelöscht werden.
Zunächst muss sich per SSH mit dem Router verbunden werden. Unter
/config/scripts
können eigene Skripte angelegt werden, die auch über
Firmware-Updates hinweg erhalten bleiben. Unter /config/scripts/ppp/ip-down.d
können Skripte abgelegt werden, die beim Trennen einer PPP-Verbindung
ausgeführt werden. Genaugenommen ist dies eine Ergänzung zu den Skripten
unter /etc/ppp/ip-down.d
. Und hier legen wir nun ein Skript an, das
die globalen IPv6-Adressen löscht, wenn die Internetverbindung getrennt wird.
Zunächst den Ordner anlegen, falls er noch nicht existiert:
mkdir -p /config/scripts/ppp/ip-down.d
In den Ordner wechseln und Skript anlegen:
cd /config/scripts/ppp/ip-down.d
vi 9999-remove-v6addr.sh
Wer vi nicht kennt: Mit der I-Taste den Einfüge-Modus aktivieren und anschließend das Skript einfügen:
#!/bin/bash
if [[ "$1" != "pppoe0" ]]; then
exit 0
fi
DEVICE=switch0
systemctl stop radvd
/sbin/ifconfig "$DEVICE" | grep -E 'inet6.*global' | awk '{print $2 "/" $4}' | while read -r ipv6addr
do
logger -t "9999-remove-v6addr" "Removing IPv6 address $ipv6addr from $DEVICE"
ip -6 addr del "$ipv6addr" dev "$DEVICE"
done
systemctl start radvd
Mit ESC wieder den Einfügemodus verlassen und mit :wq
die Datei
speichern und beenden. Anschließend das Skript noch ausführbar machen mit
chmod +x 9999-remove-v6addr.sh
.
Virtuelle Switches
Wenn weitere virtuelle Switches mit IPv6-Unterstützung verwendet werden, muss
der Teil zwischen systemctl stop
und systemctl start
dupliziert werden und
$DEVICE
dann entsprechend durch den virtuellen Switch, z.B. switch0.2
ausgetauscht werden. Wird nur ein virtueller Switch für IPv6 verwendet, kann
auch oben einfach der Name in der Variable DEVICE
angepasst werden.
Testen
Mit disconnect interface pppoe0
kann nun die Internetverbindung getrennt
werden. Der Erfolg kann im System Log des Webinterface oder mit
tail -f /var/log/messages
betrachtet werden. Da sollte nun so etwas stehen
wie:
9999-remove-v6addr: Removing IPv6 address dead:beef:…/64 from switch0
Anschließend mit connect interface pppoe0
die Verbindung wieder herstellen.
Unterschiede zum Skript aus der Quelle
- Logging hinzugefügt
- Systemd für radvd nutzen
- Lokale Adresse wird ignoriert, indem in der Zeile auch nach global
gesucht wird, statt
fe80
auszuschließen - Präfix-Länge wird abgegriffen, da inzwischen notwendig
- Skript nicht ausführen, wenn Interface nicht pppoe0, da sonst VPN-Verbindungen auch zum Löschen der IPv6-Adressen führen
radvd konfigurieren
Der Dienst, der das Präfix im Netzwerk bekannt gibt, muss noch so konfiguriert werden, dass er alte Präfixe als veraltet markiert. Da die Konfiguration dieses Dienstes immer durch die Routerkonfiguration erzeugt wird und diese leider keine zusätzlichen Optionen zulässt, müssen wir die Erzeugung der Konfiguration anpassen.
Skript anpassen
Achtung: Diese Änderung muss nach jedem Firmware-Update erneut vorgenommen werden.
Per SSH mit dem Router verbinden und die Datei
/opt/vyatta/sbin/vyatta_gen_radvd.pl
als Superuser öffnen.
sudo vi /opt/vyatta/sbin/vyatta_gen_radvd.pl
Mit der Eingabe von :243
zur Zeile 243 gehen, dort steht folgender Code:
# Write parameters out to config file
print $FD_WR " prefix $prefix {\n";
foreach my $key (keys %prefix_param_hash) {
print $FD_WR " $key $prefix_param_hash{$key};\n";
}
print $FD_WR " };\n";
Wieder mit der I-Taste in den Einfüge-Modus gehen und an das Ende
der foreach-Schleife gehen (die Zeile nur mit }
) und anschließend
die folgende Zeile einfügen:
print $FD_WR " DeprecatePrefix on;\n";
Danach kommt dann das bereits vorhandene
print $FD_WR " };\n";
Mit ESC-Taste und Eingabe von :wq
die Änderungen speichern.
Anschließend die Konfiguration neu erzeugen, z.B. indem man den
Router neu startet oder die Konfiguration ändert, z.B. unter
interfaces / switch / switch0 / ipv6 / router-advert /
prefix / ::/64 die valid-lifetime
um eine Sekunde ändert
(oder gleich mal etwas reduziert).
Testen
Mit cat /etc/radvd.conf
kann nun die erzeugte Konfiguration
geprüft werden. Hier sollte nun unter dem Präfix die Zeile
DeprecatePrefix on;
zu finden sein:
prefix ::/64 {
AdvPreferredLifetime 86400;
AdvAutonomous on;
AdvValidLifetime 86400;
AdvOnLink on;
DeprecatePrefix on;
};
Prüfen
Nach den beiden Schritten müssen ggf. die Schnittstellen der Netzwerkgeräte noch neu gestartet werden, damit die alten Präfixe verloren gehen. Die Geräte sollten nun wieder IPv6-Verbindung haben, wie man mittels Ping prüfen kann.
Um das dauerhaft korrekte Verhalten zu prüfen, auf den Router per SSH verbinden und die Verbindung neu herstellen:
disconnect interface pppoe0
connect interface pppoe0
Anschließend den Netzwerkgeräten ein bisschen Zeit für die neue IPv6-Adresse geben und wieder den Ping probieren, der nun erfolgreich sein sollte.
Die alten IPv6-Adressen verschwinden nicht sofort aus der
Schnittstelle, sondern werden nur als veraltet markiert und bleiben
noch einige Zeit erhalten. Dies dient dazu, erreichbar für Geräte
zu bleiben, die noch die alte IP-Adresse kennen. Für ausgehende
Verbindungen werden aber keine Adressen verwendet, die als veraltet
markiert sind. Wie lange die alte Adresse erhalten bleibt, wird mit
preferred-lifetime
und valid-lifetime
in der Konfiguration von
router-advert
festgelegt. Unter Linux kann man mit
ip -6 address
sehen, welche Adressen als deprecated
markiert
sind.