TL;DR — Résumé Rapide
nftables remplace iptables sur Linux avec syntaxe claire et chargement atomique. Guide de migration avec sets, NAT, limitation de débit et firewall web.
nftables est le framework moderne de classification de paquets du noyau Linux et le remplacement officiel de la chaîne d’outils héritée iptables, ip6tables, arptables et ebtables. Disponible depuis le noyau 3.13 et désormais le backend par défaut sur Debian 10+, Ubuntu 20.10+, RHEL 8+ et Fedora 18+, nftables offre une interface de commandes unifiée, une correspondance native basée sur des sets et un chargement atomique des jeux de règles qui élimine les failles de sécurité inhérentes aux mises à jour règle par règle d’iptables. Ce guide couvre le chemin de migration complet — de l’installation de nftables et la compréhension de sa hiérarchie d’objets à la construction d’un firewall de serveur web prêt pour la production avec des sets, la limitation de débit, le NAT et l’intégration persistante avec systemd.
Prérequis
Avant de commencer, assurez-vous d’avoir :
- Un serveur Linux sous noyau 3.13 ou ultérieur (Ubuntu 20.04+, Debian 10+ ou RHEL 8+ recommandés)
- Accès au terminal avec les privilèges
sudo - Accès SSH au serveur si vous configurez à distance — gardez une deuxième session ouverte comme filet de sécurité
- Familiarité avec les ports TCP/UDP et les réseaux IP de base
- Règles iptables exportées si vous prévoyez de les migrer (
sudo iptables-save > ~/iptables-backup.txt)
Pourquoi nftables Remplace iptables
La chaîne d’outils héritée de Netfilter a évolué organiquement sur deux décennies, résultant en quatre utilitaires séparés (iptables, ip6tables, arptables, ebtables) chacun avec sa propre syntaxe, interface noyau et mécanisme d’extension. nftables a été conçu dès le départ pour résoudre ces problèmes structurels.
Framework Unifié
Une seule commande nft remplace les quatre outils hérités. Une seule table de famille inet gère simultanément IPv4 et IPv6, éliminant la nécessité de dupliquer chaque règle pour les deux familles d’adresses.
Meilleure Syntaxe
nftables utilise une grammaire structurée qui se lit plus naturellement que les drapeaux iptables :
# iptables
iptables -A INPUT -p tcp --dport 443 -m state --state NEW -j ACCEPT
# Équivalent nftables
nft add rule inet filter input tcp dport 443 ct state new accept
Chargement Atomique des Règles
Avec iptables, l’ajout et la suppression de règles se font une à la fois — il existe une condition de concurrence entre chaque opération individuelle. nftables charge un jeu de règles complet comme une seule transaction atomique via nft -f, garantissant que le firewall n’est jamais dans un état partiel.
Sets et Maps Natifs
iptables nécessite l’extension séparée ipset pour correspondre efficacement à de grandes listes d’IPs ou de ports. nftables inclut des sets et des maps nativement, prenant en charge les délais d’expiration, les clés concaténées et les verdict maps sans packages supplémentaires.
Bases de la Commande nft
nftables organise tout dans une hiérarchie à trois niveaux : les tables contiennent des chaînes, les chaînes contiennent des règles. Chaque table appartient à une famille d’adresses.
Familles d’Adresses
| Famille | Trafic géré |
|---|---|
ip | IPv4 uniquement |
ip6 | IPv6 uniquement |
inet | IPv4 et IPv6 (recommandé pour les serveurs) |
arp | Protocole ARP |
bridge | Niveau bridge/switch |
netdev | Ingress sur une interface spécifique |
Gestion des Tables
sudo nft add table inet filter # créer une table
sudo nft list tables # lister toutes les tables
sudo nft delete table inet filter # supprimer la table et son contenu
sudo nft flush table inet filter # supprimer toutes les règles, conserver la structure
Gestion des Chaînes
Les chaînes de base sont attachées à un hook Netfilter. Elles nécessitent un type, un hook et une priority :
sudo nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; }
sudo nft add chain inet filter forward { type filter hook forward priority 0 \; policy drop \; }
sudo nft add chain inet filter output { type filter hook output priority 0 \; policy accept \; }
Gestion des Règles
sudo nft add rule inet filter input tcp dport 22 accept # ajouter à la fin
sudo nft insert rule inet filter input tcp dport 22 accept # insérer au début
sudo nft list chain inet filter input # voir avec les handles
sudo nft delete rule inet filter input handle 5 # supprimer par handle
Construction d’un Firewall de Base
La séquence suivante construit un firewall de référence complet étape par étape.
Étape 1 — Créer la Table et les Chaînes
sudo nft add table inet filter
sudo nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; }
sudo nft add chain inet filter forward { type filter hook forward priority 0 \; policy drop \; }
sudo nft add chain inet filter output { type filter hook output priority 0 \; policy accept \; }
Étape 2 — Accepter les Connexions Établies et le Loopback
Ces règles doivent venir en premier pour que les sessions existantes ne soient pas interrompues :
sudo nft add rule inet filter input ct state established,related accept
sudo nft add rule inet filter input ct state invalid drop
sudo nft add rule inet filter input iif lo accept
Étape 3 — Autoriser ICMP
sudo nft add rule inet filter input ip protocol icmp limit rate 10/second burst 20 packets accept
sudo nft add rule inet filter input ip6 nexthdr icmpv6 limit rate 10/second burst 20 packets accept
Étape 4 — Autoriser les Ports de Services
sudo nft add rule inet filter input tcp dport 22 accept
sudo nft add rule inet filter input tcp dport { 80, 443 } accept
Étape 5 — Rejet Final
Envoyez une erreur ICMP au trafic non correspondant plutôt que de le supprimer silencieusement :
sudo nft add rule inet filter input reject with icmpx type port-unreachable
Sets et Maps pour une Gestion Efficace des Règles
Les sets éliminent la nécessité d’écrire une règle par port ou adresse IP. Ils peuvent être mis à jour dynamiquement sans modifier les règles qui les référencent.
Sets Anonymes (En Ligne)
sudo nft add rule inet filter input tcp dport { 22, 80, 443, 8443 } accept
Sets Nommés
sudo nft add set inet filter tcp_accepted { type inet_service \; }
sudo nft add element inet filter tcp_accepted { 22, 80, 443 }
sudo nft add rule inet filter input tcp dport @tcp_accepted accept
# Ajouter ou supprimer des ports sans toucher à la règle
sudo nft add element inet filter tcp_accepted { 8080 }
sudo nft delete element inet filter tcp_accepted { 8080 }
Liste de Blocage d’IPs avec Expiration Automatique
sudo nft add set inet filter blocklist { type ipv4_addr \; timeout 24h \; }
sudo nft add element inet filter blocklist { 203.0.113.10, 198.51.100.5 }
sudo nft add rule inet filter input ip saddr @blocklist drop
Sets Concaténés (Correspondance Multi-champs)
sudo nft add set inet filter db_access { type ipv4_addr . inet_service \; }
sudo nft add element inet filter db_access { 10.0.1.20 . 3306, 10.0.1.21 . 5432 }
sudo nft add rule inet filter input ip saddr . tcp dport @db_access accept
Limitation de Débit et Suivi des Connexions
Limitation Globale de SSH
sudo nft add rule inet filter input tcp dport 22 ct state new limit rate 5/minute burst 10 packets accept
sudo nft add rule inet filter input tcp dport 22 ct state new drop
Limitation de Débit par IP Source avec des Mètres
sudo nft add rule inet filter input tcp dport 22 ct state new \
meter ssh_limit { ip saddr limit rate 3/minute burst 5 packets } accept
États de Suivi des Connexions
| État | Signification |
|---|---|
new | Premier paquet d’une nouvelle connexion |
established | Trafic de retour pour une connexion acceptée |
related | Associé à une connexion existante |
invalid | Ne peut pas être identifié — toujours supprimer |
untracked | Ignore explicitement le conntrack |
NAT et Redirection de Ports
Créer la Table NAT
sudo nft add table inet nat
sudo nft add chain inet nat prerouting { type nat hook prerouting priority -100 \; }
sudo nft add chain inet nat postrouting { type nat hook postrouting priority 100 \; }
Masquerade (NAT Source pour Routeurs/VPNs)
sudo nft add rule inet nat postrouting oif "eth0" masquerade
Redirection de Ports (NAT Destination)
sudo nft add rule inet nat prerouting iif "eth0" tcp dport 8080 dnat to 10.0.0.50:80
sudo nft add rule inet filter forward ip daddr 10.0.0.50 tcp dport 80 ct state new accept
sudo nft add rule inet filter forward ct state established,related accept
Activer le transfert IP :
echo "net.ipv4.ip_forward = 1" | sudo tee /etc/sysctl.d/99-nftables.conf
sudo sysctl -p /etc/sysctl.d/99-nftables.conf
Journalisation et Surveillance
sudo nft add rule inet filter input ct state invalid log prefix "nft_invalid: " level warn drop
sudo journalctl -k --grep="nft_" -f
sudo nft monitor
Sauvegarde et Restauration des Jeux de Règles
sudo nft list ruleset | sudo tee /etc/nftables.conf
sudo nft -c -f /etc/nftables.conf # test à sec de la syntaxe
sudo nft -f /etc/nftables.conf # appliquer atomiquement
Migration depuis iptables
Traduire des Règles Individuelles
iptables-translate -A INPUT -p tcp --dport 443 -j ACCEPT
# Sortie : nft add rule ip filter INPUT tcp dport 443 counter accept
Traduire un Jeu de Règles Complet
sudo iptables-save > /tmp/ipt-backup.txt
iptables-restore-translate -f /tmp/ipt-backup.txt > /tmp/nft-migrated.nft
sudo nft -f /tmp/nft-migrated.nft
Meilleures Pratiques de Migration
- Faites une sauvegarde d’abord —
sudo iptables-save > ~/iptables-backup.txt - Traduisez et révisez — n’appliquez jamais des règles auto-traduites sans révision
- Testez hors production — appliquez les règles traduites sur un serveur de test d’abord
- Gardez une session console — accès console cloud ou KVM comme secours
- Videz iptables après confirmation —
sudo iptables -F && sudo iptables -X - Désactivez le service hérité —
sudo systemctl disable iptables
Intégration avec systemd
sudo systemctl enable nftables
sudo systemctl start nftables
sudo systemctl reload nftables # rechargement atomique du jeu de règles
Comparaison : nftables vs iptables vs UFW vs firewalld
| Fonctionnalité | nftables | iptables | UFW | firewalld |
|---|---|---|---|---|
| Outil unique pour tout | Oui | Non (4 outils) | Oui (frontend) | Oui (frontend) |
| IPv4 + IPv6 dans une table | Oui (inet) | Non | Oui | Oui |
| Sets/maps natifs | Oui | Non (besoin d’ipset) | Non | Non |
| Remplacement atomique des règles | Oui (nft -f) | Non | Non | Partiel |
| Interface simplifiée | Non | Non | Oui | Oui |
| Flexibilité de scripting | Haute | Moyenne | Faible | Moyenne |
| Performance à grande échelle | Excellente | Bonne | Bonne | Bonne |
Scénario Réel : Serveur Web et Proxy Inverse
Vous avez un serveur de production exécutant Nginx comme proxy inverse devant deux serveurs d’application sur 10.0.0.10 et 10.0.0.11, avec une interface publique (eth0) et une interne (eth1). Exigences : accès SSH uniquement depuis votre CIDR de gestion, HTTP/HTTPS public, trafic backend uniquement depuis le réseau interne et protection contre la force brute SSH.
#!/usr/sbin/nft -f
flush ruleset
define WAN = eth0
define LAN = eth1
define MGMT_CIDR = 10.10.10.0/24
table inet filter {
set mgmt_hosts {
type ipv4_addr
flags interval
elements = { $MGMT_CIDR }
}
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
ct state invalid drop
iif lo accept
ip protocol icmp limit rate 10/second burst 20 packets accept
ip saddr @mgmt_hosts tcp dport 22 ct state new \
meter ssh_mgmt { ip saddr limit rate 5/minute burst 10 packets } accept
tcp dport { 80, 443 } accept
reject with icmpx type port-unreachable
}
chain forward {
type filter hook forward priority 0; policy drop;
ct state established,related accept
}
chain output {
type filter hook output priority 0; policy accept;
}
}
Pièges et Cas Particuliers
- L’ordre des règles est important — nftables évalue les règles de haut en bas. Placez
ct state established,related acceptavant toute règle de suppression. - Aucune table ou chaîne par défaut — nftables démarre vide. Si vous oubliez de créer une chaîne, le trafic n’est pas du tout filtré.
- flush ruleset est destructif — incluez-le toujours au début des fichiers de configuration, mais ne l’exécutez jamais interactivement sur un serveur en production sans plan de secours.
- Les variables nécessitent
define— nftables utilisedefine VAR = valuedans les fichiers de configuration ; vous ne pouvez pas utiliser des variables shell directement dans les commandesnft. - iptables et nftables peuvent entrer en conflit — si les deux s’exécutent, les règles des deux frameworks s’appliquent indépendamment.
Dépannage
Les règles ne persistent pas après redémarrage : Vérifiez que le service est activé avec sudo systemctl is-enabled nftables. Assurez-vous que /etc/nftables.conf contient flush ruleset au début et a une syntaxe nft valide.
SSH bloqué après application des règles : Accédez via la console cloud, puis exécutez sudo nft flush ruleset. Reconstruisez la configuration avec SSH autorisé avant de définir une politique de suppression.
Module noyau manquant : Exécutez lsmod | grep nf_tables. Si absent, chargez avec sudo modprobe nf_tables nft_chain_nat nft_ct.
Erreur de syntaxe dans le fichier de configuration : Utilisez sudo nft -c -f /etc/nftables.conf pour un test à sec qui signale la ligne et l’erreur exactes sans appliquer de modifications.
Résumé
nftables est le remplacement prêt pour la production d’iptables sur tout système Linux sous noyau 3.13 ou ultérieur. Sa commande nft unifiée, ses sets et maps natifs, son chargement atomique des règles et sa syntaxe plus claire abordent chaque faiblesse structurelle majeure de la chaîne d’outils héritée.
Points clés :
- Utilisez la famille d’adresses
inetpour gérer IPv4 et IPv6 depuis une seule table - Commencez toujours avec
ct state established,related acceptetiif lo accept - Utilisez des sets nommés pour gérer des listes de ports et d’IPs sans réécrire les règles
- Protégez les services d’authentification avec des mètres par IP plutôt que des limites de débit globales
- Stockez le jeu de règles dans
/etc/nftables.confet chargez-le atomiquement avecnft -f - Activez le service systemd nftables pour que le jeu de règles persiste après les redémarrages
- Utilisez
iptables-restore-translatepour convertir les jeux de règles existants et révisez soigneusement avant d’appliquer