Router/Paketfilter

Dieser Artikel wurde für die folgenden Ubuntu-Versionen getestet:

Dieser Artikel ist größtenteils für alle Ubuntu-Versionen gültig.

Zum Verständnis dieses Artikels sind folgende Seiten hilfreich:

  1. ⚓︎ Router/Multifunktionsgerät

  2. ⚓︎ Netfilter/Iptables

  3. ⚓︎ Installation von Programmen

  4. ⚓︎ Starten von Programmen

  5. ⚓︎ ein Terminal öffnen

  6. ⚓︎ mit Berechtigungen für root arbeiten

Inhaltsverzeichnis
  1. Vorüberlegungen
  2. Installation
  3. Ingress-Filter
    1. Source Routing
    2. ICMP
    3. Vereinfachtes Filter
  4. Egress-Filter
  5. Skript
  6. Links

Hier werden die praktischen Aspekte zu der im Artikel Router/Multifunktionsgerät beschriebenen Firewall für einen Border-Router besprochen. Kenntnis der oben zitierten Artikel wird in in diesem Artikel voraus gesetzt.

Vorüberlegungen

Es geht hier um einen Router auf der Grenze (border) zwischen dem unsicheren Internet und dem als sicher vorausgesetzten internem Netzwerk, d.h. die Sicherheit des internen Bereichs muss bereits durch andere, hier nicht besprochene Maßnahmen gegeben sein. Die hier besprochen Firewall soll

Die Aufgabenstellung für ingress (= Aufgabe (1)) erfordert die Filterung vor dem Routing in den Regelketten PREROUTING. Die Gebote[1] für egress (= Aufgabe (2)) könnten technisch zwar durch Regeln in den Ketten FORWARD und OUTPUT implementiert werden, jedoch ist bequemer, dies gemeinsam in den Regelketten POSTROUTING vorzunehmen.

(In diesem Artikel wird mit dem Wort „Gebot“ immer eine Anforderung aus der Aufgabenstellung gemeint und mit „Regel“ eine Realisierung eines solchen Gebotes durch eine iptables-Regel.)

Grundsätzlich sollte man auf NAT zwar aus funktionalen Gründen (z.B. dann fehlende Transparenz Ende-zu-Ende) verzichten, aber dies ist leider für einen Border-Router für das Protokoll IPv4 im Jahre 2022 eine unrealistische Anforderung. Im weiteren Artikel wird daher angenommen, dass NAT leider unvermeidlich eingesetzt werden muss; wer wider Erwarten für seine Zwecke über genügend global verwendbarer IPv4-Adressen verfügt und damit auf NAT verzichten kann, sollte die in diesem Artikel vorgestellten Beispiele nicht verwenden! Auch auf connection tracking sollte man verzichten, da dies für einen Angreifer die Angriffsfläche vergrößert und damit die Firewall unsicherer macht. Leider benötigt NAT bei Linux aber die Funktionalität connection tracking von Netfilter. Die gesamte Firewall wird daher in den Tabellen mangle und nat realisiert.

Damit beschreibt dieser Artikel wegen der anderen Aufgabenstellung einen anderen Ansatz als die üblicherweise bei den Paketfiltern für Personal Firewalls angewendete Filterung von IP-Paketen nach dem Routing in der Tabelle (table) filter von Netfilter[2]. Die Tabelle filter ist für die hier besprochene Aufgabenstellung für ingress völlig ungeeignet und für egress schlecht geeignet. Umgekehrt sind aber die in diesem Artikel besprochenen Methoden auch bei Personal Firewalls einsetzbar.

Die Aufgabenstellung[1] erfordert mehrere Untersuchungen, ob des jeweilige Paket Element bestimmter Mengen ("Martian", „interne Adresse“, „vom Typ Broadcast“, „unsere weiße Liste“ usw.) ist. Dies kann entweder durch eine Vielzahl von einzelnen Regel für jedes mögliche Element einzeln oder mittels IP-Adressmengen erfolgen. Nur die letztere Variante wird in diesem Artikel weiter besprochenen; für die technische Umsetzung benötigt werden die Erweiterungen (Module) addrtype, mark, multiport und state von iptables[2] sowie set aus dem Paket ipset.

Installation

Das Paket iptables und etliche Erweiterungen gehören immer zur Standardinstallation eines Ubuntu-Systems.

Zusätzlich muss installiert[3] werden:

Befehl zum Installieren der Pakete:

sudo apt-get install ipset 

Oder mit apturl installieren, Link: apt://ipset

Hinweis:

Alle folgenden Ausführungen setzen voraus, dass man „als root arbeitet“[5][6] bzw. sudo verwendet!

Die folgenden Filter sind Beispiele. Obwohl sie vermutlich in vielen Fällen direkt funktionieren könnten, sollte man sie erst nach sorgfältiger Prüfung und Abgleich mit den individuellen Bedürfnissen in eigener Verantwortung einsetzen.

Die Implementation von Filtern für IPv6 kann nach den gleichen Überlegungen wie hier explizit nur für IPv4 gezeigt erfolgen; man beachte dabei die Besonderheiten von IPv6 hinsichtlich Source Routing und benötigt natürlich kein NAT. Der Leser wird ausdrücklich ermutigt, bei IPv6 auf "connection tracking" zu verzichten, dieses zu deaktivieren und selber eigene zustandslose Filter zu entwerfen.

Ingress-Filter

Zuerst müssen die IP-Adressmengen Martians, Localnet, Internet und Auth-ext definiert werden. Die folgenden Shell-Befehle vereinigt man zweckmäßigerweise in einem Skript:

Folgende Regeln müssen – einzeln nacheinander – per iptables[2] in der Tabelle mangle definiert werden:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
-P PREROUTING ACCEPT
-A PREROUTING ! -i extern -j ACCEPT
-A PREROUTING -m state --state INVALID -j DROP
-A PREROUTING -m state --state RELATED,ESTABLISHED -j RETURN
-A PREROUTING -m addrtype --src-type LOCAL --limit-iface-in -j DROP
-A PREROUTING -m set --match-set Localnet src -j DROP
-A PREROUTING -m set --match-set Martians src -j DROP
-A PREROUTING -m addrtype --dst-type BROADCAST -j DROP
-A PREROUTING -m set --match-set Internet src -m addrtype --dst-type LOCAL --limit-iface-in -j RETURN
-A PREROUTING -m set --match-set Internet src -m set --match-set Localnet dst -j RETURN
-A PREROUTING -m set --match-set Auth-ext src -m addrtype --dst-type LOCAL --limit-iface-in -j RETURN
-A PREROUTING -m set --match-set Auth-ext src -m set --match-set Localnet dst -j RETURN
-A PREROUTING -m set --match-set Martians dst -j DROP
-A PREROUTING -p udp -m udp --dport 7 -j SET --add-set Auth-ext src
-A PREROUTING -p udp -m multiport --ports 161,162 -j DROP
-A PREROUTING -p icmp -j DROP
-A PREROUTING

Kontrolle: Der Befehl

iptables -t mangle -S PREROUTING 

muss die vorstehende Ausgabe ergeben.

Source Routing

Um Pakete mit den IP-Optionen für source routing (IPv4-Optionen Type 131 und 137) nach Gebot 8 zu unterdrücken, verwendet man eine Einstellung des Linux-Kernels für das Routing:

sysctl -w net.ipv4.conf.all.accept_source_route=0 

Ein Router mit dieser Einstellung leitet IP-Pakete mit einer Option für source routing nicht weiter, sondern verwirft diese mit Rückmeldung an die im Paket enthaltene Absender-Adresse.

Dies entspricht auch der Empfehlung der IETF und ist Standardeinstellung bei Ubuntu-Systemen. Da eine Aktivierung der bei IPv4 als veraltet geltenden Optionen für source routing aber technisch immer noch möglich ist, sollte man die Kernel-Variablen überprüfen:

sysctl -ar net.ipv4.conf.*.accept_source_route 

Bei IPv6 ist die funktional ähnliche Erweiterung RH0 (routing header type 0) ebenfalls veraltet (siehe RFC 5095) und im Linux-Kernel seit Version 2.6.20.10/2.6.21.1 dauerhaft deaktiviert. Das Missbrauchspotential ist bei IPv6 erheblich größer als bei IPv4.

Die Kernel-Option

sysctl -ar net.ipv6.conf.all.accept_source_route 

bewirkt bei IPv6 etwas anderes als ihr Pendant bei IPv4:

Die Unterbindung der Weiterleitung kann über eine Netfilter-Regel unter Verwendung des für IPv6 spezifischen Moduls rt an passender Stelle im Regelsatz realisiert werden:

1
ip6tables -t mangle -A PREROUTING -m rt --rt-type 0 -j DROP

Eine solche Regel verhindert auch die Rückmeldung an den Absender, welche ein zu RFC 5095 konformer IPv6-Router nach Verwerfung eines Paketes mit RH0 erzeugen muss.

ICMP

Zur Frage der Filterung eingehender ICMP-Nachrichten findet man sehr unterschiedliche Ansichten. Weitgehende Einigkeit besteht bei bestimmten Fehlermeldungen, die von Routern bei der Bearbeitung empfangener Pakete an den mutmaßlichen Absender zurück gesendet werden: Nicht sperren sollte man Rückmeldungen vom ICMP-Typ 11 (= Time Exceeded) und (schon weniger einig) dem Typ 3 (= Destination Unreachable); bei den Typen 5 (= Redirect) und 12 (= Parameter Problem) gibt es teilweise heftige strittige Diskussionen. Antworten auf selbst per ping angeforderte Echos (Typ 0 = Echo Reply) sollen natürlich nicht unterdrückt werden.

Das oben vorgestellte Filter akzeptiert alle (vorstehend beschriebene und weitere) Antworten und Rückmeldungen zu selbst ausgesendeten IP-Paketen mit der Regel in Zeile 4. Wer bestimmte Antworten und Rückmeldungen nicht zulassen möchte, muss diese durch zusätzliche Regeln vor Zeile 4 aussondern.

Alle initiativ von nicht authentifizierten Stellen stammenden Anfragen werden mit der Regel in Zeile 16 gesperrt; dies betrifft auch Echo-Anforderungen (Typ 8 = Echo Request) von nicht authentifizierten Stellen. Dies kann durch zusätzliche Regeln vor Zeile 16 modifiziert werden.

Vereinfachtes Filter

Der ganze vorstehend beschriebene Aufwand wird nur erforderlich, wenn man tatsächlich eine Initiierung neuer Verbindungen von Außen grundsätzlich ermöglichen möchte. Wenn man auf diese Anforderung verzichten kann, lässt sich das Filter drastisch vereinfachen auf:

1
2
3
-A PREROUTING ! -i extern -j ACCEPT
-A PREROUTING -m state --state RELATED,ESTABLISHED -j ACCEPT
-A PREROUTING -j DROP

Egress-Filter

Man benötigt wieder IP-Adressmengen, kann aber die oben bei Ingress-Filter definierten verwenden und auch gemeinsam für Ingress und Egress benutzen.

Egress.png Bei der Formulierung eines Filters gemäß der beim Beispiel für das Ingress-Filter gezeigten Methode ist oft die Reihenfolge der Regeln kritisch für die Funktion, da DROP, ACCEPT und RETURN für ein passendes Paket ja dessen Prüfung beenden. In diesem Kapitel wird daher eine andere Methode vorgestellt: Statt das Paket zu verwerfen oder zuzulassen und damit dessen Bearbeitung zu beenden, wird es nur als „böse“ oder „gut“ markiert, und erst am Ende des gesamten Regelsatzes werden diese Markierungen ausgewertet und über das Schicksal des Pakets entschieden. Die Auswahl der Methode hat nichts mit der Aufgabenstellung zu tun, sondern nur mit persönlichen Vorlieben. Das nebenstehende Bild zeigt das hier beschriebene Filter „bei der Arbeit“ unter Verwendung des Skripts IPTadmin.

Folgende Regeln müssen – einzeln nacheinander – per iptables[2] in der Tabelle mangle definiert werden:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
-P POSTROUTING ACCEPT
-A POSTROUTING ! -o extern -m comment --comment nicht_nach_extern -j ACCEPT
-A POSTROUTING -m state --state RELATED,ESTABLISHED -j MARK --set-xmark 0x8/0x8
-A POSTROUTING -m state --state INVALID -j DROP
-A POSTROUTING -m set ! --match-set Localnet src -m comment --comment "Gebot_2/3" -j MARK --set-xmark 0x1/0x1
-A POSTROUTING -m set ! --match-set Localnet src -m comment --comment "Gebot_2/3" -j LOG
-A POSTROUTING -m addrtype --dst-type BROADCAST -m comment --comment Gebot_6 -j MARK --set-xmark 0x1/0x1
-A POSTROUTING -m set --match-set Martians dst -m comment --comment "Gebot_4/5" -j MARK --set-xmark 0x1/0x1
-A POSTROUTING -p udp -m multiport --ports 161,162 -m comment --comment Gebot_9 -j DROP
-A POSTROUTING -d 192.168.178.1/32 -p udp -m udp --dport 53 -m comment --comment DNS -j MARK --set-xmark 0x8/0x8
-A POSTROUTING -m mark --mark 0x8/0x9 -m comment --comment The_Good -j ACCEPT
-A POSTROUTING -m mark --mark 0x1/0x9 -m comment --comment the_Bad -j DROP
-A POSTROUTING -m mark --mark 0x9/0x9 -m comment --comment and_the_Ugly -j RETURN
-A POSTROUTING -m comment --comment Catch-All -j ACCEPT

Kontrolle: Der Befehl

iptables -t mangle -S POSTROUTING 

muss bis auf die optionalen Kommentare die vorstehende Ausgabe ergeben.

Das Filter muss in den meisten Fällen noch um NAT (bzw. MASQUERADE) ergänzt werden, hierfür in der Tabelle nat diese Regeln einfügen:

1
2
-P POSTROUTING ACCEPT
-A POSTROUTING -o extern -m set --match-set Localnet src -j MASQUERADE

Kontrolle:

iptables -t nat -S POSTROUTING 

Skript

Ein Skript, welches die vorgestellten Filter für Ingress und Egress implementiert und auch die benötigten IP-Adressmengen erstellt kann als Anhang zu diesem Artikel herunter geladen werden:

Es muss in einem der in der Umgebungsvariable PATH enthaltenen Verzeichnisse als ausführbares Programm abgelegt werden, root gehören und beim Aufruf mit dem Namen der Schnittstelle zur externen Welt versorgt werden.

Beachte: Dieses Skript installiert nur die Regeln für die beschriebene Firewall. Für die generellen Einstellungen zur Funktion eines Routers lese die anderen Teile der Artikelserie Router/Multifunktionsgerät bzw. den Artikel Router/Routing-Funktion.

Die mit diesem Skript definierten Regeln können mit Hilfe des Skripts IPTadmin gesichert und nach erneuten Start auch wieder geladen werden.