Iptables Filter
Funktionsweise
- Die Regeln werden nacheinander auf das Paket angewandt, wenn eine Regel greift hört der Verarbeitungsprozess auf.
- Ansonsten wird die Default Policy angewandt.
| filter table | |||||
|---|---|---|---|---|---|
| INPUT | OUTPUT | FORWARD | |||
| rule 1 | rule 1 | rule 1 | |||
| rule 2 | rule 2 | rule 2 | |||
| rule 3 | rule 3 | rule 3 | |||
| rule 4 | rule 4 | rule 4 | |||
| POLICY | POLICY | POLICY | |||
Die filter Tabelle
Die Ketten der filter Tabelle
- FORWARD: für Pakte, die über eine Schnittstelle hereinkommen und den Rechner auch wieder verlassen.
- INPUT: für Pakete, die über eine Schnittstelle hereinkommen und einen Dienst auf dem Rechner ansprechen
- OUTPUT: für herausgehende Pakete, die von einem lokalen Dienst erzeugt wurden.
- In diesem Schaubild sind nat und mangel Tabellen ausgeblendet.
- Jedes Paket durchläuft nur eine Filter Kette
Die Filter Regeln der filter Tabelle
Regeln werden mit iptables erstellt und an Ziele geschickt.
Ziele der filter Tabelle
- 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
Syntax Allgemein
Die Momentan in der filter Tabelle gesetzten Ketten und Regeln sieht man mit
- iptables -nvL -t filter
-L # Listing -t filter # anzeigen der filter Kette -n # numerical -v # verbose
Da -t filter Default ist, kann man es auch weglassen,
- iptables -nvL -t filter
Firewallscript
Der Rumpf
Zuerst wird in dem firewall-Skript ein case start - stop Block angelegt:
- cd /usr/local/sbin/
- vi firewall
#!/bin/bash case $1 in start) echo "starte firewall" ;; stop) echo "stoppe firewall" ;; *) echo "usage: $0 start|stop" ;; esac
Script ausführbar machen
- chmod +x firewall
Testen des Scripts
- firewall start
- firewall stop
- firewall
Flushen aller vorhergehenden Regeln
#!/bin/bash
case $1 in
start)
echo "starte firewall"
iptables -F
;;
stop)
echo "stoppe firewall"
iptables -F
;;
esac
- Die neuen Funktionen die wir hier verwenden beinhalten
- -F löscht alle Regeln aller Ketten
Setzen der Default Policys
#!/bin/bash case $1 in start) echo "starte firewall" iptables -F iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP ;; stop) echo "stoppe firewall" iptables -F iptables -P INPUT ACCEPT iptables -P OUTPUT ACCEPT iptables -P FORWARD ACCEPT ;; esac
- Die neuen Funktionen die wir hier verwenden beinhalten
- -P INPUT DROP/ACCEPT setzt die default policy auf DROP bzw. ACCEPT
Momentaner Status nach firewall stop
- iptables -nvL
Chain INPUT (policy ACCEPT 56 packets, 3824 bytes) pkts bytes target prot opt in out source destination Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 35 packets, 7884 bytes) pkts bytes target prot opt in out source destination
ESTABLISHED und RELATED Pakete (Connection Tracking)
- iptables ist eine stateful Firewall
- Die bedeutet das über Verbindungen Buch geführt wird.
- Wenn das erste Paket erlaubt ist, gilt eine Verbindung als ESTABLISHED
- RELATED Paketes stehen in Beziehung zu einer Verbindung, beispielsweise ICMP Nachrichten.
- Die Idee ist nun alle ESTABLISHED und RELATED Pakete freizuschalten und nur zu entscheiden ob das erste Paket durch darf oder nicht.
Wir setzen dies mit folgenden Befehlen um:
#!/bin/bash case $1 in start) echo "starte firewall" iptables -F iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT ;; stop) echo "stoppe firewall" iptables -F iptables -P INPUT ACCEPT iptables -P OUTPUT ACCEPT iptables -P FORWARD ACCEPT ;; esac
- Verwendete Syntax
- Die neuen Funktionen die wir hier verwenden beinhalten:
- -m state: Ein Modul von iptables, das erkennt ob ein Paket eine Verbindung initiiert oder zu einer bereits errichteten Verbindung gehört.
- --state ESTABLISHED,RELATED: Der Status nach dem das Paket untersucht wird, wobei...
- ESTABLISHED: ... die Pakete sind, die zu einer Verbindung gehören. Also frühestens das 2 Paket.
- RELATED: ... die Pakete sind, die zwar neu sind, aber in einer Beziehung zu einer anderen Verbindung stehen.
- -j ACCEPT Regel springt zum ACCEPT Ziel.
Die ersten Regeln die auch treffen
- Nun haben wir zwar ein paar Regeln, aber noch würde keine jemals zutreffen, da das erste Paket jeder Verbindung immer ignoriert wird.
- Wenn wir diese Firewall aktivieren würden, dann wäre unser eigener Router nichteinmal mehr in der Lage mit sich selbst zu kommunizieren.
- Wir können momentan auch nicht von außen darauf zugreifen.
- Desweiteren kann der Rechner nicht mit der Außenwelt kommunizieren. Das aktivieren der Firewall würde also eine SSH-Verbindung unterbrechen
Das loopbackdevice
Wir lassen jetzt unsere ersten Pakete durch das sogenannte "loopback device":
#!/bin/bash case $1 in start) echo "starte firewall" iptables -F iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT #Verkehr von Rechner hinaus freischalten iptables -A OUTPUT -m state --state NEW -j ACCEPT #Verkehr über das loopback device freischalten iptables -A INPUT -i lo -m state --state NEW -j ACCEPT #Verkehr zum Rechner ZUM TCP PORT 22 erlauben iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT ;; stop) echo "stoppe firewall" iptables -F iptables -P INPUT ACCEPT iptables -P OUTPUT ACCEPT iptables -P FORWARD ACCEPT ;; esac
- Verwendete Syntax
- -o lo: output interface hier lo
- -i lo: input interface hier lo
- -m state: laden des state Moduls
- --state NEW: Das erste Paket einer Verbindung
- -j ACCEPT: springe zum ACCEPT Ziel
- -p tcp: Protokoll tcp
- --dport 22: Port 22
Momentaner Status nach firewall start
- iptables -nvL
Chain INPUT (policy DROP 3 packets, 156 bytes)
pkts bytes target prot opt in out source destination
87 6836 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 state NEW
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 state NEW
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
Chain OUTPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
63 5880 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
2 188 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state NEW
Das Logging
- iptables kann in das syslog System loggen.
- Dies landet dann ohne weitere Konfigurationsmassnahmen in /var/log/syslog
- Die Idee ist nun kurz vor der Anwendung der Default Policy zu loggen.
- Somit sehen wir den abgelehnten Verkehr.
- Das LOG Ziel beendet als einziges nicht die weitere Verarbeitung der Kette.
- Das bedeutet, dass man auch Pakete loggen kann, die man nicht ablehnt.
#!/bin/bash case $1 in start) echo "starte firewall" iptables -F iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT #Verkehr von Rechner hinaus freischalten iptables -A OUTPUT -m state --state NEW -j ACCEPT #Verkehr über das loopback device freischalten iptables -A INPUT -i lo -m state --state NEW -j ACCEPT #Verkehr zum Rechner ZUM TCP PORT 22 erlauben #Logging der Ketten vor dem Ablehnen der Pakete iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT iptables -A INPUT -j LOG --log-prefix "--iptables-drop-in--" iptables -A OUTPUT -j LOG --log-prefix "--iptables-drop-out--" iptables -A FORWARD -j LOG --log-prefix "--iptables-drop-for--" ;; stop) echo "stoppe firewall" iptables -F iptables -P INPUT ACCEPT iptables -P OUTPUT ACCEPT iptables -P FORWARD ACCEPT ;; esac
- Verwendete Syntax
- -j LOG: wird ans LOG Ziel gesendet
- --log-prefix "--iptables-for--": Wird dem Log vorangestellt.
Das Logging
- Wir schauen uns mit tail was aktuell gelogt wird
- tail -f /var/log/syslog | grep iptables
Aug 31 14:48:22 fw1 kernel: [ 398.101280] --iptables-drop-in--IN=eth0 OUT= MAC=5a:58:a5:d2:f8:95:96:83:0d:88:c6:1d:08:00 SRC=10.81.1.1 DST=10.82.227.12 LEN=84 TOS=0x00 PREC=0x00 TTL=62 ID=63817 DF PROTO=ICMP TYPE=8 CODE=0 ID=8 SEQ=1 Aug 31 14:48:23 fw1 kernel: [ 399.129448] --iptables-drop-in--IN=eth0 OUT= MAC=5a:58:a5:d2:f8:95:96:83:0d:88:c6:1d:08:00 SRC=10.81.1.1 DST=10.82.227.12 LEN=84 TOS=0x00 PREC=0x00 TTL=62 ID=64043 DF PROTO=ICMP TYPE=8 CODE=0 ID=8 SEQ=2 Aug 31 14:48:24 fw1 kernel: [ 400.153635] --iptables-drop-in--IN=eth0 OUT= MAC=5a:58:a5:d2:f8:95:96:83:0d:88:c6:1d:08:00 SRC=10.81.1.1 DST=10.82.227.12 LEN=84 TOS=0x00 PREC=0x00 TTL=62 ID=64086 DF PROTO=ICMP TYPE=8 CODE=0 ID=8 SEQ=3
Wir schalten icmp frei
... #ICMP echo-request freigeschaltet iptables -A INPUT -p icmp --icmp-type echo-request -m state --state NEW -j ACCEPT #Logging der Ketten vor dem Ablehnen der Pakete ...
- Verwendete Syntax
- -p icmp: Protokoll icmp
- --icmp-type echo-request: nur echo requests
Forwarding
- Um Pakete weiterzuleiten muss als erstes das FORWARDING im Kernel aktiviert werden.
Testen
- wenn man diesen Befehl absetzt und nichts zurück bekommt ist es deativiert
- sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 0
Aktivieren
- echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
- sysctl -p
net.ipv4.ip_forward = 1
Absichern von Netzen
- Es macht hier Sinn mit Variablen zu arbeiten
- Da wir mit einem Shell Skript arbeiten ist dies kein Problem
#!/bin/bash case $1 in start) LANDEV="ens19" WANDEV="eth0" LAN="10.82.243.0/24" WANIP="10.82.227.1" echo "starte firewall" #flushen der Regeln iptables -F #Default Policy setzen iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP #Connection Tracking iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT #Verkehr von Rechner hinaus freischalten iptables -A OUTPUT -m state --state NEW -j ACCEPT #Verkehr über das loopback device freischalten iptables -A INPUT -i lo -m state --state NEW -j ACCEPT #Verkehr zum Rechner ZUM TCP PORT 22 erlauben iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT #ping freischalten iptables -A INPUT -p icmp --icmp-type echo-request -m state --state NEW -j ACCEPT #ping und namensauflösung von innen freischalten iptables -A FORWARD -p icmp --icmp-type echo-request -s $LAN -i $LANDEV -o $WANDEV -m state --state NEW -j ACCEPT iptables -A FORWARD -p tcp --dport 53 -i $LANDEV -o $WANDEV -s $LAN -m state --state NEW -j ACCEPT iptables -A FORWARD -p udp --dport 53 -i $LANDEV -o $WANDEV -s $LAN -m state --state NEW -j ACCEPT #Logging der Ketten vor dem Ablehnen der Pakete iptables -A INPUT -j LOG --log-prefix "--iptables-drop-in--" iptables -A OUTPUT -j LOG --log-prefix "--iptables-drop-out--" iptables -A FORWARD -j LOG --log-prefix "--iptables-drop-for--" ;; stop) echo "stoppe firewall" iptables -F iptables -P INPUT ACCEPT iptables -P OUTPUT ACCEPT iptables -P FORWARD ACCEPT ;; esac
- Verwendete Syntax
- LANDEV="ens19": setzen von Variablen
- -p udp --dport 53: Protokoll udp Port 53
- -i $LANDEV -o $WANDEV: Richtung des ersten Paketes
Zusammenfassen von Ports
- Mit dem Modul multiport kann man porst des gleichen Protokolls zusammenfassen
... #Freischalten von smtp,http,imap,https,smtps,imps iptables -A FORWARD -m multiport -p tcp --dport 25,80,143,443,465,993 -i $LANDEV -o $WANDEV -s $LAN -m state --state NEW -j ACCEPT #Logging der Ketten vor dem Ablehnen der Pakete ...
Momentaner Status nach firewall start
- iptables -nvL
Chain INPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
100 7096 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 state NEW
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 state NEW
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 8 state NEW
0 0 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 LOG flags 0 level 4 prefix "--iptables-drop-in--"
Chain FORWARD (policy DROP 3 packets, 228 bytes)
pkts bytes target prot opt in out source destination
2 253 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
0 0 ACCEPT icmp -- ens19 eth0 10.82.243.0/24 0.0.0.0/0 icmptype 8 state NEW
0 0 ACCEPT tcp -- ens19 eth0 10.82.243.0/24 0.0.0.0/0 tcp dpt:53 state NEW
2 134 ACCEPT udp -- ens19 eth0 10.82.243.0/24 0.0.0.0/0 udp dpt:53 state NEW
0 0 ACCEPT tcp -- ens19 eth0 10.82.243.0/24 0.0.0.0/0 multiport dports 25,80,143,443,465,993 state NEW
3 228 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 LOG flags 0 level 4 prefix "--iptables-drop-for--"
Chain OUTPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
78 53584 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state NEW
0 0 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 LOG flags 0 level 4 prefix "--iptables-drop-out--"
Eigene Ketten
- Man kann eigene Ketten erzeugen und kann dort dann Regeln setzen.
- In diese Ketten kann man dann springen und die Regeln werden abgearbeiten.
#!/bin/bash case $1 in start) LANDEV="ens19" WANDEV="eth0" LAN="10.82.243.0/24" WANIP="10.82.227.1" echo "starte firewall" #flushen der Regeln iptables -F #löscht eigene Ketten iptables -X #Default Policy setzen iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP #Connection Tracking iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT #Verkehr von Rechner hinaus freischalten iptables -A OUTPUT -m state --state NEW -j ACCEPT #Verkehr über das loopback device freischalten iptables -A INPUT -i lo -m state --state NEW -j ACCEPT #Verkehr zum Rechner ZUM TCP PORT 22 erlauben iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT #ping freischalten iptables -A INPUT -p icmp --icmp-type echo-request -m state --state NEW -j ACCEPT iptables -N lan-to-wan iptables -A lan-to-wan -s $LAN -i $LANDEV -o $WANDEV -m state --state NEW -j ACCEPT #ping und namensauflösung von innen freischalten iptables -A FORWARD -p icmp --icmp-type echo-request -j lan-to-wan iptables -A FORWARD -p tcp --dport 53 -j lan-to-wan iptables -A FORWARD -p udp --dport 53 -j lan-to-wan #Freischalten von smtp,http,imap,https,smtps,imps iptables -A FORWARD -m multiport -p tcp --dport 25,80,143,443,465,993 -j lan-to-wan #Logging der Ketten vor dem Ablehnen der Pakete iptables -A INPUT -j LOG --log-prefix "--iptables-drop-in--" iptables -A OUTPUT -j LOG --log-prefix "--iptables-drop-out--" iptables -A FORWARD -j LOG --log-prefix "--iptables-drop-for--" ;; stop) echo "stoppe firewall" iptables -F iptables -P INPUT ACCEPT iptables -P OUTPUT ACCEPT iptables -P FORWARD ACCEPT ;; esac
- -X: löscht alle eignen Ketten der filter Tabelle
- -N lan-to-wan: erstellt eigene Kette in der filter Tabelle
- -i $LANDEV -o $WANDEV: Richtung des ersten Paketes
Spezialfälle
FTP
Prinzip
- Ftp funktioniert im Gegensatz zu den meisten anderen Protokollen über 2 Kanäle
- Es besitzt auch 2 Modi passiv und aktiv
- Prinzip von FTP
- Für Firewall ist ftp nicht so einfach zu handlen
- Man braucht sogenannte Helper Programme
- Um diese Helper Programme zu aktiveren sind 2 Schritte notwendig.
- Helper generell aktivieren
- echo net.netfilter.nf_conntrack_helper=1 >> /etc/sysctl.conf
- sysctl -p
- Laden des Moduls
- modprobe -v nf_conntrack_ftp
- Rebootfähig
- echo nf_conntrack_ftp >> /etc/modprobe.d/iptables.conf
Wie funktioniert es?
- 2 Regelen kommen zum Einsatz
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -p tcp --dport 21 -i $LAN -o $WAN -m state --staten NEW -j ACCEPT
Fall aktives FTP
- Client macht eine Cmd Verbindung zum Server zu Port 21 auf
- Die NEW Regel bewirkt das das Paket durch gelassen wird.
- Das Antwort Paket ist dann schon ESTABLISHED und darf passieren.
- Client teilt dem Server mit das er den Port 1027 für den Datenkanal geöffnet hat
- Helper Modul fängt diese Nachricht ab und teilt es dem Connection Tracking System mit.
- Server verbindet sich mit Client und wird durchgelassen wegen des RELATETD Status
- Alle Folgepakete matchen im Status "ESTABLISHED
Fall passives FTP
- Client macht eine Cmd Verbindung zum Server zu Port 21 auf
- Die NEW Regel bewirkt das das Paket durch gelassen wird.
- Das Antwort Paket ist dann schon ESTABLISHED und darf passieren.
- Client teilt dem Server mit das er den Port passives FTP will
- Server teilt dem Client den Port für den Datenkanal mit.
- Helper Modul fängt diese Nachricht ab und teilt es dem Connection Tracking System mit.
- Client verbindet sich mit Server und wird durchgelassen wegen des RELATETD Status
- Alle Folgepakete matchen im Status "ESTABLISHED


