Raspberry Pi + IPv6 Gateway

Mein Pi soll als mein IPv6 Gateway dienen, weil mein normaler Router leider nichts kann. Momentan muss man leider noch _sehr_ darauf achten welches Image man benutzt, weil nicht alle IPv6 unterstützen und ip6tables. Es sieht also noch sehr düster aus. Wenn man aber endlich eins gefunden hat und sich irgendwo einen Tunnel besorgt hat. Am Ende habe ich mich für eine Private Lösung entschieden, weil Sixxs einfach zu lange braucht :)

Bei ipv6 ist es eigentlich normal das man eine IP + ein 64er Netz bekommt. Warum? Die einzelne IP dient dazu die Verbindung zum Anbieter aufzubauen und das Netz kann dazu benutzt selber zu announcen oder als Service IPs zu benutzen. Man wirft also sprichwörtlich mit IP Adressen um sich… wenn man es hat…

Wenn man also seine IP und vielleicht später sein Netz bekommen hat kann man anfangen sein Pi in einen IPv6 Router umzuwandeln. Als erstes sollten wir dem Kernel erlauben v6 Pakete weiterzuleiten:

/sbin/sysctl -w net.ipv6.conf.all.forwarding=1

Es empfiehlt sich dies in der /etc/sysctl.conf zu verewigen, damit es auch nach einem Neustart automatisch gesetzt wird. In meinem Beispiel werde ich mein v6 Netz über ein tap0 Gerät laufen, dass kann bei jedem anders sein. Es ist keine Hexerei und einfacher geht es eigentlich nicht:

# single ip address
/sbin/ip -6 a a 2c01:118:a315:12::13/64 dev tap0
# default route to my provider
/sbin/ip -6 route add default via 2c01:118:a315:12::1 dev tap0
# my 64 network
/sbin/ip -6 a a 2c01:118:a315:44::1/64 dev eth0

Wie man erkennen kann habe ich meine einzelne IP auf dem tap0 Gerät und mein Netz auf eth0, damit ich das später in meinem “privaten” Netzwerk announcen kann. Jetzt sollte es schon möglich sein v6 Adressen zu erreichen. Dies testen wir mit einem simplen ping Test:

# ping6 itbert.de -c 5
PING itbert.de(2001:4d88:1ffc:4f6::1) 56 data bytes
64 bytes from 2001:4d88:1ffc:4f6::1: icmp_seq=1 ttl=56 time=22.9 ms
64 bytes from 2001:4d88:1ffc:4f6::1: icmp_seq=2 ttl=56 time=26.4 ms
64 bytes from 2001:4d88:1ffc:4f6::1: icmp_seq=3 ttl=56 time=20.4 ms
64 bytes from 2001:4d88:1ffc:4f6::1: icmp_seq=4 ttl=56 time=21.2 ms
64 bytes from 2001:4d88:1ffc:4f6::1: icmp_seq=5 ttl=56 time=23.0 ms

— itbert.de ping statistics —
5 packets transmitted, 5 received, 0% packet loss, time 4006ms
rtt min/avg/max/mdev = 20.427/22.810/26.405/2.062 ms

Sollte man keinen v6 Host pingen können, sollte man nochmal seinen Tunnel und die Adressen überprüfen. Ansonsten ist der kleine Pi bereit als Router zu dienen. Wie bekommen den unsere Clients dazu eine IP Adresse aus unserem Netz zu benutzen? Bei v6 gibt es an sich keinen DHCP wie man ihn von v4 kennt. Es gibt unter anderem auch keine NAT mehr. Das heißt, jeder Host aus dem ganzen Internet erreichbar ist, wenn man keine Firewall auf seinem Gateway einsetzt. Ich wette das wird noch ganz viel Spaß mit sich bringen, wenn erst mal alle Provider anfangen v6 Adressen auszuliefern. Also erstmal eine einfache Firewall einrichten:

#!/bin/bash
# script: ip6tables firewall script

IPV6T=”/sbin/ip6tables”
INFOUT=”tap0″
INFLOCAL=”eth0″
HOSTIP=”2c01:118:a315:12::13″

# First, delete all:
$IPV6T -F
$IPV6T -X

# Allow anything on the local link
$IPV6T -A INPUT  -i lo -j ACCEPT
$IPV6T -A OUTPUT -o lo -j ACCEPT

# Allow anything out on the internet
$IPV6T -A OUTPUT -o $INFOUT -j ACCEPT
# Allow established, related packets back in
$IPV6T -A INPUT  -i $INFOUT -m state –state ESTABLISHED,RELATED -j ACCEPT

# Allow the localnet access us:
$IPV6T -A INPUT -i $INFLOCAL -j ACCEPT
$IPV6T -A OUTPUT -o $INFLOCAL -j ACCEPT

# Filter all packets that have RH0 headers:
$IPV6T -A INPUT -m rt –rt-type 0 -j DROP
$IPV6T -A FORWARD -m rt –rt-type 0 -j DROP
$IPV6T -A OUTPUT -m rt –rt-type 0 -j DROP

# Allow Link-Local addresses
$IPV6T -A INPUT -s fe80::/10 -j ACCEPT
$IPV6T -A OUTPUT -s fe80::/10 -j ACCEPT

# Allow multicast
$IPV6T -A INPUT -d ff00::/8 -j ACCEPT
$IPV6T -A OUTPUT -d ff00::/8 -j ACCEPT

# Allow ICMPv6 everywhere
$IPV6T -I INPUT  -p icmpv6 -j ACCEPT
$IPV6T -I OUTPUT -p icmpv6 -j ACCEPT
$IPV6T -I FORWARD -p icmpv6 -j ACCEPT

# Allow forwarding
$IPV6T -A FORWARD -m state –state NEW -i $INFLOCAL -o $INFOUT -j ACCEPT
$IPV6T -A FORWARD -m state –state ESTABLISHED,RELATED -j ACCEPT

# SSH in
$IPV6T -A INPUT -i $INFOUT -p tcp -d $HOSTIP –dport 22 -j ACCEPT

# Set the default policy
$IPV6T -P INPUT   DROP
$IPV6T -P FORWARD DROP
$IPV6T -P OUTPUT  DROP

Das Script verbietet jeden eingehen Traffic von $INFOUT und erlaubt nur SSH zu dem Host $HOSTIP. Ausgehender Verkehr bzw. Zugriff von $INFLOCAL ist ohne Einschränkungen möglich. Jetzt sind unsere Clients von Zugriffen aus dem bösen Internet sicher.

Wenn man die Firewall eingerichtet hat, können wir uns endlich um unserer Clients kümmern. Es gibt verschiede Dienste um v6 Netze zu announcen. Die bekanntesten sind quagga und radvd. Radvd ist wesendlich kleiner und wer nur Adressen announcen will ist damit besser beraten als mit quagga.

Die Konfiguration ist einfach in einer Datei untergebracht. Leicht zu verstehen und zu erweitern:

interface eth0 {
AdvSendAdvert on;
MinRtrAdvInterval 3;
MaxRtrAdvInterval 10;
prefix 2c01:118:a315:44::/64 {
AdvOnLink on;
AdvAutonomous on;
AdvRouterAddr on;
};
route ::/0  {};
};

Bei diesem Beispiel wird das Netz 2c01:118:a315:44::/64 über eth0 announced und der default gw auf den Clients wird auch announced. Ist der Dienst gestartet, sollten auch schon die Clients eine v6 Adresse erhalten haben und der Standard Gateway ist gesetzt. Unter Archlinux funktionierte alles einwandfrei und ich musste nichts ändern. Ansonsten kann man die Route auf den Clients auch per Hand setzen:

/sbin/ip -6 r a ::/0 via 2c01:118:a315:44::1 dev eth0

Fehlen nur noch ein paar v6 Tests und man kann fröhlich in die Zukunft schauen…

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.

This site uses Akismet to reduce spam. Learn how your comment data is processed.