Netfilter est l’un des composants fondamentaux de la pile réseau Linux. Il permet au noyau d’examiner les paquets à différents endroits de leur parcours et fournit l’infrastructure nécessaire au filtrage, au NAT, au suivi de connexions, à la journalisation et à plusieurs autres traitements réseau.
Il constitue ainsi le moteur situé derrière une grande partie des fonctions de pare-feu Linux.
Netfilter travaille dans le noyau. nftables permet à l’administrateur de lui expliquer quels paquets doivent passer, être transformés, enregistrés ou disparaître dans un silence administratif total.
Netfilter, nftables et iptables : qui fait quoi ?
Ces trois termes sont souvent mélangés alors qu’ils désignent des couches différentes.
| Composant | Rôle |
|---|---|
| Netfilter | Infrastructure et sous-systèmes de filtrage réseau dans le noyau Linux |
| nf_tables | Sous-système moderne du noyau utilisé par nftables |
| nft | Commande permettant de configurer nftables depuis l’espace utilisateur |
| iptables | Interface historique de configuration du filtrage IPv4 |
| ip6tables | Équivalent historique pour IPv6 |
On peut donc simplifier ainsi :
Administrateur
│
▼
nft
│
▼
nf_tables
│
▼
Netfilter
│
▼
pile réseau du noyau Linux
iptables n’a pas totalement disparu
De très nombreux scripts, documentations et appliances utilisent encore :
iptables
ip6tables
Ces outils restent donc importants à connaître.
Mais sur de nombreuses distributions modernes, ils peuvent fonctionner via une couche de compatibilité utilisant :
nf_tables
On rencontre alors notamment :
iptables-nft
À côté existe parfois le backend historique :
iptables-legacy
Pour une nouvelle configuration administrée directement, nftables est généralement le choix à privilégier.
Pourquoi nftables a remplacé le modèle iptables ?
iptables fonctionnait avec plusieurs outils et familles séparées :
iptables
ip6tables
arptables
ebtables
nftables fournit un langage plus homogène pouvant notamment gérer :
- IPv4 ;
- IPv6 ;
- ARP ;
- bridges Ethernet ;
- filtrage à l’entrée et à la sortie des interfaces ;
- NAT ;
- sets et maps ;
- compteurs ;
- limitation de débit ;
- conntrack.
Il permet également de charger un ensemble de règles dans une transaction plutôt que d’empiler laborieusement des centaines de commandes indépendantes.
Le trajet d’un paquet dans Netfilter
Netfilter dispose de plusieurs points d’accroche appelés :
hooks
Pour IPv4 et IPv6, les principaux sont :
| Hook | Rôle |
|---|---|
prerouting |
Paquet reçu, avant la décision de routage |
input |
Paquet destiné à la machine locale |
forward |
Paquet routé à travers la machine |
output |
Paquet produit par un processus local |
postrouting |
Paquet sur le point de quitter la machine après routage |
Paquet destiné au serveur local
Le parcours simplifié ressemble à :
Interface réseau
│
▼
PREROUTING
│
▼
Décision de routage
│
▼
INPUT
│
▼
Processus local
Par exemple, une connexion SSH vers le serveur lui-même traversera la chaîne associée au hook :
input
Paquet traversant un routeur Linux
Interface LAN
│
▼
PREROUTING
│
▼
Décision de routage
│
▼
FORWARD
│
▼
POSTROUTING
│
▼
Interface WAN
La chaîne :
forward
n’est donc pas utilisée pour protéger directement les services locaux.
Elle concerne essentiellement les paquets dont Linux assure le routage.
Paquet généré localement
Processus local
│
▼
OUTPUT
│
▼
Décision / traitement
│
▼
POSTROUTING
│
▼
Interface réseau
Les familles nftables
Une table nftables appartient à une famille déterminant le type de paquets qu’elle traite.
| Famille | Utilisation |
|---|---|
ip |
IPv4 |
ip6 |
IPv6 |
inet |
IPv4 et IPv6 |
arp |
ARP |
bridge |
Trafic traversant un bridge Linux |
netdev |
Traitement directement associé aux interfaces réseau |
La famille inet : très pratique pour un pare-feu
Avec iptables, on devait historiquement maintenir :
iptables
+
ip6tables
Avec nftables, une table :
table inet firewall
peut contenir des règles communes à IPv4 et IPv6.
Cela réduit considérablement le risque de construire :
un excellent firewall IPv4
+
un IPv6 entièrement ouvert
parce que personne n'y avait pensé
Tables et chaînes avec nftables
Contrairement au modèle iptables historique, les noms de tables nftables ne sont pas prédéfinis.
On peut créer :
table inet firewall
ou :
table inet chapal_filter
Le nom est libre.
Une table contient ensuite :
- des chaînes ;
- des règles ;
- des sets ;
- des maps ;
- des compteurs et autres objets.
Une chaîne normale et une chaîne de base
Une chaîne ordinaire sert à organiser les règles.
Une base chain, elle, est attachée à un hook Netfilter.
Par exemple :
chain input {
type filter hook input priority filter;
policy drop;
}
Cette chaîne :
- est de type
filter; - est reliée au hook
input; - utilise la priorité de filtrage ;
- applique une politique par défaut
drop.
Les anciennes tables iptables
Dans le modèle iptables historique, on rencontrait notamment :
filter
Utilisée pour le filtrage classique :
ACCEPT
DROP
REJECT
nat
Utilisée pour :
- SNAT ;
- DNAT ;
- masquerading ;
- redirections.
mangle
Utilisée pour modifier certaines métadonnées ou certains champs des paquets.
raw
Utilisée notamment pour certains traitements très précoces et pour exclure certains paquets du suivi de connexions.
Avec nftables, ces noms ne décrivent plus une architecture obligatoire.
Les tables nftables sont des conteneurs. Ce sont surtout les familles, chaînes, hooks, types et priorités qui déterminent où et comment les règles sont exécutées.
Afficher le ruleset actuel
La commande fondamentale est :
sudo nft list ruleset
Elle affiche l’ensemble des :
- tables ;
- chains ;
- sets ;
- maps ;
- règles.
Pour obtenir les handles des règles :
sudo nft -a list ruleset
Les handles permettent notamment de supprimer précisément une règle.
Attention à nft flush ruleset
Cette commande :
sudo nft flush ruleset
supprime le ruleset actuellement chargé.
Une fois le ruleset vide, il n’existe plus de filtrage nftables correspondant.
Sur un serveur administré exclusivement en SSH, taper cette commande puis improviser la suite est une excellente manière de transformer une session distante en événement mémorable.
Construire un pare-feu stateful
Un pare-feu moderne ne regarde pas seulement :
adresse source
adresse destination
port
Il peut également suivre l’état logique des communications grâce à :
conntrack
Les principaux états conntrack
| État | Signification simplifiée |
|---|---|
new |
Nouvelle communication ou trafic n’ayant pas encore été vu dans les deux directions |
established |
Communication déjà observée dans les deux directions |
related |
Nouvelle communication liée à une connexion existante |
invalid |
Paquet ne pouvant pas être associé correctement à une connexion |
untracked |
Paquet volontairement exclu du suivi |
La règle fondamentale
ct state established,related accept
Elle signifie :
« Si cette communication a déjà été autorisée ou lui est légitimement associée, laissez passer les paquets suivants. »
C’est ce qui permet par exemple à une machine ayant initié une connexion HTTPS de recevoir les réponses sans écrire une règle séparée pour chaque port source éphémère.
Exemple de pare-feu nftables pour un serveur
Voici une base simple :
#!/usr/sbin/nft -f
flush ruleset
table inet firewall {
chain input {
type filter hook input priority filter;
policy drop;
iifname "lo" accept
ct state invalid drop
ct state established,related accept
meta l4proto { icmp, ipv6-icmp } accept
tcp dport 22 accept
}
chain forward {
type filter hook forward priority filter;
policy drop;
}
chain output {
type filter hook output priority filter;
policy accept;
}
}
Que fait ce ruleset ?
La politique d’entrée est :
drop
Donc tout ce qui n’est pas explicitement autorisé est bloqué.
Les exceptions sont :
- le loopback ;
- les connexions déjà établies ou liées ;
- ICMP et ICMPv6 ;
- SSH sur TCP/22.
Le trafic transféré est refusé par défaut et le trafic sortant est autorisé.
Pourquoi autoriser loopback ?
L’interface :
lo
est utilisée pour les communications locales :
127.0.0.1
::1
De nombreux programmes dépendent de ces communications internes.
La règle classique est :
iifname "lo" accept
Faut-il bloquer le ping ?
Pas systématiquement.
La règle historique :
iptables -A INPUT -p icmp -j DROP
est souvent présentée comme un durcissement.
En réalité, ICMP ne sert pas uniquement à :
ping
Il participe notamment :
- au diagnostic ;
- aux notifications d’erreur ;
- à Path MTU Discovery ;
- au fonctionnement normal d’IP.
Avec IPv6, ICMPv6 est encore plus important puisqu’il participe notamment à :
- Neighbor Discovery ;
- Router Discovery ;
- Path MTU Discovery ;
- différents mécanismes fondamentaux d’IPv6.
Bloquer ICMPv6 au hasard n’endurcit pas nécessairement IPv6. Cela peut surtout le casser de manière suffisamment subtile pour rendre le diagnostic désagréable.
Limiter uniquement certains pings
Pour limiter les requêtes ICMP IPv4 sans supprimer tout le protocole :
icmp type echo-request limit rate 5/second accept
Le filtrage ICMP complet doit cependant être conçu en tenant compte des messages nécessaires au fonctionnement du protocole.
Autoriser plusieurs ports simplement
nftables sait manipuler directement des ensembles.
Au lieu de trois règles :
tcp dport 22 accept
tcp dport 80 accept
tcp dport 443 accept
on peut écrire :
tcp dport { 22, 80, 443 } accept
Restreindre SSH à un réseau d’administration
Par exemple :
ip saddr 192.0.2.0/24 tcp dport 22 accept
Cette règle autorise SSH uniquement depuis le réseau IPv4 indiqué.
En production, cette approche peut être beaucoup plus pertinente que :
TCP/22 ouvert au monde entier
si l’architecture permet une administration depuis un réseau dédié ou un VPN.
ACCEPT, DROP et REJECT
accept
accept
Le paquet est accepté par cette chaîne.
drop
drop
Le paquet est abandonné silencieusement.
L’émetteur devra généralement attendre son timeout ou déterminer autrement que la communication n’aboutit pas.
reject
reject
Le trafic est refusé mais une réponse appropriée peut être envoyée à l’émetteur.
DROP n’est pas toujours plus sécurisé que REJECT
On entend parfois :
DROP
=
invisible
=
sécurisé
C’est trop simpliste.
Le choix dépend du contexte.
REJECT peut être préférable pour certains services internes parce qu’il permet au client de comprendre immédiatement que l’accès est interdit au lieu d’attendre un timeout.
Journaliser les paquets
Une règle nftables peut journaliser un paquet :
log prefix "nft-input: "
Elle peut également combiner journalisation et décision :
log prefix "nft-drop: " counter drop
Ne loguez pas absolument tout
Sur une interface exposée à Internet :
log every dropped packet
peut produire énormément d’événements.
Une limitation est souvent préférable :
limit rate 5/second log prefix "nft-drop: " counter drop
Sinon, le firewall peut parfaitement repousser l’attaque tout en remplissant votre stockage de journaux jusqu’à ce qu’un autre problème prenne le relais.
Les compteurs
Le mot-clé :
counter
maintient un compteur :
- de paquets ;
- d’octets.
Exemple :
tcp dport 22 counter accept
Puis :
sudo nft list ruleset
permet d’observer combien de paquets ont utilisé la règle.
C’est extrêmement utile pour différencier :
la règle ne fonctionne pas
de :
aucun paquet n'arrive jamais jusqu'à elle
Le NAT
Network Address Translation modifie certaines informations d’adressage d’une connexion.
Les formes courantes sont :
- SNAT ;
- DNAT ;
- masquerade ;
- redirect.
SNAT
Le :
Source NAT
modifie l’adresse source.
Il est typiquement utilisé lorsqu’un réseau privé sort vers Internet à travers une adresse publique.
DNAT
Le :
Destination NAT
modifie l’adresse ou le port de destination.
C’est notamment ce qui permet une redirection :
IP publique:2222
↓
192.168.50.10:22
Masquerade
masquerade est une forme de SNAT particulièrement pratique lorsque l’adresse de sortie peut varier.
On l’utilise fréquemment sur :
- routeurs domestiques ;
- connexions DHCP ;
- interfaces dont l’adresse publique n’est pas fixe.
Exemple de NAT avec nftables
Supposons :
LAN :
192.168.50.0/24
interface LAN :
lan0
interface Internet :
wan0
Une table NAT IPv4 pourrait contenir :
table ip nat {
chain prerouting {
type nat hook prerouting priority dstnat;
policy accept;
}
chain postrouting {
type nat hook postrouting priority srcnat;
policy accept;
ip saddr 192.168.50.0/24 oifname "wan0" masquerade
}
}
Le NAT ne suffit pas pour transformer Linux en routeur
Pour router des paquets IPv4, le noyau doit également autoriser le forwarding :
sudo sysctl -w net.ipv4.ip_forward=1
Le paramètre correspondant vaut par défaut :
0
désactivé
sur un hôte Linux conventionnel.
Rendre le forwarding persistant
Selon la distribution, on peut créer par exemple :
/etc/sysctl.d/99-router.conf
avec :
net.ipv4.ip_forward=1
puis charger la configuration selon les outils du système.
Le forwarding doit lui aussi être filtré
Activer :
ip_forward=1
n’implique pas que tout trafic entre toutes les interfaces doit être autorisé.
Une chaîne dédiée peut contrôler précisément les flux :
chain forward {
type filter hook forward priority filter;
policy drop;
ct state invalid drop
ct state established,related accept
iifname "lan0" oifname "wan0" accept
}
Cette configuration permet aux machines du LAN d’initier du trafic vers Internet et autorise les réponses grâce à conntrack.
Exemple de redirection de port
Pour rediriger :
WAN TCP/2222
↓
192.168.50.10 TCP/22
on peut ajouter :
chain prerouting {
type nat hook prerouting priority dstnat;
policy accept;
iifname "wan0" tcp dport 2222 dnat to 192.168.50.10:22
}
Et il faut autoriser le forwarding correspondant
Le NAT et le filtrage sont deux choses différentes.
Une redirection DNAT n’accorde pas automatiquement l’autorisation de traverser la chaîne forward.
On pourra par exemple autoriser explicitement :
iifname "wan0" oifname "lan0" \
ip daddr 192.168.50.10 tcp dport 22 \
ct state new accept
Les paquets suivants de la connexion seront ensuite couverts par :
ct state established,related accept
Changer le port SSH n’est pas une protection majeure
Rediriger :
2222
→
22
peut réduire une partie du bruit généré par les bots recherchant uniquement TCP/22.
Mais cela ne remplace pas :
- l’authentification par clés ;
- la désactivation des méthodes inutiles ;
- les restrictions d’origine ;
- les mises à jour ;
- la surveillance ;
- éventuellement un VPN d’administration.
Un scanner de ports n’est généralement pas paralysé psychologiquement par le fait que SSH se trouve sur 2222.
nftables et IPv6
Avec une table :
inet
on peut appliquer de nombreuses règles à IPv4 et IPv6 simultanément.
Par exemple :
tcp dport 22 accept
peut concerner les deux familles.
Si une règle ne doit concerner qu’IPv4 :
ip saddr 192.0.2.0/24 tcp dport 22 accept
Pour IPv6 :
ip6 saddr 2001:db8:1234::/48 tcp dport 22 accept
Ne copiez pas aveuglément une politique IPv4 vers IPv6
IPv6 possède notamment :
- ICMPv6 ;
- Neighbor Discovery ;
- Router Advertisement ;
- Router Solicitation ;
- Path MTU Discovery.
Le firewall doit donc être conçu avec une compréhension correcte du protocole plutôt qu’avec :
tout ce qui commence par ICMP
→ DROP
Les anciennes commandes iptables équivalentes
Pour comprendre les installations existantes, voici l’ancien style.
Politique restrictive
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
Loopback
iptables -A INPUT -i lo -j ACCEPT
Connexions établies
iptables -A INPUT \
-m conntrack --ctstate ESTABLISHED,RELATED \
-j ACCEPT
SSH
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
Masquerading
iptables -t nat -A POSTROUTING \
-o eth0 \
-j MASQUERADE
DNAT
iptables -t nat -A PREROUTING \
-i eth0 \
-p tcp \
--dport 2222 \
-j DNAT \
--to-destination 192.168.50.10:22
-m state ou -m conntrack ?
L’ancien exemple :
-m state --state ESTABLISHED,RELATED
reste connu et peut encore fonctionner.
Mais le module :
state
ne représente qu’un sous-ensemble des fonctions du module :
conntrack
La forme iptables plus explicite est donc :
-m conntrack --ctstate ESTABLISHED,RELATED
Et avec nftables :
ct state established,related accept
Persistance des règles avec nftables
Une règle ajoutée directement avec :
nft add rule ...
modifie le ruleset actuellement chargé dans le noyau.
Elle n’est pas nécessairement persistante après redémarrage.
Sur Debian
La configuration principale se trouve généralement dans :
/etc/nftables.conf
Le paquet peut être installé avec :
sudo apt install nftables
Puis le service activé :
sudo systemctl enable --now nftables
Vérifier la syntaxe avant de charger
Avant d’appliquer un fichier :
sudo nft -c -f /etc/nftables.conf
L’option :
-c
--check
vérifie la validité des commandes sans appliquer les modifications.
Si tout est correct :
sudo nft -f /etc/nftables.conf
Le chargement par fichier est transactionnel
L’un des avantages importants de nftables est la possibilité de préparer un ruleset complet puis de le charger avec :
nft -f fichier
Le changement peut ainsi être traité comme une transaction plutôt que comme une longue série de modifications successives laissant temporairement le firewall dans un état intermédiaire.
Attention malgré tout aux serveurs distants
Une configuration syntaxiquement correcte peut parfaitement contenir :
policy drop
+
aucune règle SSH
Le programme :
nft -c
vous dira alors que la syntaxe est valide.
Et il aura raison.
Votre session SSH mourra néanmoins avec une dignité irréprochable.
Pour une modification distante importante :
- conservez si possible un accès console ou hors bande ;
- vérifiez les règles SSH avant application ;
- préparez un mécanisme de retour arrière ;
- évitez les expériences créatives sur un système inaccessible physiquement.
Sets : éviter des dizaines de règles répétitives
nftables possède des ensembles natifs.
Par exemple :
set admin_ipv4 {
type ipv4_addr
elements = { 192.0.2.10, 192.0.2.20 }
}
On peut ensuite écrire :
ip saddr @admin_ipv4 tcp dport 22 accept
Les sets sont particulièrement pratiques pour gérer :
- des listes d’adresses ;
- des ports ;
- des réseaux ;
- des éléments dynamiques ;
- des listes très importantes.
Une règle peut combiner plusieurs conditions
Exemple :
iifname "lan0" \
ip saddr 192.168.50.0/24 \
tcp dport { 22, 80, 443 } \
ct state new \
counter accept
Le paquet doit ici correspondre à plusieurs critères :
- arriver par
lan0; - provenir du réseau indiqué ;
- viser l’un des ports autorisés ;
- appartenir à une nouvelle connexion.
L’ordre des règles compte
Les règles d’une chaîne sont évaluées dans leur ordre.
Par exemple :
tcp dport 22 drop
tcp dport 22 accept
La seconde règle n’aidera pas beaucoup les connexions déjà supprimées par la première.
Lorsqu’un verdict terminal comme :
accept
drop
reject
est atteint dans le contexte correspondant, l’évaluation suit les règles de traitement de Netfilter et des chaînes concernées.
Les policies
Une chaîne de base peut avoir une politique par défaut :
policy accept
ou :
policy drop
Pour un serveur exposé, une stratégie classique consiste à utiliser :
input → drop
forward → drop
output → accept
puis à ouvrir explicitement les services nécessaires.
Faut-il filtrer OUTPUT ?
Pas systématiquement.
Une politique restrictive en sortie peut être pertinente dans certains environnements :
- serveurs hautement cloisonnés ;
- appliances ;
- systèmes à exigences de sécurité strictes ;
- environnements où les destinations autorisées sont connues.
Mais cela exige de prendre en compte :
- DNS ;
- NTP ;
- mises à jour ;
- API ;
- supervision ;
- sauvegardes ;
- services distribués.
Une politique OUTPUT DROP mal conçue permet de découvrir très rapidement combien de services apparemment « locaux » dépendent en réalité du réseau.
Dépanner un firewall nftables
Commencez par afficher la configuration :
sudo nft -a list ruleset
Vérifiez ensuite :
- la bonne table ;
- la bonne famille ;
- le hook correct ;
- l’interface ;
- les adresses ;
- les ports ;
- les compteurs ;
- l’ordre des règles ;
- les états conntrack.
Observer conntrack
Avec les outils correspondants installés :
sudo conntrack -L
permet d’examiner la table de suivi des connexions.
On peut notamment y retrouver :
- protocole ;
- adresses ;
- ports ;
- états ;
- informations NAT.
Tracer les règles nftables
nftables dispose également d’un mécanisme de trace.
Une règle peut activer le tracing sur un trafic ciblé :
meta nftrace set 1
puis on peut observer les événements avec :
sudo nft monitor trace
Il est préférable de limiter soigneusement le trafic tracé, sans quoi un serveur actif peut produire suffisamment de détails pour transformer l’analyse en lecture intégrale du trafic mondial.
Firewall et routage sont différents
Netfilter ne remplace pas la table de routage.
Le noyau décide toujours comment atteindre une destination à partir de ses routes.
Commandes utiles :
ip addr
ip route
ip rule
Le firewall décide ensuite notamment si certains paquets sont :
acceptés
bloqués
transformés
Un paquet peut donc échouer parce que :
aucune route n'existe
même si le firewall l’aurait volontiers accepté.
Firewall et ports ouverts sont différents
Autoriser :
tcp dport 443 accept
ne crée pas un serveur HTTPS.
Il faut également qu’un programme écoute réellement sur ce port.
Vérification :
ss -lntp
Inversement, un service peut parfaitement écouter sur :
0.0.0.0:443
tout en restant inaccessible depuis le réseau parce que nftables le bloque.
Firewall et sécurité applicative sont différents
Autoriser TCP/443 signifie essentiellement :
le trafic HTTPS peut atteindre le serveur
Cela ne garantit absolument pas que :
- le serveur Web est à jour ;
- l’application est sécurisée ;
- les mots de passe sont corrects ;
- les permissions sont appropriées ;
- aucune vulnérabilité n’existe.
Un firewall décide qui peut frapper à la porte. Il ne vérifie pas que la personne qui ouvre derrière connaît son métier.
Erreurs classiques
Confondre Netfilter et iptables
Netfilter est l’infrastructure du noyau.
iptables n’est qu’une manière historique de la configurer.
Copier des règles iptables de 2012 dans un nouveau serveur
Elles peuvent parfois fonctionner, mais nftables offre aujourd’hui une architecture plus cohérente pour une nouvelle configuration.
Bloquer tout ICMP
Vous risquez de supprimer :
- des informations d’erreur importantes ;
- des mécanismes de MTU ;
- des fonctions essentielles d’IPv6.
Oublier IPv6
Protéger uniquement :
IPv4
sur une machine disposant également d’une adresse IPv6 publique laisse potentiellement un autre chemin d’accès.
Oublier ESTABLISHED,RELATED
Un firewall stateful devient rapidement beaucoup plus compliqué sans cette règle.
Confondre INPUT et FORWARD
INPUT
→ destiné au firewall lui-même
FORWARD
→ traverse le firewall
Faire du DNAT sans autoriser FORWARD
Le paquet est correctement redirigé puis correctement bloqué.
Deux mécanismes fonctionnent donc parfaitement et le résultat final ne fonctionne absolument pas.
Faire du masquerade sans activer le forwarding
Même problème :
NAT correct
+
routeur qui refuse de router
=
connexion inexistante
Modifier un firewall SSH sans plan de retour
Cette erreur possède généralement une durée pédagogique directement proportionnelle à la distance séparant l’administrateur du serveur.
Journaliser chaque paquet
Le log doit être suffisamment détaillé pour diagnostiquer sans devenir lui-même une forme de déni de service contre votre stockage.
Checklist d’un pare-feu hôte simple
- utiliser nftables pour une nouvelle configuration ;
- préférer une table
inetlorsque les règles doivent couvrir IPv4 et IPv6 ; - autoriser loopback ;
- rejeter les états invalides lorsque pertinent ;
- autoriser
established,related; - ouvrir uniquement les services nécessaires ;
- traiter correctement ICMP et ICMPv6 ;
- utiliser une policy restrictive pour les entrées non souhaitées ;
- journaliser avec mesure ;
- vérifier les compteurs ;
- rendre la configuration persistante ;
- tester avant de modifier un serveur distant.
Checklist d’un routeur Linux
- activer le forwarding IP nécessaire ;
- définir les routes ;
- filtrer la chaîne
forward; - autoriser les connexions établies et liées ;
- autoriser explicitement LAN vers WAN selon la politique ;
- ajouter SNAT ou masquerade pour IPv4 si l’architecture l’exige ;
- ajouter DNAT uniquement pour les services publiés ;
- ouvrir les flux correspondants dans
forward; - tester IPv4 et IPv6 séparément ;
- vérifier le ruleset après chaque modification importante.
Exemple complet pour un petit routeur IPv4
Hypothèses :
LAN :
192.168.50.0/24
interface interne :
lan0
interface Internet :
wan0
Ruleset simplifié :
#!/usr/sbin/nft -f
flush ruleset
table inet firewall {
chain input {
type filter hook input priority filter;
policy drop;
iifname "lo" accept
ct state invalid drop
ct state established,related accept
meta l4proto { icmp, ipv6-icmp } accept
iifname "lan0" tcp dport 22 accept
}
chain forward {
type filter hook forward priority filter;
policy drop;
ct state invalid drop
ct state established,related accept
iifname "lan0" oifname "wan0" accept
}
chain output {
type filter hook output priority filter;
policy accept;
}
}
table ip nat {
chain prerouting {
type nat hook prerouting priority dstnat;
policy accept;
}
chain postrouting {
type nat hook postrouting priority srcnat;
policy accept;
ip saddr 192.168.50.0/24 oifname "wan0" masquerade
}
}
Avec :
net.ipv4.ip_forward=1
la machine peut alors servir de routeur IPv4 NAT simple, sous réserve que :
- les interfaces existent sous ces noms ;
- les routes soient correctes ;
- le réseau corresponde réellement à l’exemple ;
- la politique de sécurité convienne à l’environnement.
Résumé des commandes nftables essentielles
| Action | Commande |
|---|---|
| Afficher tout | nft list ruleset |
| Afficher avec handles | nft -a list ruleset |
| Vérifier un fichier | nft -c -f fichier |
| Charger un fichier | nft -f fichier |
| Vider toutes les règles | nft flush ruleset |
| Observer les modifications | nft monitor |
| Observer les traces | nft monitor trace |
Les points essentiels à retenir
- Netfilter est une infrastructure du noyau Linux ; ce n’est pas synonyme d’iptables.
- nftables et la commande
nftconstituent aujourd’hui l’interface moderne pour configurer le filtrage Netfilter. - iptables reste important pour les systèmes et scripts historiques et peut utiliser le backend nf_tables.
- Les tables
filter,nat,mangleetrawappartiennent surtout au modèle iptables historique ; les tables nftables sont des conteneurs nommés librement. - Les hooks principaux sont
prerouting,input,forward,outputetpostrouting. inputconcerne la machine locale ;forwardconcerne le trafic qui la traverse.- La famille
inetpermet de gérer IPv4 et IPv6 dans un même ruleset. - conntrack permet un filtrage stateful avec notamment
new,established,relatedetinvalid. ct state established,related acceptest l’une des règles fondamentales d’un firewall stateful.- DROP et REJECT n’ont pas le même comportement et aucun des deux n’est universellement supérieur.
- Il ne faut pas bloquer aveuglément ICMP, et encore moins ICMPv6.
- NAT et filtrage sont deux mécanismes distincts.
- DNAT ne remplace pas une règle FORWARD autorisant le trafic.
- Le masquerading ne transforme pas à lui seul Linux en routeur : le forwarding IP doit également être activé.
- Les logs doivent généralement être limités pour éviter les volumes excessifs.
nft -c -fpermet de vérifier la syntaxe avant application, mais ne peut pas deviner que vous venez d’oublier d’autoriser votre propre accès SSH.
Conclusion : le firewall Linux moderne
Netfilter n’est pas simplement une liste de ports ouverts et fermés. C’est une infrastructure complète située au cœur de la pile réseau Linux.
Son fonctionnement peut être résumé ainsi :
paquet
↓
hook Netfilter
↓
chaîne nftables
↓
règles
↓
conntrack / NAT / filtrage / log
↓
verdict
↓
suite du parcours ou disparition administrative
Pour une nouvelle configuration, nftables permet d’exploiter cette architecture de manière beaucoup plus cohérente que l’ancien empilement historique d’iptables, ip6tables, arptables et ebtables.
La bonne approche consiste donc à comprendre :
le trajet du paquet
+
le hook concerné
+
son état conntrack
+
la politique souhaitée
+
l'éventuel NAT
plutôt qu’à accumuler des règles trouvées au hasard jusqu’à ce que le ping recommence à fonctionner.
Un paquet arrive. Netfilter l’observe. nftables consulte la politique. Conntrack ressort son dossier.
Et si personne ne peut justifier sa présence :
drop
Le processus est froid, méthodique et remarquablement moins susceptible à la négociation qu’un véritable vigile.
