# iptables — Linux-Firewall mit netfilter steuern

> Praxis-Guide zu iptables — die Linux-Firewall über netfilter steuern, mit Chains, Tables, Targets, NAT, Connection Tracking und persistenten Regeln.

Source: https://www.jpkc.com/db/cheatsheets/security/iptables/

<!-- PROSE:intro -->
iptables ist das klassische Frontend für die netfilter-Firewall im Linux-Kernel: Mit einem einzigen Befehl filterst du Pakete, baust NAT-Regeln oder schließt offene Ports ab. Regeln organisierst du in Tables (filter, nat, mangle, raw) und Chains (INPUT, OUTPUT, FORWARD), die jedes Paket der Reihe nach durchläuft, bis ein Target wie ACCEPT, DROP oder REJECT greift. Auf modernen Systemen löst nftables das Tool zunehmend ab – über iptables-nft bleibt die gewohnte Syntax aber als Kompatibilitätsschicht erhalten. Dieser Guide zeigt dir die wichtigsten Optionen für den Alltag, vom Auflisten der Regeln bis zur stateful Firewall mit Connection Tracking.
<!-- PROSE:intro:end -->

## Regeln auflisten

`iptables -L` — Listet alle Regeln der filter-Table auf.

```bash
sudo iptables -L
```

`iptables -L -n` — Listet Regeln mit numerischen Adressen und Ports auf (keine DNS-Auflösung).

```bash
sudo iptables -L -n
```

`iptables -L -v` — Listet Regeln mit Paket-/Byte-Zählern auf.

```bash
sudo iptables -L -v
```

`iptables -L -n -v --line-numbers` — Listet Regeln mit Zeilennummern, numerisch und ausführlich auf. Das nützlichste Format.

```bash
sudo iptables -L -n -v --line-numbers
```

`iptables -L CHAIN` — Listet die Regeln einer bestimmten Chain auf (INPUT, OUTPUT, FORWARD).

```bash
sudo iptables -L INPUT -n
```

`iptables -t TABLE -L` — Listet die Regeln einer bestimmten Table auf (filter, nat, mangle, raw).

```bash
sudo iptables -t nat -L -n
```

`iptables -S` — Listet Regeln im iptables-save-Format auf (leichter zu lesen und erneut anzuwenden).

```bash
sudo iptables -S
```

`iptables -S CHAIN` — Listet die Regeln einer bestimmten Chain im Save-Format auf.

```bash
sudo iptables -S INPUT
```

## Grundlegende Regelverwaltung

`iptables -A CHAIN RULE` — Hängt eine Regel ans Ende einer Chain an.

```bash
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
```

`iptables -I CHAIN RULE` — Fügt eine Regel am Anfang einer Chain ein.

```bash
sudo iptables -I INPUT -p tcp --dport 443 -j ACCEPT
```

`iptables -I CHAIN NUM RULE` — Fügt eine Regel an einer bestimmten Position ein (Zeilennummer).

```bash
sudo iptables -I INPUT 3 -p tcp --dport 8080 -j ACCEPT
```

`iptables -D CHAIN RULE` — Löscht eine Regel anhand ihrer Spezifikation.

```bash
sudo iptables -D INPUT -p tcp --dport 80 -j ACCEPT
```

`iptables -D CHAIN NUM` — Löscht eine Regel anhand ihrer Zeilennummer.

```bash
sudo iptables -D INPUT 3
```

`iptables -R CHAIN NUM RULE` — Ersetzt eine Regel an einer bestimmten Zeilennummer.

```bash
sudo iptables -R INPUT 2 -p tcp --dport 8443 -j ACCEPT
```

## Chains verwalten

`iptables -P CHAIN TARGET` — Setzt die Default-Policy einer eingebauten Chain (ACCEPT oder DROP). Vorsicht: `-P INPUT DROP` über SSH sperrt dich aus, wenn keine ACCEPT-Regel für deine Verbindung existiert – setze sie vorher.

```bash
sudo iptables -P INPUT DROP
```

`iptables -F` — Leert (löscht) alle Regeln in allen Chains. Steht die Policy auf DROP, kann ein Flush eine Remote-/SSH-Sitzung aussperren – idealerweise lokal an der Konsole ausführen.

```bash
sudo iptables -F
```

`iptables -F CHAIN` — Leert alle Regeln einer bestimmten Chain.

```bash
sudo iptables -F INPUT
```

`iptables -Z` — Setzt alle Paket- und Byte-Zähler auf null.

```bash
sudo iptables -Z
```

`iptables -N CHAIN` — Erstellt eine neue benutzerdefinierte Chain.

```bash
sudo iptables -N MY_CHAIN
```

`iptables -X CHAIN` — Löscht eine benutzerdefinierte Chain (muss leer und unreferenziert sein).

```bash
sudo iptables -X MY_CHAIN
```

`iptables -E OLD NEW` — Benennt eine benutzerdefinierte Chain um.

```bash
sudo iptables -E MY_CHAIN NEW_CHAIN
```

## Match-Kriterien

`-p PROTOCOL` — Filtert nach Protokoll: tcp, udp, icmp, all.

```bash
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
```

`-s SOURCE/MASK` — Filtert nach Quell-IP oder -Netz.

```bash
sudo iptables -A INPUT -s 192.168.1.0/24 -j ACCEPT
```

`-d DEST/MASK` — Filtert nach Ziel-IP oder -Netz.

```bash
sudo iptables -A OUTPUT -d 10.0.0.0/8 -j DROP
```

`--dport PORT` — Filtert nach Ziel-Port (erfordert -p tcp oder -p udp).

```bash
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
```

`--sport PORT` — Filtert nach Quell-Port.

```bash
sudo iptables -A INPUT -p tcp --sport 1024:65535 -j ACCEPT
```

`--dport PORT1:PORT2` — Filtert einen Bereich von Ziel-Ports.

```bash
sudo iptables -A INPUT -p tcp --dport 8000:9000 -j ACCEPT
```

`-i INTERFACE` — Filtert nach eingehendem Interface (für INPUT und FORWARD).

```bash
sudo iptables -A INPUT -i eth0 -j ACCEPT
```

`-o INTERFACE` — Filtert nach ausgehendem Interface (für OUTPUT und FORWARD).

```bash
sudo iptables -A OUTPUT -o lo -j ACCEPT
```

`! -s SOURCE` — Negiert einen Match (NOT).

```bash
sudo iptables -A INPUT ! -s 192.168.1.0/24 -j DROP
```

## Targets (Aktionen)

`-j ACCEPT` — Lässt das Paket durch.

`-j DROP` — Verwirft das Paket stillschweigend (keine Antwort).

`-j REJECT` — Weist das Paket ab und sendet einen ICMP-Fehler.

`-j REJECT --reject-with TYPE` — Weist mit einem bestimmten ICMP-Typ ab: icmp-port-unreachable, tcp-reset usw.

```bash
sudo iptables -A INPUT -p tcp --dport 23 -j REJECT --reject-with tcp-reset
```

`-j LOG` — Protokolliert das Paket in syslog/journal und verarbeitet es danach weiter.

```bash
sudo iptables -A INPUT -j LOG --log-prefix 'IPT-DROP: '
```

`-j LOG --log-prefix 'PREFIX'` — Protokolliert mit einem eigenen Präfix zur leichten Identifikation in den Logs.

```bash
sudo iptables -A INPUT -p tcp --dport 22 -j LOG --log-prefix 'SSH: '
```

`-j RETURN` — Kehrt aus der aktuellen Chain in die aufrufende Chain zurück.

## Connection Tracking (Stateful)

`-m conntrack --ctstate STATE` — Filtert nach Verbindungsstatus: NEW, ESTABLISHED, RELATED, INVALID.

```bash
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
```

`-m conntrack --ctstate NEW` — Filtert nur neue Verbindungen.

```bash
sudo iptables -A INPUT -p tcp --dport 80 -m conntrack --ctstate NEW -j ACCEPT
```

`-m conntrack --ctstate INVALID` — Filtert Pakete, die zu keiner bekannten Verbindung gehören.

```bash
sudo iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
```

## Erweiterte Module

`-m multiport --dports P1,P2,P3` — Filtert mehrere Ports in einer einzigen Regel.

```bash
sudo iptables -A INPUT -p tcp -m multiport --dports 80,443,8080 -j ACCEPT
```

`-m iprange --src-range IP1-IP2` — Filtert einen Bereich von Quell-IPs.

```bash
sudo iptables -A INPUT -m iprange --src-range 192.168.1.100-192.168.1.200 -j ACCEPT
```

`-m limit --limit RATE` — Begrenzt die Trefferrate (z. B. 5/min, 1/sec).

```bash
sudo iptables -A INPUT -p icmp -m limit --limit 1/sec -j ACCEPT
```

`-m limit --limit-burst N` — Setzt das Burst-Limit für die Ratenbegrenzung.

```bash
sudo iptables -A INPUT -p icmp -m limit --limit 1/sec --limit-burst 4 -j ACCEPT
```

`-m recent --name LIST --set` — Fügt die Quell-IP einer benannten Tracking-Liste hinzu.

```bash
sudo iptables -A INPUT -p tcp --dport 22 -m recent --name ssh --set
```

`-m recent --name LIST --rcheck --seconds S --hitcount N` — Prüft, ob die Quell-IP N-mal in S Sekunden aufgetreten ist.

```bash
sudo iptables -A INPUT -p tcp --dport 22 -m recent --name ssh --rcheck --seconds 60 --hitcount 4 -j DROP
```

`-m comment --comment 'TEXT'` — Fügt einer Regel einen Kommentar zur Dokumentation hinzu.

```bash
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT -m comment --comment 'Allow HTTP'
```

## NAT-Table

`iptables -t nat -A POSTROUTING -o IFACE -j MASQUERADE` — Aktiviert NAT/Masquerading für Internet-Sharing.

```bash
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
```

`iptables -t nat -A PREROUTING -p tcp --dport PORT -j DNAT --to-destination IP:PORT` — Port-Forwarding: leitet eingehenden Verkehr an einen anderen Host/Port weiter.

```bash
sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.100:80
```

`iptables -t nat -A PREROUTING -p tcp --dport PORT -j REDIRECT --to-port PORT` — Leitet Verkehr auf einen anderen lokalen Port um.

```bash
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
```

`iptables -t nat -A POSTROUTING -s NETWORK -j SNAT --to-source IP` — Source NAT: ändert die Quell-IP für ausgehende Pakete.

```bash
sudo iptables -t nat -A POSTROUTING -s 10.0.0.0/8 -j SNAT --to-source 203.0.113.1
```

## Sichern & Wiederherstellen

`iptables-save` — Gibt alle aktuellen Regeln in einem wiederherstellbaren Format aus. Regeln sind nicht persistent – ohne diesen Schritt (oder netfilter-persistent) gehen sie beim Reboot verloren.

```bash
sudo iptables-save > /etc/iptables/rules.v4
```

`iptables-restore < FILE` — Stellt Regeln aus einer gespeicherten Datei wieder her.

```bash
sudo iptables-restore < /etc/iptables/rules.v4
```

`iptables-save -t TABLE` — Sichert nur die Regeln einer bestimmten Table.

```bash
sudo iptables-save -t filter
```

`iptables-save -c` — Sichert die Regeln inklusive Paket-/Byte-Zähler.

```bash
sudo iptables-save -c > rules-with-counters.v4
```

## Typische Firewall-Muster

`iptables -A INPUT -i lo -j ACCEPT` — Lässt jeglichen Loopback-Verkehr zu (essenziell).

```bash
sudo iptables -A INPUT -i lo -j ACCEPT
```

`iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT` — Lässt bestehende und zugehörige Verbindungen zu (Basisregel einer stateful Firewall).

```bash
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
```

`iptables -A INPUT -p tcp -m multiport --dports 22,80,443 -j ACCEPT` — Lässt SSH, HTTP und HTTPS zu.

```bash
sudo iptables -A INPUT -p tcp -m multiport --dports 22,80,443 -j ACCEPT
```

`iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT` — Lässt Ping-Anfragen zu.

```bash
sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
```

`iptables -P INPUT DROP` — Setzt die Default-Policy auf DROP (verweigert alles nicht ausdrücklich Erlaubte). Erst nach den ACCEPT-Regeln oben setzen, sonst sperrst du dich per SSH aus; die Regeln anschließend mit `iptables-save` persistieren.

```bash
sudo iptables -P INPUT DROP
```

<!-- PROSE:outro -->
## Fazit

iptables wirkt durch seine Optionsflut zunächst sperrig, folgt aber einer klaren Logik: Pakete durchlaufen Chains, bis ein Target über ihr Schicksal entscheidet. Wer die Reihenfolge der Regeln und das Zusammenspiel von Connection Tracking und Default-Policy verstanden hat, baut damit robuste Firewalls. Denk daran, deine Regeln mit `iptables-save` oder `netfilter-persistent` zu sichern – sonst sind sie nach dem nächsten Reboot verloren. Und teste eine Default-Policy DROP nach Möglichkeit lokal oder über eine zweite Sitzung, bevor du dich selbst aussperrst.

## Weiterführende Links

- [iptables(8) – Manpage](https://man7.org/linux/man-pages/man8/iptables.8.html) – vollständige Optionsreferenz (englisch)
- [iptables – Arch Wiki](https://wiki.archlinux.org/title/Iptables) – ausführlicher Praxis-Guide (englisch)
- [iptables – Wikipedia](https://de.wikipedia.org/wiki/Iptables) – Hintergrund und Geschichte
<!-- PROSE:outro:end -->

## Verwandte Kommandos

- [age](https://www.jpkc.com/db/cheatsheets/security/age/) – moderne Datei-Verschlüsselung mit einfachen Schlüsseln
- [clamav](https://www.jpkc.com/db/cheatsheets/security/clamav/) – Open-Source-Virenscanner für Dateien und Mails
- [fail2ban](https://www.jpkc.com/db/cheatsheets/security/fail2ban/) – sperrt Angreifer nach fehlgeschlagenen Login-Versuchen automatisch

