Tutorial NFTables

Updated on 2024-12-17 by mh

Sowohl NFTables als auch der alte Standard IPTables ermöglichen die grundlegenden Funktionen einer Firewall, wie das Filtern (Erlauben/Blockieren) bestimmter Netzwerkpakete, das Protokollieren oder das Umleiten dieser. Zusätzlich kann das Network Address Translation (NAT) ebenfalls umgesetzt werden.

Warum NFTables?

Im Laufe der Zeit wurden die IPTables komplizierter. Es gibt Werkzeuge für IPv4, IPv6 und für die Zuordnung von IP- zu MAC-Adressen (arptables). Dadurch gab es viele Regeln mehrfach. NFTables, welches ebenfalls auf Netfilter basiert, nahm sich dem Problem an und ermöglicht sämtliche Funktionen in einem Werkzeug mit dem Namen nft. Im System bereits bestehende IPTables-Regeln werden durch iptables-translate in NFTables umgewandelt. In Debian gehören NFTables seit Buster zum neuen Standard.

Unterschiede zwischen NFTables und IPTables

  • Sämtliche Regeln werden über nft verwaltet (NFTables).
  • Beide arbeiten mit Tabellen und Ketten (chains).
    • IPTables hat standardmäßig bestimmte Tabellen (wie z.B. Filter, NAT etc.) und Ketten (wie INPUT, FORWARD, usw.).
    • NFTables hat dies nicht.
  • Alle Regeln bei NFTables sind persistent.
  • Regeln sind in NFTables flexibler.
    • Mehrere Aktionen können in einer einzelnen Regel angegeben werden.
    • Bei IPTables war nur eine einzige Aktion möglich (z.B. -j ACCEPT oder -j LOG). Wer mehrere Regeln erstellt, spart sich Wiederholungen durch den hierarchischen Aufbau.

Einstieg in NFTables

Debian und Ubuntu haben NFTables standardmäßig installiert. Um zu prüfen, ob dies auch der Fall ist, kann folgender Befehl eingegeben werden:

sudo lsmod | egrep ^nf_tables

Mit:

sudo nft list ruleset

lässt sich eine Liste aller aktiven Regeln anzeigen.

Befehle per CLI ausführen: Anlegen der ersten Tabelle, Kette und Regel

Es kann gewählt werden, ob wie bei IPTables Konsolenbefehle verwendet werden, oder ob alles in die Konfigurationsdatei gespeichert werden soll. In diesem Beispiel wird mit einer Tabelle angefangen, die eine Protokollfamilie festlegt. Es wird das Beispiel einer simplen inet Tabelle verwendet, welche für alle Internetprotokolle steht, wie IPv4 und IPv6. Insgesamt existieren sechs Familien, man könnte z.B. auch ip angeben, um ausschließlich IPv4-Datenverkehr zu behandeln. Oder ip6 für IPv6. Zuletzt folgt der frei wählbare Name der Tabelle basic-filter:

sudo nft add table inet basic-filter

Dadurch wurde nun eine Tabelle mit dem Namen basic-filter erzeugt. Diese Tabelle sieht wie folgt aus und ist derzeit noch leer. Mit dem list ruleset Befehl kann sie angezeigt werden.

table inet basic-filter {

}

Innerhalb dieser erzeugten leeren Tabelle können nun die Ketten angelegt werden. Eine Kette hat hier einen bestimmten Typ und reagiert auf ein Ereignis. Das Wichtige hier ist: Ketten und Regeln enthalten Sonderzeichen wie z.B. geschweifte Klammern, die von der Shell interpretiert werden. Um dies richtig zu nutzen, muss mit einem Schrägstrich \ escaped werden. Es können aber auch einfache Anführungszeichen ' verwendet werden. Diese sollten wie im folgenden Beispiel nach dem nft Befehl kommen:

sudo nft 'add chain inet basic-filter input { type filter hook input priority filter; ... }'

An der … Stelle würden nun die Regeln folgen, die wir uns im Folgenden aber besser in einer eigenen Datei anschauen. Das ist deutlich komfortabler und übersichtlicher als längere Konsolenbefehle zu nutzen.

Die Grundlegenden Regeln als eine Configdatei

Hierfür kann eine frei wählbare Datei wie z.B. meine_ersten_nft_rules.conf erstellt werden. In dieser definieren wir die Regeln wie folgt:

#!/usr/sbin/nft -f

# Optional: Löscht alle möglicherweise bereits existierenden Regeln
# flush ruleset

table inet basic-filter {
        chain input {
                type filter hook input priority filter
                policy drop
                ct state { established, related } accept

                iifname lo accept
                ct state new tcp dport ssh log prefix "Neue SSH-Verbindung " accept
        }
}

Diese Beispiel-Tabelle kann als Vorlage verwendet werden. Die Konfigdatei legt eine Tabelle und eine Kette (chain) an, bei der auf eingehende IPv4- und IPv6-Pakete reagiert wird. Des Weiteren werden hier nur SSH- und lokale Verbindungen auf der Loopback-Schnittstelle (eure IP) akzeptiert. Alle anderen Pakete werden verworfen.

Gehen wir nun die wichtigsten Punkte in dieser Datei durch:

  • flush ruleset: Mit flush ruleset werden alle möglicherweise bereits existierenden Regeln gelöscht. Dies ist Sinnvoll, wenn es keine weiteren Regeln gibt. So wird sichergestellt, dass nur die daraufhin folgenden Regeln vorhanden sein sollen. Diese Option ist jedoch nur zu verwenden, fals es bereits keine wichtigen Regeln gibt, die von anderen Programmen erzeugt wurden, wie z.B. Docker.

  • Da nftables wie schon iptables in Tabellen organisiert ist, wird hier zunächst eine angelegt. In diesem Beispiel steht inet für die Protokollfamilie, d.H. für IPv4 und IPv6. Der Name basic-filter ist frei wählbar, sollte aber möglichst aussagekräftig sein. Es empfihlt sich einen Namen zu verwenden, um die Funktion der Tabelle zu beschreiben, dadurch ist es einfacher zu erkennen was Sie macht. Achtung!!: Sehr generische Namen wie filter, nat etc. sollten nicht gewählt werden, hier kann es ggf. zu Konflikten kommen. Etwa derzeit mit KVM, dort wird derzeit noch eine Kompatibilitätsschicht verwendet, die mit nativen nftables Regeln nicht funktioniert.

  • Es folgt eine Kette, die ebenfalls frei wählbarbennannt werrden darf. Im Beispiel wurde sie input genannt. Es empfiehlt sich eine Benennung, die auf den Hook (siehe unten) schließen lässt.

  • filter ist einer von drei Typen (filter, route, nat) die verwendet werden können. Wie der Name vermuten lässt, können damit Pakete anhand verschiedener Kriterien gefiltert werden. Dieser Typ ist der am hüfigsten verbreitetste. Für andere Anwendungsfälle gibt es u.a. noch nat.

  • hook gibt ein Ereignis von Netfilter an. Oder anders ausgedrückt die Stelle im Lebenslauf eines Pakets, an der diese Regel greift. Insgesamt stehen sechs Hooks zur Verfügung (ingress, prerouting, input, forward, output, postrouting). Je nach verwendetem Hook erreichen möglicherweise nicht alle Pakete eine Regel. Mit input jedoch kann sicher sein, dass die Pakete für unser System bestimmt sind.

  • Mit der Priorität (priority) wird festgelegt, welche Regel Vorrang hat.

  • Die Standardaktion policy drop verwirft alle Pakete, die nicht den gesetzten Regeln entsprechen.

  • ct state steht für connection tracking und gibt den Zustand eines Paketes an. Established sind weitere Pakete einer Verbindung, die bereits berechtigt wurde. Related dagegen erwartete neue Verbindung einer bestehenden Hauptverbindung, wie etwa ein FTP-Datenkanal. Bei FTP gibt es einen Steuerkanal, der Meta-Informationen wie Verzeichnisinhalte überträgt. Soll eine Datei hoch- oder heruntergeladen werden, öffnet dieser Steuerkanal eine zweite Verbindung für den Inhalt. Diese zweite Verbindung wird hiermit erlaubt.

  • Es folgt eine Regel, die per iifname nur auf die Loopback-Schnittstelle (lo ist der Standardname) angewendet wird. Sie erlaubt jeglichen Datenverkehr auf dieser Schnittstelle, die nur für lokale Verbindungen auf dem Server selbst genutzt wird.

  • Schlussendlich werdem neue SSH-Verbindungen auf dem Standardport 22 erlaubt. Die Anweisung dport steht für destination port, also Zielport. Hier kann man auch eine beliebige Portnummer angeben, z.B. 81. Im Beispiel ist zusätzlich mit log die Protokollierung aktiviert. prefix schreibt die folgende Zeichenkette in das Log, damit sie später wieder zu finden ist.

  • Ein weiterer Vorteil der Datei: nftables erspart dem Nutzer die Wiederholungen. Auf der Konsole müssten für die Kette (chain) beispielsweise immer Name und Typ der Tabelle angeben werden. Da die Datei hierarchisch aufgebaut ist, entfällt dies dort.

Logging von Paketen

NFTables ermöglicht es, Pakete gezielt zu loggen. Dies ist hilfreich, um verdächtigen Netzwerkverkehr zu überwachen oder zu diagnostizieren, welche Regeln greifen. Um das Logging zu aktivieren muss in die Regel das Attribut log übergeben werden. Beispiel:

nft add rule inet basic-filter input log prefix "DROP: " level warning drop  

Mit dieser Regel werden gedroppte Pakete gelogt. Es sind neue Begriffe/Attribute hinzugekommen, deren Erklärung folgende ist:

  • log: Aktiviert das Logging für Pakete, die die Regel treffen.

  • prefix: Ein individueller Präfix, der die Log-Einträge kennzeichnet (z.B. DROP oder AAA).

  • level:Der Log-Level (z.B. info, warning, debug)

  • drop: Pakete werden nach dem Logging verworfen.

Der Log Level

Der Log-Level bestimmt die Priorität der Log-Nachrichten aus dem oberen Beispiel. Es gibt acht Verschiedene Level um Nachrichten zu loggen. Anbei in der Liste werden diese Erklärt:

  • emerg: Notfall

  • alert: Alarm

  • crit: Kritisch

  • err: Fehler

  • warning: Warnung

  • notice: Hinweis

  • info: Information

  • debug: Debugging

Ein Beispiel für SSH Verbindungen

Mit dieser hier dargestellten Regel wird der Traffic der SSH Verbindung mitgeschieben.

nft add rule inet basic-filter input tcp dport 22 ct state new log prefix "SSH-ATTEMPT: " level notice  

Es können aber auch Limitierungen eingebaut werden, um die Überlastung des Systems durch zu viele Logs zu vermeiden. Das ganze ist als Rate-Limiting bekannt und funktioniert wie folgt:

nft add rule inet basic-filter input limit rate 10/minute log prefix "LIMITED-LOG: " level info drop  

Hier loggt diese Regel maximal 10 Pakete pro Minute.

Logs anzeigen lassen

Um die Logs sich anzeigen zu lassen muss man bei NFTables nichts besonderes tun. NFTables schreibt die Log-Nachrichten in:

/var/log/kern.log
/var/log/syslog

mit dem Befehl: tail -f /var/log/kern.log kann sich das Log ausgegeben werden. Es kann aber auch gezielter nach Einträgen gesucht werden indem der Befehl journalctl -k | grep "DROP:" verwendet wird.

Quelle

  • https://u-labs.de/portal/einstiegt-in-nftables-so-funktioniert-die-neue-firewall-unterschiede-zu-iptables/
  • https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains#Base_chain_types