Skip to content

Pare-feu nftables de base pour serveurs Linux

Construire un pare-feu nftables en deny par défaut, durcir les sysctls réseau et réduire la surface des services exposés sur tout serveur Linux.

Publié le Mis à jour le 3 min de lecture

Un pare-feu est le contrôle le moins coûteux et le plus rentable que vous puissiez placer devant un serveur Linux, et pourtant la plupart des machines acceptent tout par défaut en comptant uniquement sur le fait que les services n'écoutent pas. Cette hypothèse s'effondre dès qu'un démon se lie à 0.0.0.0 par erreur. Ce guide construit un pare-feu inet en deny par défaut avec nftables, ajoute les sysctls réseau que le pare-feu ne peut pas imposer, et montre comment énumérer puis réduire l'ensemble des services réellement exposés. Le résultat est une base que vous pouvez déployer sur tout hôte Debian, Ubuntu, RHEL ou Fedora récent.

Pourquoi le deny par défaut

Il existe deux façons d'écrire une politique de pare-feu. Une liste de blocage accepte tout et bloque le trafic indésirable ; elle échoue en mode ouvert, donc tout service oublié reste joignable. Une liste d'autorisation rejette tout et n'accepte que ce que vous nommez ; elle échoue en mode fermé, donc une erreur coûte la disponibilité d'un seul service au lieu d'un trou silencieux. Pour un serveur, le deny par défaut est le seul choix défendable. Le minimum à autoriser est le trafic loopback, les paquets appartenant à des connexions déjà initiées (established,related), les messages ICMP nécessaires au bon fonctionnement du réseau, et la poignée de services entrants que cet hôte offre réellement, à commencer par SSH.

Un jeu de règles nftables complet

nftables remplace l'ancienne séparation iptables/ip6tables par une unique famille inet qui couvre IPv4 et IPv6 d'un coup. Écrivez la politique dans /etc/nftables.conf :

#!/usr/sbin/nft -f

flush ruleset

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

        ct state established,related accept
        ct state invalid drop
        iif lo accept

        # ICMP / ICMPv6 essentiels
        ip protocol icmp icmp type { echo-request, destination-unreachable, time-exceeded, parameter-problem } accept
        ip6 nexthdr icmpv6 icmpv6 type { echo-request, destination-unreachable, time-exceeded, parameter-problem, packet-too-big, nd-neighbor-solicit, nd-neighbor-advert, nd-router-advert, nd-router-solicit } accept

        # SSH
        tcp dport ssh ct state new accept

        # Journaliser et rejeter le reste
        limit rate 5/minute log prefix "nft-drop-in: " flags all counter drop
    }

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

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

Chargez-le, activez-le au démarrage et inspectez le jeu de règles actif :

sudo nft -f /etc/nftables.conf
sudo systemctl enable --now nftables
sudo nft list ruleset

Ajoutez les autres services à l'écoute explicitement, une règle chacun, par exemple tcp dport { 80, 443 } ct state new accept pour un serveur web. Gardez une session SSH ouverte pendant l'application pour qu'une erreur ne vous verrouille pas dehors. Voir durcissement du noyau et services & systemd pour les couches voisines.

Les front ends firewalld et ufw

Sur RHEL et Fedora, firewalld est le front end managé au-dessus de nftables. Définissez une zone par défaut en deny et ajoutez les services par nom :

sudo firewall-cmd --set-default-zone=drop
sudo firewall-cmd --zone=drop --add-service=ssh
sudo firewall-cmd --runtime-to-permanent

Sur Ubuntu, ufw est l'enveloppe conviviale :

sudo ufw default deny incoming
sudo ufw allow OpenSSH
sudo ufw enable

Choisissez un seul front end par hôte. N'éditez pas /etc/nftables.conf à la main tant que firewalld ou ufw gère aussi le jeu de règles, sinon les deux s'écraseront mutuellement.

Sysctls de durcissement réseau

Le pare-feu ne peut pas changer la façon dont le noyau lui-même traite les redirections, le routage à la source ou les paquets usurpés. Réglez cela dans un drop-in dédié /etc/sysctl.d/90-network-hardening.conf :

# Filtrage par chemin inverse (anti-usurpation)
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

# Ignorer et ne jamais envoyer de redirections ICMP
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0

# Rejeter les paquets routés à la source
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0

# Protection contre les SYN flood
net.ipv4.tcp_syncookies = 1

# Journaliser les paquets usurpés / martiens
net.ipv4.conf.all.log_martians = 1

# Ignorer les pings broadcast (protection smurf)
net.ipv4.icmp_echo_ignore_broadcasts = 1

# Désactiver les annonces de routeur IPv6 si inutilisées
net.ipv6.conf.all.accept_ra = 0
net.ipv6.conf.default.accept_ra = 0

Appliquez tous les drop-ins et vérifiez une valeur :

sudo sysctl --system
sysctl net.ipv4.tcp_syncookies

Réduire les services exposés

Un pare-feu ne justifie pas de faire tourner des services dont vous n'avez pas besoin. Listez chaque socket en écoute avec le processus propriétaire :

sudo ss -tulpn

Tout ce qui est lié à 0.0.0.0 ou [::] est joignable depuis le réseau. Lorsqu'un service n'est consommé que localement (une base de données, un exporteur de métriques, un cache), liez-le à 127.0.0.1 dans sa configuration au lieu de compter uniquement sur le pare-feu. Désactivez les démons que vous n'utilisez pas du tout plutôt que de les filtrer. Associez ceci à accès & authentification et détection d'intrusion pour une défense en profondeur.

Vérification

Confirmez le pare-feu, les sysctls et les services à l'écoute après chaque modification :

sudo nft list ruleset
sudo systemctl is-enabled nftables
sysctl net.ipv4.conf.all.rp_filter net.ipv4.tcp_syncookies
sudo ss -tulpn

Depuis un hôte externe, scannez un port que vous n'avez pas autorisé et confirmez qu'il est filtré :

nmap -Pn -p 22,80,443,3306 votre.serveur.exemple

Seuls les ports explicitement acceptés doivent apparaître ouverts ; tout le reste doit être filtré ou fermé.

Guides associés

Durcir le noyau Linux avec les paramètres sysctl, le blacklisting de modules et le mode lockdown. Exemples concrets /etc/sysctl.d et modprobe.d avec vérification.