Zum Inhalt springen

IPv6/Paketfilter

Aus Foxwiki
Die 5 zuletzt angesehenen Seiten:  BigBlueButton/Installation » IP/Fragmentierung » IPv6/Header » PhpMyAdmin » IPv6/Paketfilter
Version vom 11. Mai 2025, 08:50 Uhr von Dirkwagner (Diskussion | Beiträge) (Die Seite wurde neu angelegt: „== 7 Der Paketfilter == Bis jetzt haben wir uns größtenteils ungeschützt im IPv6Internet umherbewegt. * Auf felis finden wir mit der WindowsFirewall einen akzeptablen Grundschutz vor. * Der Host lynx und der Router fuzzball haben aber noch keinen Paketfilter. * Mit der Einrichtung von angepassten Paketfiltern werden wir diese Missstände nun beheben. * Angepasst deshalb, weil sich die Anforderungen an die Paketfilter von Hosts und Routern untersche…“)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)

7 Der Paketfilter

Bis jetzt haben wir uns größtenteils ungeschützt im IPv6Internet umherbewegt.

  • Auf felis finden wir mit der WindowsFirewall einen akzeptablen Grundschutz vor.
  • Der Host lynx und der Router fuzzball haben aber noch keinen Paketfilter.
  • Mit der Einrichtung von angepassten Paketfiltern werden wir diese Missstände nun beheben.
  • Angepasst deshalb, weil sich die Anforderungen an die Paketfilter von Hosts und Routern unterscheiden.
  • Zunächst schauen wir uns an, wie das Filtern von Paketen unter Linux grundsätzlich funktioniert.
  • Anschließend schreiben wir einen Paketfilter für lynx, dabei erlernen wir nebenbei den Umgang mit den wichtigsten Werkzeugen der Filterwartung.
  • Danach schreiben wir einen Paketfilter für fuzzball, der dem besonderen Umstand Rechnung trägt, dass fuzzball ein Router ist.

7.1 Einführung in Netfilter

Als Paketfilter werden wir das Netfilter -Framework des Linux Kernels verwenden.

  • Technisch gesehen befindet sich der Paketfilter damit im sogenannten Kernelspace, was erhebliche Geschwindigkeitsvorteile mit sich bringt.
  • Gesteuert wird Netfilter von Kommandos aus dem Userspace, zum Beispiel aus einem Terminal heraus.1 Im Kernelspace, also dort wo die Pakete über Interfaces das System betreten, befinden sich auch

1

Als Kernelspace wird der Teil des Betriebssystems bezeichnet, in dem der Kernel, und damit auch die Treiber, laufen. 
  • Er ist aus dem Userspace, wo die Programme der Nutzer laufen, nicht ohne Umwege erreichbar.

Architektur

Abbildung 7.1 Netfilter im Kernelspace, ip6tables im Userspace $ip6tables Userspace NetfilterRegeln sixxs eth1 Kernelspace IPv6

Internet internal die Regeln des Paketfilters.

  • Sie können deshalb direkt angewendet werden.

ip6tables Eines der Kommandos zum Verwalten und Anzeigen der Netfilter-Regeln ist ip6tables.

  • Es lädt die Netfilter-Regeln aus dem Kernel herunter, modifiziert sie entsprechend den mitgegebenen Parametern, und lädt sie dann wieder in den Kernel hinein.

Der Ablauf ist in Abbildung 7.1 dargestellt. Regeln Wenn man Pakete filtert, möchte man bestimmte Gruppen von Paketen erkennen, um ihnen eine definierte Behandlung zukommen zu lassen.

  • Und sei es nur, um sie wegen ihrer Gefährlichkeit oder Unerwünschtheit zu verwerfen.
  • Derartige Pakete erkennt Netfilter anhand von Regeln.
  • In einer Regeln sind die Kriterien festgelegt, denen ein Paket genügen muss, um von der Regel erfasst zu werden.

Chains Gruppen von Regeln organisiert Netfilter in Regelketten, den sogenannten Chains.

  • Dabei gibt es eingebaute Chains, beispielsweise INPUT, FORWARD und OUTPUT, aber auch nutzerdefinierte Chains.

Tabellen Die Chains wiederum werden in Tabellen zusammengefasst, daher auch der Name ip6tables des entsprechenden Werkzeugs.

  • Sofern nicht anders angegeben, nutzen wir die Tabelle filter.
  • Bei der Nutzung von ip6tables wird diese Tabelle automatisch gewählt, darum verzichten wir bei der Definition von Regeln oft auf die explizite Angabe des Tabellennamens.

Chains der filter-Tabelle Pakete die durch die filter-Tabelle laufen, passieren eine der bereits vordefinierten Chains.

  • Das betrifft sowohl Pakete für die das System nur ein Zwischenstopp ist, als auch Pakete

INPUT FORWARD Lokaler Prozess OUTPUT Netfilter

Abbildung 7.2 Die NetfilterChains der Tabelle filter die an das System selbst gerichtet sind oder von dort stammen.

  • Pakete für das System landen dann üblicherweise in einem lokalen Prozess oder einem Socket.
  • Darunter können wir uns einen Dienst vorstellen, zum Beispiel einen DNSoder Webserver.
  • Die eingebauten Chains der filter-Tabelle sind:

INPUT Pakete die für einen lokalen Prozess oder Socket bestimmt sind, gehen durch diese Chain. OUTPUT Pakete die von einem lokalen Prozess oder Socket kommen, werden durch diese Chain geschickt. FORWARD Pakete die auf einem Interface eintreffen, und das System sogleich wieder verlassen, passieren diese Chain. Das trifft auch auf Pakete zu, die das System auf dem gleichen Interface verlassen, auf dem sie gekommen sind. Die Chains der filter-Tabelle sind in auch Abbildung 7.2 dargestellt. Die filter-Tabelle wird nur dazu genutzt, Pakete zu erkennen und über ihr Schicksal zu entscheiden.

  • In der filter-Tabelle können Pakete nicht verändert werden.

Deshalb sei hier auch die Tabelle mangle erwähnt.

  • Sie erlaubt nämlich die Modifikation von Paketen.
  • Damit stellt sie ein sehr mächtiges Werkzeug im Netfilter-Framework dar.
  • Unter IPv4

nutzt man die mangle-Tabelle zur Implementierung von SNAT und PAT. Chains der mangle-Tabelle

Abbildung 7.3 Nutzerdefinierte Chain innerhalb einer Netfilter-Chain Netfilter-Chain Nutzerdefinierte Chain RegelRegel1 2 Regel A Regel B Regel C Regel 3 Zusätzlich zur INPUT-, OUTPUT- und FORWARD-Chain enthält die mangle-Tabelle auch folgende Chains: PREROUTING Hier gehen alle Pakete durch, die über ein Interface eingetroffen sind.

  • Diese können in der Chain verändert werden, noch bevor die Routingentscheidung getroffen wurde.

POSTROUTING Kurz bevor Pakete das System verlassen, werden sie durch diese Chain geschickt.

  • Auch hier ist wieder eine Veränderung möglich.
  • Möchte man SNAT nutzen, wäre dies der richtige Ort um die Quelladresse zu manipulieren.

Beispiel Abbildung 7.3 zeigt die Regeln 1 bis 3 einer Netfilter-Chain und die Regeln A bis C einer nutzerdefinierten Chain. Die Position jeder einzelnen Regel oder Chain ist entscheidend für die Leistungsfähigkeit und die Sicherheit des Paketfilters. Regeln werden stets in der Reihenfolge ihres Auftretens in einer Tabelle abgearbeitet.

  • Die nutzerdefinierte Chain aus der Abbildung 7.3 ist zwischen den Regeln 2 und 3 der NetfilterChain positioniert, somit lautet die endgültige Reihenfolge der Regeln:

• Regel 1 • Regel 2 • Regel A • Regel B • Regel C • Regel 3

7.1 Einführung in Netfilter

Zu filternde Pakete werden gegen die Regeln geprüft, bis eine der Regeln zutrifft.

  • Hat eine Regel dem Paket ein abschließendes Schicksal bescheinigt, werden die folgenden Regeln nicht mehr durchlaufen.
  • Das Verfahren wird auch First Match genannt.
  • Durch die geschickte Positionierung der Regeln lässt sich ein effizienter Paketfilter erstellen.

Nachdem ein Paket eine Chain der filter-Tabelle durchlaufen hat, sollte sein weiteres Schicksal feststehen.

  • Nun kann es vorkommen, dass keine der Regeln in der Chain auf das Paket angewendet werden konnte.
  • Auch besteht nicht die Verpflichtung, überhaupt Regeln in eine Chain einzupflegen.
  • Und so tritt gelegentlich der Fall ein, dass die sogenannte Default Policy der Chain greifen muss.
  • Die Default Policy einer Chain legt fest, wie mit Paketen zu verfahren ist, die am Ende der Chain angekommen sind.

Die typischen Default Policies sind: ACCEPT Das Paket wird zugelassen. DROP Das Paket wird verworfen. Neben den Kriterien, nach denen ein Paket erkannt wird, definieren die Regeln auch, was bei einem Treffer passieren soll. Im Netfilter-Jargon spricht man von einem Target, und meint damit das weitere Schicksal des betroffenen Paketes.

  • Zwei der eingebauten Targets, und zwar ACCEPT und DROP, haben wir bei den Default Policies schon kennengelernt.
  • Es existieren noch weitere Targets:

First Match Default Policies Targets RETURN Die aktuelle Chain wird verlassen.

  • Von einer nutzerdefinierte Chain springt man hiermit zurück in die Netfilter-Chain.
  • Befindet sich die Regel, welche dieses Target nutzt, bereits in einer Netfilter-Chain, dann wird die Default Policy angewendet.

REJECT Das Paket wird verworfen, die Quelle erhält eine Fehlermeldung.

  • Die Fehlermeldung wird als ICMPv6-Nachricht

Nutzerdefinierte Chains als Targets Connection Tracking LOG TOS QUEUE,formuliert.

  • Eine Ausnahme kann bei TCP-Paketen konfiguriert werden, dort ist auch ein Verbindungsabbruch mit TCP-Reset einstellbar.

Der Kernel schreibt eine Zeile, mit den wichtigsten Header-Informationen des Paketes, in das Systemlog.

  • Dies ist ein besonderes Target, denn es beendet das Filtern nicht.
  • Der Filter fährt bei der nächsten Regel fort.

Das Feld Traffic Class im IPv6-Header wird mit einem zu definierenden Wert überschrieben.

  • Da hier eine Veränderung des Paketes stattfindet, ist dieses Target nur in der mangle-Tabelle erlaubt.

NFQUEUE Das Paket wird in den Userspace befördert, wo es von einem Prozess verarbeitet werden kann.

  • Das Target wird genutzt um aufwändige Analysen durchzuführen, die im Kernelspace wegen ihrer Komplexität nicht gut aufgehoben wären.

Alternativ kann als Target auch eine nutzerdefinierte Chain angegeben werden.

  • Die dadurch gewonnene Flexibilität ist enorm.
  • So kann man verdächtige Pakete durch eine Chain mit besonders strengen Regeln schicken, oder vertraute Adressbereiche an langsamen Chains vorbeischleusen.
  • Wir werden diese Funktion später nutzen, um potentiell gefährliche Protokolle in speziellen Chains zu entschärfen.

Das Netfilter-Framework unterstützt Connection Tracking, ein Feature mit dem sich Stateful Packet Inspection (SPI) realisieren lässt.

  • Das heißt, wir können unterschiedliche Regeln auf Pakete anwenden, abhängig davon, ob sie eine neue oder eine bestehende Verbindung repräsentieren.
  • Damit wird ein Kompromiss möglich, der es erlaubt neue Verbindungen mit aufwändigen Regeln zu bearbeiten.
  • Trotzdem werden bestehende Verbindungen nicht negativ beeinflusst, da wir die entsprechenden Pakete zügig passieren lassen können. Über jede Verbindung wird vom Connection Tracking anhand eines Datensatzes Buch geführt.
  • Dieser besteht aus dem Netzwerkprotokoll (IPv6), der Quell- und Zieladresse, dem Upper

Layer Protocol und zusätzlichen Daten des Upper Layer Protocol. Die zusätzlichen Daten des Upper Layer Protocols sind bei TCP die Portnummern von Quelle und Ziel.

  • Gleichzeitig bietet die TCP-Statemachine Netfilter weitere Anhaltspunkte für das Connection Tracking.2 Bei UDP stehen nur die Portnummern zur Verfügung, da es sich um ein verbindungsloses Protokoll handelt.

Wenn eine Verbindung keine zusätzlichen Daten bereitstellt, wird eine Pseudo-Verbindung angenommen.

  • Sie basiert auf den wenigen vorhandenen Daten des Datensatzes der Verbindung.
  • Dann arbeitet die Plausibilitätsprüfung für solche Verbindungen mit vordefinierten Ablaufzeiten für Pakete.
  • Bleiben passende Pakete während eines gewissen Zeitraums aus, gilt die Verbindung als beendet.

Das Connection Tracking des Netfilter-Frameworks unterscheidet zwischen zugehörigen und verwandten Paketen.

  • Pakete die einer Verbindung zugehörig sind, dienen dem Austausch von Daten in der Verbindung.
  • Es handelt sich um jene Pakete, die zwischen den beteiligten Nodes hin und her wandern.

Verwandte Pakete hingegen sind jene Pakete, die zwar einer Verbindung zugeordnet werden können, dieser aber nicht direkt angehören.

  • Damit sind hauptsächlich ICMPv6-Fehlermeldungen gemeint, ohne die eine Verbindung häufig nicht zustande kommen kann.
  • Verwandte Pakete sind daher ebenso wichtig für eine Verbindung wie die zugehörigen Pakete.

Die verschiedenen Zustände einer Verbindung lassen sich bequem in den Netfilter-Regeln abfragen.

  • Ein Paket kann also nicht nur nach seiner Herkunft, seinen Eigenschaften und seinen Header-Feldern bewertet werden, sondern auch danach, in welchem Zusammenhang es zu bereits behandelten Paketen steht.
  • Die wichtigsten Zustände lauten:

2

Die TCP-Statemachine liefert detaillierte Informationen über den aktuellen Zustand einer TCP-Verbindung. 
  • Gerade bei Verbindungen, welche noch nicht vollständig ausgehandelt sind, erleichtern diese Informationen die Bewertung der Plausibilität eintreffender Pakete.

Connection Tracking mit TCP und UDP Connection Tracking mit anderen Protokollen Verwandte Pakete Zustände im Connection Tracking

Abbildung 7.4 Beispiel für die Zustände des Connection Trackings Host A Router 1 3 NEW UDP-Datagramm ESTABLISHED UDP-Datagramm RELATED ICMPv6 Parameter Problem Host2 B Beispiel Connection Tracking NEW Mit diesem Paket würde eine neue Verbindung im Connection Tracking geführt werden.

  • Es repräsentiert die erste Kontaktaufnahme durch, oder mit, einem anderen Node.

ESTABLISHED Das Paket gehört zu einer bestehenden Verbindung. RELATED Das Paket ist mit einer bestehenden Verbindung verwandt und für das Funktionieren dieser wahrscheinlich wichtig.

  • Das Auftreten des Paketes wurde vom Connection Tracking bereits erwartet.

INVALID Das Paket ist ungültig.

  • Es wurde entweder nicht erwartet, oder es passt nicht zu der Verbindung, in der es auftrat.
  • Falsch gesetzte Flags in TCP-Segmenten führen ebenfalls zu diesem Zustand.

UNTRACKED Das Paket wird vom Connection Tracking ignoriert.

  • Diesen Zustand muss der Administrator des Paketfilters manuell vergeben, es findet nur in Sonderfällen oder bei der Fehlersuche Anwendung.

Das Beispiel aus Abbildung 7.4 verdeutlicht die Zustände des Connection Trackings.

  • Host A und Host B kommunizieren über den gemeinsamen Router.
  • Auf dem Router läuft ein Linux-Kernel mit Netfilter.
  • Das erste Paket, das der Router sieht, ist ein UDP-Datagramm von Host A an Host B.
  • Da das Connection Tracking auf dem Router dieses Paket keiner bestehenden

Verbindung zuordnen kann, erstellt er eine neue Pseudo-Verbindung.

  • Das Paket hat den Zustand NEW.
  • Kurz darauf trifft ein Antwortpaket von Host B ein.
  • Das Connection Tracking kann das Paket der eben erstellten Verbindung zuordnen und versieht das Paket daher mit dem Zustand ESTABLISHED.

Leider konnte der Host A das Paket nicht verarbeiten, der Grund könnte zum Beispiel ein unbekannter Parameter in einem Extension Header gewesen sein.

  • Der Host A antwortet mit der ICMPv6-Fehlermeldung Parameter Problem.
  • Auf dem Router erkennt das Connection Tracking, dass es sich hierbei um ein verwandtes Paket handelt und ordnet es der bestehenden Verbindung zu.
  • Es erhält den Zustand RELATED.

7.2 Host-Paketfilter

Nach der Theorie zu Netfilter werden wir uns nun wieder der Praxis widmen.

  • Mit dem Kommando ip6tables können wir, wir erinnern uns, die Netfilter-Regeln verändern.

Genau das werden wir jetzt auf lynx ausprobieren.

  • Wir schreiben uns einen Paketfilter für lynx.
  • Nicht nur um uns mit den Parametern von ip6tables vertraut zu machen, sondern auch um lynx zu schützen.
  • Dabei sind im Workshop mehrere Varianten des gleichen Kommandos angegeben, eine Lang- und eine Kurzform.
  • Es reicht natürlich, nur eine der beiden Varianten einzugeben.
  • Die Kürzere ist schneller getippt, die Längere hilft gerade Anfängern zu verstehen, welche Bedeutung die Parameter haben.

Der erste Schritt beim Erstellen eines neuen Paketfilters ist das Beseitigen von Altlasten.

  • Alle Regeln der Netfilter-Chains müssen gelöscht werden, damit sie nicht mit den neuen Regeln in Konflikt treten.
  • Im Netfilter-Jargon spricht man vom sogenannten flushen der Chains.
  • Für jede der relevanten Tabellen muss ein eigener Flush durchgeführt werden.

Die Kommandos lauten: ip6tables benutzen Regeln in Netfilter-Chains löschen

root@lynx :~# ip6tables -- flush -- table filter
root@lynx :~# ip6tables -- flush -- table mangle

Alternative Kurzformen

root@lynx :~# ip6tables -F
root@lynx :~# ip6tables -F -t mangle Alle nutzerdefinierten Chains löschen Sowohl in der Lang- als auch in der Kurzform können wir uns die Angabe der Tabelle filter sparen. 
  • Bei fehlender Angabe geht ip6tables immer davon aus, dass wir die Tabelle filter meinen.

Wir haben die Tabellen erfolgreich von allen Regeln befreit. Was jetzt noch fehlt, ist das Löschen von nutzerdefinierten Chains, die vielleicht noch in den Netfilter-Chains der Tabellen eingehängt sind.

Die Kommandos lauten:

root@lynx :~# ip6tables -- delete - chain -- table filter
root@lynx :~# ip6tables -- delete - chain -- table mangle Alternative Kurzformen:
root@lynx :~# ip6tables -X
root@lynx :~# ip6tables -X -t mangle Regeln auflisten Vom Erfolg unserer Löschaktionen können wir uns überzeugen, indem wir ip6tables mit dem Parameter zur Auflistung der Regeln aufrufen. 
  • Es sollten keine Regeln angezeigt werden.
  • Das Kommando lautet:
root@lynx :~# ip6tables -- list
Chain INPUT ( policy ACCEPT )
target
 prot opt source
Chain FORWARD ( policy ACCEPT )
target
 prot opt source
Chain OUTPUT ( policy ACCEPT )
target
 prot opt source
destination
destination
destination Alternative Kurzform:
root@lynx :~# ip6tables -L

7.2 Host-Paketfilter

Wir sehen die Chains INPUT, FORWARD und OUTPUT ohne Regeln.

  • Die Spalten target, prot (Protokoll), opt (Optionen), source und destination sind jeweils leer.

Eine Sache jedoch fällt auf: Die Default Policies sind alle auf das Target ACCEPT eingestellt.

  • Damit würde der Paketfilter alle Pakete, die nicht von einer Regel betroffen sind, akzeptieren.

Das Verfahren wird auch Blacklisting genannt, da man explizite Regeln für unerwünschte Pakete definieren muss.

  • Für die Chains INPUT und FORWARD werden wir aber Whitelisting verwenden.
  • Das heißt, eingehende Pakete müssen von einer unserer Regeln erfasst und für unschädlich befunden werden.

Andernfalls sollen sie verworfen werden.

  • Die Default Policies der betroffen Chains werden wir jetzt auf das Target DROP einstellen.

Die Kommandos lauten:

root@lynx :~# ip6tables -- policy INPUT DROP
root@lynx :~# ip6tables -- policy FORWARD DROP
Defaultsetzen
Policy Alternative Kurzformen:
root@lynx :~# ip6tables -P INPUT DROP
root@lynx :~# ip6tables -P FORWARD DROP Wir listen die Regeln wieder auf, um uns vom Erfolg der Maßnahme zu überzeugen:
root@lynx :~# ip6tables -- list
Chain INPUT ( policy DROP )
target
 prot opt source
Chain FORWARD ( policy DROP )
target
 prot opt source
destination
destination Wenn man einen Paketfilter, so wie wir, Schritt für Schritt aufbaut, dann möchte man die Regeln nach und nach hinten anfügen. 
  • Bei ip6tables wird dann von append gesprochen.
  • Eine Regel für ein Paket soll nicht nur das Paket erfassen, sondern auch eine Entscheidung über sein weiteres Schicksal treffen.

Diese Entscheidung wird mit einem Sprung zu einem Target realisiert.

  • Da wir auf lynx keine Pakete weiterleiten werden, es handelt sich schließlich nicht um einen Router, fügen wir eine Regel hinzufügen, Sprünge definieren

Regeln184 löschen Regeln an die FORWARD-Chain an, die alle Pakete verwirft. Das Verwerfen geschieht durch einen Sprung in das DROPTarget. Das Kommando lautet:

root@lynx :~# ip6tables -- append FORWARD -- jump DROP Alternative Kurzform:
root@lynx :~# ip6tables -A FORWARD -j DROP Ein kurzer Blick auf die FORWARD-Chain zeigt, dass die Regel wie erwartet angefügt wurde:
root@lynx :~# ip6tables -- list FORWARD Chain FORWARD ( policy DROP )
target
 prot opt source
 destination
DROP
 all
 anywhere
 anywhere Übrigens, diese Regel wäre natürlich nicht nötig gewesen, denn die Default Policy der FORWARD-Chain hätte schon für einen Sprung ins DROP-Target gesorgt. 
  • Wir haben diese Regel nur zu Übungszwecken eingefügt.

Belasten wir Netfilter lieber nicht mit unnötigen Regeln, und löschen die eben angefügte Regel aus der FORWARD-Chain wieder.

  • Das Löschen von Regeln verläuft ähnlich dem hinzufügen.
  • Die Regel wird mit allen ihren Parametern übergeben, auch mit dem ursprünglichen Sprungparameter.
  • Entscheidend ist der Aufruf des Parameters delete anstatt append.

Das Kommando lautet:

root@lynx :~# ip6tables -- delete FORWARD -- jump DROP Alternative Kurzform:
root@lynx :~# ip6tables -D FORWARD -j DROP Ein erneuter Blick auf die FORWARD-Chain zeigt, dass die Regel entfernt wurde:
root@lynx :~# ip6tables -- list FORWARD Chain FORWARD ( policy DROP )

target

prot opt source destination Im Moment erlauben wir keine eingehenden Pakete, auch nicht jene vom Loopback Interface. 
  • Ein kleiner Test zeigt diesen offensichtlichen Missstand auf:

Parameter Interface

user@lynx :~ $ ping6 -c 3 ::1
PING ::1 (::1) 56 data bytes
--- ::1 ping statistics -- 3 packets transmitted ,
 received , 1
 % packet loss ,  time 2 8 ms 

Datenverkehr auf dem Loopback Interface verlässt den Node per Definition nie.

  • Es gibt eigentlich keine Gründe, wieso wir ihn verbieten sollten.
  • Daher erlauben wir alle Pakete, sofern sie über das Loopback-Interface hinein oder hinaus wollen.
  • Die Parameter unterscheiden sich je nach betroffener Chain, in der INPUT-Chain benutzen wir den Parameter für das Eingangs-Interface, in der OUTPUT-Chain den für das Ausgangs-Interface.
  • In der FORWARD-Chain könnten wir, wenn wir wollten, sogar beide Parameter gleichzeitig benutzen.

Die Kommandos lauten:

root@lynx :~# ip6tables -- append INPUT --in - interface lo ' -- jump ACCEPT
root@lynx :~# ip6tables -- append OUTPUT --out - interface ' lo -- jump ACCEPT Alternative Kurzformen:
root@lynx :~# ip6tables -A INPUT -i lo -j ACCEPT
root@lynx :~# ip6tables -A OUTPUT -o lo -j ACCEPT Jetzt klappt es auch mit dem Echo Request an die Loopback Address:
user@lynx :~ $ ping6 -c 3 ::1
PING ::1 (::1) 56 data bytes
64 bytes from ::1: icmp_seq =1 ttl =64 time = .123 ms

3 packets transmitted , 3 received , % packet loss , time  2 ms
Nutzerdefinierte Chain erstellen

Wenn man es ganz genau nimmt, war der Eintrag in der OUTPUT-Chain nicht notwendig, denn diese springt per Default Policy in das Target ACCEPT.

  • Um uns die Möglichkeit offen zu halten, die Default Policy der OUTPUT-Chain noch zu ändern, tragen wir diese Regel dennoch ein.
  • Die Regeln sind so allgemein gehalten, dass sie Netfilter nicht wahrnehmbar belasten.

Ein sehr mächtiges Werkzeug von Netfilter sind die nutzerdefinierten Chains.

  • Zu Übungszwecken werden wir gleich zwei von ihnen erstellen.

Die Kommandos lauten:

root@lynx :~# ip6tables --new - chain allwatchedover
root@lynx :~# ip6tables --new - chain lovinggrace Nutzerdefinierte Chain löschen Nutzerdefinierte Chain umbenennen Alternative Kurzformen:
root@lynx :~# ip6tables -N allwatchedover
root@lynx :~# ip6tables -N lovinggrace Für liebevolle Gunst ist in der objektiven Welt eines Paketfilters kein Platz, die Chain lovinggrace soll daher wieder gelöscht werden.

Das Kommando lautet:

root@lynx :~# ip6tables -- delete - chain lovinggrace Alternative Kurzform:
root@lynx :~# ip6tables -X lovinggrace Auch der Name der Chain allwatchedover ist nicht perfekt.

Denn sie soll später dazu dienen, Pakete die in Ungnade gefallen sind, vor dem Verwerfen noch im Systemlog zu notieren. Passender wäre wohl ein Name wie trashlog, daher benennen wir die Chain um. Das Kommando lautet:

root@lynx :~# ip6tables -- rename - chain allwatchedover trashlog

7.2 Host-Paketfilter

Alternative Kurzform:

root@lynx :~# ip6tables -E allwatchedover trashlog Die trashlog-Chain wird allerlei unerwünschten Paketen als Target dienen. 
  • Ihre wichtigste Aufgabe ist daher das Verwerfen der Pakete.
  • Mit einer Default Policy lässt sich diese Aufgabe nicht erledigen, da nutzerdefinierte Chains keine Default Policies besitzen dürfen.
  • Es bleibt also nur der Sprung zum DROP-Target aus der Chain selbst heraus.
  • Gerade wenn ein Paketfilter noch nicht ausgereift ist, kann es sehr hilfreich sein, mitzuschreiben welche Pakete als unerwünscht erkannt wurden.
  • Häufig übersieht man eine Kleinigkeit und verwirft fälschlicherweise legitime Pakete.
  • Vor dem endgültigen Verwerfen werden wir die Pakete daher, versehen mit einem Hinweis auf die trashlog-Chain, in das Systemlog schreiben lassen.
  • Weil Netfilter Meldungen im Systemlog standardmäßig mit dem Loglevel warning versieht, müssen wir auch hier eine Anpassung vornehmen.
  • Warnungen sind für wichtigere Dinge reserviert, es reicht wenn wir von unerwünschten Paketen Notiz nehmen.

Nutzerdefinierte Chain füllen Die Kommandos lauten:

root@lynx :~# ip6tables -- append trashlog -- jump LOG --log - level notice --log - prefix " TRASHLOG : "
root@lynx :~# ip6tables -- append trashlog -- jump DROP Alternative Kurzformen:
root@lynx :~# ip6tables -A trashlog -j LOG --log - level notice --log - prefix " TRASHLOG : "
root@lynx :~# ip6tables -A trashlog -j DROP Übrigens, mit log-level und log-prefix sind uns soeben die ersten Parameter begegnet, von denen es keine Kurzform gibt.

Unsere nutzerdefinierte Chain lassen wir uns wieder von ip6tables anzeigen:

root@lynx :~# ip6tables -- list trashlog
Chain trashlog ( references )
target
 prot opt source
 destination
LOG
 all
 anywhere
 anywhere  LOG level notice prefix ’ TRASHLOG : ’
DROP
 all
 anywhere
 anywhere
Connection
Tracking Der Auflistung können wir gleich mehrere Informationen entnehmen. 
  • Zum einen sehen wir, das die Chain noch nicht von einer Regel als Target genutzt wird (0 references).
  • Zum anderen sehen wir hier auch, mit welchem Loglevel die Meldungen in das Systemlog geschrieben werden, nämlich notice.
  • Dem aufmerksamen Betrachter wird auch nicht entgangen sein, dass für diese Chain keine Default Policy angezeigt wird.
  • Denn nutzerdefinierte Chains dürfen bekanntlich keine Default Policy besitzen.

Das Connection Tracking wird als Erweiterung, als sogenannte Match Extension, nachgeladen.

  • Wenn eine Erweiterung geladen wird, sind zusätzliche Parameter nutzbar, die von der Erweiterung eingebracht werden.
  • Wir werden die Erweiterung Connection Tracking häufig benutzen.
  • Zunächst sollen alle eingehenden Pakete, die vom Connection Tracking als ungültig erkannt wurden, in die nutzerdefinierte Chain trashlog springen.

Dort werden sie im Systemlog vermerkt und dann verworfen. Das Kommando lautet:

root@lynx :~# ip6tables -- append INPUT -- match conntrack -- ctstate INVALID -- jump trashlog Alternative Kurzform:
root@lynx :~# ip6tables -A INPUT -m conntrack -- ctstate INVALID -j trashlog Bestehende Verbindungen und ihre verwandten Pakete sollen den Paketfilter ungehindert passieren können. 
  • Daher erlauben wir alle eingehenden Pakete die das Connection Tracking einer bestehenden Verbindung zuordnen konnte.

Das Kommando lautet:

root@lynx :~# ip6tables -- append INPUT -- match conntrack -- ctstate ESTABLISHED , RELATED -- jump ACCEPT

7.2 Host-Paketfilter

Alternative Kurzform:

root@lynx :~# ip6tables -A INPUT -m conntrack -- ctstate ' ESTABLISHED , RELATED -j ACCEPT Mit dem Parameter protocol, in der Kurzform schlicht p, lässt sich das Protokoll definieren, auf das eine Regel zutreffen muss. 
  • Das Protokoll kann als Protokollnummer, so wie sie im IPv6-Header auftaucht, angegeben werden.
  • Alternativ kann auch die ausgeschriebene Variante genutzt werden.
  • Die gängigsten Protokolle im Überblick:
tcp
Transmission Control Protocol
udp
User Datagram Protocol
ipv6
IPv6-in-IPv6
icmpv6
Internet Control Message Protocol v6

Wenn in einer Regel das Protokoll spezifiziert wird, dann werden weitere Parameter nutzbar.

  • Bei ICMPv6 wird unter anderem der Parameter icmpv6-type nutzbar.
  • Ihm kann die Typnummer einer ICMPv6 Message als Zahl oder ausgeschriebene Variante übergeben werden.
  • Die ausgeschriebenen Typen, manche von ihnen sogar mit alternativer Schreibweise, sind:

• destination-unreachable • no-route • communication-prohibited • address-unreachable • port-unreachable • packet-too-big • time-exceeded, ttl-exceeded • ttl-zero-during-transit • ttl-zero-during-reassembly • parameter-problem • bad-header • unknown-header-type Parameter Protokoll • unknown-option • echo-request, ping • echo-reply, pong • router-solicitation • router-advertisement • neighbour-solicitation, neighbor-solicitation • neighbour-advertisement, neighbor-advertisement • redirect NDP und SLAAC erlauben

Wie Sie sicher schon bemerkt haben, hat der NetworkManager auf lynx inzwischen seine Konnektivität verloren.

  • Das liegt unter anderem daran, dass ICMPv6 Messages vom Paketfilter noch nicht akzeptiert werden.
  • Wie wir wissen, organisiert sich der Link aber ausschließlich über ICMPv6 Messages.

Wir sollten diese also zügig wieder zulassen, um die Konnektivität zurückzugewinnen.

  • Eine Einschränkung werden wir dennoch vornehmen, wir erlauben nur ICMPv6 Messages, die sowohl vom Hop Limit als auch vom Typ her in die typische Kommunikation des Neighbor Discovery Protocols hineinpassen.

Dazu erstellen wir uns eine nutzerdefinierte Chain namens ndp-slaac, füllen diese mit Regeln, und hängen sie abschließend für alle ICMPv6-Pakete in die INPUT-Chain ein:

root@lynx :~# ip6tables --new - chain ndp - slaac

Eine zusätzliche Erweiterung, sie heißt hl, ist für die Analyse des Hop Limits zuständig.

  • Wir laden sie wie gewohnt mit match nach.

In den ersten Regeln der Chain ndp-slaac erlauben wir NDP:

root@lynx :~# ip6tables -- append ndp - slaac -- protocol  icmpv6 -- icmpv6 - type router - solicitation -- match hl --hl - eq 255 -- jump ACCEPT
root@lynx :~# ip6tables -- append ndp - slaac -- protocol icmpv6 -- icmpv6 - type router - advertisement -- match hl --hl - eq 255 -- jump ACCEPT
root@lynx :~# ip6tables -- append ndp - slaac -- protocol icmpv6 -- icmpv6 - type neighbor - solicitation -- match hl --hl - eq 255 -- jump ACCEPT
root@lynx :~# ip6tables -- append ndp - slaac -- protocol icmpv6 -- icmpv6 - type neighbor - advertisement -- match hl --hl - eq 255 -- jump ACCEPT Auch Umleitungen werden wir akzeptieren:
root@lynx :~# ip6tables -- append ndp - slaac -- protocol icmpv6 -- icmpv6 - type redirect -- match hl --hl - eq 255 -- jump ACCEPT Und natürlich MLDv1 und MLDv2, um die Selbstorganisation des Links nicht zu gefährden:
  1. Typ 13 : Multicast Listener Query ( MLDv1 , MLDv2 )
root@lynx :~# ip6tables -- append ndp - slaac -- protocol icmpv6 -- icmpv6 - type 13 -- match hl --hl - eq 1 -- jump ACCEPT
  1. Typ 131: Multicast Listener Report ( MLDv1 )
root@lynx :~# ip6tables -- append ndp - slaac -- protocol icmpv6 -- icmpv6 - type 131 -- match hl --hl - eq 1 -- jump ACCEPT
  1. Typ 132: Multicast Listener Done ( MLDv1 )
root@lynx :~# ip6tables -- append ndp - slaac -- protocol icmpv6 -- icmpv6 - type 132 -- match hl --hl - eq 1 -- jump ACCEPT
  1. Typ 143: Multicast Listener Report ( MLDv2 )
root@lynx :~# ip6tables -- append ndp - slaac -- protocol icmpv6 -- icmpv6 - type 143 -- match hl --hl - eq 1 -- jump ACCEPT Zuletzt wird die nutzerdefinierte Chain noch in die INPUTChain eingehängt:
root@lynx :~# ip6tables -- append INPUT -- protocol icmpv6 -- jump ndp - slaac Nun sollte der NetworkManager wieder in der Lage sein, Konnektivität herzustellen.

Aus Platzgründen wird hier auf eine Angabe der alternativen Kurzform verzichtet.

Parameter Quelle und Ziel Die wohl wichtigsten Parameter eines jeden Paketfilters sind Quell- und Zieladressen von Paketen.

  • Dabei ist die Angabe von einzelnen Adressen, von Listen (mit Kommata getrennte Adressen) oder Präfixen möglich.
  • Die Leistungsfähigkeit des Paketfilters hängt stark davon ab, wie gut die Adressen aggregiert sind.
  • Das heißt, immer wenn es möglich ist, mehrere Adressen als Präfix auszudrücken, sollte dies geschehen.

Um die Fehlersuche am internen Link zu erleichtern, erlauben wir Echo Request aus dem Präfix für Link-local Addresses. Das Kommando lautet:

root@lynx :~# ip6tables -- append INPUT -- source fe8 ::/1 -- destination fe8 ::/1 -- protocol icmpv6 -- icmpv6 - type echo - request -- match conntrack -- ctstate NEW -- jump ACCEPT Alternative Kurzform:
root@lynx :~# ip6tables -A INPUT -s fe8 ::/1 -d fe8 ::/1 -p icmpv6 -- icmpv6 - type echo - request -m conntrack -- ctstate NEW -j ACCEPT
Parameter Port

Wenn wir die Regeln auf ein Upper Layer Protocol anwenden, können wir auch auf die diversen Parameter des jeweiligen Protokolls zugreifen.

  • Beispielhaft sei hier der Parameter zum Filtern von Portnummern erwähnt.
  • Auch hier sind wieder mehrere Angaben möglich.
  • Neben alleinstehenden Portnummern sind auch durch Kommata getrennte Listen, aber auch ganze Portbereiche gültige Werte.
  • Portbereiche werden in der Form Erster-Port:Letzter-Port angegeben.
  • Ausgeschriebene Varianten existieren ebenfalls, die komplette Liste befindet sich in der Datei /etc/services und wird hier aus Platzgründen ausgespart.
  • Wir nutzen den Parameter Port, um auf lynx den Fernwartungsdienst Secure Shell (SSH) für den internen Link freizugeben.

Das Kommando lautet:

root@lynx :~# ip6tables -- append INPUT -- source fe8 ::/1 -- protocol tcp -- destination - port 22 -- match conntrack -- ctstate NEW -- jump ACCEPT

Alternative Kurzform:

root@lynx :~# ip6tables -A INPUT -s fe8 ::/1 -p tcp -- dport 22 -m conntrack -- ctstate NEW -j ACCEPT Die ausgehenden Verbindungen von lynx werden vom Connection Tracking erfasst. 
  • Alle eingehenden Pakete, die zu diesen Verbindungen gehören, werden über die Zustände ESTABLISHED und RELATED ins System hineingelassen.
  • Deshalb sind, sofern man bei dieser großzügigen Konfiguration für ausgehende Verbindungen bleiben möchte, keine weiteren Regeln für die OUTPUT-Chain nötig.

Wir haben jetzt einen funktionierenden Paketfilter auf lynx, der leider nicht von Dauer ist.

  • Denn die Netfilter-Regeln überleben einen Neustart nicht.
  • Das Kommando ip6tables-save kann uns aber weiterhelfen.
  • Es liest alle Regeln aus und gibt sie in einem Format wieder, das für ip6tables lesbar ist:
root@lynx :~# ip6tables - save Q -A INPUT -i lo -j ACCEPT -A INPUT -m conntrack -- ctstate INVALID -j trashlog -A INPUT -m conntrack -- ctstate RELATED , ESTABLISHED -j ACCEPT -A INPUT -p ipv6 - icmp -j ndp - slaac Q
COMMIT Wir leiten die Ausgabe von ip6tables-save in eine Datei um:
root@lynx :~# ip6tables - save > / etc / packetfilter Ausgehende Verbindungen Regeln sichern So stehen uns die Regeln auch nach einem Neustart noch zur Verfügung, wir müssen sie dann nur noch in den Kernel laden.

Die Datei /etc/packetfilter von lynx ist in Anhang C Paketfilter von lynx zu sehen.

Regeln richtig

Es gibt zwei Möglichkeiten, Netfilter nach dem Systemstart laden
wieder mit den vorher definierten Regeln zu versorgen. 
  • Die beliebteste scheint zu sein, die mit ip6tables beginnenden Kommandos in ein Shell-Skript zu schreiben, und dieses auszuführen.
  • Davon soll an dieser Stelle dringend abgeraten werden! Uns ist aus dem Abschnitt 7.1 Einführung in Netfilter bekannt, dass bei jedem Aufruf von ip6tables der gesamte Regelsatz aus dem Kernel heruntergeladen wird.
  • Dann wird der Regelsatz modifiziert, zum Beispiel durch anfügen einer Regel.
  • Der geänderte Regelsatz wird dann wieder in den Kernel geladen.
  • Auch wenn der Vorgang blitzartig vonstatten zu gehen scheint, so stellt er doch eine unnötige Belastung für das System dar.
  • Ein weiterer, viel wichtigerer, Grund gegen das eben beschriebene Vorgehen ist im Herzen des Betriebssystems zu finden: Dem Scheduler.
  • Der Scheduler legt fest, wann ein Prozess Rechenzeit bekommt, und wann ihm zugunsten eines anderen Prozesses Rechenzeit entzogen wird.

Jeder Aufruf von ip6tables ist ein eigener Prozess.

  • Das bedeutet, dass es vorkommen kann, dass der Scheduler einem der vielen ip6tables-Prozesse zu irgendeinem Zeitpunkt Rechenzeit entzieht.
  • Andere Prozesse belegen dann den Prozessor bis ip6tables diesen dann wieder in Beschlag nehmen darf.
  • Während ip6tables pausiert, haben wir einen unfertigen Paketfilter im Kernel, denn es stehen unter Umständen noch Regeln zum Laden aus.
  • Dass ein halbfertiger Paketfilter, auch wenn er nur wenige Millisekunden existiert, keine gute Idee ist, leuchtet ein.

Regeln wiederherstellen Das Kommando ip6tables-restore bietet für das Problem eine Lösung an.

  • Es lädt den gesamten Regelsatz auf einmal in den Kernel, und lässt sich dabei auch nicht unterbrechen.

Wir laden unseren Packetfilter testweise erneut in den Kernel:

root@lynx :~# ip6tables - restore < / etc / packetfilter

Beachten Sie bitte die Richtung in welche die spitze Klammer zeigt.

  • Eine falsch gesetze Klammer wird zu Datenverlust in der Datei /etc/packetfilter führen.

Datei: /etc/rc.local

#!/ bin / sh -e
#
# By default this script does nothing .
ip6tables - restore < / etc / packetfilter
exit

Abbildung 7.5 Skript rc.local

Auf lynx machen wir es uns einfach, indem wir die Wiederherstellung nach dem Systemstart automatisch ausführen.

  • Dazu verändern wir die Datei /etc/rc.local wie in Abbildung 7.5

gezeigt. Als Faustregel gilt: Den Paketfilter mit ip6tables erstellen und modifizieren, anschließend mit ip6tables-save abspeichern. Den Paketfilter im produktiven Betrieb immer mit ip6tablesrestore in den Kernel laden. Wir haben soeben ip6tables im Schnellverfahren kennengelernt.

  • Die vorgestellten Parameter sind nur ein kleiner Teil des riesigen Funktionsumfangs von ip6tables und dem NetfilterFramework.
  • Bitte nehmen Sie sich etwas Zeit, um im Umgang mit den vorgestellten Werkzeugen Handlungssicherheit zu erlangen.
  • Spätestens wenn wir den komplexeren Paketfilter für fuzzball schreiben, wird dies hilfreich sein.
  • Wie so oft hilft ein Studium der Hilfeseiten, abrufbar mit man ip6tables, weiter.

Wiederherstellung nach Systemstart Faustregel Weiterführendes Studium

7.3 Router-Paketfilter

Das Filtern von Paketen auf einem Router stellt eine besondere Herausforderung dar.

  • Auf der einen Seite sollen sich Router, die zwischen zwei kommunizierenden Hosts sitzen, nicht unnötig in die Kommunikation einmischen oder diese gar beeinträchtigen.
  • Auf der anderen Seite möchte man als Betreiber eines Routers nach Möglichkeit keine unerwünschten oder schädlichen Pakete verarbeiten.
  • Darüber hinaus kann ein Router oft nur Vermutungen darüber anstellen, ob ein Paket erwünscht, unerwünscht oder gar schädlich ist.
  • Manchmal lässt Anforderungen

Zonen Zonen und Interfaces sich nicht einmal feststellen, ob ein Paket in einem gewissen Kontext überhaupt Sinn ergibt.

  • Nicht zuletzt deshalb ist es auch umstritten, ob auf einem Router überhaupt Pakete gefiltert werden sollten.
  • Da fuzzball bei uns nicht nur für das reine Routing zuständig ist, sondern auch einen Resolving DNS Server bereitstellt und als NAT64-Gateway fungiert, gibt es guten Grund, einen Paketfilter zu installieren.
  • Der Router ist nämlich zentrale Austauschpunkt für Daten unseres Lern- und Bastelnetzwerkes mit dem IPv6-Internet.
  • Wir werden als schädlich erkannte Pakete grundsätzlich verwerfen und alle anderen überwiegend auf Plausibilität prüfen.
  • Glücklicherweise nimmt uns das Connection Tracking den Großteil der Plausibilitätsprüfungen ab.

Beim Schreiben komplexer Paketfilter verliert man leicht den Überblick.

  • Eine Möglichkeit, dem Vorzubeugen, ist das Arbeiten mit Zonen.
  • Eine Zone ist dann ein Bereich eines Netzwerkes, für den einheitliche Regeln gelten.
  • Auch wir werden mit Zonen arbeiten, um eine einfache Abstraktion vom Konkreten zu erreichen.
  • Dazu definieren wir eine Zone Untrusted, in der sich alle Systeme befinden, die nicht unter unserer Kontrolle stehen.
  • Unter anderem der Teil des IPv6Internets, der sich nicht in unserem Lern- und Bastelnetzwerk abspielt.
  • Alles was am Link internal geschieht, halten wir für vertrauenswürdig, diese Zone trägt daher den Namen Trusted.

Zonengrenzen befinden sich immer an Interfaces, und niemals inmitten eines Links.

  • Zwei oder mehr Zonen können sich daher auch nur innerhalb eines Nodes treffen.
  • In Abbildung

7.6 sind die Zonen zu sehen, in denen sich fuzzball befindet. Der Weg ins IPv6-Internet führt über das Interface sixxs, es zeigt in die Zone Untrusted.

  • Daher sind Pakete die über sixxs ins System gelangen besonders streng zu filtern.
  • Ebenfalls der Zone Untrusted wird das Interface nat64 zugeordnet.
  • Pakete die über dieses Interface in das System gelangen, stammen aus dem IPv4-Internet, welches ebenfalls nicht unter unserer Kontrolle steht.
  • Pakete die über eth1 empfangen werden, kom
Untrusted
IPv6
Internet
IPv4
Internet
sixxs
nat64
eth1
 fuzzball
internal
Trusted

Abbildung 7.6 Zonen von fuzzball

men aus der Zone Trusted, denn sie stammen von Systemen die wir unter Kontrolle haben. Die Zonen lassen sich nicht ohne weiteres auf die eingebauten Chains übertragen.

  • So laufen alle eingehenden Pakete durch die Chain INPUT, unabhängig davon ob sie aus einer Trusted- oder Untrusted-Zone stammen.
  • In den Regeln muss daher das betroffene Interface berücksichtigt werden.
  • Darum ist es manchmal sinnvoll, nutzerdefinierte Chains für eine Zone zu erstellen, und diese abhängig vom Interface einzuhängen.

An anderen Stellen wiederum ist es praktischer, für bestimmte Protokolle nutzerdefinierte Chains anzulegen.

  • Die können dann in allen betroffenen Zonen verwendet werden.
  • Der Paketfilter von fuzzball wird von beiden Techniken Gebrauch machen.

Zonen und Chains Oft müssen Pakete ihre Zone verlassen um ein Ziel in einer anderen Zone zu erreichen.

  • Solche Pakete, die von einer Zone in eine andere befördert werden wollen, sollen ebenfalls vom Paketfilter geprüft werden.
  • Sie passieren die Chain FORWARD.
  • In dieser Chain treffen mehrere Zonen aufeinander.

Um herauszufinden, von welcher Zone in welche andere Zone ein Paket befördert werden möchte, müssen wir auf die betroffenen Interfaces schauen.

  • Ein- und ausgehendes Interface sind in den Regeln der FORWARD-Chain wichtige Parameter.

Zonenübertritte Wir beginnen nun mit dem Aufbau des Paketfilters für fuzzball. Der erste Schritt ist das Entfernen aller möglicherweise bestehenden Regeln: Vorhandene Regeln entfernen

root@fuzzball :~#
ip6tables
-- flush
root@fuzzball :~#
ip6tables
-- flush -- table mangle
root@fuzzball :~#
ip6tables
-- delete - chain
root@fuzzball :~#
ip6tables
-- delete - chain -- table mangle Vom Erfolg der Maßnahme werden wir uns überzeugen:
root@fuzzball :~# ip6tables -- list
Chain INPUT ( policy ACCEPT )
target
 prot opt source
Chain FORWARD ( policy ACCEPT )
target
 prot opt source
Chain OUTPUT ( policy ACCEPT )
target
 prot opt source
destination
destination
destination
Default Policies Wir sehen, dass in den Chains INPUT, FORWARD und OUTPUT keine Regeln existieren.

Wir können also nun dem Aufbau des Paketfilters beginnen.

  • Zuerst legen wir die Default Policies der Chains INPUT und FORWARD fest.
  • Grundsätzlich sollen Pakete verworfen werden.
  • Wir betreiben in diesen Chains also Whitelisting:
root@fuzzball :~# ip6tables -- policy INPUT DROP
root@fuzzball :~# ip6tables -- policy FORWARD DROP Auch hier lassen wir uns das Ergebnis der letzten Kommandos anzeigen:
root@fuzzball :~# ip6tables -- list
Chain INPUT ( policy DROP )
target
 prot opt source
Chain FORWARD ( policy DROP )
target
 prot opt source
destination
destination
Loopback
Interface Die Default Policies verweisen jetzt auf das Target DROP für ein kommentarloses Verwerfen von Paketen.

Das wohl einzige Interface auf fuzzball, welches uneingeschränktes Vertrauen genießt, ist das Loopback Interface.

  • Pakete von und zum Loopback Interface dürfen den Paketfilter ungehindert passieren:
root@fuzzball :~# ip6tables -- append INPUT --in - interface lo -- jump ACCEPT
root@fuzzball :~# ip6tables -- append OUTPUT --out - interface lo -- jump ACCEPT Für Pakete die verworfen werden sollen, aber dennoch von Interesse sein könnten, erstellen wir eine nutzerdefinierte Chain.

Sie dient anderen Regeln als Target.

  • Die Chain schreibt Pakete mit dem Level Notice ins Systemlog, anschließend verwirft sie die Pakete:

Chain für verworfene Pakete

root@fuzzball :~# ip6tables -- new - chain trashlog
root@fuzzball :~# ip6tables -- append trashlog -- jump LOG --log - level notice --log - prefix " TRASHLOG : "
root@fuzzball :~# ip6tables -- append trashlog -- jump DROP Ein kurzer Blick auf die Chain zeigt, ob sie wie gewünscht angelegt wurde:
root@fuzzball :~# ip6tables -- list trashlog
Chain trashlog ( references )
target
 prot opt source
 destination
LOG
 all
 anywhere
 anywhere LOG level notice prefix ’ TRASHLOG : ’
DROP
 all
 anywhere
 anywhere Pakete bestehender Verbindungen und ihre verwandten Pakete sollen den Paketfilter ungehindert passieren. 
  • Die Plausibilitätsprüfung für diese Pakete hat das Connection Tracking bereits erledigt.
  • Wir fügen die entsprechende Regel der INPUTChain hinzu:
root@fuzzball :~# ip6tables -- append INPUT -- match conntrack -- ctstate ESTABLISHED , RELATED -- jump ACCEPT
Connection Tracking

nutzen Eingehende ungültige Pakete, egal aus welcher Zone sie stammen, werden wir verwerfen.

  • Da ungültige Pakete manchmal auf Fehlkonfigurationen hinweisen, lassen wir sie zur Zwecken der Fehlerbehebung ins Systemlog schreiben:

Ungültige Pakete verwerfen

root@fuzzball :~# ip6tables -- append INPUT -- match conntrack -- ctstate INVALID -- jump trashlog Ohne Angabe eines Interfaces, trifft diese Regel auf alle eingehenden Pakete, und damit auch auf alle Zonen, zu.

Extension Header Der Routing Header Typ 0 wurde als gefährlich eingestuft und gilt als veraltet.

  • Auch andere Extension Header könnten, abhängig von der Reihenfolge ihres Auftretens und ihrer Parameter, in Zukunft unerwünscht sein.
  • Um den Überblick nicht zu verlieren, erstellen wir eine nutzerdefinierte Chain namens bad-eh, in der alle unerwünschten Extension Header benannt werden.
  • Der Routing Header Typ 0 wird mit einer passenden Regel verworfen:
root@fuzzball :~# ip6tables -- new - chain bad - eh
root@fuzzball :~# ip6tables -- append bad - eh -- match rt --rt - type -- jump DROP Andere Regeln können bei Bedarf später hinzugefügt werden.

Damit die Regel wirksam wird, hängen wir die eben erstellte Chain in die INPUT-Chain ein:

root@fuzzball :~# ip6tables -- append INPUT -- jump bad - eh
Neighbor Discovery

Sowohl auf den Links der Trusted-Zone, als auch auf den Links der Untrusted-Zone, benötigen wir das Neighbor Discovery Protocol für die Selbstorganisation des Links.

  • Dazu schreiben wir uns eine nutzerdefinierte Chain ndp-minimal mit den nötigen Regeln für NDP:
root@fuzzball :~# ip6tables -- new - chain ndp - minimal
root@fuzzball :~# ip6tables -- append ndp - minimal -- protocol icmpv6 -- icmpv6 - type neighbor - solicitation -- match hl --hl - eq 255 -- jump ACCEPT
root@fuzzball :~# ip6tables -- append ndp - minimal -- protocol icmpv6 -- icmpv6 - type neighbor - advertisement -- match hl --hl - eq 255 -- jump ACCEPT Auch auf das Umleitungen von Pakete lassen wir uns ein:
root@fuzzball :~# ip6tables -- append ndp - minimal -- protocol icmpv6 -- icmpv6 - type redirect -- match hl --hl - eq 255 -- jump ACCEPT MLDv1 und MLDv2 sind vorgeschrieben und notwendig, darum erlauben wir die beiden Protokolle ebenfalls:
  1. Typ 13 : Multicast Listener Query ( MLDv1 , MLDv2 )
root@fuzzball :~# ip6tables -- append ndp - minimal -- protocol icmpv6 -- icmpv6 - type 13 -- match hl --hl - eq 1 -- jump ACCEPT
  1. Typ 131: Multicast Listener Report ( MLDv1 )
root@fuzzball :~# ip6tables -- append ndp - minimal -- protocol icmpv6 -- icmpv6 - type 131 -- match hl --hl - eq 1 -- jump ACCEPT
  1. Typ 132: Multicast Listener Done ( MLDv1 )
root@fuzzball :~# ip6tables -- append ndp - minimal -- protocol icmpv6 -- icmpv6 - type 132 -- match hl --hl - eq 1 -- jump ACCEPT
  1. Typ 143: Multicast Listener Report ( MLDv2 )
root@fuzzball :~# ip6tables -- append ndp - minimal -- protocol icmpv6 -- icmpv6 - type 143 -- match hl --hl - eq 1 -- jump ACCEPT Danach hängen wir die Chain ndp-minimal in die INPUT-Chain ein, jedoch nur für eintreffende ICMPv6-Pakete:
root@fuzzball :~# ip6tables -- append INPUT -- protocol icmpv6 -- jump ndp - minimal Auch von dieser Regel sind wieder alle Zonen betroffen.

Als nächstes werden wir eingehende Router Solicitations von der Trusted-Zone erlauben, denn für diese ist fuzzball der zuständige Router:

Router Solicitations
root@fuzzball :~# ip6tables -- append INPUT --in - interface eth1 -- protocol icmpv6 -- icmpv6 - type router - solicitation -- match hl --hl - eq 255 -- jump ACCEPT In den Router Advertisements verteilen wir die Adresse des Resolving DNS Servers. 
  • Dessen Dienste sollten wir für die Trusted-Zone ebenfalls freigeben:
ResolvingServer DNS
root@fuzzball :~# ip6tables -- append INPUT --in - interface eth1 -- protocol udp -- destination - port 53 -- match conntrack -- ctstate NEW -- jump ACCEPT
root@fuzzball :~# ip6tables -- append INPUT --in - interface eth1 -- protocol tcp -- destination - port 53 -- match conntrack -- ctstate NEW -- jump ACCEPT Widmen wir uns nun der Chain FORWARD. 
  • Durch sie laufen alle Pakete hindurch, die von einem Interface zu einem anderen müssen.
  • In unserem Fall bedeutet das auch immer einen Forwarding filtern
Connection Tracking

Zonenwechsel von Trusted zu Untrusted oder umgekehrt.

  • Wäre fuzzball in weiteren Zonen vertreten, dann würde durch diese Chain auch der Verkehr zwischen den anderen Zonen laufen.

Auch für weitergeleitete Pakete kann Netfilter ein Connection Tracking durchführen.

  • Das nimmt uns eine Menge Arbeit beim definieren von Regeln ab.
  • Gleichzeitig erhöht ein frühzeitiges Durchlassen von unschädlichen Paketen die Effizienz der Regelabarbeitung.
  • Bestehende Verbindungen und allen damit verwandten Paketen erlauben wir deshalb auch in der FORWARD-Chain das Passieren:
root@fuzzball :~# ip6tables -- append FORWARD -- match conntrack -- ctstate ESTABLISHED , RELATED -- jump ACCEPT
Extension Header Nutzerdefinierte Chain für ICMPv6

Gefährliche Extension Header werden wir auch beim Forwarding nicht akzeptieren.

  • Darum hängen wir die nutzerdefinierte Chain bad-eh auch in der FORWARD-Chain ein:
root@fuzzball :~# ip6tables -- append FORWARD -- jump bad - eh Bei den Upper Layer Protocols hat sich im Bereich Forwarding nichts Wesentliches im Vergleich zu IPv4 geändert. 
  • Den Schwerpunkt des Filterns legen wir deshalb auf ICMPv6 fest.

Wir starten mit einer neuen nutzerdefinierten Chain namens icmpv6-filter :

root@fuzzball :~# ip6tables -- new - chain icmpv6 - filter
Link-local Addresses

Link-local Addresses besitzen bekanntlich nur auf ihrem eigenen Link Gültigkeit.

  • Deshalb dürfen sie niemals weitergeleitet werden.
  • Pakete die als Quell- oder Zieladresse eine Link-local Addresses enthalten, werden daher verworfen:
root@fuzzball :~# ip6tables -- append icmpv6 - filter -- source fe8 ::/1 -- jump DROP
root@fuzzball :~# ip6tables -- append icmpv6 - filter -- destination fe8 ::/1 -- jump DROP

Echo Requests sind ein nützliches Werkzeug bei der Fehlersuche, darum werden wir sie nicht grundsätzlich verbieten.

  • Einige Einschränkungen werden wir aber machen.
  • Nodes aus der Trusted-Zone sollen Echo Request an jeden versenden dürfen:
root@fuzzball :~# ip6tables -- append icmpv6 - filter -- source 2 a 1 :198:2 :8 a23 ::/64 -- protocol icmpv6 -- icmpv6 - type echo - request -- match conntrack -- ctstate NEW -- jump ACCEPT
Echo Requests

Aber nur bestimmte Nodes aus der Trusted-Zone dürfen vom Rest der Welt mit Echo Requests angesprochen werden. Die Liste können Sie beliebig erweitern.

  • Im Workshop geben wir lynx frei, felis bleibt für Echo Requests unerreichbar.
root@fuzzball :~# ip6tables -- append icmpv6 - filter -- destination 2 a 1 :198:2 :8 a23 :2 : ff : fe6 : d1e -- protocol icmpv6 -- icmpv6 - type echo - request -- match conntrack -- ctstate NEW -- jump ACCEPT Das Präfix und die Adresse in den Parametern von ip6tables müssen Sie natürlich an Ihre eigenen Gegebenheiten anpassen.

Die Antwortpakete (Echo Replies) für die eben erstellten Regeln werden dank Connection Tracking frühzeitig erlaubt.

  • Andere Echo Replies sind davon allerdings nicht betroffen.
  • Zum Beispiel Echo Replies die an eine Multicast Address verschickt werden.
  • So ein Verhalten ist schädlich und kann von Betroffenen sogar als Angriff aufgefasst werden.
  • Echo Replies auf Multicast Addresses werden wir daher grundsätzlich verwerfen:
root@fuzzball :~# ip6tables -- append icmpv6 - filter -- destination ff ::/8 -- protocol icmpv6 -- icmpv6 - type echo - reply -- jump DROP Echo Replies ICMPv6 Error Messages für bestehende Verbindungen werden vom Connection Tracking erkannt und wurden von uns bereits erlaubt. 
  • Darüber hinaus sollen die Nodes in der Trusted-Zone die Möglichkeit erhalten, auch ungefragt Fehlermeldungen zu verschicken.

Error Messages

Wir beginnen mit der wichtigsten Fehlermeldung wenn es um Path MTU Discovery geht, nämlich der Packet Too Big Error Message:

root@fuzzball :~# ip6tables -- append icmpv6 - filter -- source 2 a 1 :198:2 :8 a23 ::/64 -- protocol icmpv6 -- icmpv6 - type packet - too - big -- jump ACCEPT Auch das Überschreiten der Zeitgrenze für den Zusammenbau von Fragmenten dürfen Nodes aus der Trusted-Zone anzeigen:
root@fuzzball :~# ip6tables -- append icmpv6 - filter -- source 2 a 1 :198:2 :8 a23 ::/64 -- protocol icmpv6 -- icmpv6 - type ttl - zero - during - reassembly -- jump ACCEPT Probleme beim Auswerten von Headern oder Parametern sollen ebenso den Paketfilter passieren dürfen:
root@fuzzball :~# ip6tables -- append icmpv6 - filter -- source 2 a 1 :198:2 :8 a23 ::/64 -- protocol icmpv6 -- icmpv6 - type bad - header -- jump ACCEPT
root@fuzzball :~# ip6tables -- append icmpv6 - filter -- source 2 a 1 :198:2 :8 a23 ::/64 -- protocol icmpv6 -- icmpv6 - type unknown - header - type -- jump ACCEPT
root@fuzzball :~# ip6tables -- append icmpv6 - filter -- source 2 a 1 :198:2 :8 a23 ::/64 -- protocol icmpv6 -- icmpv6 - type unknown - option -- jump ACCEPT In der Trusted-Zone befinden sich nicht nur Hosts, sondern auch fuzzball als Router ist mit einem Interface in der Zone vertreten. 
  • Daher erlauben wir auch die Fehlermeldungen, die für Router typisch sind, nämlich Destination Unreachable und Hop Limit Exceeded:
root@fuzzball :~# ip6tables -- append icmpv6 - filter -- source 2 a 1 :198:2 :8 a23 ::/64 -- protocol icmpv6 -- icmpv6 - type destination - unreachable -- jump ACCEPT
root@fuzzball :~# ip6tables -- append icmpv6 - filter -- source 2 a 1 :198:2 :8 a23 ::/64 -- protocol icmpv6 -- icmpv6 - type ttl - zero - during - transit -- jump ACCEPT
Neighbor Discovery Protocol

Auf keinen Fall dürfen ICMPv6-Nachrichten den Router passieren, die außerhalb des lokalen Links nichts zu suchen haben. Als erstes verwerfen wir NDP:

root@fuzzball :~# ip6tables -- append icmpv6 - filter -- protocol icmpv6 -- icmpv6 - type neighbor - solicitation -- jump DROP
root@fuzzball :~# ip6tables -- append icmpv6 - filter -- protocol icmpv6 -- icmpv6 - type neighbor - advertisement -- jump DROP
root@fuzzball :~# ip6tables -- append icmpv6 - filter -- protocol icmpv6 -- icmpv6 - type router - solicitation -- jump DROP
root@fuzzball :~# ip6tables -- append icmpv6 - filter -- protocol icmpv6 -- icmpv6 - type router - advertisement -- jump DROP

Auch Umleitungen haben beim Forwarding nichts verloren:

root@fuzzball :~# ip6tables -- append icmpv6 - filter -- protocol icmpv6 -- icmpv6 - type redirect -- jump DROP

Die Protokolle MLDv1 und MLDv2 sind zwischen den Zonen ebenfalls unerwünscht.

  1. Typ 13 : Multicast Listener Query ( MLDv1 , MLDv2 )
root@fuzzball :~# ip6tables -- append icmpv6 - filter -- protocol icmpv6 -- icmpv6 - type 13 -- jump DROP
  1. Typ 131: Multicast Listener Report ( MLDv1 )
root@fuzzball :~# ip6tables -- append icmpv6 - filter -- protocol icmpv6 -- icmpv6 - type 131 -- jump DROP
  1. Typ 132: Multicast Listener Done ( MLDv1 )
root@fuzzball :~# ip6tables -- append icmpv6 - filter -- protocol icmpv6 -- icmpv6 - type 132 -- jump DROP
  1. Typ 143: Multicast Listener Report ( MLDv2 )
root@fuzzball :~# ip6tables -- append icmpv6 - filter -- protocol icmpv6 -- icmpv6 - type 143 -- jump DROP
ICMPv6-Nachrichten zur Neunummerierung von Netzwerken sollen auch nicht weitergeleitet werden
Router
Renumbering
  1. Typ 138:
root@fuzzball :~# ip6tables -- append icmpv6 - filter -- protocol icmpv6 -- icmpv6 - type 147 -- jump DROP Mit den ICMPv6-Nachrichten Node Information Query kann man von einem Node Informationen einholen, zum Beispiel seinen Hostnamen. 
  • Der Node antwortet dann mit einem Node Information Reply, der die gewünschten Informationen enthält.

Das Verfahren ist in RFC 4620 [CH06] spezifiziert und gilt als experimentell.

  • Solange wir dafür keine Verwendung haben, verwerfen wir die zugehörigen Pakete deshalb:
Node-Informationen
  1. Typ 139: Node Information Query
root@fuzzball :~# ip6tables -- append icmpv6 - filter -- protocol icmpv6 -- icmpv6 - type 139 -- jump DROP
  1. Typ 14 : Node Information Reply
root@fuzzball :~# ip6tables -- append icmpv6 - filter -- protocol icmpv6 -- icmpv6 - type 14 -- jump DROP Mobile IPv6

Da wir kein Mobile IPv6 einsetzen, werden wir auch alle entsprechenden IPCMv6-Nachrichten verwerfen:

  1. Typ 144: Home Agent Address Discovery Request
root@fuzzball :~# ip6tables -- append icmpv6 - filter -- protocol icmpv6 -- icmpv6 - type 144 -- jump DROP
  1. Typ 145: Home Agent Address Discovery Reply
root@fuzzball :~# ip6tables -- append icmpv6 - filter -- protocol icmpv6 -- icmpv6 - type 145 -- jump DROP
  1. Typ 146 Mobile Prefix Solicitation
root@fuzzball :~# ip6tables -- append icmpv6 - filter -- protocol icmpv6 -- icmpv6 - type 146 -- jump DROP
  1. Typ 147: Mobile Prefix Advertisement
root@fuzzball :~# ip6tables -- append icmpv6 - filter -- protocol icmpv6 -- icmpv6 - type 147 -- jump DROP Alle weiteren ICMPv6-Pakete verwerfen wir:
root@fuzzball :~# ip6tables -- append icmpv6 - filter -- jumpDROP

Sollte es Probleme beim Forwarding geben, und der Verdacht fällt auf verworfene ICMPv6-Pakete, dann ersetzen wir das Target der zuletzt eingefügten Regeln durch trashlog. Dann werden die Pakete weiterhin verworfen, aber wir können den Vorgang im Systemlog beobachten.

  • Mit den Erkenntnissen lassen sich dann gegebenenfalls neue Regeln formulieren.

Zum Abschluss hängen wir die nutzerdefinierte Chain icmpv6filter noch in die FORWARD-Chain ein:

root@fuzzball :~# ip6tables -- append FORWARD -- protocol icmpv6 -- jump icmpv6 - filter
Upper Layer Protocols

Das Filtern von Upper Layer Protocols ist ein Thema, welches weder zum Titel des Workshops passt, noch in dessen Rahmen ausreichend behandelt werden könnte.

  • Die folgenden Regeln erlauben einfach jede neue Verbindung aus der TrustedZone in die Untrusted-Zone:
Datei
/etc/rc.local
#!/ bin / sh -e
#
# By default this script does nothing .
ip6tables - restore < / etc / packetfilter
exit Abbildung 7.7 Skript rc.local
root@fuzzball :~# ip6tables -- append FORWARD --in - interface eth1 --out - interface sixxs -- match conntrack -- ctstate NEW -- jump ACCEPT
root@fuzzball :~# ip6tables -- append FORWARD --in - interface eth1 --out - interface nat64 -- match conntrack -- ctstate NEW -- jump ACCEPT Betrachten Sie diese beiden Regeln bitte als Notbehelf im Rahmen des Workshops, und nicht als Ersatz für einen durchdachten Paketfilter. 
  • Dort wo dieses Kapitel endet, fängt das klassische Paketfiltern der höheren Protokolle an.

Wie schon bei lynx durchgeführt, werden wir auch für fuzzball die Regeln sichern.

  • Nicht nur des effizienteren Formates wegen, sondern auch um alle erstellten Regeln im Überblick zu behalten.
  • Wir leiten die Ausgabe von ip6tables-save wieder in eine Datei um:
Regeln sichern
root@fuzzball :~# ip6tables - save > / etc / packetfilter Die Datei /etc/packetfilter von fuzzball ist in Anhang D Paketfilter von fuzzball zu sehen.

Bei jedem Systemstart werden wir den Paketfilter in den Kernel laden, damit fuzzball sofort und sicher seine Arbeit aufnehmen kann.

  • Dazu verändern wir die Datei /etc/rc.local wie in Abbildung 7.7 gezeigt.

Viele der vorgestellten Regeln verwerfen ungewollte Pakete kommentarlos.

  • Im produktiven Betrieb ist es häufig notwendig, einen Kompromiss zwischen dem Mitschreiben von Paketen und der Geschwindigkeit des Paketfilters zu finden.
  • In unserem Lern- und Bastelnetzwerk sind wir diesen Zwängen nicht ausgesetzt, und könnten theoretisch jedes verworfene
Regeln wiederherstellen Verworfene Pakete mitschreiben
Systemlog auswerten

Paket dokumentieren.

  • Dazu müssen nur die Targets der entsprechenden Regeln auf die nutzerdefinierte Chain trashlog zeigen.
  • Im Folgenden Beispiel wurde die Regel für eingehende Echo Requests auf trashlog umgeleitet.
  • Ein Echo Request von außerhalb wurde daraufhin verworfen, aber vorher im Systemlog hinterlegt.
  • Einen Blick auf das Systemlog erhalten wir mit dem Kommando dmesg, welches hier ausgeführt wurde:
root@fuzzball :~# dmesg
TRASHLOG : IN = sixxs OUT = eth1 MAC = SRC =2 1: 7 f8 : 33:
:
: a1 5 :7821:
1 DST =2 a 1 : 198: 2 :8 a23 :
:
: bad : affe LEN =1 4 TC = HOPLIMIT =59 FLOWLBL = PROTO = ICMPv6 TYPE =128 CODE = ID =76 9 SEQ =1
Erfahrungen sammeln

Die gezeigte Zeile wurde vom verworfenen Paket erzeugt.

  • Alle wichtigen Informationen sind enthalten, so dass Vorfälle nachvollzogen werden können.
  • In diesem Fall wurde ein Echo Request mit dem Identifier 7609 und der Sequenznummer 1 verworfen.

Beschäftigen Sie sich ruhig noch eine Weile mit dem Paketfilter von fuzzball.

  • Schreiben Sie Pakete mit, und versuchen Sie anhand des Systemlogs nachzuvollziehen, was passiert ist.