nftables est le pare-feu du noyau Linux moderne : c'est lui qui filtre réellement les paquets, sous UFW comme sous Firewalld. L'outil nft remplace iptables avec une syntaxe unifiée, des sets natifs et de meilleures performances. Ce guide s'adresse à ceux qui veulent écrire leurs règles directement en nftables, sans frontend : serveurs minimalistes, conteneurs, appliances, ou rulesets versionnés en IaC. Vous partirez d'un ruleset serveur complet, puis verrez les sets, le NAT et la persistance.
Si vous cherchez d'abord une prise en main simple, un frontend comme UFW ou Firewalld reste plus rapide. nftables direct s'adresse à qui veut le contrôle total.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- La différence entre nftables et iptables et quand écrire du
nftdirect. - Les briques : tables, chaînes, hooks et politique par défaut.
- Un ruleset serveur complet avec filtrage stateful.
- Les sets pour gérer des listes d'adresses proprement.
- Le NAT, le masquerade et le port forwarding.
- Rendre le ruleset persistant au redémarrage.
Prérequis
Section intitulée « Prérequis »- Un serveur Linux récent (RHEL 8+, Debian 10+, Ubuntu 20.04+) et un accès root.
- Les concepts de filtrage : politique par défaut, flux entrants/sortants, connexions à état. En cas de doute, voir Introduction aux pare-feux.
- Un accès console de secours avant d'appliquer une politique
dropsur un serveur distant.
nftables ou iptables ?
Section intitulée « nftables ou iptables ? »iptables et nftables pilotent tous les deux Netfilter, le sous-système de filtrage du noyau. nftables est le successeur officiel : sur les distributions récentes, iptables n'est souvent qu'un wrapper (iptables-nft) qui traduit vers nftables en interne.
| Critère | iptables | nftables |
|---|---|---|
| Statut | Legacy, maintenu par compatibilité | Standard depuis Linux 3.13 (2014) |
| Syntaxe | Une commande par table (iptables, ip6tables...) | Une commande nft, IPv4 et IPv6 unifiés |
| Listes d'IP | Nécessite ipset en plus | Sets natifs |
| Performance | Règles évaluées linéairement | Sets et maps en temps constant |
| Comptage | Compteurs par défaut | Compteurs à la demande (plus rapide) |
En clair : sur un système moderne, écrivez du nftables. iptables ne sert plus qu'à lire d'anciennes configurations ou à faire tourner des scripts legacy.
Quand écrire du nftables directement
Section intitulée « Quand écrire du nftables directement »La règle générale reste d'utiliser le frontend par défaut de votre distribution (UFW sur Debian/Ubuntu, Firewalld sur RHEL). Mais nft direct est justifié dans plusieurs cas :
- Serveur minimaliste ou conteneur où l'on ne veut aucun démon supplémentaire.
- Ruleset versionné en Git et déployé par Ansible ou un script (infrastructure as code).
- Règles avancées que les frontends exposent mal : maps, priorités de hooks, filtrage par intervalle.
- Appliance ou passerelle où vous maîtrisez tout le trafic.
Installer nftables
Section intitulée « Installer nftables »nftables est présent sur tous les noyaux récents ; seul l'outil nft et le service peuvent manquer.
sudo apt update && sudo apt install -y nftablessudo systemctl enable --now nftablesnft --version# nftables v1.0.6 (Lester Gooch #5)sudo dnf install -y nftablessudo systemctl enable --now nftablesnft --versionTables, chaînes et hooks
Section intitulée « Tables, chaînes et hooks »Trois notions structurent nftables. Une table est un conteneur de règles pour une famille de protocoles (inet couvre IPv4 et IPv6 d'un coup). Une chaîne regroupe des règles ; une chaîne dite de base s'accroche à un hook du noyau, un point de passage du paquet.
Les hooks principaux pour le filtrage et le NAT :
| Hook | Moment | Usage typique |
|---|---|---|
input | Paquet destiné à la machine | Filtrer les flux entrants |
output | Paquet émis par la machine | Filtrer les flux sortants |
forward | Paquet routé à travers la machine | Passerelle, routeur |
prerouting | Avant décision de routage | DNAT, port forwarding |
postrouting | Après routage, avant émission | SNAT, masquerade |
Chaque chaîne de base porte une politique par défaut (policy drop ou policy accept) appliquée quand aucune règle n'a matché.
Un premier ruleset serveur
Section intitulée « Un premier ruleset serveur »Voici un ruleset serveur complet en famille inet (IPv4 + IPv6). Il pose une politique drop par défaut, n'autorise que l'essentiel, et journalise le reste. Ce ruleset a été appliqué et vérifié sur nftables 1.0.6.
#!/usr/sbin/nft -fflush ruleset
table inet filter { chain input { type filter hook input priority filter; policy drop;
iif "lo" accept ct state established,related accept ct state invalid drop ip protocol icmp accept tcp dport { 80, 443 } accept tcp dport 22 accept limit rate 5/minute log prefix "nft-drop: " drop } chain forward { type filter hook forward priority filter; policy drop; } chain output { type filter hook output priority filter; policy accept; }}Chaque ligne compte :
ct state established,related acceptautorise les réponses aux connexions déjà ouvertes : c'est le cœur du filtrage stateful. Sans elle, votre serveur ne recevrait aucune réponse.ct state invalid dropjette les paquets incohérents, souvent des scans.tcp dport { 80, 443 }utilise une liste anonyme : plus lisible qu'une règle par port.limit rate 5/minute logjournalise les paquets bloqués sans inonder les logs.
Validez toujours avant d'appliquer, avec l'option -c (check) qui ne charge rien :
sudo nft -c -f /etc/nftables.conf # validation seulesudo nft -f /etc/nftables.conf # applicationsudo nft list ruleset # vérificationSets : gérer des listes d'adresses
Section intitulée « Sets : gérer des listes d'adresses »Un set est une liste nommée, évaluée en temps constant. C'est l'équivalent natif d'ipset, idéal pour une allowlist d'administration.
table inet filter { set ssh_autorises { type ipv4_addr elements = { 192.168.1.10, 10.0.0.5 } } chain input { type filter hook input priority filter; policy drop; # ... règles précédentes ... tcp dport 22 ip saddr @ssh_autorises accept }}La règle ip saddr @ssh_autorises n'accepte le SSH que depuis les adresses du set. Ajouter une IP ne demande pas de recharger tout le ruleset :
sudo nft add element inet filter ssh_autorises { 203.0.113.7 }Les maps vont plus loin en associant une clé à une valeur (par exemple un port à une décision), utiles pour du routage de règles compact.
NAT et masquerade
Section intitulée « NAT et masquerade »Pour qu'une passerelle partage sa connexion, ajoutez une table nat avec une chaîne postrouting. Le masquerade réécrit l'adresse source des paquets sortants avec l'IP de l'interface, la forme de SNAT adaptée aux IP dynamiques.
table ip nat { chain postrouting { type nat hook postrouting priority srcnat; policy accept; oifname "eth0" masquerade }}N'oubliez pas d'activer le routage du noyau, sinon les paquets ne traversent pas la machine :
echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-forward.confsudo sysctl --systemPort forwarding avec DNAT
Section intitulée « Port forwarding avec DNAT »Pour rediriger un port public vers un service interne, utilisez une chaîne prerouting avec dnat. Testé sur nftables 1.0.6 :
table ip nat { chain prerouting { type nat hook prerouting priority dstnat; policy accept; tcp dport 8080 dnat to 192.168.1.20:80 }}Ici, tout le trafic arrivant sur le port 8080 est réécrit vers 192.168.1.20:80. Combinez prerouting (DNAT) et postrouting (masquerade) pour une passerelle complète.
Rendre le ruleset persistant
Section intitulée « Rendre le ruleset persistant »Un ruleset chargé avec nft disparaît au redémarrage. Deux réflexes le rendent permanent.
-
Écrire le ruleset dans
/etc/nftables.conf(le fichier lu par le service), en le commençant parflush rulesetpour repartir propre. -
Activer le service qui recharge ce fichier au démarrage :
Fenêtre de terminal sudo systemctl enable --now nftables -
Vérifier après un reboot que les règles sont bien là :
Fenêtre de terminal sudo nft list ruleset
Comme le fichier est un script texte, versionnez-le dans Git et déployez-le par Ansible : c'est tout l'intérêt de nftables direct en infrastructure as code.
nftables et Docker
Section intitulée « nftables et Docker »Docker écrit ses propres règles dans Netfilter pour publier les ports des conteneurs. Un flush ruleset manuel efface ces règles et casse le réseau des conteneurs jusqu'au prochain redémarrage du démon Docker.
La bonne pratique : laissez Docker gérer ses chaînes, et placez vos règles dans une table séparée plutôt que de vider le ruleset global. Sur une passerelle qui héberge aussi des conteneurs, cloisonnez avec soin et testez après chaque changement.
Aide-mémoire nftables
Section intitulée « Aide-mémoire nftables »Les commandes du quotidien pour inspecter et modifier un ruleset actif.
sudo nft list ruleset # tout le rulesetsudo nft -a list ruleset # avec les handles (pour supprimer)sudo nft list table inet filter # une table précisesudo nft add rule inet filter input tcp dport 8443 acceptsudo nft delete rule inet filter input handle 12 # via le handlesudo nft flush ruleset # tout effacer (attention !)Dépannage
Section intitulée « Dépannage »| Symptôme | Cause probable | Solution |
|---|---|---|
| Verrouillé hors du serveur | policy drop sans règle SSH | Accès console, ajouter la règle port 22 |
| Aucune réponse aux requêtes | Pas de règle ct state established | Autoriser established,related |
| Règles perdues au reboot | Ruleset non persistant | Écrire /etc/nftables.conf + activer le service |
| Conteneurs Docker injoignables | flush ruleset a effacé les chaînes Docker | Redémarrer docker, isoler vos règles |
| Paquets bloqués invisibles | Pas de journalisation | Ajouter une règle log prefix avant drop |
À retenir
Section intitulée « À retenir »- nftables est le moteur de filtrage de tous les Linux modernes ;
iptablesn'est plus qu'un wrapper. - Structure : tables (familles), chaînes accrochées à des hooks, politique par défaut.
- Un bon ruleset serveur est stateful (
ct state established,related) et drop par défaut. - Les sets remplacent
ipsetpour les listes d'adresses ; les maps vont plus loin. - NAT en
postrouting(masquerade), port forwarding enprerouting(dnat). - Rendez le ruleset persistant via
/etc/nftables.confet le servicenftables.
FAQ : Questions fréquentes
Section intitulée « FAQ : Questions fréquentes »nft pour IPv4 et IPv6), des sets natifs (plus besoin d'ipset) et une évaluation plus efficace des règles. Sur les distributions modernes, iptables n'est souvent qu'un wrapper (iptables-nft) qui traduit vers nftables. En pratique, sur un système récent, écrivez du nftables.nft directement donne un contrôle total, utile pour un serveur minimaliste, un conteneur ou un ruleset versionné en IaC. En revanche, ne mélangez jamais des règles nft manuelles avec un frontend actif : UFW et Firewalld gèrent leurs propres chaînes, et les deux configurations se contredisent silencieusement./etc/nftables.conf (en le commençant par flush ruleset), puis activez le service qui recharge ce fichier au démarrage :sudo systemctl enable --now nftables
Comme /etc/nftables.conf est un script texte, versionnez-le dans Git et déployez-le par Ansible : c'est tout l'intérêt de nftables en infrastructure as code.postrouting :table ip nat {
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
oifname "eth0" masquerade
}
}
Activez aussi le routage du noyau (net.ipv4.ip_forward = 1). Pour rediriger un port vers un service interne (port forwarding), utilisez une chaîne prerouting avec dnat, par exemple tcp dport 8080 dnat to 192.168.1.20:80.nft flush ruleset manuel efface ces règles et coupe le réseau des conteneurs jusqu'au prochain redémarrage du démon Docker. Sur une machine qui héberge des conteneurs, ne videz jamais le ruleset global : placez vos règles dans une table séparée, laissez Docker gérer ses chaînes, et testez après chaque changement.