Zum Inhalt springen
sw
en

Tippe um zu suchen

Linux

Linux-Firewall: iptables und nftables im Vergleich

iptables vs. nftables im Detail: Ketten, Tabellen, conntrack, NAT, ufw/firewalld als Frontends und wie du Regeln im KMU-Betrieb persistent machst.

13 Min Lesezeit Fortgeschritten Zuletzt aktualisiert:

Warum das Thema mehr ist als „Firewall an, Firewall aus”

Jede moderne Linux-Distribution bringt einen Paketfilter im Kernel mit: Netfilter. Das ist das Framework, das Pakete auf ihrem Weg durch den Kernel abfangen, filtern, verändern (NAT) oder verwerfen kann. Die Frage ist nur, mit welchem Werkzeug du mit Netfilter sprichst – und genau hier beginnt die Verwirrung, die dir in jedem Schweizer KMU früher oder später begegnet: Der alte Server läuft noch mit klassischem iptables, der neue Debian-Host nutzt nftables, und auf der Workstation regelt ufw alles im Hintergrund. Wer nicht versteht, wie diese Ebenen zusammenhängen, verliert beim Troubleshooting schnell den Überblick – vor allem, wenn ein Kunde anruft, weil eine Anwendung plötzlich keine Verbindung mehr aufbaut.

Dieser Artikel zeigt dir die Architektur unter der Haube, den echten Unterschied zwischen iptables und nftables, wie NAT und Port-Forwarding funktionieren, was conntrack mit Stateful Filtering zu tun hat, und wie du Regeln über einen Reboot hinweg persistent machst.

Netfilter, iptables und nftables: Wer macht was?

Ein häufiges Missverständnis: iptables und nftables sind keine Firewalls im Kernel – sie sind Userspace-Werkzeuge, die Regeln in Netfilter-Strukturen im Kernel schreiben. Netfilter selbst ist seit Kernel 2.4 (Jahr 2001) fester Bestandteil des Linux-Kernels und stellt Hook-Punkte bereit, an denen Pakete abgefangen werden können.

  • iptables (seit 1998/2001) nutzt die klassischen Netfilter-Hooks direkt und verwaltet Regeln in vier bis fünf Tabellen (filter, nat, mangle, raw, security) mit fest vordefinierten Ketten.
  • nftables (seit Kernel 3.13, 2014) ist der offizielle Nachfolger. Es nutzt eine eigene, generischere Kernel-Schnittstelle (nf_tables) mit einer internen virtuellen Maschine, die kompilierten Bytecode ausführt. Tabellen und Ketten sind hier nicht mehr fest vorgegeben, sondern werden vom Administrator selbst definiert.
  • iptables-nft: Seit Debian 10 (Buster) und den meisten aktuellen Distributionen ist der klassische iptables-Befehl nur noch eine Kompatibilitätsschicht, die deine Regeln in nftables-Syntax übersetzt. Der eigentliche Kernel-Regelsatz liegt also längst in nftables – du tippst nur noch die alte Syntax ein.

iptables-Ketten im Detail: INPUT, OUTPUT, FORWARD

Auch wenn du künftig eher nftables schreiben wirst, musst du das klassische Kettenmodell verstehen – es taucht in jeder Doku, jedem Legacy-Server und jeder Zertifizierung auf.

Die filter-Tabelle (Standardtabelle für reines Filtern) hat drei Standardketten:

KetteWann greift sieTypischer Einsatz
INPUTPakete mit Ziel = dieser HostSSH, HTTP, DB-Zugriff auf den Server selbst einschränken
OUTPUTPakete, die dieser Host selbst erzeugtAusgehenden Traffic kontrollieren (z. B. nur bestimmte Ziel-IPs erlauben)
FORWARDPakete, die durch den Host hindurch geroutet werdenDer Host als Router/Gateway zwischen zwei Netzen

Dazu kommen weitere Tabellen mit eigenen Ketten: nat (mit PREROUTING, POSTROUTING, INPUT, OUTPUT) für Adressübersetzung, mangle für das Modifizieren von Paket-Metadaten (TTL, TOS/DSCP) und raw zum Ausklinken aus dem Connection-Tracking.

Ein typisches, restriktives iptables-Regelwerk für einen Server sieht so aus:

# Alles verwerfen, was nicht explizit erlaubt ist
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Loopback immer erlauben (essenziell fuer lokale Dienste)
iptables -A INPUT -i lo -j ACCEPT

# Bestehende Verbindungen durchlassen (siehe conntrack weiter unten)
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# SSH nur von internem Management-Netz
iptables -A INPUT -p tcp -s 10.10.5.0/24 --dport 22 -j ACCEPT

# HTTPS fuer alle
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# ICMP (Ping) fuer Diagnose zulassen
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

# Rest verwerfen und loggen
iptables -A INPUT -j LOG --log-prefix "IPTABLES-DROP: " --log-level 4
iptables -A INPUT -j DROP

nftables: Architektur und Syntax

nftables kehrt das Prinzip um: Es gibt keine vordefinierten Tabellen oder Ketten. Du legst alles selbst an, was Übersicht schafft, aber am Anfang ungewohnt ist. Dafür bekommst du eine einheitliche Syntax für IPv4, IPv6, ARP und Bridging-Traffic (über die Adressfamilie inet), statt vier getrennter Tools (iptables, ip6tables, arptables, ebtables).

Grundstruktur: Tabelle → Kette → Regel

# Tabelle anlegen (Adressfamilie inet = IPv4 + IPv6 gemeinsam)
nft add table inet filter

# Basis-Kette fuer eingehenden Traffic anlegen
# hook input = Netfilter-Hook, priority 0 = Standardprioritaet, policy drop = Default-Politik
nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; }

# Regeln hinzufuegen
nft add rule inet filter input iif lo accept
nft add rule inet filter input ct state established,related accept
nft add rule inet filter input tcp dport 22 ip saddr 10.10.5.0/24 accept
nft add rule inet filter input tcp dport 443 accept
nft add rule inet filter input icmp type echo-request accept
nft add rule inet filter input log prefix "NFT-DROP: " drop

Der produktive Weg ist aber nicht die interaktive Eingabe einzelner Befehle, sondern eine deklarative Konfigurationsdatei unter /etc/nftables.conf:

#!/usr/sbin/nft -f

flush ruleset

table inet filter {
    chain input {
        type filter hook input priority 0; policy drop;

        iif lo accept
        ct state established,related accept
        ct state invalid drop

        tcp dport 22 ip saddr 10.10.5.0/24 accept
        tcp dport { 80, 443 } accept
        icmp type echo-request accept

        log prefix "NFT-DROP: " drop
    }

    chain forward {
        type filter hook forward priority 0; policy drop;
    }

    chain output {
        type filter hook output priority 0; policy accept;
    }
}

Aktivieren mit nft -f /etc/nftables.conf und prüfen mit nft list ruleset.

iptables vs. nftables: Die Entscheidungstabelle

Kriteriumiptables (legacy)nftables
Kernel-SchnittstelleDirekter Netfilter-Zugriff, pro Protokollfamilie eigenes BinaryEinheitliche nf_tables-API, ein Binary (nft) fuer alle Familien
Performance bei vielen RegelnLinear (jede Regel wird sequenziell geprueft)Bytecode-VM, Sets/Maps mit Hash-Lookup – deutlich schneller bei grossen Regelsaetzen
SyntaxHistorisch gewachsen, viele SpezialfaelleKonsistenter, deklarativ, aber neue Lernkurve
IPv4/IPv6 gemeinsam verwaltenNein (getrennte Tools iptables/ip6tables)Ja, ueber Adressfamilie inet
Atomare Regel-UpdatesNur mit iptables-restoreNativ mit nft -f (ganze Ruleset-Datei atomar geladen)
Verfuegbarkeit auf aktuellen DistrosUeber Kompatibilitaetsschicht (iptables-nft)Nativ seit Debian 10, RHEL 8, Ubuntu 20.04
Doku/Community-Beispiele im NetzRiesig, jahrzehntealtWachsend, aber noch nicht so umfassend
Empfehlung fuer NeuprojekteNein, nur bei Legacy-ZwangJa

Frontends: ufw und firewalld

Weder rohes iptables noch rohes nftables sind im Alltag besonders komfortabel. Deshalb setzen die meisten Distributionen auf ein Frontend, das die Regeln im Hintergrund generiert.

ufw (Uncomplicated Firewall) – Ubuntu/Debian-Welt

ufw ist bewusst simpel gehalten und für Server mit überschaubarem Regelwerk gedacht.

# Status und aktivieren
sudo ufw status verbose
sudo ufw enable

# Grundregeln
sudo ufw default deny incoming
sudo ufw default allow outgoing

# Dienste erlauben (nutzt /etc/services fuer Namen)
sudo ufw allow ssh
sudo ufw allow 443/tcp
sudo ufw allow from 10.10.5.0/24 to any port 22

# Regel mit Kommentar (hilft bei der Doku!)
sudo ufw allow 3389/tcp comment 'RDP fuer Terminalserver'

# Regel loeschen
sudo ufw status numbered
sudo ufw delete 3

# Anwendungsprofile (definiert in /etc/ufw/applications.d/)
sudo ufw app list
sudo ufw allow 'Nginx Full'

ufw arbeitet standardmässig auf Basis von iptables (bzw. iptables-nft), es gibt aber auch einen nftables-Backend-Modus (/etc/ufw/ufw.confIPT_SYSCTL/Backend-Auswahl je nach Version).

firewalld – RHEL/CentOS/Fedora/SUSE-Welt

firewalld denkt in Zonen statt in linearen Regeln – ein Konzept, das für Laptops mit wechselnden Netzen (Büro, Heimnetz, öffentliches WLAN) entwickelt wurde, sich aber auch für Server mit mehreren Interfaces (LAN, DMZ, Management) eignet.

# Aktive Zone eines Interfaces anzeigen
firewall-cmd --get-active-zones

# Interface einer Zone zuweisen
sudo firewall-cmd --zone=internal --change-interface=eth1 --permanent

# Dienst dauerhaft in einer Zone erlauben
sudo firewall-cmd --zone=public --add-service=https --permanent
sudo firewall-cmd --zone=internal --add-port=3306/tcp --permanent

# Aenderungen aktivieren (ohne Neustart)
sudo firewall-cmd --reload

# Rich Rules fuer komplexere Faelle (z.B. Quell-IP + Zeitfenster)
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="203.0.113.10" service name="ssh" accept' --permanent

# Aktuelle Konfiguration einer Zone anzeigen
firewall-cmd --zone=public --list-all

firewalld nutzt seit Version 0.6+ nftables als Standard-Backend (früher iptables-direct). Das kannst du in /etc/firewalld/firewalld.conf über FirewallBackend=nftables prüfen bzw. umstellen.

Stateful Filtering: Wie conntrack funktioniert

Der grösste konzeptionelle Sprung gegenüber einfachen Paketfiltern ist Connection Tracking (conntrack). Ohne conntrack müsstest du für jede TCP-Verbindung sowohl die ausgehende Anfrage als auch die zugehörige Antwort explizit erlauben – bei dynamischen Portbereichen (Ephemeral Ports, meist 32768–60999) praktisch unmöglich sauber zu pflegen.

conntrack führt eine Tabelle aller aktiven Verbindungen im Kernel und ordnet jedes Paket einem von vier Zuständen zu:

ZustandBedeutung
NEWErstes Paket einer neuen Verbindung (z. B. TCP SYN)
ESTABLISHEDTeil einer bereits bestätigten Verbindung (Antwortverkehr)
RELATEDGehört logisch zu einer bestehenden Verbindung, ist aber technisch eine neue (z. B. FTP-Datenkanal, ICMP-Fehlermeldung zu einer TCP-Session)
INVALIDPasst zu keiner bekannten Verbindung – meist ein Hinweis auf fehlerhafte oder manipulierte Pakete

Damit reicht eine einzige Regel, um den gesamten Rückverkehr für bereits erlaubte Verbindungen freizugeben:

# iptables
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# nftables
nft add rule inet filter input ct state established,related accept

Die conntrack-Tabelle selbst kannst du live einsehen und analysieren – extrem nützlich beim Troubleshooting von NAT- oder Timeout-Problemen:

# conntrack-Tool installieren (meist im Paket conntrack)
sudo apt install conntrack

# Aktive Verbindungen anzeigen
sudo conntrack -L

# Live mitverfolgen
sudo conntrack -E

# Groesse und Auslastung der Tabelle
cat /proc/sys/net/netfilter/nf_conntrack_max
cat /proc/sys/net/netfilter/nf_conntrack_count

NAT und Port-Forwarding

NAT (Network Address Translation) findet in einer eigenen Tabelle statt, die früh (PREROUTING) bzw. spät (POSTROUTING) im Paketweg ansetzt.

Klassisches Masquerading (Internet-Gateway für ein LAN)

# iptables
iptables -t nat -A POSTROUTING -o eth0 -s 192.168.10.0/24 -j MASQUERADE

# nftables
nft add table ip nat
nft add chain ip nat postrouting { type nat hook postrouting priority 100 \; }
nft add rule ip nat postrouting oif eth0 ip saddr 192.168.10.0/24 masquerade

MASQUERADE eignet sich für dynamische WAN-IPs (DHCP/PPPoE). Hast du eine statische öffentliche IP, ist SNAT (Source NAT) die etwas performantere und explizitere Variante, weil der Kernel die IP nicht bei jedem Paket neu ermitteln muss:

iptables -t nat -A POSTROUTING -o eth0 -s 192.168.10.0/24 -j SNAT --to-source 203.0.113.5

Port-Forwarding (DNAT) – Beispiel: Interner RDP-Server von aussen erreichbar

# iptables: Eingehende Pakete auf Port 33890 an internen Host umleiten
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 33890 -j DNAT --to-destination 192.168.10.50:3389

# Passende FORWARD-Regel nicht vergessen!
iptables -A FORWARD -p tcp -d 192.168.10.50 --dport 3389 -j ACCEPT

# nftables-Aequivalent
nft add table ip nat
nft add chain ip nat prerouting { type nat hook prerouting priority -100 \; }
nft add rule ip nat prerouting iif eth0 tcp dport 33890 dnat to 192.168.10.50:3389
nft add rule inet filter forward ip daddr 192.168.10.50 tcp dport 3389 accept

Entscheidungsablauf für ein typisches Gateway-Setup

  1. IP-Forwarding aktivieren – ohne das leitet der Kernel gar nichts weiter:
    echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.conf
    sudo sysctl -p
  2. NAT-Regel definieren (MASQUERADE für dynamische WAN-IP, SNAT für statische).
  3. FORWARD-Policy auf DROP setzen und nur explizit benötigte Ziele/Ports freigeben.
  4. conntrack-Regel für Rückverkehr in FORWARD nicht vergessen (ct state established,related accept).
  5. Testen von aussen – idealerweise über einen externen Scan (z. B. von einem Mobilfunknetz aus), nicht nur aus dem eigenen LAN, weil Hairpin-NAT sich anders verhält.

Regeln persistent machen

Sowohl iptables- als auch nftables-Regeln leben standardmässig nur im Kernel-Speicher – nach einem Reboot sind sie weg, wenn du nicht für Persistenz sorgst.

iptables persistent (Debian/Ubuntu)

sudo apt install iptables-persistent

# Aktuelle Regeln sichern
sudo netfilter-persistent save
# Entspricht: iptables-save > /etc/iptables/rules.v4
#             ip6tables-save > /etc/iptables/rules.v6

# Manuelles Backup/Restore
sudo iptables-save > /etc/iptables/rules.v4
sudo iptables-restore < /etc/iptables/rules.v4

iptables persistent (RHEL/CentOS)

sudo dnf install iptables-services
sudo systemctl enable iptables
sudo service iptables save

nftables persistent

nftables hat Persistenz von Haus aus eingebaut, weil die Konfiguration ohnehin als Datei vorliegt:

# Systemd-Service ist meist schon vorhanden
sudo systemctl enable nftables

# Konfiguration liegt unter /etc/nftables.conf (Debian) bzw.
# /etc/sysconfig/nftables.conf (RHEL)
sudo nft list ruleset > /etc/nftables.conf

sudo systemctl restart nftables

ufw / firewalld

Beide Frontends kümmern sich selbst um Persistenz – ufw schreibt nach /etc/ufw/, firewalld nach /etc/firewalld/. Solange du mit den jeweiligen CLI-Befehlen arbeitest (und bei firewalld --permanent nicht vergisst), überlebt die Konfiguration Reboots automatisch.

Troubleshooting-Checkliste

Wenn eine Verbindung blockiert wird und du nicht weisst warum:

# 1. Welches Backend laeuft ueberhaupt?
iptables --version
nft --version

# 2. Aktuelles Regelwerk mit Zaehlern anzeigen (zeigt welche Regel matcht)
iptables -L -v -n --line-numbers
nft list ruleset -a

# 3. Live mitschneiden, was ankommt
tcpdump -i eth0 port 443 -nn

# 4. Kernel-Logs pruefen (bei LOG-Regeln)
journalctl -k -f | grep DROP

# 5. conntrack-Status der betroffenen Verbindung
conntrack -L | grep 192.168.10.50

Fehlt dir Netzwerkwissen für die Interpretation der Paketmitschnitte, hilft Wireshark – Grundlagen der Paketanalyse als Ergänzung zu tcpdump.

Weiterlernen

Videos

YouTube
Einstieg in nftables: So funktioniert die neue Firewall als Nachfolger von iptables & Vergleich

Kommentare

Frage, Verbesserungsvorschlag oder eigene Erfahrung zu diesem Artikel? Schreib einen Kommentar. Neue Beiträge erscheinen nach kurzer Moderation.

  • Lade Kommentare …
Kommentar schreiben