IP6Tables - from scratch: Unterschied zwischen den Versionen
Zeile 3: | Zeile 3: | ||
Der Linux-Kernel enthält fortgeschrittene Tools für Packet-Filtering, der Prozess für die Kontrolle von Netzwerkpaketen bei ihrem Versuch einzudringen, durch und aus dem System hinaus zu dringen. Kernels vor der 2.4 Version konnten Pakete mit ipchains manipulieren, die Listen von Regeln verwendeten, die für Pakete in jeder Phase des Filterungsprozesses angewandt werden. Die Einführung des 2.4-Kernels hat iptables mit sich gebracht, die den ipchains gleichen, aber deren Wirkungsbereich und Kontrollmöglichkeiten bei der Filterung von Paketen erweitern. | Der Linux-Kernel enthält fortgeschrittene Tools für Packet-Filtering, der Prozess für die Kontrolle von Netzwerkpaketen bei ihrem Versuch einzudringen, durch und aus dem System hinaus zu dringen. Kernels vor der 2.4 Version konnten Pakete mit ipchains manipulieren, die Listen von Regeln verwendeten, die für Pakete in jeder Phase des Filterungsprozesses angewandt werden. Die Einführung des 2.4-Kernels hat iptables mit sich gebracht, die den ipchains gleichen, aber deren Wirkungsbereich und Kontrollmöglichkeiten bei der Filterung von Paketen erweitern. | ||
− | == | + | ==iptables Allgemein== |
Iptables beinhaltet das englische Wort tables, was für Tabellen steht, und genauso kann man es sich auch vorstellen, denn in seinen 3 Tabellen sammeln sich die Ketten in denen Regeln zum Kontrollieren, Manipulieren oder Extrahieren von Paketen angegeben werden. | Iptables beinhaltet das englische Wort tables, was für Tabellen steht, und genauso kann man es sich auch vorstellen, denn in seinen 3 Tabellen sammeln sich die Ketten in denen Regeln zum Kontrollieren, Manipulieren oder Extrahieren von Paketen angegeben werden. | ||
===Tabellen=== | ===Tabellen=== | ||
− | Wie Pakete verarbeitet werden wird schon in den Tabellen vorgegeben. | + | Wie Pakete verarbeitet werden wird schon in den Tabellen vorgegeben. iptables besitzt standardmäßig drei Tabellen: '''mangle''', '''nat''' und '''filter'''. |
Die Tabelle '''mangle''' (übersetzt: zerhauen) ermöglicht es dem Kernel, Daten im Paket-Header zu verändern. | Die Tabelle '''mangle''' (übersetzt: zerhauen) ermöglicht es dem Kernel, Daten im Paket-Header zu verändern. |
Version vom 30. März 2020, 07:20 Uhr
Die Verwendung von Firewalls mit iptables
Der Linux-Kernel enthält fortgeschrittene Tools für Packet-Filtering, der Prozess für die Kontrolle von Netzwerkpaketen bei ihrem Versuch einzudringen, durch und aus dem System hinaus zu dringen. Kernels vor der 2.4 Version konnten Pakete mit ipchains manipulieren, die Listen von Regeln verwendeten, die für Pakete in jeder Phase des Filterungsprozesses angewandt werden. Die Einführung des 2.4-Kernels hat iptables mit sich gebracht, die den ipchains gleichen, aber deren Wirkungsbereich und Kontrollmöglichkeiten bei der Filterung von Paketen erweitern.
iptables Allgemein
Iptables beinhaltet das englische Wort tables, was für Tabellen steht, und genauso kann man es sich auch vorstellen, denn in seinen 3 Tabellen sammeln sich die Ketten in denen Regeln zum Kontrollieren, Manipulieren oder Extrahieren von Paketen angegeben werden.
Tabellen
Wie Pakete verarbeitet werden wird schon in den Tabellen vorgegeben. iptables besitzt standardmäßig drei Tabellen: mangle, nat und filter.
Die Tabelle mangle (übersetzt: zerhauen) ermöglicht es dem Kernel, Daten im Paket-Header zu verändern.
NAT wird benutzt um interne und externe IP-Adressen zu übersetzen (= Network Adress Translation). Regeln in dieser Tabelle ändern die IP und/oder den Port des Ziels oder Quelle.
Die Tabelle filter prüft alle für die Firewall ankommenden Pakete und entscheidet ob sie durchgelassen oder geblockt werden.
Jede dieser Tabellen besitzt nun mehrere Ketten:
- mangle (Paketmanipulationen): enthält alle Ketten
- nat (Network Adress Translation): enthält die Ketten PREROUTING, OUTPUT und POSTROUTING
- filter (Paketfilter): enthält die Ketten FORWARD, INPUT und OUTPUT
Ketten
Die Ketten sind eine Sammlung von Regeln. D.h. das jede Kette mehrere Regeln besitzen kann um ein Paket durchzulassen oder zu blockieren. Es sind fünf Typen von Standardketten vorhanden. Manche dieser Ketten werden von allen Paketen und einige nur, je nachdem welches Ziel sie haben, durchlaufen. Man könnte auch sagen die Ketten unterscheiden wo welche Regeln angewendet werden. Die Regeln einer Kette werden nacheinander abgearbeitet und wenn eine zutrifft, ist die Bearbeitung in dieser Kette beendet (es gibt Ausnahmen):
- PREROUTING: alle Pakete kommen hier durch bevor eine Routing-Entscheidung getroffen wird
- FORWARD: für alle Pakete, die von der einen zu einer anderen Netzwerkschnittstelle weitergeleitet werden - also keine Pakete die an einen lokalen Dienst gerichtet sind
- INPUT: für Pakete die über eine Schnittstelle hereinkommen und einen Dienst auf dem Rechner ansprechen
- OUTPUT: für die über eine Schnittstelle herausgehenden Pakete, die von einem lokalen Dienst kommen
- POSTROUTING: alle Pakete kommen am Ende der Verarbeitung hier durch
Regeln
Mit einer Regel wird entschieden was mit einem Paket passieren soll. Jede besitzt bestimmte Parameter nach denen sie überprüft ob die Informationen eines Paketes auf sie zutreffen. Wenn die Parameter zutreffend sind, wird das Paket meist an ein neues Ziel verwiesen oder es wird eine Methode angewandt. Für die Bearbeitung der Pakete gibt es mehrere Ziele und Methoden. Häufig benutzte sind:
- ACCEPT: das Paket kann passieren
- REJECT: das Paket wird zurückgewiesen und ein Fehlerpaket wird gesendet
- LOG: schreibt einen Eintrag in die syslog
- DROP: das Paket wird ignoriert und keine Antwort gesendet
- REDIRECT: die Ziel-Adresse des Paketes wird hiermit so verändert, dass es zum lokalen Rechner gesendet wird
- MASQUERADE: die Quell-Adresse des Paketes wird durch die IP-Adresse der Schnittstelle ersetzt, auf dem es den Rechner verlässt
- SNAT
- DNAT
Somit funktioniert ip6tables wie eine Art Sammlung von Schablonen die nacheinander auf ein Paket abgebildet werden und bei einem Treffer eine bestimmte Aktion auf das Paket ausführen. Falls keine der Schablonen passen sollte wird eine Standard Aktion ausgeführt die für alle Pakete gilt die nicht auf eine Schablone passen.
Konzept-Bild
Syntax Allgemein
Wie schon zu erwarten bedient man ip6tables mit dem Befehl ip6tables. Folgende Dinge sind vorab zu beachten:
Die Momentan in der filter Tabelle gesetzten Ketten und Regeln kann man sich mit
root@hutze:~# ip6tables -L
ausgeben lassen, wobei man die Ausgabe noch mit den Operanden
-n # für numerical -v # für verbose
erweitern kann.
Dabei ist es wichtig zu bemerken das jede ip6tables zeile ohne -t option von einem -t filter ausgeht. Was bedeutet das es die Filter Tabelle geschrieben wird. Um die anderen Tabellen zu schreiben braucht man -t nat und -t mangle
Die 3 Tabellen von ip6tables spricht man jeweils mit
ip6tables [-t filter] ip6tables -t nat ip6tables -t mangle
an.
Jeder dieser Tabellen Angaben folgt für gewöhnlich eine Kette. Diese sind: INPUT OUTPUT und FORWARD sowie ausschließlich für nat und mangle auch PREROUTING und POSTROUTING. Und müssen mit dem davor stehenden Operanden -A ( Append - englisch für Anhängen ) definiert werden.
Beispiele:
ip6tables -A INPUT ip6tables -t nat -A POSTROUTING
Wenn man also Regeln aufstellen will muss man immer die Tabelle und das dazugehörige Kettenglied übergeben, damit der Router genau weiß was wo zu tun ist.
Die Tabellen und Regeln von ip6tables könnte man theoretisch auch alle einzeln nacheinander in der Konsole eingeben was aber nicht ganz Sinn der Sache ist. Also bedienen wir uns für unsere Firewall einem simplen Bash-Skript.
Positionierung der Firewall vor Ubuntu 16.04
Eine Firewall kann man unter Linux ganz einfach mit einem vi-Dokument beginnen. Damit die daraus entstehende Firewall auch ausgeführt wird müssen wir es in den entsprechenden Verzeichnissen vermerken. Das Skript selbst sollte nach /etc/init.d/ mit einem softlink mit dem prefix "S99" in /etc/rc2.d damit es beim Starten automatisch ausgeführt wird.
root@hutze:~# touch firewall root@hutze:~# mv firewall /etc/init.d root@hutze:~# ln -s /etc/init.d/firewall /etc/rc2.d/S99firewall
Positionierung der Firewall ab Ubuntu 16.04
Ab Ubuntu 16.04 wurde das übliche init durch das neue systemd ersetzt. Daher muss die Firewall in /usr/local/sbin platziert werden und wie im unteren Link angegeben der Service-File erstellt werden
Der Rumpf
Zuerst wird in dem firewall-Skript ein case start - stop Block angelegt:
#!/bin/bash case $1 in start) echo "starte firewall" ;; stop) echo "stoppe firewall" ;; *) echo "usage: $0 start|stop" ;; esac
Filter Tabelle
Beginnen wir unsere Firewall mit ihrer simpelsten Funktion: dem Paketfilter.
Flushing
Bevor wir unsere eigenen Regeln entwerfen, sollten wir sichergehen das sich keine alten Regeln einschleichen und zu unerwarteten Komplikationen führen. Dieses wird durch das sogenannte "flushing" erreicht, welches mit folgender Zeile geschieht:
#!/bin/bash case $1 in start) echo "starte firewall" ip6tables -F ip6tables -t nat -F ip6tables -t mangle -F
;; stop) echo "stoppe firewall" ip6tables -F ip6tables -t nat -F ip6tables -t mangle -F
;; esac
Ohne flushing kann es auch passieren das sich unsere Regeln bei jedem Neustart der Firewall addieren.
- Verwendete Syntax
- Der Operand -F löst das flushing aus mit dem alle Regeln in der angegebenen Tabelle ( hier "-t filter" da keine angegeben ) entfernt werden
- Wichtig
- Wenn man zukünftig auch Regeln in die nat und mangle Tabellen schreiben möchte, muss man dazu sichergehen das auch diese bei jedem Start und Stop jeweils geflusht werden damit keine Komplikationen entstehen.
Default policy
Als nächstes definieren wir was passieren soll falls keine unserer Regeln zutreffen sollte, auch gennannt "default policy"
Dies geschieht mit folgenden Zeilen:
#!/bin/bash case $1 in start) echo "starte firewall" ip6tables -F ip6tables -P INPUT DROP ip6tables -P OUTPUT DROP ip6tables -P FORWARD DROP ;; stop) echo "stoppe firewall" ip6tables -F ip6tables -P INPUT ACCEPT ip6tables -P OUTPUT ACCEPT ip6tables -P FORWARD ACCEPT ;; esac
- Verwendete Syntax
- Wie in Syntax Allgemein angegeben muss die "default policy" auf alle 3 Anlaufstellen angewendet werden.
- Nach der Anlaufstelle geben wir an was mit den Paketen zu tun ist.
- Mit DROP lässt die gestartete Firewall alle Pakete fallen die nicht auf eine Regel passen.
- Mit ACCEPT lässt die gestoppte Firewall alle Pakete durch.
ESTABLISHED und RELATED Pakete
Ein Vorteil von ip6tables zu seinen Vorgängern ist die Funktion seinen Paketfilter nur auf die ersten Pakete einer Verbindung zu begrenzen und so Ressourcen zu sparen.
Dieses wird erreicht mit folgenden Zeilen
#!/bin/bash case $1 in start) echo "starte firewall" ip6tables -F ip6tables -P INPUT DROP ip6tables -P OUTPUT DROP ip6tables -P FORWARD DROP ip6tables -A INPUT conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A FORWARD conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A OUTPUT conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ;; stop) echo "stoppe firewall" ip6tables -F ip6tables -P INPUT ACCEPT ip6tables -P OUTPUT ACCEPT ip6tables -P FORWARD ACCEPT ;; esac
- Verwendete Syntax
- Die neuen Funktionen die wir hier verwenden beinhalten:
- conntrack: Das Modul von ip6tables das erkennt ob ein Paket eine Verbindung initiiert oder zu einer bereits errichteten Verbindung gehört.
- --cstate ESTABLISHED,RELATED: Der Status nach dem das Paket untersucht wird, wobei
- ESTABLISHED: Für alle Pakete steht die nicht das erste Paket einer Verbindung ist die in beide Richtungen sendet. (TCP)
- RELATED: Für alle Pakete steht die eine 2t Verbindung öffnen wollen. (FTP,ICMP)
- -j ACCEPT: Benutzt die angegebene Operation auf das Paket, hier ACCEPT.
loopback device
Nun haben wir schon ein paar Regeln aber noch keine die bisher zutreffen kann. Wenn wir diese Firewall aktivieren würden wäre unser eigener Router Nichtmal mehr in der Lage mit sich selbst zu kommunizieren. Da er dies über das sogennante "loopback device" lassen wir jetzt unsere ersten Pakete durch.
#!/bin/bash case $1 in start) echo "starte firewall" ip6tables -F ip6tables -P INPUT DROP ip6tables -P OUTPUT DROP ip6tables -P FORWARD DROP ip6tables -A INPUT conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A FORWARD conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A OUTPUT conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A OUTPUT -o lo conntrack --cstate NEW -j ACCEPT ip6tables -A INPUT -i lo conntrack --cstate NEW -j ACCEPT ;; stop) echo "stoppe firewall" ip6tables -F ip6tables -P INPUT ACCEPT ip6tables -P OUTPUT ACCEPT ip6tables -P FORWARD ACCEPT ;; esac
- Verwendete Syntax
- Hier geben wir nun zum ersten mal zur Anlaufstelle auch das jeweilige Interface das angelaufen wird mit an:
- Mit -o lo beschreiben wir als output also Ausgang die Schnittstelle lo was für das loopback device steht
- Genauso -i lo wobei lo hier als Eingang angegeben wird. In einem Satz:
- Alle Pakete die von unserem Router aus lo Ausgehen durchlassen
- Alle Pakete die an unserem Router an lo Ankommen durchlassen
Fernwartung
Angenommen unser Router mit der Firewall steht nicht im selben Netz wie unser üblicher Arbeitsrechner, ist es von Vorteil auch von außen auf ihn zugreifen zugreifen zu können. In unserem Beispiel ist das äußere Netz auch ein LAN.
#!/bin/bash case $1 in start) echo "starte firewall" ip6tables -F ip6tables -P INPUT DROP ip6tables -P OUTPUT DROP ip6tables -P FORWARD DROP ip6tables -A INPUT conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A FORWARD conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A OUTPUT conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A OUTPUT -o lo -j ACCEPT ip6tables -A INPUT -i lo -j ACCEPT ip6tables -A INPUT -i eth0 -s 192.168.241.10 -p tcp --dport 22 conntrack --cstate NEW -j ACCEPT ;; stop) echo "stoppe firewall" ip6tables -F ip6tables -P INPUT ACCEPT ip6tables -P OUTPUT ACCEPT ip6tables -P FORWARD ACCEPT ;; esac
- Verwendete Syntax
- -s: Passt auf die angegebene Quell IP-Adresse, hier 192.168.241.10
- -p: Passt auf ein Protokoll, hier tcp
- -dport: Passt auf Ziel Port, hier 22 (ssh)
- --cstate NEW: Passt auf Pakete die eine Verbindung Initiieren
Adressen zusammenfassen
ip6tables -A INPUT -i eth0 -s 192.168.241.10,10.81.3.1 -p tcp --dport 22 conntrack --cstate NEW -j ACCEPT
DNS-Server und HTTP
Jetzt möchten wir mit unserem Router ins Internet gehen können. Dazu müssen wir 2 Dinge tun, zuerst müssen wir erlauben das er auf DNS-Server zugreifen kann.
#!/bin/bash case $1 in start) echo "starte firewall" ip6tables -F ip6tables -P INPUT DROP ip6tables -P OUTPUT DROP ip6tables -P FORWARD DROP ip6tables -A INPUT conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A FORWARD conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A OUTPUT conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A OUTPUT -o lo -j ACCEPT ip6tables -A INPUT -i lo -j ACCEPT ip6tables -A INPUT -i eth0 -s 192.168.241.10 -p tcp --dport 22 conntrack --cstate NEW -j ACCEPT ip6tables -A OUTPUT -o eth0 -p tcp -d 192.168.240.21 --dport 53 conntrack --cstate NEW -j ACCEPT ip6tables -A OUTPUT -o eth0 -p udp -d 192.168.240.21 --dport 53 conntrack --cstate NEW -j ACCEPT ;; stop) echo "stoppe firewall" ip6tables -F ip6tables -P INPUT ACCEPT ip6tables -P OUTPUT ACCEPT ip6tables -P FORWARD ACCEPT ;; esac
- Verwendete Syntax
- -d: Das selbe Prinzip wie auch bei -s aber auf eine Ziel Adresse
Dann müssen wir auch noch eine Regel für HTTP aufstellen damit wir auch Internetseiten aufrufen dürfen
#!/bin/bash case $1 in start) echo "starte firewall" ip6tables -F ip6tables -P INPUT DROP ip6tables -P OUTPUT DROP ip6tables -P FORWARD DROP ip6tables -A INPUT conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A FORWARD conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A OUTPUT conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A OUTPUT -o lo -j ACCEPT ip6tables -A INPUT -i lo -j ACCEPT ip6tables -A INPUT -i eth0 -s 192.168.241.10 -p tcp --dport 22 conntrack --cstate NEW -j ACCEPT ip6tables -A OUTPUT -o eth0 -p tcp -d 192.168.240.21 --dport 53 conntrack --cstate NEW -j ACCEPT ip6tables -A OUTPUT -o eth0 -p udp -d 192.168.240.21 --dport 53 conntrack --cstate NEW -j ACCEPT ip6tables -A OUTPUT -o eth0 -p tcp --dport 80 conntrack --cstate NEW -j ACCEPT ;; stop) echo "stoppe firewall" ip6tables -F ip6tables -P INPUT ACCEPT ip6tables -P OUTPUT ACCEPT ip6tables -P FORWARD ACCEPT ;; esac
ICMP
Jetzt wollen wir testen können ob unser Router erreichbar ist. Dazu müssen wir ICMP freischalten
#!/bin/bash case $1 in start) echo "starte firewall" ip6tables -F ip6tables -P INPUT DROP ip6tables -P OUTPUT DROP ip6tables -P FORWARD DROP ip6tables -A INPUT conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A FORWARD conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A OUTPUT conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A OUTPUT -o lo -j ACCEPT ip6tables -A INPUT -i lo -j ACCEPT ip6tables -A INPUT -i eth0 -s 192.168.241.10 -p tcp --dport 22 conntrack --cstate NEW -j ACCEPT ip6tables -A OUTPUT -o eth0 -p tcp -d 192.168.240.21 --dport 53 conntrack --cstate NEW -j ACCEPT ip6tables -A OUTPUT -o eth0 -p udp -d 192.168.240.21 --dport 53 conntrack --cstate NEW -j ACCEPT ip6tables -A OUTPUT -o eth0 -p tcp --dport 80 conntrack --cstate NEW -j ACCEPT ip6tables -A INPUT -i eth0 -p icmp --icmp-type 8 -j ACCEPT ;; stop) echo "stoppe firewall" ip6tables -F ip6tables -P INPUT ACCEPT ip6tables -P OUTPUT ACCEPT ip6tables -P FORWARD ACCEPT ;; esac
- Verwendete Syntax
- --icmp-type 8 Beschränkt erlaubte ICMP Pakete auf typ 8 ( echo )
NAT Tabelle
NAT steht für Network Address Translation, also eine Übersetzung von Netzwerk Adressen, sei es in Namen oder auch einfach nur in andere IP-Adressen. Iptables kann diesen Job übernehmen und zwar auf verschiedene Art und Weise.
- Wichtig
- Da wir nun beginnen NAT regeln in die firewall zu schreiben dürfen wir nicht vergessen die Zeile zum flushen eben jener hinzuzufügen
MASQUERADE
Masquerading ist wohl die simpelste Form von NAT, hiermit ersetzt der Router einfach jede Quell IP-Adresse jedes zu routenden Paketes mit seiner eigenen, sowie bei einem Antwort Paket die Ziel Adresse wieder mit der Original Quell Adresse.In ip6tables erreicht man diese Funktion mit folgender Zeile
#!/bin/bash case $1 in start) echo "starte firewall" ip6tables -F ip6tables -F -t nat ip6tables -P INPUT DROP ip6tables -P OUTPUT DROP ip6tables -P FORWARD DROP ip6tables -A INPUT conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A FORWARD conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A OUTPUT conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A OUTPUT -o lo -j ACCEPT ip6tables -A INPUT -i lo -j ACCEPT ip6tables -A INPUT -i eth0 -s 192.168.241.10 -p tcp --dport 22 conntrack --cstate NEW -j ACCEPT ip6tables -A OUTPUT -o eth0 -p tcp -d 192.168.240.21 --dport 53 conntrack --cstate NEW -j ACCEPT ip6tables -A OUTPUT -o eth0 -p udp -d 192.168.240.21 --dport 53 conntrack --cstate NEW -j ACCEPT ip6tables -A OUTPUT -o eth0 -p tcp --dport 80 conntrack --cstate NEW -j ACCEPT ip6tables -A INPUT -i eth0 -p icmp --icmp-type 8 -j ACCEPT ip6tables -t nat -A POSTROUTING -s 172.23.242.0/24 -j MASQUERADE -o eth0 ;; stop) echo "stoppe firewall" ip6tables -F ip6tables -F -t nat ip6tables -P INPUT ACCEPT ip6tables -P OUTPUT ACCEPT ip6tables -P FORWARD ACCEPT ;; esac
- Verwendete Syntax
- -t nat: Hier sehen wir zum ersten mal wie man eine andere Tabelle außer Filter anspricht
- POSTROUTING: Damit der Router weiß das er den Adressen Tausch NACH dem Routing ausführen soll
- -j MASQUERADE: Eine weitere Aktion die auf ein Paket ausgeführt werden kann, hier unser NAT
- -s 172.23.242.0/24: Hier wird nicht nur eine IP-Adresse, sondern ein ganzer Netzbereich als Quelle angegeben
FORWARD
Um den an die Firewall angeschlossenen Rechnern einen Netzzugang zu gestatten müssen wir deren DNS Anfragen zulassen
#!/bin/bash case $1 in start) echo "starte firewall" ip6tables -F ip6tables -F -t nat ip6tables -P INPUT DROP ip6tables -P OUTPUT DROP ip6tables -P FORWARD DROP ip6tables -A INPUT conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A FORWARD conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A OUTPUT conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A OUTPUT -o lo -j ACCEPT ip6tables -A INPUT -i lo -j ACCEPT ip6tables -A INPUT -i eth0 -s 192.168.241.10 -p tcp --dport 22 conntrack --cstate NEW -j ACCEPT ip6tables -A OUTPUT -o eth0 -p tcp -d 192.168.240.21 --dport 53 conntrack --cstate NEW -j ACCEPT ip6tables -A OUTPUT -o eth0 -p udp -d 192.168.240.21 --dport 53 conntrack --cstate NEW -j ACCEPT ip6tables -A OUTPUT -o eth0 -p tcp --dport 80 conntrack --cstate NEW -j ACCEPT ip6tables -A INPUT -i eth0 -p icmp --icmp-type 8 -j ACCEPT ip6tables -t nat -A POSTROUTING -s 172.23.242.0/24 -j MASQUERADE -o eth0 ip6tables -A FORWARD -i vmbr1 -o vmbr0 -p tcp --dport 53 conntrack --cstate NEW -j ACCEPT ip6tables -A FORWARD -i vmbr1 -o vmbr0 -p udp --dport 53 conntrack --cstate NEW -j ACCEPT ;; stop) echo "stoppe firewall" ip6tables -F ip6tables -F -t nat ip6tables -P INPUT ACCEPT ip6tables -P OUTPUT ACCEPT ip6tables -P FORWARD ACCEPT ;; esac
- Verwendete Syntax
- -i : Hier wird die Schnittstelle definiert auf der die Anfragen an die Firewall eingehen
- -o: Hier wird die Schnittstelle definiert auf die Anfragen die Firewall verlassen
- FORWARD: Damit die Firewall weiß, dass das Paket weitergeleitet werden soll
- --dport: Hier wird der Zielport der Anfragen definiert
MULTIPORT
Ausser dem DNS müssen zum arbeiten noch andere Ports geöffnet werden. Um nicht für jeden eine einzelne Regel anlegen zu müssen bietet sich die Nutzung des Parameters Multiport an.
#!/bin/bash case $1 in start) echo "starte firewall" ip6tables -F ip6tables -F -t nat ip6tables -P INPUT DROP ip6tables -P OUTPUT DROP ip6tables -P FORWARD DROP ip6tables -A INPUT conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A FORWARD conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A OUTPUT conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A OUTPUT -o lo -j ACCEPT ip6tables -A INPUT -i lo -j ACCEPT ip6tables -A INPUT -i eth0 -s 192.168.241.10 -p tcp --dport 22 conntrack --cstate NEW -j ACCEPT ip6tables -A OUTPUT -o eth0 -p tcp -d 192.168.240.21 --dport 53 conntrack --cstate NEW -j ACCEPT ip6tables -A OUTPUT -o eth0 -p udp -d 192.168.240.21 --dport 53 conntrack --cstate NEW -j ACCEPT ip6tables -A OUTPUT -o eth0 -p tcp --dport 80 conntrack --cstate NEW -j ACCEPT ip6tables -A INPUT -i eth0 -p icmp --icmp-type 8 -j ACCEPT ip6tables -t nat -A POSTROUTING -s 172.23.242.0/24 -j MASQUERADE -o eth0 ip6tables -A FORWARD -i vmbr1 -o vmbr0 -p tcp --dport 53 conntrack --cstate NEW -j ACCEPT ip6tables -A FORWARD -i vmbr1 -o vmbr0 -p udp --dport 53 conntrack --cstate NEW -j ACCEPT ip6tables -A FORWARD -i vmbr1 -o vmbr0 -p tcp -m multiport --dport 22,25,80,443,143 conntrack --cstate NEW -j ACCEPT ;; stop) echo "stoppe firewall" ip6tables -F ip6tables -F -t nat ip6tables -P INPUT ACCEPT ip6tables -P OUTPUT ACCEPT ip6tables -P FORWARD ACCEPT ;; esac
- Verwendete Syntax
- -m multiport: Hiermit weiß die Firewall, daß unter --dport mehrere Ports hinterlegt wurden
SNAT
SNAT ist Masquerading sehr ähnlich, der einzige Unterschied besteht darin das man sich bei SNAT die ersetzende IP-Adresse wählen kann. Da wir schon Masquerading eingebaut haben, hängen wir SNAT nicht auch noch mit in unsere Firewall.
Hier aber ein Beispiel:
ip6tables -t nat -A POSTROUTING -j SNAT -o eth0 -s 172.23.242.0/24 --to-source 192.168.242.100
- Verwendete Syntax
- -j SNAT: Die auszuführende Aktion, hier SNAT
- --to-source 192.168.242.100: Die Angabe zu welcher IP-Adresse ersetzt wird, hier die des Routers.
NETMAP
Eine weiter Form des NAT in ip6tables ist NETMAP. Statt wie bei MASQUERADE oder SNAT, ersetzt NETMAP die Quell Adresse nicht nur mit einer bestimmten Adresse, sondern bildet das gesamte Quell Netz auf ein anderes ab.
SNAT-Beispiel:
ip6tables -t nat -A POSTROUTING -j NETMAP -o eth0 -s 172.23.242.0/24 --to 195.145.95.0/24
DNAT-Beispiel:
ip6tables -t nat -A PREROUTING -j NETMAP -i eth0 -d 195.145.95.0/24 --to 172.23.242.0/24
- Verwendete Syntax
- -j NETMAP: Aktion die auf Pakete ausgeführt wird, hier NETMAP
DNAT, port forwarding
Da das interne Netz nicht von außen angesprochen werden kann, wie es bei normalen Routern die ins Internet führen ja auch der Fall ist, bedient man sich hierfür einer Technik namens port forwarding, was bedeutet das ein Programm das über einen bestimmten Port mit dem Router kommuniziert an eine andere IP-Adresse und einen anderen Port weitergeleitet wird.
#!/bin/bash case $1 in start) echo "starte firewall" ip6tables -F ip6tables -F -t nat ip6tables -P INPUT DROP ip6tables -P OUTPUT DROP ip6tables -P FORWARD DROP ip6tables -A INPUT conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A FORWARD conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A OUTPUT conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A OUTPUT -o lo -j ACCEPT ip6tables -A INPUT -i lo -j ACCEPT ip6tables -A INPUT -i eth0 -s 192.168.241.10 -p tcp --dport 22 conntrack --cstate NEW -j ACCEPT ip6tables -A OUTPUT -o eth0 -p tcp -d 192.168.240.21 --dport 53 conntrack --cstate NEW -j ACCEPT ip6tables -A OUTPUT -o eth0 -p udp -d 192.168.240.21 --dport 53 conntrack --cstate NEW -j ACCEPT ip6tables -A OUTPUT -o eth0 -p tcp --dport 80 conntrack --cstate NEW -j ACCEPT ip6tables -A INPUT -i eth0 -p icmp --icmp-type 8 -j ACCEPT ip6tables -t nat -A POSTROUTING -j MASQUERADE -o eth0 -s 172.23.242.0/24 ip6tables -t nat -A PREROUTING -j DNAT -i eth0 -p tcp --dport 3333 --to-dest 172.23.242.100:22 ;; stop) echo "stoppe firewall" ip6tables -F ip6tables -F -t nat ip6tables -P INPUT ACCEPT ip6tables -P OUTPUT ACCEPT ip6tables -P FORWARD ACCEPT ;; esac
- Verwendete Syntax
- PREROUTING: Die Aktion soll noch vor einer Routingentscheidung durchgeführt werden
DNAT für alle Protokolle/Ports - one IP
ip6tables -t nat -A PREROUTING -d $1stIP -j DNAT --to-destination $2ndIP
Alle Pakete die an die Adresse $1stIP gehen werden an die Adresse $2nIP umgeleitet
DNAT auf einen Port
ip6tables -t nat -A PREROUTING -p tcp -d $1stIP --dport $EINGANGSPORT -j DNAT --to-destination $2ndIP
Alle Pakete die an den Port $EINGANGSPORT der Adresse $1stIP gehen werden an die Adresse $2nIP umgeleitet
DNAT Portumleitung
ip6tables -t nat -A PREROUTING -p tcp -d $1stIP --dport $EINGANGSPORT -j DNAT --to-destination $2ndIP:$WUNSCHPORT
Alle Pakete die an den Port $EINGANGSPORT der Adresse $1stIP gehen werden an den Port $WUNSCHPORT der Adresse $2nIP umgeleitet
(Wenn die Destination IP der Host ist, reicht die Schnittstellenangabe! ip6tables -t nat -A PREROUTING -p tcp -i $WANDEV --dport $EINGANGSPORT -j DNAT --to-destination $2ndIP:$WUNSCHPORT
FORWARD
ip6tables -t nat -A PREROUTING -j DNAT -i $WAN -p tcp --dport $EINGANGSPORT --to $2ndIP:$WUNSCHPORT ip6tables -A FORWARD -p tcp -d $2ndIP --dport $WUNSCHPORT -j ACCEPT conntrack --cstate NEW
FULL NAT
ip6tables -t nat -A PREROUTING -d $1stIP -j DNAT --to-destination $2ndIP ip6tables -t nat -A POSTROUTING -s $2ndIP -j SNAT --to-source $1stIP
- Verwendete Syntax
- PREROUTING: Paket wird nach der Routingentscheidung geändert
- -j DNAT: Aktion die auf Pakete ausgeführt wird, hier DNAT
- --to-dest 172.23.242.100:22: IP-Adresse und Port zu denen weitergeleitet wird
- In einem Satz:
- Ändere bei allen Paketen die auf eth0 ankommen und den Port 3333 ansprechen die Ziel Adresse zu 172.23.242.100 und Port zu 22
Logging
Damit wir sehen können was so alles an unserer Firewall abprallt, nicht nur um Störenfriede zu erkennen, sondern auch um zu sehen was wir vielleicht für uns freischalten müssen, können wir ein logging einrichten das automatisch alle Pakete die nicht durchgelassen wurden an den syslog deamon weitergeben der die Vorkommnisse in die syslog schreibt.
#!/bin/bash case $1 in start) echo "starte firewall" ip6tables -F ip6tables -F -t nat ip6tables -P INPUT DROP ip6tables -P OUTPUT DROP ip6tables -P FORWARD DROP ip6tables -A INPUT conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A FORWARD conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A OUTPUT conntrack --cstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A OUTPUT -o lo -j ACCEPT ip6tables -A INPUT -i lo -j ACCEPT ip6tables -A INPUT -i eth0 -s 192.168.241.10 -p tcp --dport 22 conntrack --cstate NEW -j ACCEPT ip6tables -A OUTPUT -o eth0 -p tcp -d 192.168.240.21 --dport 53 conntrack --cstate NEW -j ACCEPT ip6tables -A OUTPUT -o eth0 -p udp -d 192.168.240.21 --dport 53 conntrack --cstate NEW -j ACCEPT ip6tables -A OUTPUT -o eth0 -p tcp --dport 80 conntrack --cstate NEW -j ACCEPT ip6tables -A INPUT -i eth0 -p icmp --icmp-type 8 -j ACCEPT ip6tables -t nat -A POSTROUTING -j MASQUERADE -o eth0 -s 172.23.242.0/24 ip6tables -t nat -A PREROUTING -j DNAT -i eth0 --dport 3333 --to-dest 172.23.242.100:22 ip6tables -A INPUT -j LOG --log-prefix "--ip6tables-in--" ip6tables -A OUTPUT -j LOG --log-prefix "--ip6tables-out--" ip6tables -A FORWARD -j LOG --log-prefix "--ip6tables-for--" ;; stop) echo "stoppe firewall" ip6tables -F ip6tables -F -t nat ip6tables -P INPUT ACCEPT ip6tables -P OUTPUT ACCEPT ip6tables -P FORWARD ACCEPT ;; esac
Diese Zeilen sollten ganz am Ende bleiben, damit auch sichergestellt ist das nur Pakete die alle Regeln durchlaufen haben dort landen.
- Verwendete Syntax
- -j LOG: Aktion die auf Pakete ausgeführt wird, hier LOG
- --log-prefix "--ip6tables-in--": Schreibt --ip6tables-in-- , vor jedes Paket das am INPUT verworfen wurde,
logging file ändern
netstat-nat and conntrack
- netstat-nat (vielleicht veraltet)
- conntrack
contrack table löschen
- conntrack -F
DNAT weiterleitung bis auf einen port
#!/bin/bash SSHPORT="4567" 1stIP="WEITERLEITUNGS-IP" 2ndIP="CONNECT-IP" case $1 in start) echo "starte firewall" ip6tables -F ip6tables -F -t nat ip6tables -F -t mangle ip6tables -X ip6tables -X -t nat ip6tables -X -t mangle ip6tables -t nat -N innat ip6tables -t nat -A innat -j RETURN -p tcp --dport $SSHPORT ip6tables -t nat -A innat -j DNAT --to $1stIP ip6tables -t nat -A PREROUTING -d $2ndIP -j innat ip6tables -t nat -A POSTROUTING -j SNAT -s $1stIP --to $2ndIP ;; stop) echo "stoppe firewall" ip6tables -F ip6tables -F -t nat ip6tables -F -t mangle ip6tables -X ip6tables -X -t nat ip6tables -X -t mangle ;; esac
- Verwendete Syntax
- -N innat: Hier wird eine neue Kette mit dem Namen "innat" angelegt
mark
ip6tables -t mangle -A PREROUTING -j MARK -p tcp --dport 25 --set-mark 9 ip6tables -t nat -A PREROUTING -j REDIRECT -p tcp --dport 25 --to 52525 ip6tables -A INPUT -j ACCEPT -m mark --mark 9
Alle ankommenden Pakete, die den angegebenen Bedingungen entsprechen (hier: TCP-Pakete mit Zielport 25) werden markiert. Es sind bis zu 32 verschiedene Markierungen möglich.
Anhand dieser Markierungen können die Pakete nun, wie in unserem Beispiel auf einen anderen Port (52525) umgeleitet werden, ohne, dass dieser Port nach aussen geöffnet werden muss.
Weiterhin werden im obigen Beispiel alle eingehenden Pakete, die den Marker 9 targen automatisch von der Firewall durchgelassen.
Mangle
MSS Reduktion
ip6tables -t mangle -A FORWARD -p tcp -i $LAN -o $WAN --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1400
Markieren und Freischalten
ip6tables -t mangle -A PREROUTING -j MARK -i $WAN -p tcp --dport 22 -d $TELIP --set-mark 0x8 ip6tables -t nat -A PREROUTING -j DNAT -i $WAN -p tcp --dport 22 -d $TELIP --to 192.168.244.1:8472 ip6tables -t filter -A FORWARD -j ACCEPT -m mark --mark 0x8
VPN Tunnel zulassen
Über den switch policy ist es möglich alle Pakete, die zu einem bestimmten VPN-Tunnel gehören durch die Firewall zu lassen.
ACHTUNG!
Dies funktioniert nicht, wenn der Tunnel genattet wird!
Ein VPN-Tunnel
ip6tables -A FORWARD -i $LAN -o $WAN -s $LEFTNET -d $RIGHTNET -m policy --dir out --pol ipsec conntrack --cstate NEW -j ACCEPT
ip6tables -A FORWARD -i $WAN -o $LAN -s $RIGHTNET -d $LEFTNET -m policy --dir in --pol ipsec conntrack --cstate NEW -j ACCEPT
- Verwendete Syntax
- $LAN: Bezeichnet die dem Netzwerk zugewandte Schnittstelle
- $WAN: Bezeichnet die dem Internet zugewandte Schnittstelle
- $LEFTNET: Bezeichnet das auf unserer Seite hinter der Firewall liegende Netzwerk
- $RIGHTNET: Bezeichnet das auf der anderen Seite des VPN-Tunnels liegende Netzwerk
- -m policy: Ruft das Modul "policy" auf
- --pol ipsec: Bezeichnet die zu betrachtende policy. Hier IPSEC
- --dir in/out: Legt die Richtung fest in welcher Richtung die policy betrachtet werden soll
ip6tables -A INPUT -i eth0 -p esp conntrack --cstate NEW -j ACCEPT
ESP-Protokoll zulassen
Mehrere VPN-Tunnel
Wenn wir auf unserer Firewall mehrere Tunnel haben, die wir entsprechend filtern wollen, bietet es sich an eine neue Kette zu erstellen. Das Ergebnis ist zwar in beiden Fällen das Gleiche aber durch die Kette wird unsere Firewall übersichtlicher und wir sparen uns auch einiges an Schreibarbeit.
ip6tables -N vpn-in-accept ip6tables -A vpn-in-accept -m policy --dir in --pol ipsec conntrack --cstate NEW -j ACCEPT ip6tables -A vpn-in-accept -j RETURN ip6tables -N vpn-out-accept ip6tables -A vpn-out-accept -m policy --dir out --pol ipsec conntrack --cstate NEW -j ACCEPT ip6tables -A vpn-out-accept -j RETURN
Und nun wenden wir die neue Kette an
ip6tables -A FORWARD -i $LAN -o $WAN -s $LEFTNET -d $RIGHTNET -j vpn-out-accept ip6tables -A FORWARD -i $WAN -o $LAN -s $RIGHTNET -d $LEFTNET -j vpn-in-accept
Alle Pakete von einem VPN-Tunnel zulassen
Hier werden alle Pakete die von dem VPN Tunnel kommen zugelassen.
ip6tables -A FORWARD -i $WAN -m policy --pol ipsec --mode tunnel --dir in -j ACCEPT
limit module
modul laden
in jeder regel in der wir limits benutzen wollen müssen wir das modul laden
-m limit
optionen
- ip6tables -A INPUT -p icmp -m icmp -m limit --limit 4/second --limit-burst 10 -j ACCEPT
Das bedeutet folgendes:
- Es dürfen 4 Pakete pro Sekunde durchgelassen werden.
- Wenn mehr als 4 Pakete pro Sekunde kommen, dürfen insgesamt 10 Pakete ohne Limitierung durch.
- Nach diesen 10 Paketen, dürfen wieder nur 4 pro Sekunde durch.
- Wenn weniger als 4 Pakete pro Sekunde ankommen, wird die Differenz wieder frei (limit von 4-X Pakete/s) und steht wieder zum überziehen bereit.
--limit
als Begrenzung optionen kann man definieren wie viele aktionen pro zeiteinheit zugelassen werden
1/second,2/minute,3/hour,4/day, oder 1/s,2m/,3/h,4/d
–limit-burst
definiert wie viele aktionen mehr als die limitierung zugelassen werden bevor das definierte limit einsetzt
diese regel lässt bis zu 10 Verbindungen in einer Sekunde zu wird dies überschritten setzt die Limitierung von 4 ICMP Packeten pro Sekunden ein. Für jede Sekunde in der das Limit von 4 packeten nicht erreicht wird werden die übrigen erlaubten pakete dem burst wider gut geschrieben das heißt wen der burst voll ist dauert es 2,5 sekunden (ohne das icmp packete kommen) bis der burst wider seinen Ursprungswert ereicht oder 5 sekunden in denen pro sekunden 2 packete kommen
DoS atacken
Beschränkt die Anzahl der neuen tcp Verbindungen die wir aufbauen können auf 1 pro Sekunde
- ip6tables -A INPUT -p icmp -m icmp --icmp-type address-mask-request -j DROP
- ip6tables -A INPUT -p icmp -m icmp --icmp-type timestamp-request -j DROP
- ip6tables -A INPUT -p icmp -m icmp -m limit --limit 1/second -j ACCEPT
ftp
Vorrausetzung
- ip6tables -A FORWARD conntrack --cstate ESTABLISHED,RELATED -j ACCEPT
Basically newer kernels ( >= 4.7 ) are deprecating the automatic helper module's port assignment in favor of explicit rules.
Short fix to get the old behaviour:
- echo 1 > /proc/sys/net/netfilter/nf_conntrack_helper
Sowohl aktives als auch passives FTP wird nach laden der Module über den RELATED Status gehandled. Module laden
- modprobe -v nf_conntrack_ftp
- modprobe -v nf_nat_ftp
Client auf Server im Internet
- ip6tables -A FORWARD -i $LAN -o $WAN -p tcp --dport 21 conntrack --cstate NEW -j ACCEPT
FTP Server im LAN mit Inside NAT
- ip6tables -A FORWARD -i $WAN -o $LAN -p tcp --dport 21 -d $FTPSERVER_LAN conntrack --cstate NEW -j ACCEPT
- ip6tables -t nat -A PREROUTING -j DNAT -i $WAN -p tcp --dport 21 --to-dest $FTPSERVER_LAN