update-alternatives
.Ceci est une ancienne révision du document !
Table des matières
Nftables
Le couple Netfilter/Iptables dont le projet fut initié par Paul “Rusty” Russell au tout début du siècle. Si Netfilter reste d'actualité en évoluant au fil du temps, Iptables, de l'aveu même de son initiateur en était arrivé à un point où toute évolution devenait problématique, le code devenant difficile à maintenir et les commandes trop nombreuses (iptables, ip6tables, ebtables, arptables…).
Nftables, apparu depuis le kernel 3.13 en 2014, reprend toutes les idées accumulées dans le projet iptables, en les organisant de façon plus cohérente, avec un code entièrement revu.
La transition
De très nombreux pare-feu ont été mis en place en utilisant iptables. De très nombreux outils ont été développés, qui sont des surcouches d'Iptables pour aider à créer des protections contre les attaques comme fail2ban, Shorewall et bien d'autres. Certains de ces outils sont maintenant (04/2025) adaptés à Nftables, d'autres pas encore, ou ne le seront jamais. La transition ne peut donc se faire qu'en douceur.
Regardons comment Debian a traité le problème. La version stable au 03/04/2025 est la version «Bookworm» 12.10 (kernel 6.1) et elle installe Nftables par défaut. Cependant, le paquet IPtables existe toujours, dont la description est la suivante:
apt show iptables Package: iptables Version: 1.8.9-2 ... Description: outils d'administration pour le filtrage de paquets et le NAT Le cadriciel iptables/xtables a été remplacé par nftables. La migration doit être envisagée. . Iptables est le programme en ligne de commande pour l'espace utilisateur, utilisé pour configurer l'ensemble des règles de filtrage de paquets et de NAT sous Linux. Il est destiné aux administrateurs système et réseau. . Ce paquet fournit plusieurs utilitaires différents, dont les plus importants sont : . iptables-nft, iptables-nft-save, iptables-nft-restore (version basée sur nft) . iptables-legacy, iptables-legacy-save, iptables-legacy-restore (version traditionnelle) . ip6tables-nft, ip6tables-nft-save, ip6tables-nft-restore (version basée sur nft) . ip6tables-legacy, ip6tables-legacy-save, ip6tables-legacy-restore (version traditionnelle) . arptables-nft, arptables-nft-save, arptables-nft-restore (version basée sur nft) . ebtables-nft, ebtables-nft-save, ebtables-nft-restore (version basée sur nft)Le paquet propose donc une sorte d'interprète iptables/Nftables, avec malgré tout les anciennes commandes iptables et ip6tables natives pour les irréductibles.
Iptables encore
Nous allons installer ce paquet qui ne l'est donc plus par défaut. Nous allons le faire sur la Debian «Trixie» encore à l'état “testing” au 03/04/2025.
apt install iptables
Installing:
iptables
Installing dependencies:
libip4tc2 libip6tc2 libnetfilter-conntrack3 libnfnetlink0
Paquets suggérés :
firewalld
Summary:
Upgrading: 0, Installing: 5, Removing: 0, Not Upgrading: 0
Download size: 458 kB
Space needed: 2 799 kB / 8 040 MB available
Continue? [O/n] o
Réception de :1 http://deb.debian.org/debian trixie/main amd64 libip4tc2 amd64 1.8.11-2 [20,0 kB]
Réception de :2 http://deb.debian.org/debian trixie/main amd64 libip6tc2 amd64 1.8.11-2 [20,3 kB]
Réception de :3 http://deb.debian.org/debian trixie/main amd64 libnfnetlink0 amd64 1.0.2-3 [14,4 kB]
Réception de :4 http://deb.debian.org/debian trixie/main amd64 libnetfilter-conntrack3 amd64 1.1.0-1 [42,1 kB]
Réception de :5 http://deb.debian.org/debian trixie/main amd64 iptables amd64 1.8.11-2 [361 kB]
458 ko réceptionnés en 0s (1 646 ko/s)
Sélection du paquet libip4tc2:amd64 précédemment désélectionné.
(Lecture de la base de données... 36101 fichiers et répertoires déjà installés.)
Préparation du dépaquetage de .../libip4tc2_1.8.11-2_amd64.deb ...
Dépaquetage de libip4tc2:amd64 (1.8.11-2) ...
Sélection du paquet libip6tc2:amd64 précédemment désélectionné.
Préparation du dépaquetage de .../libip6tc2_1.8.11-2_amd64.deb ...
Dépaquetage de libip6tc2:amd64 (1.8.11-2) ...
Sélection du paquet libnfnetlink0:amd64 précédemment désélectionné.
Préparation du dépaquetage de .../libnfnetlink0_1.0.2-3_amd64.deb ...
Dépaquetage de libnfnetlink0:amd64 (1.0.2-3) ...
Sélection du paquet libnetfilter-conntrack3:amd64 précédemment désélectionné.
Préparation du dépaquetage de .../libnetfilter-conntrack3_1.1.0-1_amd64.deb ...
Dépaquetage de libnetfilter-conntrack3:amd64 (1.1.0-1) ...
Sélection du paquet iptables précédemment désélectionné.
Préparation du dépaquetage de .../iptables_1.8.11-2_amd64.deb ...
Dépaquetage de iptables (1.8.11-2) ...
Paramétrage de libip4tc2:amd64 (1.8.11-2) ...
Paramétrage de libip6tc2:amd64 (1.8.11-2) ...
Paramétrage de libnfnetlink0:amd64 (1.0.2-3) ...
Paramétrage de libnetfilter-conntrack3:amd64 (1.1.0-1) ...
Paramétrage de iptables (1.8.11-2) ...
update-alternatives: utilisation de « /usr/sbin/iptables-legacy » pour fournir « /usr/sbin/iptables » (iptables) en mode automatique
update-alternatives: utilisation de « /usr/sbin/ip6tables-legacy » pour fournir « /usr/sbin/ip6tables » (ip6tables) en mode automatique
update-alternatives: utilisation de « /usr/sbin/iptables-nft » pour fournir « /usr/sbin/iptables » (iptables) en mode automatique
update-alternatives: utilisation de « /usr/sbin/ip6tables-nft » pour fournir « /usr/sbin/ip6tables » (ip6tables) en mode automatique
update-alternatives: utilisation de « /usr/sbin/arptables-nft » pour fournir « /usr/sbin/arptables » (arptables) en mode automatique
update-alternatives: utilisation de « /usr/sbin/ebtables-nft » pour fournir « /usr/sbin/ebtables » (ebtables) en mode automatique
Traitement des actions différées (« triggers ») pour man-db (2.13.0-1) ...
Traitement des actions différées (« triggers ») pour libc-bin (2.41-6) ...
Faisons le point sur les alternatives1).
update-alternatives --config iptables Il existe 2 choix pour l'alternative iptables (qui fournit /usr/sbin/iptables). Sélection Chemin Priorité État ------------------------------------------------------------ * 0 /usr/sbin/iptables-nft 20 mode automatique 1 /usr/sbin/iptables-legacy 10 mode manuel 2 /usr/sbin/iptables-nft 20 mode manuel Appuyez surQu'est-ce à dire ? Nous gardons l'alternative par défaut, à savoir utiliser iptables-nft justement sans le savoir obligatoirement. Pour vérifier et en même temps décortiquer le principe des alternatives:pour conserver le choix actuel [*], ou tapez le numéro de sélection :
which iptables /usr/sbin/iptables ls -l /usr/sbin/iptables lrwxrwxrwx 1 root root 26 20 nov. 10:03 /usr/sbin/iptables -> /etc/alternatives/iptables ls -l /etc/alternatives/iptables lrwxrwxrwx 1 root root 22 26 mars 17:52 /etc/alternatives/iptables -> /usr/sbin/iptables-nftDonc, un lien qui pointe vers un autre lien qui pointe vers la commande alternative. Bref, en gardant cette alternative, nous allons utiliser nftables sans le savoir, en utilisant toujours des règles de type
iptables
, ce qui permet de laisser du temps pour faire évoluer les outils annexes comme fail2ban qui sait désormais utiliser Nftables.
Premier pas
Écrivons quelques règles simples comme nous les avons déjà vues sur notre maquette précédente:
iptables -A INPUT -p tcp --dport 23 -j ACCEPT iptables -A INPUT -p udp --dport 68 -j ACCEPT iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -P INPUT DROP
En français:
laisser entrer les connexions TCP sur le port 23 (Telnet) laisser entrer les datagrammes UDP sur le port 68 (DHCP) laisser entrer toutes les connexions déjà établies ou relatives à une connexion déjà établie mettre tout le reste à la poubelle
Pour IPv6 c'est un peu la même chose à part qu'il vaut mieux laisser passer ICMP vu la façon dont la configuration «sans état» se fait, de même que l'on peut faire confiance aux adresses de lien local,mais ne plus autoriser l'accès au port 23 pour les adresses «lien global»:
ip6tables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT ip6tables -A INPUT -p ipv6-icmp -j ACCEPT ip6tables -A INPUT -s fe80::/64 -j ACCEPT ip6tables -P INPUT DROP
Vérification:
iptables --list Chain INPUT (policy DROP) target prot opt source destination ACCEPT tcp -- anywhere anywhere tcp dpt:telnet ACCEPT udp -- anywhere anywhere udp dpt:bootpc ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination ip6tables --list Chain INPUT (policy DROP) target prot opt source destination ACCEPT ipv6-icmp -- anywhere anywhere ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED ACCEPT all -- fe80::/64 anywhere Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destinationEt puisque nous utilisons la traduction IPtables/Nftables, voyons si le nouvel outil «nft» s'y retrouve:
En mode interactif SVP!
nft -i nft> list tables table ip filter table ip6 filter nft> list table ip filter # Warning: table ip filter is managed by iptables-nft, do not touch! table ip filter { chain INPUT { type filter hook input priority filter; policy drop; tcp dport 23 counter packets 1528 bytes 81891 accept udp dport 68 counter packets 0 bytes 0 accept ct state related,established counter packets 0 bytes 0 accept } } nft> list table ip6 filter # Warning: table ip filter is managed by iptables-nft, do not touch! table ip6 filter { chain INPUT { type filter hook input priority filter; policy drop; ct state related,established counter packets 0 bytes 0 accept meta l4proto ipv6-icmp counter packets 38 bytes 2704 accept ip6 saddr fe80::/64 counter packets 0 bytes 0 accept } }Nous sentons bien qu'en version «nft» ça veut dire la même chose, mais avec une syntaxe complètement différente qui ressemble déjà beaucoup à un fichier de configuration.
À priori, nous avons toujours deux tables séparées, pour IPv4 et pour IPv6, sauf que nft sait gérer les deux dans le même environnement:
nft list ruleset # Warning: table ip filter is managed by iptables-nft, do not touch! table ip filter { chain INPUT { type filter hook input priority filter; policy drop; tcp dport 23 counter packets 496 bytes 26436 accept udp dport 68 counter packets 0 bytes 0 accept ct state related,established counter packets 20 bytes 2060 accept } } # Warning: table ip6 filter is managed by iptables-nft, do not touch! table ip6 filter { chain INPUT { type filter hook input priority filter; policy drop; ct state related,established counter packets 0 bytes 0 accept meta l4proto ipv6-icmp counter packets 28 bytes 1968 accept ip6 saddr fe80::/64 counter packets 0 bytes 0 accept }Ce qui permet d'avoir beaucoup plus facilement une vue de l'ensemble du filtrage.
Il semble donc relativement simple de traduire des pare-feux iptables en pare-feux nftables, mais comme indiqué dans le «warning»: il faudra choisir son camp une fois pour toutes si l'on doit modifier quelque chose par la suite.
Migration
Sur cette première manip, essayons de migrer définitivement vers Nftables.
Sauvegarde des règles iptables
iptables-save > rules-v4-Iptables.txt ip6tables-save > rules-v6-Iptables.txt
Le lecteur attentif aura remarqué que dans ce cas simple les règles sont identiques en IPv4 et IPv6 et que donc la seconde ligne est inutile. Mais dans le cas général, les règles IPv4 et IPv6 ne sont pas forcément les mêmes!
Traduire ces règles en syntaxe nft
iptables-restore-translate -f rules-v4-Iptables.txt > ruleset.nft ip6tables-restore-translate -f rules-v6-Iptables.txt >> ruleset.nft
À l'issue de cette étape, le fichier ruleset.nft
a donc cette allure:
cat ruleset.nft # Translated by iptables-restore-translate v1.8.11 on Thu Mar 27 11:32:55 2025 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 rule ip filter INPUT tcp dport 23 counter accept add rule ip filter INPUT udp dport 68 counter accept add rule ip filter INPUT ct state related,established counter accept # Completed on Thu Mar 27 11:32:55 2025 # Translated by ip6tables-restore-translate v1.8.11 on Thu Mar 27 11:33:15 2025 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 rule ip6 filter INPUT ct state related,established counter accept add rule ip6 filter INPUT meta l4proto ipv6-icmp counter accept add rule ip6 filter INPUT ip6 saddr fe80::/64 counter accept # Completed on Thu Mar 27 11:33:15 2025
Création du fichier de configuration nftables
Très simple. On commence par virer les éventuels parasites, puis on injecte notre fichier de traduction:
nft flush ruleset nft -f ruleset.nftEt l'on admire le résultat:
nft list ruleset table ip filter { chain INPUT { type filter hook input priority filter; policy drop; tcp dport 23 counter packets 35 bytes 1837 accept UDP DPORT 68 counter packets 0 bytes 0 accept ct state established,related counter packets 0 bytes 0 accept } chain FORWARD { type filter hook forward priority filter; policy accept; } chain OUTPUT { type filter hook output priority filter; policy accept; } } table ip6 filter { chain INPUT { type filter hook input priority filter; policy drop; ct state established,related counter packets 0 bytes 0 accept meta l4proto ipv6-icmp counter packets 2 bytes 200 accept ip6 saddr fe80::/64 counter packets 0 bytes 0 accept } chain FORWARD { type filter hook forward priority filter; policy accept; } chain OUTPUT { type filter hook output priority filter; policy accept; } }Le système a rajouté les chaînes INPUT et FORWARD qui restent vides dans notre cas (trop) simple. En effet, il a été omis d'autoriser les entrées et les sorties sur l'interface locale, aussi bien en IPv4 qu'en IPv6, ce qui pourrait perturber le fonctionnement de certains services utilisant un socket inet plutôt qu'un socket unix pour communiquer entre eux.