Passer au contenu principal
Divers

Netfilter sous Linux : nftables, filtrage, conntrack et NAT

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 inet lorsque 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 nft constituent 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, mangle et raw appartiennent surtout au modèle iptables historique ; les tables nftables sont des conteneurs nommés librement.
  • Les hooks principaux sont prerouting, input, forward, output et postrouting.
  • input concerne la machine locale ; forward concerne le trafic qui la traverse.
  • La famille inet permet de gérer IPv4 et IPv6 dans un même ruleset.
  • conntrack permet un filtrage stateful avec notamment new, established, related et invalid.
  • ct state established,related accept est 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 -f permet 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.