nftables est le framework moderne de classification de paquets dans le noyau Linux, concu comme successeur des outils historiques iptables, ip6tables, arptables et ebtables. Depuis son introduction dans le noyau Linux 3.13, nftables est devenu le backend de filtrage par defaut sur la plupart des distributions Linux majeures, notamment Debian 10+, Ubuntu 20.10+, RHEL 8+ et Fedora 18+. Ce guide fournit une presentation complete des concepts, de la syntaxe et des configurations pratiques de nftables pour securiser des serveurs Linux, y compris le NAT, la limitation de debit, les ensembles, la journalisation et la migration depuis iptables.

Prerequis

Avant de commencer, assurez-vous de disposer de :

  • Ubuntu Server 20.04, 22.04 ou 24.04 (ou toute distribution Linux avec un noyau 3.13 ou ulterieur)
  • Un acces terminal avec des privileges sudo
  • Un acces SSH au serveur (en cas de configuration a distance)
  • Une comprehension de base des ports TCP/UDP, de l’adressage IP et des concepts reseau
  • Une familiarite avec les concepts d’iptables (utile mais non obligatoire)

Qu’est-ce que nftables ?

nftables est un sous-systeme du noyau Linux qui fournit le filtrage de paquets, la traduction d’adresses reseau (NAT), la manipulation de paquets et la classification de trafic avec etat. Il remplace les outils historiques de Netfilter (iptables, ip6tables, arptables, ebtables) par un framework unique et unifie gere via l’utilitaire en ligne de commande nft.

Principaux avantages de nftables par rapport a iptables :

  • Outil unifie — une seule commande nft remplace iptables, ip6tables, arptables et ebtables
  • Syntaxe plus claire — format de regles plus lisible et coherent avec une grammaire appropriee
  • Meilleures performances — structures de donnees natives d’ensembles et de maps pour une correspondance efficace avec de grandes listes d’adresses IP, de ports ou d’interfaces
  • Remplacement atomique des regles — chargement atomique de jeux de regles complets, sans interruption lors des mises a jour
  • Pas de tables ni de chaines predefinies — vous ne creez que ce dont vous avez besoin, reduisant la surcharge
  • Prise en charge double pile integree — la famille inet gere a la fois IPv4 et IPv6 dans une seule table

nftables vs iptables

Comprendre les differences cles facilite la transition :

Fonctionnaliteiptablesnftables
Commandeiptables, ip6tables, arptables, ebtablesnft (outil unique)
Familles d’adressesOutil separe par familleFamille inet unifiee pour IPv4/IPv6
SyntaxeBasee sur des options (-A, -j, -p)Grammaire structuree (add rule ... accept)
EnsemblesNecessite l’extension ipsetEnsembles et maps natifs integres
Mises a jour des reglesInsertion/suppression lineaireRemplacement atomique via -f
Chaines predefiniesChaines obligatoires (INPUT, OUTPUT, FORWARD)Aucune par defaut ; vous creez tables et chaines selon vos besoins
PerformancesEvaluation lineaire des reglesRecherches optimisees dans les ensembles, expressions binaires
Interface noyauxtables (une par outil)nf_tables (API unifiee)

Installation de nftables sur Ubuntu

Sur Ubuntu 22.04 et versions ulterieures, nftables est disponible dans les depots par defaut. Installez-le :

sudo apt update
sudo apt install nftables

Activez et demarrez le service pour que les regles persistent entre les redemarrages :

sudo systemctl enable nftables
sudo systemctl start nftables

Verifiez l’installation :

nft --version

Sortie attendue :

nftables v1.0.6 (Lester Gooch #4)

Consultez le jeu de regles actuel :

sudo nft list ruleset

Si aucune regle n’a ete configuree, la sortie sera vide. C’est normal — contrairement a iptables, nftables demarre sans aucune table ni chaine.

Concepts Fondamentaux

nftables organise le filtrage de paquets selon une hierarchie de tables, chaines et regles. La comprehension de cette hierarchie est essentielle.

Familles d’Adresses

Chaque table appartient a une famille d’adresses qui determine le trafic qu’elle traite :

FamilleDescription
ipTrafic IPv4 uniquement
ip6Trafic IPv6 uniquement
inetIPv4 et IPv6 (recommande)
arpProtocole ARP
bridgeTrafic au niveau du pont
netdevTrafic entrant sur une interface specifique

Pour la plupart des configurations serveur, utilisez la famille inet pour gerer a la fois IPv4 et IPv6 avec un seul jeu de regles.

Tables

Les tables sont des conteneurs pour les chaines et les ensembles. Elles ont un nom et appartiennent a une famille d’adresses. Contrairement a iptables, il n’y a pas de tables predefinies — vous les creez selon vos besoins :

sudo nft add table inet filter
sudo nft add table inet nat

Chaines

Les chaines contiennent des regles et definissent le moment ou ces regles sont evaluees. Il existe deux types :

  • Chaines de base — rattachees a un hook Netfilter (input, output, forward, prerouting, postrouting). Ce sont les points d’entree du traitement des paquets.
  • Chaines regulieres — non rattachees a un hook ; utilisees comme cibles de saut pour organiser les regles.

Les chaines de base necessitent un type, un hook et une priorite :

sudo nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; }

Regles

Les regles sont les instructions de correspondance et d’action au sein d’une chaine. Elles se composent d’expressions (criteres de correspondance) et d’un verdict (accept, drop, reject, etc.) :

sudo nft add rule inet filter input tcp dport 22 accept

Creation de Tables et de Chaines

Construisons une configuration de pare-feu complete etape par etape. Commencez par creer la table :

sudo nft add table inet filter

Creez les chaines de base avec les politiques par defaut :

# Chaine d'entree : rejeter tout le trafic entrant par defaut
sudo nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; }

# Chaine de transfert : rejeter le trafic transfere par defaut
sudo nft add chain inet filter forward { type filter hook forward priority 0 \; policy drop \; }

# Chaine de sortie : autoriser tout le trafic sortant par defaut
sudo nft add chain inet filter output { type filter hook output priority 0 \; policy accept \; }

Listez vos tables et chaines pour confirmer :

sudo nft list tables
sudo nft list chains

Ecriture des Regles

Accepter les Connexions Etablies et Associees

Les premieres regles de votre chaine d’entree doivent accepter le trafic appartenant a des connexions etablies ou associees. Cela garantit que le trafic de retour de vos connexions sortantes n’est pas bloque :

sudo nft add rule inet filter input ct state established,related accept

Autoriser le Trafic Loopback

Les services locaux communiquent via l’interface loopback. Autorisez-la toujours :

sudo nft add rule inet filter input iif lo accept

Rejeter les Connexions Invalides

Eliminez les paquets qui ne font partie d’aucune connexion connue :

sudo nft add rule inet filter input ct state invalid drop

Autoriser ICMP

Autorisez le ping et les autres messages ICMP pour le diagnostic :

sudo nft add rule inet filter input ip protocol icmp accept
sudo nft add rule inet filter input ip6 nexthdr icmpv6 accept

Autoriser des Services Specifiques

Acceptez le trafic sur des ports specifiques :

# Autoriser SSH
sudo nft add rule inet filter input tcp dport 22 accept

# Autoriser HTTP et HTTPS
sudo nft add rule inet filter input tcp dport { 80, 443 } accept

# Autoriser un port d'application personnalise
sudo nft add rule inet filter input tcp dport 8080 accept

# Autoriser un port UDP (ex. WireGuard)
sudo nft add rule inet filter input udp dport 51820 accept

Restreindre par Adresse Source

Autoriser SSH uniquement depuis un sous-reseau de confiance :

sudo nft add rule inet filter input ip saddr 192.168.1.0/24 tcp dport 22 accept

Rejeter au Lieu de Supprimer

Supprimer (drop) n’envoie aucune reponse ; rejeter (reject) renvoie une erreur ICMP. Ajoutez un rejet comme derniere regle pour un comportement reseau plus propre :

sudo nft add rule inet filter input reject with icmpx type port-unreachable

Afficher le Jeu de Regles Complet

sudo nft list ruleset

Exemple de sortie :

table inet filter {
    chain input {
        type filter hook input priority 0; policy drop;
        ct state established,related accept
        iif "lo" accept
        ct state invalid drop
        ip protocol icmp accept
        ip6 nexthdr ipv6-icmp accept
        tcp dport 22 accept
        tcp dport { 80, 443 } accept
        reject with icmpx type port-unreachable
    }

    chain forward {
        type filter hook forward priority 0; policy drop;
    }

    chain output {
        type filter hook output priority 0; policy accept;
    }
}

Configuration du NAT

nftables gere le NAT via une table dediee avec des chaines de prerouting et de postrouting.

Creer la Table NAT et les Chaines

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 \; }

NAT Source (Masquerade)

Masquer le trafic sortant d’un reseau interne via l’interface publique du serveur. C’est courant pour les routeurs et les passerelles VPN :

sudo nft add rule inet nat postrouting oif "eth0" masquerade

Pour un sous-reseau source specifique :

sudo nft add rule inet nat postrouting ip saddr 10.0.0.0/24 oif "eth0" masquerade

SNAT Statique

Si votre serveur dispose d’une adresse IP publique statique et que vous souhaitez definir explicitement l’adresse source :

sudo nft add rule inet nat postrouting ip saddr 10.0.0.0/24 oif "eth0" snat to 203.0.113.1

NAT de Destination (Redirection de Ports)

Rediriger le trafic entrant sur un port vers un hote interne :

# Rediriger le port 8080 vers le serveur interne 10.0.0.50:80
sudo nft add rule inet nat prerouting iif "eth0" tcp dport 8080 dnat to 10.0.0.50:80

N’oubliez pas d’autoriser le trafic redirige dans votre table de filtrage :

sudo nft add rule inet filter forward ip daddr 10.0.0.50 tcp dport 80 accept
sudo nft add rule inet filter forward ct state established,related accept

Activer le Transfert IP

Le NAT necessite que le transfert IP soit active dans le noyau :

sudo sysctl -w net.ipv4.ip_forward=1

Rendez-le persistant :

echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.d/99-nftables.conf
sudo sysctl -p /etc/sysctl.d/99-nftables.conf

Limitation de Debit et Suivi de Connexions

Limiter les Connexions Entrantes

Protegez-vous contre les attaques par force brute en limitant le debit de connexion. Par exemple, limiter SSH a 5 nouvelles connexions par minute et par adresse IP source :

sudo nft add rule inet filter input tcp dport 22 ct state new limit rate 5/minute accept

Pour une tolerance de rafale (autoriser de courtes rafales au-dessus du debit) :

sudo nft add rule inet filter input tcp dport 22 ct state new limit rate 5/minute burst 10 packets accept

Limitation par Source avec les Meters

Les meters (anciennement appeles ensembles dynamiques) permettent une limitation de debit par adresse IP source :

sudo nft add rule inet filter input tcp dport 22 ct state new meter ssh-rate { ip saddr limit rate 3/minute burst 5 packets } accept

Cela limite chaque adresse IP source individuelle a 3 nouvelles connexions SSH par minute, avec une rafale de 5 paquets.

Etats du Suivi de Connexions

nftables utilise le sous-systeme conntrack pour le filtrage avec etat. Etats disponibles :

EtatDescription
newPremier paquet d’une nouvelle connexion
establishedFait partie d’une connexion deja etablie
relatedAssocie a une connexion etablie (ex. canal de donnees FTP)
invalidNon associe a aucune connexion connue
untrackedExplicitement contourne par conntrack

Limiter les Inondations 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 ip protocol icmp drop

Ensembles et Maps

Les ensembles et les maps sont l’une des fonctionnalites les plus puissantes de nftables, permettant des correspondances efficaces avec de grands groupes de valeurs sans ecrire de regles individuelles.

Ensembles Anonymes

Les ensembles anonymes sont definis en ligne au sein d’une regle :

sudo nft add rule inet filter input tcp dport { 22, 80, 443, 8080 } accept

Ensembles Nommes

Les ensembles nommes sont definis separement et peuvent etre mis a jour dynamiquement sans modifier les regles qui les referencent :

# Creer un ensemble nomme pour les ports TCP autorises
sudo nft add set inet filter allowed_ports { type inet_service \; }

# Ajouter des elements a l'ensemble
sudo nft add element inet filter allowed_ports { 22, 80, 443, 8080 }

# Utiliser l'ensemble dans une regle
sudo nft add rule inet filter input tcp dport @allowed_ports accept

Mettez a jour l’ensemble sans modifier la regle :

# Ajouter un nouveau port
sudo nft add element inet filter allowed_ports { 3000 }

# Supprimer un port
sudo nft delete element inet filter allowed_ports { 8080 }

Ensembles d’Adresses IP

# Creer un ensemble pour les IP bloquees
sudo nft add set inet filter blocked_ips { type ipv4_addr \; }

# Peupler l'ensemble
sudo nft add element inet filter blocked_ips { 203.0.113.100, 198.51.100.50, 192.0.2.75 }

# Rejeter le trafic provenant des IP bloquees
sudo nft add rule inet filter input ip saddr @blocked_ips drop

Ensembles avec Expiration Automatique

Creez des ensembles dont les entrees expirent automatiquement :

sudo nft add set inet filter temp_block { type ipv4_addr \; timeout 1h \; }
sudo nft add element inet filter temp_block { 203.0.113.100 timeout 30m }
sudo nft add rule inet filter input ip saddr @temp_block drop

Maps pour les Recherches de Verdict

Les maps associent une cle a un verdict, permettant des decisions efficaces par valeur :

# Creer une map de verdict basee sur les ports
sudo nft add map inet filter port_policy { type inet_service : verdict \; }
sudo nft add element inet filter port_policy { 22 : accept, 80 : accept, 443 : accept, 23 : drop }

# Utiliser la map dans une regle
sudo nft add rule inet filter input tcp dport vmap @port_policy

Ensembles Concatenes

Correspondance sur plusieurs champs simultanement :

# Creer un ensemble correspondant a des combinaisons IP + port
sudo nft add set inet filter allowed_access { type ipv4_addr . inet_service \; }
sudo nft add element inet filter allowed_access { 10.0.1.20 . 3306, 10.0.1.21 . 5432 }
sudo nft add rule inet filter input ip saddr . tcp dport @allowed_access accept

Journalisation des Regles

nftables fournit une journalisation flexible pour la surveillance et le debogage des regles de pare-feu.

Journalisation de Base

Journaliser les paquets avant de les rejeter :

sudo nft add rule inet filter input tcp dport 23 log prefix \"Telnet attempt: \" drop

Journalisation avec Limitation de Debit

Evitez la saturation des journaux en limitant le debit de journalisation :

sudo nft add rule inet filter input ct state invalid log prefix \"Invalid packet: \" limit rate 5/minute drop

Niveaux de Journalisation

nftables prend en charge les niveaux syslog standards :

sudo nft add rule inet filter input tcp dport 22 ct state new log prefix \"SSH connection: \" level info accept

Niveaux disponibles : emerg, alert, crit, err, warn, notice, info, debug.

Consultation des Journaux

Les journaux nftables sont ecrits dans le journal du noyau. Consultez-les avec :

sudo dmesg | grep "nft"
sudo journalctl -k --grep="Telnet attempt"

Pour une journalisation persistante, configurez rsyslog pour ecrire les messages nftables dans un fichier dedie :

# /etc/rsyslog.d/10-nftables.conf
:msg, contains, "nft" /var/log/nftables.log

Redemarrez rsyslog :

sudo systemctl restart rsyslog

Migration depuis iptables

Si vous avez des regles iptables existantes, nftables fournit des outils pour faciliter la migration.

Utilisation d’iptables-translate

La commande iptables-translate convertit des regles iptables individuelles en syntaxe nft :

iptables-translate -A INPUT -p tcp --dport 22 -j ACCEPT

Sortie :

nft add rule ip filter INPUT tcp dport 22 counter accept

Traduction d’un Jeu de Regles Complet

Exportez l’integralite de votre configuration iptables et traduisez-la :

iptables-save > /tmp/iptables-rules.txt
iptables-restore-translate -f /tmp/iptables-rules.txt > /tmp/nftables-rules.nft

Examinez le fichier traduit puis chargez-le :

sudo nft -f /tmp/nftables-rules.nft

Verification de la Couche de Compatibilite

Ubuntu moderne utilise iptables-nft comme backend par defaut. Verifiez quel backend utilise votre systeme :

update-alternatives --query iptables

Ou :

iptables --version

Si vous voyez nf_tables dans la sortie, vos commandes iptables sont deja traduites en nftables en interne.

Bonnes Pratiques de Migration

  1. Exporter les regles existantes — sauvegardez vos regles iptables actuelles avant de commencer
  2. Traduire et verifier — utilisez iptables-restore-translate et examinez attentivement la sortie
  3. Tester en environnement non productif — appliquez les regles traduites sur un serveur de test d’abord
  4. Purger les anciennes regles — une fois les regles nft confirmees, purgez iptables avec iptables -F
  5. Desactiver le service iptables — arretez et desactivez le service iptables pour eviter les conflits
  6. Activer le service nftables — assurez-vous que le service nftables est active pour la persistance

Chargement de Jeux de Regles depuis des Fichiers

Pour les environnements de production, gerer votre jeu de regles dans un fichier est l’approche recommandee. Voici un exemple de configuration complet :

#!/usr/sbin/nft -f

# Purger les regles existantes
flush ruleset

# Definir les variables
define WAN_IF = eth0
define LAN_IF = eth1
define LAN_NET = 10.0.0.0/24
define ALLOWED_TCP = { 22, 80, 443 }

table inet filter {
    set blocked_ips {
        type ipv4_addr
        elements = { 203.0.113.100, 198.51.100.50 }
    }

    chain input {
        type filter hook input priority 0; policy drop;

        # Suivi de connexions
        ct state established,related accept
        ct state invalid drop

        # Loopback
        iif lo accept

        # Rejeter les IP bloquees
        ip saddr @blocked_ips drop

        # ICMP
        ip protocol icmp limit rate 10/second accept
        ip6 nexthdr ipv6-icmp limit rate 10/second accept

        # Services autorises avec limitation de debit sur SSH
        tcp dport 22 ct state new limit rate 5/minute burst 10 packets accept
        tcp dport { 80, 443 } accept

        # Rejet final
        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;
    }
}

Sauvegardez-le dans /etc/nftables.conf et chargez-le :

sudo nft -f /etc/nftables.conf

Verifiez :

sudo nft list ruleset

Reference des Commandes nft

CommandeDescription
nft list rulesetAfficher le jeu de regles complet
nft list tablesLister toutes les tables
nft list table inet filterAfficher les regles d’une table specifique
nft list chainsLister toutes les chaines
nft list chain inet filter inputAfficher les regles d’une chaine specifique
nft list setsLister tous les ensembles nommes
nft add table inet <nom>Creer une nouvelle table
nft delete table inet <nom>Supprimer une table et tout son contenu
nft flush table inet <nom>Supprimer toutes les regles d’une table
nft add chain inet <table> <chaine> { type filter hook input priority 0 \; }Creer une chaine de base
nft add rule inet <table> <chaine> <expression> <verdict>Ajouter une regle a la fin d’une chaine
nft insert rule inet <table> <chaine> <expression> <verdict>Inserer une regle au debut d’une chaine
nft delete rule inet <table> <chaine> handle <n>Supprimer une regle par son numero de handle
nft add set inet <table> <nom> { type <type> \; }Creer un ensemble nomme
nft add element inet <table> <nom> { <elements> }Ajouter des elements a un ensemble
nft flush rulesetSupprimer toutes les tables, chaines et regles
nft -f <fichier>Charger un jeu de regles depuis un fichier
nft monitorSurveiller les changements du jeu de regles en temps reel

Depannage

Les Regles ne Prennent pas Effet

Verifiez que le jeu de regles est charge :

sudo nft list ruleset

Verifiez que vos chaines sont rattachees aux bons hooks et ont la priorite attendue :

sudo nft list chains

Assurez-vous qu’il n’y a pas de regles iptables en conflit :

sudo iptables -L -n

Perte d’Acces SSH

Si vous perdez l’acces SSH apres avoir applique des regles :

  1. Accedez au serveur via une console (console web du fournisseur cloud, KVM ou acces physique)
  2. Purgez toutes les regles : sudo nft flush ruleset
  3. Verifiez que l’acces est retabli
  4. Reconstruisez vos regles en vous assurant que SSH est autorise avant de definir une politique de rejet

Debogage de la Correspondance des Regles

Ajoutez des compteurs aux regles pour voir lesquelles correspondent au trafic :

sudo nft add rule inet filter input tcp dport 22 counter accept

Consulter les compteurs :

sudo nft list chain inet filter input

La sortie du compteur affiche les paquets et octets correspondants :

tcp dport 22 counter packets 150 bytes 12000 accept

Les Regles ne Persistent pas apres le Redemarrage

Assurez-vous que le service nftables est active :

sudo systemctl enable nftables

Sauvegardez le jeu de regles actuel :

sudo nft list ruleset | sudo tee /etc/nftables.conf

Verifiez que le fichier de configuration est syntaxiquement valide :

sudo nft -c -f /etc/nftables.conf

Problemes de Modules du Noyau

Si les commandes nft echouent, verifiez que les modules du noyau requis sont charges :

lsmod | grep nf_tables

Chargez-les manuellement si necessaire :

sudo modprobe nf_tables
sudo modprobe nft_chain_nat

Resume

nftables est le remplacement definitif d’iptables sur les systemes Linux modernes. Son interface de commande unifiee, sa prise en charge native des ensembles et des maps, son remplacement atomique des regles et sa syntaxe plus claire en font une amelioration significative par rapport aux outils historiques. Que vous configuriez un simple pare-feu d’hote ou une passerelle NAT complexe avec limitation de debit et ensembles dynamiques, nftables fournit les outils pour construire des configurations de pare-feu efficaces et maintenables.

Points cles a retenir :

  • Utilisez la famille inet pour gerer a la fois IPv4 et IPv6 dans une seule table
  • Autorisez toujours les connexions etablies/associees et le trafic loopback en premier
  • Exploitez les ensembles nommes pour gerer des listes dynamiques d’adresses IP et de ports sans reecrire les regles
  • Utilisez la limitation de debit sur les services d’authentification comme SSH pour attenuer les attaques par force brute
  • Gerez votre jeu de regles dans un fichier et chargez-le de maniere atomique avec nft -f
  • Activez le service systemd nftables pour la persistance entre les redemarrages
  • Utilisez iptables-translate et iptables-restore-translate pour migrer les jeux de regles existants

Pour une experience de gestion de pare-feu de plus haut niveau sur Ubuntu, consultez notre guide sur la Configuration du Pare-feu UFW sur Ubuntu Server. Pour completer votre pare-feu avec un acces distant securise, consultez Renforcement SSH pour les Serveurs Linux.