iptables stirbt! Fail2Ban auf nftables umstellen.

nftables ist eine (nicht mehr ganz so neue, aber dafür fast unbekannte) Benutzerschnittstelle für die Debian-Firewall. Dagegen gilt iptables als “die” Benutzerschnittstelle zur Debian-Firewall, aber gilt auch als veraltet. Bis Debian Buster (Debian 10) läuft iptables zwar noch problemlos, zuletzt aber im Kompatibilätsmodus, da im Hintergrund bereits seit Debian Stretch (Debian 9) das Framework von nft werkelt. Nicht zuletzt, weil iptables selbst gar nicht mit IPv6-Adressen umgehen kann, dafür wurde die “Krücke” ip6tables geschaffen.

Das kostet vor allem Leistung und Geschwindigkeit.

Das “neue” nftables löst iptables, ip6tables, arptables und ebtables ab und vereint alle Funktionen unter einem Hut.

Nun läuft auf meinen Debian-Systemen mittlerweile die Version Buster, so dass es an der Zeit ist, langsam mal mit der Entwicklung mitzugehen und iptables in Rente zu schicken. Spätestens mit Debian Bullseye (Debian 11) ist nach der aktuellen Planung der Einsatz von iptables sowieso Geschichte.

Hinweis zur Sicherheit

Lest erst diesen Beitrag durch und bereitet euch vor. Während der Installation ist das System weder durch eine Firewall noch durch Fail2Ban geschützt, da diese Dienste während der Installation abgeschaltet sind!

Einige Schritte lassen sich vorbereiten, so könnt ihr wertvolle Zeit sparen. Oder trennt den Server direkt nach der Installation von nftables vom Internet. Eine Internetverbindung wird nur für das Herunterladen der Installationspakete benötigt!

Vorbereitung

Zuerst werden die bisherigen Filterregeln gespeichert, da beide Programme auf dem Kernel-Netzfilter aufbauen, aber grundlegend unterschiedliche Syntaxes verwenden.

mkdir /tmp/nftables && cd /tmp/nftables
iptables-save > rules.txt
ip6tables-save > rules6.txt

In den dadurch erzeugten Dateien /tmp/nftables/rules.txt und /tmp/nftables/rules6.txt sollten noch die bisherigen Filterregeln von Fail2Ban rausgeschmissen werden, da diese nach dem erneuten Start von Fail2Ban durch das Programm gesetzt werden.

Die Dateien werden später in der neuen Firewall eingelesen.

Installation

Die folgenden Befehle löschen die bestehenden Filterregeln, beenden Fail2Ban, installieren nftables und aktivieren dessen automatischen Start beim Systemstart. iptables wird dabei automatisch aus dem Systemstart gelöscht.

ACHTUNG: Mit der Eingabe der folgenden Befehle ist das System ungeschützt im Internet! nftables wird nach der Installation automatisch aktiviert und enthält vorerst keinerlei Konfiguration!

systemctl stop fail2ban
iptables -F
ip6tables -F
apt install nftables
systemctl enable nftables.service --now

Ab jetzt wird keine Internetverbindung mehr benötigt.

Jetzt wird noch der Kompatibilätsmodus von iptables auf “nft” gesetzt.
(Dieser Schritt ist nur notwendig, falls iptables überhaupt auf den Kompatibilätsmodus geschaltet wurde. Ansonsten ist dies die “Defaulteinstellung” von Debian Buster)

update-alternatives --set iptables /usr/sbin/iptables-nft
update-alternatives --set ip6tables /usr/sbin/ip6tables-nft

Das wars. Kurz und schmerzlos, oder? Jetzt schnell weiter, damit der Server nicht zu lange ungeschützt ist!

nftables anpassen

Oben haben wir die aktuellen Filterregeln von iptables gespeichert, nun konvertieren wir diese und speichern diese in der Konfigurationsdatei von nftables, damit sie auch nach einem Neustart zur Verfügung stehen und geladen werden.

cd /tmp/nftables
iptables-restore-translate -f save.txt >> /etc/nftables/ruleset.nft
ip6tables-restore-translate -f save6.txt >> /etc/nftables/ruleset.nft

Die Datei /tmp/nftables/ruleset.nft enthält nun beides, Regeln zu IPv4 und IPv6. Jetzt kommt ein bisschen Handarbeit. Mit einem Editor der Wahl wird die Datei noch bearbeitet, denn nftables kann ja, im Gegensatz zu iptables/ip6tables mit beiden Adresstypen umgehen. Die Regeln, für die in der Datei nun beide Adresstypen vorhanden sind, werden wie folgt vereinfacht:

Aus diesen iptables/ip6tables-Regeln 

##iptables
*filter
:INPUT DROP [128522:15809150]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [109888:13405809]
:main - [0:0]
##ip6tables
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:main - [0:0]
##iptables
add table ip filter
add chain ip filter INPUT { type filter hook input priority 0; policy drop; }
add chain ip filter FORWARD { type filter hook forward priority 0; policy accept; }
add chain ip filter OUTPUT { type filter hook output priority 0; policy accept; }
add chain ip filter main
##ip6tables
add table ip6 filter
add chain ip6 filter INPUT { type filter hook input priority 0; policy drop; }
add chain ip6 filter FORWARD { type filter hook forward priority 0; policy accept; }
add chain ip6 filter OUTPUT { type filter hook output priority 0; policy accept; }
add chain ip6 filter main

werden diese nftables-Regeln

add table inet filter
add chain inet filter INPUT { type filter hook input priority 0; policy drop; }
add chain inet filter FORWARD { type filter hook forward priority 0; policy accept; }
add chain inet filter OUTPUT { type filter hook output priority 0; policy accept; }
add chain inet filter main

Gleichzeitig kann der Code noch weiter vereinfacht werden. Wollte man in iptables den SSH-Port für IPv4 und IPv6 freigeben, brauchte man vier Zeilen in zwei Konfigurationsdateien. Mit nftables reicht eine Zeile:

## iptables-Syntax, jeweils für IPv4 und IPv6 anzulegen
-A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp --sport 22 -m conntrack --ctstate ESTABLISHED -j ACCEPT
## nftables-Syntax. Durch "inet" werden gleichzeitig IPv4 und IPv6 behandelt
add rule inet filter input tcp dport 22 ct state new,established accept

Ganz an den Anfang der Datei kommt sicherheitshalber ein flush tables. Ist die Bearbeitung fertig, wird nftables über die Datei informiert echo 'include "/etc/nftables/ruleset.nft"' >> /etc/nftables.rules und mit nft -f /etc/nftables.rules neu geladen.

Fail2Ban anpassen

Nun muss Fail2Ban gesagt werden, dass die Blockaden zukünftig mit nftables gesetzt werden sollen.

Dazu werden folgende Einstellungen gesetzt, bzw. ergänzt.
Angezeigt sind jeweils nur die Änderungen, der Rest bleibt bestehen!

Für den nächsten Schritt müsst ihr die Version von Fail2Ban mit fail2ban-client -v ermitteln und entsprechend der angezeigten Version im passenden Abschnitt weiterlesen.

Fail2Ban < 0.9.4

Erst mit Version 0.9.4 hat Fail2Ban entsprechende Actionscripte erhalten, um mit nftables arbeiten zu können. Aber für diese alten Versionen können die passenden Scripte nachgeladen werden. Geht dazu einfach auf GitHub und holt euch die drei Dateien, die mit nftables beginnen. Auf der Kommandozeile könnt ihr das mit diesem Einzeiler erledigen:

cd /etc/fail2ban/action.d/ && wget https://raw.githubusercontent.com/fail2ban/fail2ban/master/config/action.d/nftables-*.conf

Diese Dateien enthalten bereits die Scripte, um die passenden Chains in nftables anzulegen. Daher könnt ihr den nächsten Schritt überspringen und in Fail2Ban < 0.10, Fail2Ban vorbereiten weiterlesen.

Fail2Ban < 0.10

Fail2Ban kleiner als Version 0.10 unterstützt noch kein IPv6. Daher darf die Firewall-Chain nicht auf inet (IPv4 und IPv6) gestellt werden, sondern nur auf ip, was bei Netfilter mit IPv4 gleichzusetzen ist. Zusätzlich muss die Filterkette per Hand angelegt werden.

nftables vorbereiten

Es wird eine neue Datei /etc/nftables/fail2ban.conf mit folgendem Inhalt angelegt (evtl. muss der Ordner erst noch mit mkdir /etc/nftables angelegt werden):

#!/usr/sbin/nft -f

table ip fail2ban {
    chain input {
        type filter hook input priority 100;
    }
}

Die Hauptconfig muss nun noch von dieser Datei Kenntnis haben, das erreicht ihr mit echo 'include "etc/nftables/fail2ban.conf"' >> /etc/nftables.rules, anschließend wird die neue Datei mit nft -f /etc/nftables/fail2ban.conf geladen und aktiviert.

Fail2Ban vorbereiten

Die Datei /etc/fail2ban/jail.local wird an den folgenden Stellen geändert:

[DEFAULT]
banaction =             nftables-multiport
banaction_allports =    nftables-allports
chain =                 input

[recidive]
banaction =             nftables-allports

Außerdem wird noch eine Datei /etc/fail2ban/action.d/nftables-common.local angelegt, die den folgenden Inhalt bekommt:

[Init]
nftables_family =   ip
nftables_table =    fail2ban

blocktype =         drop

nftables_set_prefix =

Fail2Ban >= 0.10

Ab Verson 0.10 unterstützt Fail2Ban die Nutzung von IPv4 und IPv6, auch die Anlage der Filterkette wird mittlerweile automatisch erledigt. Daher beschränken sich die Aufgaben auf die Änderung an der /etc/fail2ban/jail.local. In der Datei sind folgende Änderungen notwenig:

[DEFAULT]
banaction =             nftables-multiport
banaction_allports =    nftables-allports
chain =                 input

[recidive]
banaction =             nftables-allports

Fail2Ban, alle Versionen

Anschließend wird Fail2ban mit  systemctl start fail2ban wieder gestartet und greift nun automatisch auf die “neue” Firewall zu.

Erst jetzt ist der Server wieder geschützt! 

Fertig!

So, das war es soweit. Sollte ich was vergessen haben, oder etwas unklar sein, einfach unten in die Kommentare.

Kommentar verfassen