Iptables Filter

Aus Xinux Wiki
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 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 Ports 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 dort dann Regeln setzen.
  • Über die Default-Ketten kann man in diese Ketten springen, um die Regeln dort abzuarbeiten.
#!/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

  1. Client macht eine Cmd Verbindung zum Server zu Port 21 auf
  2. Die NEW Regel bewirkt das das Paket durch gelassen wird.
  3. Das Antwort Paket ist dann schon ESTABLISHED und darf passieren.
  4. Client teilt dem Server mit das er den Port 1027 für den Datenkanal geöffnet hat
  5. Helper Modul fängt diese Nachricht ab und teilt es dem Connection Tracking System mit.
  6. Server verbindet sich mit Client und wird durchgelassen wegen des RELATETD Status
  7. Alle Folgepakete matchen im Status "ESTABLISHED

Fall passives FTP

  1. Client macht eine Cmd Verbindung zum Server zu Port 21 auf
  2. Die NEW Regel bewirkt das das Paket durch gelassen wird.
  3. Das Antwort Paket ist dann schon ESTABLISHED und darf passieren.
  4. Client teilt dem Server mit das er den Port passives FTP will
  5. Server teilt dem Client den Port für den Datenkanal mit.
  6. Helper Modul fängt diese Nachricht ab und teilt es dem Connection Tracking System mit.
  7. Client verbindet sich mit Server und wird durchgelassen wegen des RELATETD Status
  8. Alle Folgepakete matchen im Status "ESTABLISHED