# nftables — Die moderne Linux-Firewall mit nft

> Praxis-Guide zu nftables — dem modernen iptables-Nachfolger. Tables, Chains, Rules, Sets und NAT mit der nft-Syntax, plus abgesicherte Firewall-Setups.

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

<!-- PROSE:intro -->
nftables ist die vereinheitlichte Firewall des Linux-Kernels und löst die alten Werkzeuge iptables, ip6tables, arptables und ebtables unter einem einzigen Befehl ab: `nft`. Statt vier getrennter Toolsets verwaltest du IPv4, IPv6, ARP und Bridge-Traffic mit einer einheitlichen Syntax aus Tables, Chains, Rules, Sets und Maps. Regeländerungen werden atomar eingespielt, und benannte Sets halten große Adresslisten performant und wartbar. Dieser Guide führt dich vom Auflisten bestehender Regeln über Match-Ausdrücke und NAT bis zum kompletten, abgesicherten Firewall-Setup.
<!-- PROSE:intro:end -->

## Regeln auflisten

`nft list ruleset` — Listet alle Regeln über alle Tables und Families hinweg auf.

```bash
sudo nft list ruleset
```

`nft list tables` — Listet alle Tables auf.

```bash
sudo nft list tables
```

`nft list table FAMILY TABLE` — Listet alle Chains und Rules in einer bestimmten Table auf.

```bash
sudo nft list table inet filter
```

`nft list chain FAMILY TABLE CHAIN` — Listet die Rules einer bestimmten Chain auf.

```bash
sudo nft list chain inet filter input
```

`nft -a list ruleset` — Listet alle Regeln mit Handle-Nummern auf (zum Löschen nötig).

```bash
sudo nft -a list ruleset
```

`nft -s list ruleset` — Listet Regeln ohne String-Übersetzung auf (numerische Protokolle/Ports).

```bash
sudo nft -s list ruleset
```

`nft -j list ruleset` — Gibt die Regeln im JSON-Format aus.

```bash
sudo nft -j list ruleset
```

## Adressfamilien

`ip` — Nur IPv4 (entspricht iptables).

`ip6` — Nur IPv6 (entspricht ip6tables).

`inet` — IPv4 und IPv6 in einer Table. Für die meisten Fälle empfohlen.

`arp` — ARP-Protokoll (entspricht arptables).

`bridge` — Bridge-/Layer-2-Filterung (entspricht ebtables).

`netdev` — Ingress-Filterung auf Geräteebene (vor dem Routing).

## Tables verwalten

`nft add table FAMILY NAME` — Legt eine neue Table an.

```bash
sudo nft add table inet filter
```

`nft delete table FAMILY NAME` — Löscht eine Table samt allen Chains/Rules.

```bash
sudo nft delete table inet filter
```

`nft flush table FAMILY NAME` — Entfernt alle Rules aus einer Table (Chains bleiben erhalten).

```bash
sudo nft flush table inet filter
```

`nft flush ruleset` — Entfernt alle Tables, Chains und Rules. **Vorsicht:** Bei Remote-Zugriff und einer Default-`policy drop` sperrst du dich damit aus (Lockout) — vorher SSH/established erlauben und nur lokal testen.

```bash
sudo nft flush ruleset
```

## Chains verwalten

`nft add chain FAMILY TABLE CHAIN '{ type TYPE hook HOOK priority PRIO; policy POLICY; }'` — Legt eine Base-Chain mit Hook, Priority und Policy an. Vorsicht mit `policy drop` ohne vorherige Accept-Regeln (z. B. für SSH/established) – siehe das abgesicherte Setup unten.

```bash
sudo nft add chain inet filter input '{ type filter hook input priority 0; policy drop; }'
```

`nft add chain FAMILY TABLE CHAIN` — Legt eine reguläre (Nicht-Base-)Chain zum Organisieren von Rules an.

```bash
sudo nft add chain inet filter tcp_chain
```

`nft delete chain FAMILY TABLE CHAIN` — Löscht eine Chain (muss leer sein).

```bash
sudo nft delete chain inet filter tcp_chain
```

`nft flush chain FAMILY TABLE CHAIN` — Entfernt alle Rules aus einer Chain.

```bash
sudo nft flush chain inet filter input
```

## Regeln hinzufügen

`nft add rule FAMILY TABLE CHAIN STATEMENT` — Hängt eine Rule ans Ende einer Chain an.

```bash
sudo nft add rule inet filter input tcp dport 80 accept
```

`nft insert rule FAMILY TABLE CHAIN STATEMENT` — Fügt eine Rule am Anfang einer Chain ein.

```bash
sudo nft insert rule inet filter input tcp dport 443 accept
```

`nft add rule FAMILY TABLE CHAIN position HANDLE STATEMENT` — Fügt eine Rule nach einem bestimmten Handle ein.

```bash
sudo nft add rule inet filter input position 8 tcp dport 8080 accept
```

`nft insert rule FAMILY TABLE CHAIN position HANDLE STATEMENT` — Fügt eine Rule vor einem bestimmten Handle ein.

```bash
sudo nft insert rule inet filter input position 8 tcp dport 22 accept
```

## Regeln löschen

`nft delete rule FAMILY TABLE CHAIN handle HANDLE` — Löscht eine Rule anhand ihrer Handle-Nummer (Handles mit -a anzeigen).

```bash
sudo nft delete rule inet filter input handle 12
```

`nft flush chain FAMILY TABLE CHAIN` — Löscht alle Rules in einer Chain.

```bash
sudo nft flush chain inet filter input
```

## Match-Ausdrücke

`tcp dport PORT` — Matcht den TCP-Zielport.

```bash
sudo nft add rule inet filter input tcp dport 22 accept
```

`udp dport PORT` — Matcht den UDP-Zielport.

```bash
sudo nft add rule inet filter input udp dport 53 accept
```

`tcp dport { P1, P2, P3 }` — Matcht mehrere Ports über anonyme Sets.

```bash
sudo nft add rule inet filter input tcp dport { 80, 443, 8080 } accept
```

`tcp dport P1-P2` — Matcht einen Port-Bereich.

```bash
sudo nft add rule inet filter input tcp dport 8000-9000 accept
```

`ip saddr ADDRESS` — Matcht die Quell-IPv4-Adresse.

```bash
sudo nft add rule inet filter input ip saddr 192.168.1.0/24 accept
```

`ip daddr ADDRESS` — Matcht die Ziel-IPv4-Adresse.

```bash
sudo nft add rule inet filter output ip daddr 10.0.0.0/8 drop
```

`ip6 saddr ADDRESS` — Matcht die Quell-IPv6-Adresse.

```bash
sudo nft add rule inet filter input ip6 saddr fd00::/8 accept
```

`ip saddr { A1, A2, A3 }` — Matcht mehrere Quelladressen.

```bash
sudo nft add rule inet filter input ip saddr { 10.0.0.1, 10.0.0.2 } accept
```

`iifname INTERFACE` — Matcht den Namen der eingehenden Schnittstelle.

```bash
sudo nft add rule inet filter input iifname "eth0" accept
```

`oifname INTERFACE` — Matcht den Namen der ausgehenden Schnittstelle.

```bash
sudo nft add rule inet filter output oifname "lo" accept
```

`meta l4proto icmp` — Matcht das ICMP-Protokoll.

```bash
sudo nft add rule inet filter input meta l4proto icmp accept
```

`ct state { established, related }` — Matcht den Connection-Tracking-Zustand.

```bash
sudo nft add rule inet filter input ct state { established, related } accept
```

`ct state invalid` — Matcht ungültige Verbindungszustände.

```bash
sudo nft add rule inet filter input ct state invalid drop
```

`ct state new` — Matcht neue Verbindungen.

```bash
sudo nft add rule inet filter input ct state new tcp dport 22 accept
```

## Aktionen (Verdicts)

`accept` — Lässt das Paket durch.

`drop` — Verwirft das Paket stillschweigend.

`reject` — Weist das Paket mit einem ICMP-Fehler zurück.

`reject with TYPE` — Weist das Paket mit einem bestimmten Nachrichtentyp zurück.

```bash
sudo nft add rule inet filter input tcp dport 23 reject with tcp reset
```

`log prefix "TEXT"` — Protokolliert das Paket mit einem Präfix.

```bash
sudo nft add rule inet filter input tcp dport 22 log prefix "SSH: " accept
```

`counter` — Zählt Pakete und Bytes, die auf diese Rule passen.

```bash
sudo nft add rule inet filter input tcp dport 80 counter accept
```

`jump CHAIN` — Springt zur weiteren Verarbeitung in eine andere Chain.

```bash
sudo nft add rule inet filter input tcp dport { 80, 443 } jump web_chain
```

`return` — Kehrt aus der aktuellen Chain zurück.

`limit rate N/TIME` — Begrenzt die Trefferrate (z. B. 5/minute, 1/second).

```bash
sudo nft add rule inet filter input icmp type echo-request limit rate 1/second accept
```

## NAT

`nft add chain ip nat postrouting '{ type nat hook postrouting priority 100; }'` — Legt eine NAT-Postrouting-Chain an.

```bash
sudo nft add chain ip nat postrouting '{ type nat hook postrouting priority 100; }'
```

`masquerade` — Maskiert ausgehenden Traffic (dynamisches SNAT).

```bash
sudo nft add rule ip nat postrouting oifname "eth0" masquerade
```

`dnat to ADDRESS:PORT` — Destination-NAT (Port-Weiterleitung).

```bash
sudo nft add rule ip nat prerouting tcp dport 8080 dnat to 192.168.1.100:80
```

`snat to ADDRESS` — Source-NAT mit einer statischen IP.

```bash
sudo nft add rule ip nat postrouting ip saddr 10.0.0.0/8 snat to 203.0.113.1
```

`redirect to :PORT` — Leitet auf einen lokalen Port um.

```bash
sudo nft add rule ip nat prerouting tcp dport 80 redirect to :8080
```

## Benannte Sets

`nft add set FAMILY TABLE NAME '{ type TYPE; }'` — Legt ein benanntes Set an.

```bash
sudo nft add set inet filter blocked_ips '{ type ipv4_addr; }'
```

`nft add element FAMILY TABLE SET '{ ELEM1, ELEM2 }'` — Fügt einem Set Elemente hinzu.

```bash
sudo nft add element inet filter blocked_ips '{ 10.0.0.1, 10.0.0.2 }'
```

`nft delete element FAMILY TABLE SET '{ ELEM }'` — Entfernt ein Element aus einem Set.

```bash
sudo nft delete element inet filter blocked_ips '{ 10.0.0.1 }'
```

`nft list set FAMILY TABLE SET` — Zeigt den Inhalt eines benannten Sets.

```bash
sudo nft list set inet filter blocked_ips
```

`ip saddr @SET_NAME drop` — Verwendet ein benanntes Set in einer Rule.

```bash
sudo nft add rule inet filter input ip saddr @blocked_ips drop
```

## Speichern & Wiederherstellen

`nft list ruleset > FILE` — Speichert den aktuellen Regelsatz in eine Datei. Ohne `/etc/nftables.conf` plus aktivierten `nftables`-Service sind Regeln nicht persistent und gehen beim Neustart verloren.

```bash
sudo nft list ruleset > /etc/nftables.conf
```

`nft -f FILE` — Lädt Regeln aus einer Datei.

```bash
sudo nft -f /etc/nftables.conf
```

`nft -c -f FILE` — Prüft/validiert eine Regelsatz-Datei, ohne sie anzuwenden.

```bash
sudo nft -c -f /etc/nftables.conf
```

## Typisches Firewall-Setup

`nft add table inet filter` — Schritt 1: Legt eine Filter-Table für IPv4 und IPv6 an.

```bash
sudo nft add table inet filter
```

`nft add chain inet filter input '{ type filter hook input priority 0; policy drop; }'` — Schritt 2: Legt die Input-Chain mit Drop-Policy an. **Achtung:** Ab jetzt wird alles verworfen, wofür keine Rule existiert — füge die SSH-/established-Regeln (Schritt 4 und 6) zuerst hinzu, sonst sperrst du dich bei Remote-Zugriff aus.

```bash
sudo nft add chain inet filter input '{ type filter hook input priority 0; policy drop; }'
```

`nft add rule inet filter input iifname "lo" accept` — Schritt 3: Erlaubt Loopback-Traffic.

```bash
sudo nft add rule inet filter input iifname "lo" accept
```

`nft add rule inet filter input ct state { established, related } accept` — Schritt 4: Erlaubt bestehende Verbindungen.

```bash
sudo nft add rule inet filter input ct state { established, related } accept
```

`nft add rule inet filter input ct state invalid drop` — Schritt 5: Verwirft ungültige Pakete.

```bash
sudo nft add rule inet filter input ct state invalid drop
```

`nft add rule inet filter input tcp dport { 22, 80, 443 } accept` — Schritt 6: Erlaubt SSH, HTTP, HTTPS.

```bash
sudo nft add rule inet filter input tcp dport { 22, 80, 443 } accept
```

`nft add rule inet filter input icmp type echo-request accept` — Schritt 7: Erlaubt Ping.

```bash
sudo nft add rule inet filter input icmp type echo-request accept
```

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

Mit nftables verwaltest du IPv4, IPv6 und Bridge-Filterung in einem einzigen, konsistenten Framework — statt vier getrennter Legacy-Tools. Plane neue Regelsätze in einer `/etc/nftables.conf`, validiere sie mit `nft -c -f` und aktiviere den `nftables`-Service, damit sie einen Neustart überstehen. Und teste jede Default-`policy drop` zuerst lokal: Auf einem entfernten Server kostet ein vergessenes SSH-Accept schnell den Zugang.

## Weiterführende Links

- [nftables-Wiki](https://wiki.nftables.org/) – offizielle Dokumentation und Anleitungen (englisch)
- [nft(8) – Manpage](https://man7.org/linux/man-pages/man8/nft.8.html) – alle Optionen im Überblick (englisch)
- [Netfilter – Wikipedia](https://de.wikipedia.org/wiki/Netfilter) – Hintergrund zu nftables und seinen Vorgängern
<!-- PROSE:outro:end -->

## Verwandte Kommandos

- [age](https://www.jpkc.com/db/cheatsheets/security/age/) – moderne Datei-Verschlüsselung auf der Kommandozeile
- [clamav](https://www.jpkc.com/db/cheatsheets/security/clamav/) – Open-Source-Virenscanner für Linux-Server
- [fail2ban](https://www.jpkc.com/db/cheatsheets/security/fail2ban/) – sperrt Angreifer-IPs anhand von Log-Mustern

