Iptables Filter
Zur Navigation springen
Zur Suche springen
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 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 mangle Tabellen ausgeblendet.
- Jedes Paket durchläuft nur eine Filter Kette
Installation
- apt install iptables
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
Test Lab
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 Policies
#!/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
Konfigurationsdatei
- Es macht hier Sinn mit Variablen zu arbeiten
- Da wir mit einem Shell Skript arbeiten, ist dies kein Problem
- Wir lagern die Variablen per source Kommando aus.
- Dazu legen wir eine Datei /usr/local/etc/firewall.cfg an
- Wir belegen sie entsprechend:
- cat /usr/local/etc/firewall.cfg
WANDEV="enp0s3" DMZDEV="enp0s8" LANDEV="enp0s9" DMZ="10.88.201.0/24" LAN="192.168.201.0/24" WANIP="192.168.6.201" SERVER="10.88.201.21" DESKTOP="192.168.201.11" HOST="192.168.6.200" DNS="192.168.6.200" PSEUDO="10.88.0.0/16"
ESTABLISHED und RELATED Pakete (Connection Tracking)
- iptables ist eine stateful Firewall
- Das 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
#Einlesen der Konfigurationsdatei
source /usr/local/etc/firewall.cfg
case $1 in
start)
echo "starte firewall"
#Löschen aller Reglen
iptables -F
iptables -F -t nat
#Setzen der Default Policy auf DROP
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
#Aktivieren des Connection Tracking Konzeptes
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"
#Löschen aller Reglen
iptables -F
iptables -F -t nat
#Setzen der Default Policy auf ACCEPT
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
;;
*)
echo "usage: $0 start|stop"
;;
esac
- Verwendete Syntax
- Die hier neu verwendeten Funktionen 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 zutreffenden Regeln
- 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
Erste Regeln
- Wir lassen jetzt unsere ersten Pakete durch das sogenannte "loopback device".
- Wir lassen jeden Traffic zu, der von der Firewall selbst initiert wird.
- Egal vorher kann auf den SSH Port zugegriffen werden.
- Man soll den die Firewall anpingen können.
#!/bin/bash
#Einlesen der Konfigurationsdatei
source /usr/local/etc/firewall.cfg
case $1 in
start)
echo "starte firewall"
#Löschen aller Reglen
iptables -F
iptables -F -t nat
#Setzen der Default Policy auf DROP
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
#Aktivieren des Connection Tracking Konzeptes
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
#ICMP echo-request freigeschaltet
iptables -A INPUT -p icmp --icmp-type echo-request -m state --state NEW -j ACCEPT
;;
stop)
echo "stoppe firewall"
#Löschen aller Reglen
iptables -F
iptables -F -t nat
#Setzen der Default Policy auf ACCEPT
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
;;
*)
echo "usage: $0 start|stop"
;;
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
- -p icmp: Protokoll icmp
- --icmp-type echo-request: nur echo requests
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
#Einlesen der Konfigurationsdatei
source /usr/local/etc/firewall.cfg
case $1 in
start)
echo "starte firewall"
#Löschen aller Reglen
iptables -F
iptables -F -t nat
#Setzen der Default Policy auf DROP
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
#Aktivieren des Connection Tracking Konzeptes
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
#ICMP echo-request freigeschaltet
iptables -A INPUT -p icmp --icmp-type echo-request -m state --state NEW -j ACCEPT
###Neuer Block Anfang###
#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--
###Neuer Block Ende###
;;
stop)
echo "stoppe firewall"
#Löschen aller Reglen
iptables -F
iptables -F -t nat
#Setzen der Default Policy auf ACCEPT
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
;;
*)
echo "usage: $0 start|stop"
;;
esac
Die Log
- 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
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 deaktiviert
- 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
Absichern von Netzen Das Skript
- Wir wollen als erstes den Zugang per ssh zum Server in der DMZ für den Host erlauben.
- Der weiteren soll der Server in die weite Welt pingen dürfen
- Der Nameserver des Klassensaals soll benutzt werden.
#!/bin/bash
#Einlesen der Konfigurationsdatei
source /usr/local/etc/firewall.cfg
case $1 in
start)
echo "starte firewall"
#Löschen aller Reglen
iptables -F
iptables -F -t nat
#Setzen der Default Policy auf DROP
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
#Aktivieren des Connection Tracking Konzeptes
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
#ICMP echo-request freigeschaltet
iptables -A INPUT -p icmp --icmp-type echo-request -m state --state NEW -j ACCEPT
#Freischalten der Server Administration über ssh vom HOST
iptables -A FORWARD -s $HOST -i $WANDEV -o $DMZDEV -p tcp --dport 22 -d $SERVER -m state --state NEW -j ACCEPT
#echo request vom server in die weite Welt erlauben
iptables -A FORWARD -s $SERVER -i $DMZDEV -p icmp --icmp-type 8 -m state --state NEW -j ACCEPT
#Nameserverzugriff auf DNS freischalten
iptables -A FORWARD -s $DMZ -i $DMZDEV -o $WANDEV -p udp --dport 53 -d $DNS -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"
#Löschen aller Reglen
iptables -F
iptables -F -t nat
#Setzen der Default Policy auf ACCEPT
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
;;
*)
echo "usage: $0 start|stop"
;;
esac
;Verwendete Syntax
- LANDEV="ens19": setzen von Variablen
- -p udp --dport 53: Protokoll udp Port 53
- -i $LANDEV -o $WANDEV: Richtung des ersten Paketes
Zugriff des Servers auf das Internet
- Um Pakete zu installieren braucht der Server Internet Zugriff
- Die geht leider nicht ohne NAT, dies wird im nächsten Kapitel ausführlicher besprochen.
#!/bin/bash
#Einlesen der Konfigurationsdatei
source /usr/local/etc/firewall.cfg
case $1 in
start)
echo "starte firewall"
#Löschen aller Reglen
iptables -F
iptables -F -t nat
#Setzen der Default Policy auf DROP
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
#Aktivieren des Connection Tracking Konzeptes
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
#ICMP echo-request freigeschaltet
iptables -A INPUT -p icmp --icmp-type echo-request -m state --state NEW -j ACCEPT
#Freischalten der Server Administration über ssh vom HOST
iptables -A FORWARD -s $HOST -i $WANDEV -o $DMZDEV -p tcp --dport 22 -d $SERVER -m state --state NEW -j ACCEPT
#echo request vom server in die weite Welt erlauben
iptables -A FORWARD -s $SERVER -i $DMZDEV -p icmp --icmp-type 8 -m state --state NEW -j ACCEPT
#Nameserverzugriff auf DNS freischalten
iptables -A FORWARD -s $DMZ -i $DMZDEV -o $WANDEV -p udp --dport 53 -d $DNS -m state --state NEW -j ACCEPT
#Zugriff auf HTTP und HTTPS
iptables -A FORWARD -s $DMZ -i $DMZDEV -o $WANDEV -p tcp --dport 80 -m state --state NEW -j ACCEPT
iptables -A FORWARD -s $DMZ -i $DMZDEV -o $WANDEV -p tcp --dport 443 -m state --state NEW -j ACCEPT
#Ab hier kommen die Nat Regeln
#Ausnamen vom SNAT
iptables -t nat -A POSTROUTING -s $DMZ -o $WANDEV -d $PSEUDO -j RETURN
iptables -t nat -A POSTROUTING -s $DMZ -o $WANDEV -d 192.168.6.0/24 -j RETURN
#SNAT der DMZ
iptables -t nat -A POSTROUTING -s $DMZ -o $WANDEV -j SNAT --to-source $WANIP
#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"
#Löschen aller Reglen
iptables -F
iptables -F -t nat
#Setzen der Default Policy auf ACCEPT
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
;;
*)
echo "usage: $0 start|stop"
;;
esac
Zugriff von außen auf den Server
- Die Dienste 25, 80 und 993 sollen von überallaus erreichbar sein.
#!/bin/bash
#Einlesen der Konfigurationsdatei
source /usr/local/etc/firewall.cfg
case $1 in
start)
echo "starte firewall"
#Löschen aller Reglen
iptables -F
iptables -F -t nat
#Setzen der Default Policy auf DROP
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
#Aktivieren des Connection Tracking Konzeptes
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
#ICMP echo-request freigeschaltet
iptables -A INPUT -p icmp --icmp-type echo-request -m state --state NEW -j ACCEPT
#Freischalten der Server Administration über ssh vom HOST
iptables -A FORWARD -s $HOST -i $WANDEV -o $DMZDEV -p tcp --dport 22 -d $SERVER -m state --state NEW -j ACCEPT
#echo request vom server in die weite Welt erlauben
iptables -A FORWARD -s $SERVER -i $DMZDEV -p icmp --icmp-type 8 -m state --state NEW -j ACCEPT
#Nameserverzugriff auf DNS freischalten
iptables -A FORWARD -s $DMZ -i $DMZDEV -o $WANDEV -p udp --dport 53 -d $DNS -m state --state NEW -j ACCEPT
#Zugriff auf HTTP und HTTPS
iptables -A FORWARD -s $DMZ -i $DMZDEV -o $WANDEV -p tcp --dport 80 -m state --state NEW -j ACCEPT
iptables -A FORWARD -s $DMZ -i $DMZDEV -o $WANDEV -p tcp --dport 443 -m state --state NEW -j ACCEPT
#Ports von überall erreichbar sein sollen.
iptables -A FORWARD -i $WANDEV -o $DMZDEV -m multiport -p tcp --dport 25,80,993 -d $SERVER -m state --state NEW -j ACCEPT
#Ab hier kommen die Nat Regeln
#Ausnamen vom SNAT
iptables -t nat -A POSTROUTING -s $DMZ -o $WANDEV -d $PSEUDO -j RETURN
iptables -t nat -A POSTROUTING -s $DMZ -o $WANDEV -d 192.168.6.0/24 -j RETURN
#SNAT der DMZ
iptables -t nat -A POSTROUTING -s $DMZ -o $WANDEV -j SNAT --to-source $WANIP
#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"
#Löschen aller Reglen
iptables -F
iptables -F -t nat
#Setzen der Default Policy auf ACCEPT
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
;;
*)
echo "usage: $0 start|stop"
;;
esac
- Mit dem Modul multiport kann man Ports des gleichen Protokolls zusammenfassen
... #Freischalten von smtp,http,imap,https,smtps,imaps 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 ...
Zugriff vom Lan auf die Welt
- Das Lan soll den Nameserver in der DMZ nutzen
- HTTP und HTTPS sollen von überall erreichbar sein.
#!/bin/bash
#Einlesen der Konfigurationsdatei
source /usr/local/etc/firewall.cfg
case $1 in
start)
echo "starte firewall"
#Löschen aller Reglen
iptables -F
iptables -F -t nat
#Setzen der Default Policy auf DROP
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
#Aktivieren des Connection Tracking Konzeptes
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
#ICMP echo-request freigeschaltet
iptables -A INPUT -p icmp --icmp-type echo-request -m state --state NEW -j ACCEPT
#Freischalten der Server Administration über ssh vom HOST
iptables -A FORWARD -s $HOST -i $WANDEV -o $DMZDEV -p tcp --dport 22 -d $SERVER -m state --state NEW -j ACCEPT
#echo request vom server in die weite Welt erlauben
iptables -A FORWARD -s $SERVER -i $DMZDEV -p icmp --icmp-type 8 -m state --state NEW -j ACCEPT
#Nameserverzugriff auf DNS freischalten
iptables -A FORWARD -s $DMZ -i $DMZDEV -o $WANDEV -p udp --dport 53 -d $DNS -m state --state NEW -j ACCEPT
#Zugriff auf HTTP und HTTPS
iptables -A FORWARD -s $DMZ -i $DMZDEV -o $WANDEV -p tcp --dport 80 -m state --state NEW -j ACCEPT
iptables -A FORWARD -s $DMZ -i $DMZDEV -o $WANDEV -p tcp --dport 443 -m state --state NEW -j ACCEPT
#Ports von überall erreichbar sein sollen.
iptables -A FORWARD -i $WANDEV -o $DMZDEV -m multiport -p tcp --dport 25,80,993 -d $SERVER -m state --state NEW -j ACCEPT
#Nameserverzugriff von LAN auf DNS in der DMZ freischalten
iptables -A FORWARD -s $LAN -i $LANDEV -o $DMZDEV -p udp --dport 53 -d $SERVER -m state --state NEW -j ACCEPT
#http und https in die weite Welt
iptables -A FORWARD -s $LAN -i $LANDEV -o $WANDEV -m multiport -p tcp --dport 80,443 -m state --state NEW -j ACCEPT
#icmp in die weite Welt
iptables -A FORWARD -s $LAN -i $LANDEV -o $WANDEV -p icmp --icmp-type 8 -m state --state NEW -j ACCEPT
#Ab hier kommen die Nat Regeln
#SNAT der LAN
iptables -t nat -A POSTROUTING -s $LAN -o $WANDEV -j SNAT --to-source $WANIP
#Ausnamen vom SNAT der DMZ
iptables -t nat -A POSTROUTING -s $DMZ -o $WANDEV -d $PSEUDO -j RETURN
iptables -t nat -A POSTROUTING -s $DMZ -o $WANDEV -d 192.168.6.0/24 -j RETURN
#SNAT der DMZ
iptables -t nat -A POSTROUTING -s $DMZ -o $WANDEV -j SNAT --to-source $WANIP
#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"
#Löschen aller Reglen
iptables -F
iptables -F -t nat
#Setzen der Default Policy auf ACCEPT
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
;;
*)
echo "usage: $0 start|stop"
;;
esac
Eigene Ketten
- Man kann eigene Ketten erzeugen und dort dann Regeln setzen.
- Über die Default-Ketten kann man in diese Ketten springen, um die Regeln dort abzuarbeiten.
Eigene Ketten Beispiel 1
- Hier erstellen wir eigene Ketten für die jeweligen Richtungen
- Wir springen je nach Richtung in die dazugehörige Kette
- In diesen eigenen Ketten schalten wir dann frei was wir brauchen
- Wenn nichts zutrifft wird zurück gesprungen und die Default Policy trifft.
#!/bin/bash
#Einlesen der Konfigurationsdatei
source /usr/local/etc/firewall.cfg
case $1 in
start)
echo "starte firewall"
#Löschen aller Reglen
iptables -F
iptables -F -t nat
#Löscheneigener Ketten
iptables -X
iptables -X -t nat
#Setzen der Default Policy auf DROP
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
#Aktivieren des Connection Tracking Konzeptes
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
#ICMP echo-request freigeschaltet
iptables -A INPUT -p icmp --icmp-type echo-request -m state --state NEW -j ACCEPT
iptables -N wan2lan
iptables -N lan2wan
iptables -N wan2dmz
iptables -N dmz2wan
iptables -N lan2dmz
iptables -N dmz2lan
iptables -A FORWARD -i $WANDEV -o $LANDEV -m state --state NEW -j wan2lan
iptables -A FORWARD -i $LANDEV -o $WANDEV -m state --state NEW -j lan2wan
iptables -A FORWARD -i $WANDEV -o $DMZDEV -m state --state NEW -j wan2dmz
iptables -A FORWARD -i $DMZDEV -o $WANDEV -m state --state NEW -j dmz2wan
iptables -A FORWARD -i $LANDEV -o $DMZDEV -m state --state NEW -j lan2dmz
iptables -A FORWARD -i $DMZDEV -o $LANDEV -m state --state NEW -j dmz2lan
#Freischalten der Server Administration über ssh vom HOST
iptables -A wan2dmz -s $HOST -p tcp --dport 22 -d $SERVER -j ACCEPT
#echo request vom server in die weite Welt erlauben
iptables -A dmz2wan -s $SERVER -p icmp --icmp-type 8 -j ACCEPT
iptables -A dmz2lan -s $SERVER -p icmp --icmp-type 8 -j ACCEPT
#Nameserverzugriff auf DNS freischalten
iptables -A dmz2wan -s $DMZ -p udp --dport 53 -d $DNS -j ACCEPT
#Nameserverzugriff auf DNS freischalten normalerweise bei Clients nicht notwendig
iptables -A dmz2wan -s $DMZ -p tcp --dport 53 -d $DNS -j ACCEPT
#Zugriff auf HTTP und HTTPS
iptables -A dmz2wan -s $DMZ -p tcp --dport 80 -j ACCEPT
iptables -A dmz2wan -s $DMZ -p tcp --dport 443 -j ACCEPT
#Ports von überall erreichbar sein sollen.
iptables -A wan2dmz -m multiport -p tcp --dport 25,80,993 -d $SERVER -j ACCEPT
#Nameserverzugriff von LAN auf DNS in der DMZ freischalten
iptables -A lan2dmz -s $LAN -p udp --dport 53 -d $SERVER -j ACCEPT
#http und https in die weite Welt
iptables -A lan2wan -s $LAN -m multiport -p tcp --dport 80,443 -j ACCEPT
#icmp in die weite Welt
iptables -A lan2wan -s $LAN -p icmp --icmp-type 8 -j ACCEPT
#Ab hier kommen die Nat Regeln
#Ausnahmen vom SNAT
iptables -t nat -A POSTROUTING -s $DMZ -o $WANDEV -d $PSEUDO -j RETURN
iptables -t nat -A POSTROUTING -s $DMZ -o $WANDEV -d 192.168.6.0/24 -j RETURN
#SNAT der DMZ
iptables -t nat -A POSTROUTING -s $DMZ -o $WANDEV -j SNAT --to-source $WANIP
iptables -t nat -A POSTROUTING -s $LAN -o $WANDEV -j SNAT --to-source $WANIP
#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"
#Löschen aller Reglen
iptables -F
iptables -F -t nat
#Setzen der Default Policy auf ACCEPT
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
;;
*)
echo "usage: $0 start|stop"
;;
esac
Eigene Ketten Beispiel 2
- Wir erstellen eigene Ketten je mit je einer Regel dass der Verkehr erlaubt ist.
- Wir springen pro Regel in die richtige Kette
#!/bin/bash
#Einlesen der Konfigurationsdatei
source /usr/local/etc/firewall.cfg
case $1 in
start)
echo "starte firewall"
#Löschen aller Reglen
iptables -F
iptables -F -t nat
#Löscheneigener Ketten
iptables -X
iptables -X -t nat
#Setzen der Default Policy auf DROP
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
#Aktivieren des Connection Tracking Konzeptes
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
#ICMP echo-request freigeschaltet
iptables -A INPUT -p icmp --icmp-type echo-request -m state --state NEW -j ACCEPT
iptables -N wan2lan
iptables -A wan2lan -i $WANDEV -o $LANDEV -m state --state NEW -j ACCEPT
iptables -N lan2wan
iptables -A lan2wan -i $LANDEV -o $WANDEV -m state --state NEW -j ACCEPT
iptables -N wan2dmz
iptables -A wan2dmz -i $WANDEV -o $DMZDEV -m state --state NEW -j ACCEPT
iptables -N dmz2wan
iptables -A dmz2wan -i $DMZDEV -o $WANDEV -m state --state NEW -j ACCEPT
iptables -N lan2dmz
iptables -A lan2dmz -i $LANDEV -o $DMZDEV -m state --state NEW -j ACCEPT
iptables -N dmz2lan
iptables -A dmz2lan -i $DMZDEV -o $LANDEV -m state --state NEW -j ACCEPT
#Freischalten der Server Administration über ssh vom HOST
iptables -A FORWARD -s $HOST -p tcp --dport 22 -d $SERVER -j wan2dmz
#echo request vom server in die weite Welt erlauben
iptables -A FORWARD -s $SERVER -p icmp --icmp-type 8 -j dmz2wan
iptables -A FORWARD -s $SERVER -p icmp --icmp-type 8 -j dmz2lan
#Nameserverzugriff auf DNS freischalten
iptables -A FORWARD -s $DMZ -p udp --dport 53 -d $DNS -j dmz2wan
#Nameserverzugriff auf DNS freischalten normalerweise bei Clients nicht notwendig
iptables -A FORWARD -s $DMZ -p tcp --dport 53 -d $DNS -j dmz2wan
#Zugriff auf HTTP und HTTPS
iptables -A FORWARD -s $DMZ -p tcp --dport 80 -j dmz2wan
iptables -A FORWARD -s $DMZ -p tcp --dport 443 -j dmz2wan
#Ports von überall erreichbar sein sollen.
iptables -A FORWARD -m multiport -p tcp --dport 25,80,993 -d $SERVER -j wan2dmz
#Nameserverzugriff von LAN auf DNS in der DMZ freischalten
iptables -A FORWARD -s $LAN -p udp --dport 53 -d $SERVER -j lan2dmz
#http und https in die weite Welt
iptables -A FORWARD -s $LAN -m multiport -p tcp --dport 80,443 -j lan2wan
#icmp in die weite Welt
iptables -A FORWARD -s $LAN -p icmp --icmp-type 8 -j lan2wan
#Ab hier kommen die Nat Regeln
#Ausnamen vom SNAT
iptables -t nat -A POSTROUTING -s $DMZ -o $WANDEV -d $PSEUDO -j RETURN
iptables -t nat -A POSTROUTING -s $DMZ -o $WANDEV -d 192.168.6.0/24 -j RETURN
#SNAT der DMZ
iptables -t nat -A POSTROUTING -s $DMZ -o $WANDEV -j SNAT --to-source $WANIP
iptables -t nat -A POSTROUTING -s $LAN -o $WANDEV -j SNAT --to-source $WANIP
#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"
#Löschen aller Reglen
iptables -F
iptables -F -t nat
#Setzen der Default Policy auf ACCEPT
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
;;
*)
echo "usage: $0 start|stop"
;;
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
- Cmd-Channel
- Date-Channel
- Es besitzt zudem 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 Regeln kommen zum Einsatz
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -p tcp --dport 21 -s $LAN -i $LANDEV -o $WANDEV -m state --state NEW -j ACCEPT
Fall aktives FTP
- Client macht eine Cmd Verbindung zum Server zu Port 21 auf
- Die NEW Regel bewirkt, dass 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 RELATED 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, dass das Paket durch gelassen wird.
- Das Antwortpaket 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 RELATED Status
- Alle Folgepakete matchen im Status "ESTABLISHED"
Limit Module
Modul laden
- Für jede Regel in der wir limits benutzen wollen, müssen wir das Modul laden.
-m limit
limit-Modul
- Erlaubt eine Grenze für die Anzahl der in Übereinstimmung mit einer Regel zu überprüfenden Pakete zu setzen.
- Dies ist besonders nützlich, wenn zusammen mit einem LOG-Target verwendet.
- Auf diese Weise verhindern Sie, dass die zahlreichen übereinstimmenden Pakete Ihre Protokolldateien nicht mit wiederholten Nachrichten überfüllen
- Und somit zu viele Systemressourcen beanspruchen.
- Das limit-Modul erlaubt die folgenden Optionen:
- --limit
- Bestimmt die Zahl der Übereinstimmungen innerhalb eines bestimmten Zeitraums,
- Dies wird der mit einem Anzahl- und Zeitmodifikator in dem Format <number> /<Zeit> angegeben.
- Mit --limit 5/hour, zum Beispiel, kann die Regel nur 5 Mal in einer Stunde übereinstimmen.
- Wenn keine Anzahl- und Zeitarbeiter angegeben sind, wird der Standardwert 3/hour angenommen.
--limit-burst
- Setzt eine Grenze für die Anzahl von Paketen, deren Übereinstimmung mit einer Regel gleichzeitig geprüft --limit-Option verwendet werden.
- Man kann außerdem einen maximalen Grenzwert setzen.
- Wenn keine Zahl festgelegt wird, können anfangs nur fünf Pakete in Übereinstimmung mit der Regel überprüft werden.
Optionen
- iptables -A INPUT -m limit --limit 2/minute --limit-burst 5 -j LOG --log-prefix "--iptables-drop-in--"
- Das bedeutet folgendes
- Es werden anfangs 5 Pakete geloggt
- Ab der 2. Minute können nur noch 2 Pakete geloggt werden.
- wenn das Limit nicht erreicht wird, regeneriert sich der Limitburst um 1 pro Zeiteinheit, in unserem Fall 1 pro Minute.
- 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.
DoS atacken
- Beschränkt die Anzahl der neuen tcp Verbindungen, die wir aufbauen können auf 1 pro Sekunde
- iptables -A INPUT -p icmp -m icmp --icmp-type address-mask-request -j DROP
- iptables -A INPUT -p icmp -m icmp --icmp-type timestamp-request -j DROP
- iptables -A INPUT -p icmp -m icmp -m limit --limit 1/second -j ACCEPT