IPv6-Firewall für einen IPv6-Tunnel einrichten (Raspberry Pi)

Wenn man den Raspberry Pi als IPv6-Tunnel-Endpunkt oder IPv6-Gateway betreibt, dann ist "jeder Rechner im LAN" mit einer eigenen globalen IPv6-Adresse weltweit erreichbar. Jeder kann von außen, sofern eine IPv6-Adresse aus dem LAN bekannt ist, auf diese Rechner zugreifen. Es ist jetzt nicht mehr so, wie man es von IPv4 kennt, per NAT hinter einem Router verstecken kann. Das hat die Konsequenz, dass man dafür sorgen muss, dass auf dem Raspberry Pi eine entsprechend konfigurierte IPv6-Firewall aktiv ist.

Aufgabe

  1. Richten Sie eine IPv6-Firewall auf dem Raspberry Pi ein, die unerwünschte Zugriffe von außen verhindert und erwünschte Zugriffe zulässt.
  2. Prüfen Sie, ob die Firewall funktioniert.

Lösung

Diese Lösung basiert darauf, dass der Raspberry Pi als SixXS-Tunnel-Endpunkt oder IPv6-Gateway betrieben wird. Diese Lösung ist ein Vorschlag, der je nach Anwendungsfall angepasst werden muss.

Es gibt sehr viele Möglichkeiten eine Firewall mit Linux zu betreiben. In diesem Fall entscheiden wir uns für "ip6tables". Es handelt sich dabei um einen Paketfilter, was für eine einfache Firewall ausreicht.

Zuerst erstellen wir uns eine Setup-Datei für die Firewall-Regeln.

sudo nano ip6tables.rules.sh

In diese Datei schreiben wir folgende Regeln rein:

#!/bin/bash
# Datei : ip6tables.rules.sh
# Test  : IPv6-Stateful-Firewall für einen IPv6-Tunnel oder -Gateway
# Stand : 2014-12-16

# Alle Regeln löschen
ip6tables -F
ip6tables -X
ip6tables -t mangle -F
ip6tables -t mangle -X

# Alle Pakete mit RH0-Header verwerfen
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

# Verbindungen zum Localhost erlauben
ip6tables -A INPUT  -i lo -j ACCEPT
ip6tables -A OUTPUT -o lo -j ACCEPT

# Alle Verbindungen zum lokalen Netzwerk erlauben
ip6tables -A INPUT   -i eth0 -j ACCEPT
ip6tables -A FORWARD -i eth0 -o eth0 -j ACCEPT
ip6tables -A OUTPUT  -o eth0 -j ACCEPT

# Alle link-lokalen Verbindungen erlauben
ip6tables -A INPUT  -s fe80::/10 -j ACCEPT
ip6tables -A OUTPUT -s fe80::/10 -j ACCEPT

# Alle Multicast-Verbindungen erlauben
ip6tables -A INPUT  -d ff00::/8 -j ACCEPT
ip6tables -A OUTPUT -d ff00::/8 -j ACCEPT

# ICMPv6 erlauben
ip6tables -I INPUT   -p icmpv6 -j ACCEPT
ip6tables -I FORWARD -p icmpv6 -j ACCEPT
ip6tables -I OUTPUT  -p icmpv6 -j ACCEPT

# Weiterleitungen erlauben (nur im Gateway-Betrieb sinnvoll)
ip6tables -A FORWARD -m state --state NEW -i eth0 -o sixxs -j ACCEPT
ip6tables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
ip6tables -A FORWARD -m state --state INVALID -j DROP

# Pakete mit No-Next-Header weiterleiten erlauben
ip6tables -A FORWARD -p ipv6-nonxt -m length --length 40 -j ACCEPT

# Alle ausgehenden Verbindungen über den Tunnel erlauben
ip6tables -A OUTPUT -o sixxs -j ACCEPT

# Alle von innen aufgebaute Verbindungen über den Tunnel erlauben
ip6tables -A INPUT  -i sixxs -m state --state ESTABLISHED,RELATED -j ACCEPT

# Alle eingehenden SSH-Verbindungen (Port 22) erlauben
#ip6tables -A INPUT -p tcp --dport 22 -j ACCEPT

# Alle eingehenden HTTP-Verbindungen (Port 80) erlauben
#ip6tables -A INPUT -p tcp --dport 80 -j ACCEPT

# Default-Einstellungen
ip6tables -P INPUT   DROP
ip6tables -P FORWARD DROP
ip6tables -P OUTPUT  DROP

Diese Regeln wurden nach besten Wissen und Gewissen geprüft. Ich übernehme keinerlei Haftung für Schäden die durch diese Regeln entstehen und garantiere ebenfalls nicht die Richtigkeit und Vollständigkeit der Regeln. Eine Garantie, dass diese Regeln in jedem Fall und für alle Zeit korrekt sind, gibt es nicht.

Anschließend speichern und schließen: Strg + O, Return, Strg + X.

Dann muss die Datei zuerst ausführbar gemacht werden, um sie danach auszuführen.

sudo chmod 744 ip6tables.rules.sh
sudo ./ip6tables.rules.sh

Eine Bestätigung für den Erfolg bekommt man nicht. Wenn die Kommandozeile ohne Fehlermeldung zurückkehrt, dann bedeutet dass, dass kein Fehler auftrat.

Die IPv6-Firewall ist jetzt konfiguriert. Allerdings nur temporär. Nach einem Neustart wären diese Regeln wieder weg. Das ist auch erst mal gut so. Bevor wir die Regeln dauerhaft übernehmen, wollen wir wissen, ob die Firewall-Regeln funktionieren.

Dazu gehen wir auf eine Webseite, die einen IPv6-Scanner betreibt: http://www.ipv6scanner.com/.

Geben Sie hier die IPv6-Adresse des Raspberry Pi ein. Die Adresse bekommen Sie mit "ifconfig". Schauen Sie hier nach dem Interface "eth0" und der Zeile mit "inet6-Adresse", die mit "Global" gekennzeichnet ist.

IPv6-Port-Scanner

Während dem Scan erscheinen nacheinander einige Ports (nicht alle). Wenn der "IPV6 State" eines Ports auf "Filtered" steht, dann ist alles in Ordnung. Prinzipiell darf ein Port auch "Open" sein. Aber dann sollte man wissen, welcher Dienst auf diesen Port "hört" und was er macht. Ein "offener Port" ist immer ein möglicher Angriffspunkt.

Die Datei mit den Firewall-Regeln kann man jederzeit abändern und ergänzen. Man darf nur nicht vergessen, sie erneut auszuführen, wenn man die Änderungen übernehmen will. Und ganz wichtig, man sollte die Regeln darauf prüfen, ob sie funktionieren.

Dazu kann man sich eine Statistik anzeigen lassen. Hier sieht man, wieviele und welche Verbindungen geblockt oder erlaubt wurden.

sudo ip6tables -nvL

Die IPv6-Firewall ist jetzt konfiguriert. Allerdings nur temporär. Nach einem Neustart des Raspberry Pi wären diese Regeln weg. Wenn man Änderungen am Regel-Set dauerhaft übernehmen will, dann müssen diese gespeichert werden.

sudo sh -c "ip6tables-save > /etc/iptables/rules.v6"

Auch hier gibt es keine Bestätigung. Bei Erfolg kehrt einfach die Kommandozeile zurück. Um sicher zu gehen, kann man sich die aktuellen Firewall-Regeln für IPv6 in folgender Datei ansehen:

cat /etc/iptables/rules.v6

Wenn man möchte kann man noch einen Reboot machen, um zu testen, ob die Regeln auch wirklich nach einem Neustart verwendet werden. Das ist aber nicht notwendig.

Wichtige Hinweise

Die Art und Weise, wie die Firewall hier konfiguriert wird, davon wird in der Regel abgeraten. In dem die ip6tables-Kommandos in ein Shell-Skript geschrieben und dieses dann an einem Stück ausgeführt wird, wird für jedes ip6tables-Kommando ein Prozess angestoßen, der Rechenleistung und Zeit braucht. Beim Ausführen des Skripts wird der Paketfilter gelöscht und neu aufgesetzt. Während weniger Millisekunden arbeitet die Firewall mit einem unfertigen Paketfilter, was logischerweise keine gute Idee ist.
Angesichts dessen, dass die Befehlsliste bzw. das Shell-Skript relativ kurz ist, kann man diese Lösung gerade noch so akzeptieren. Wenn das Skript aber noch länger wird, bspw. mit persönlichen Einstellungen, sollte man auf diese Lösung verzichten und die ip6tables-Konfiguration direkt und NICHT per Skript vornehmen.

Diese Anleitung und die darin verwendeten Firewall-Regeln erheben keinen Anspruch auf Richtigkeit und Vollständigkeit. Sowohl die Anleitung als auch die Regeln sind nur als Anregung zu verstehen.
Eine Firewall sicher und richtig zu konfigurieren gelingt nur mit viel Erfahrung und in dem immer wieder die aufgestellten Regeln überprüft und an die aktuelle Sicherheitslage angepasst werden.