Introduction : De `iptables` à `nftables`
Le pare-feu est le premier rempart de la sécurité d'un serveur. Alors qu'`iptables` a longtemps été la norme, `nftables` offre une syntaxe plus simple, une meilleure performance et une gestion unifiée pour IPv4 et IPv6. Ce guide expert détaille la construction d'un ruleset `nftables` sécurisé et résilient pour un serveur de production.
Section 1 : La Fondation - Politique "Default Deny"
Le principe fondamental d'un pare-feu sécurisé est de tout interdire par défaut et de n'autoriser que le trafic explicitement nécessaire.
Le fichier de configuration principal se trouve dans /etc/nftables.conf.
#!/usr/sbin/nft -f
# Vide l'ensemble des règles existantes
flush ruleset
# La table 'inet' gère à la fois IPv4 et IPv6
table inet filter {
# Chaîne pour le trafic entrant destiné au serveur
chain input {
type filter hook input priority 0;
policy drop; # POLITIQUE PAR DÉFAUT : TOUT REJETER
# Accepter le trafic déjà établi ou lié (essentiel pour un pare-feu stateful)
ct state established,related accept
# Accepter le trafic sur l'interface de loopback (localhost)
iif lo accept
# Rejeter les paquets invalides pour nettoyer les logs
ct state invalid drop
# Permettre le ping (ICMP echo request)
ip protocol icmp icmp type echo-request accept
ip6 nexthdr icmpv6 icmpv6 type echo-request accept
# Autoriser les connexions SSH (sur le port personnalisé) et web
tcp dport { 2222, 80, 443 } accept
}
# Chaîne pour le trafic qui ne fait que transiter par le serveur (ex: routeur)
chain forward {
type filter hook forward priority 0;
policy drop; # On bloque tout par défaut
}
# Chaîne pour le trafic sortant, initié par le serveur lui-même
chain output {
type filter hook output priority 0;
policy accept; # On autorise tout le trafic sortant pour commencer
}
}
Pour appliquer ces règles : sudo nft -f /etc/nftables.conf. Pour qu'elles persistent après un redémarrage : sudo systemctl enable nftables.service.
Section 2 : Utilisation des `sets` pour une Gestion Efficace
Les `sets` sont une des grandes forces de `nftables`. Ils permettent de créer des listes (d'IPs, de ports...) qui peuvent être mises à jour dynamiquement et utilisées dans les règles, ce qui est bien plus performant que des centaines de règles individuelles.
table inet filter {
# Déclaration d'un set nommé 'blacklist' qui contiendra des adresses IPv4
set blacklist {
type ipv4_addr
flags dynamic
}
chain input {
# ... autres règles ...
# Bloquer toute adresse IP présente dans le set 'blacklist'
ip saddr @blacklist drop
# ... autres règles ...
}
}
Vous pouvez ensuite ajouter des IPs à ce set à la volée, sans recharger tout le ruleset :
sudo nft add element inet filter blacklist { 1.2.3.4, 5.6.7.8 }
Section 3 : Stratégies Actives Anti-Scan et Anti-DoS
Nous pouvons utiliser `nftables` pour détecter et bloquer automatiquement les comportements malveillants.
- Limitation de débit (Rate-Limiting) sur SSH : Pour contrer les attaques par force brute, on peut limiter le nombre de nouvelles connexions par minute depuis une même IP.
# Dans la chaîne 'input' # Autorise 4 nouvelles connexions par minute sur le port SSH, rejette le reste. tcp dport 2222 ct state new limit rate 4/minute accept - Détection de scan de ports : Une technique consiste à ajouter les IPs qui scannent vos ports à un set, puis à les bannir.
table inet filter { set port_scanners { type ipv4_addr flags dynamic timeout 1h # L'IP sera retirée du set après 1 heure } chain input { # ... # Si une nouvelle connexion TCP n'est pas sur les ports autorisés... tcp dport != { 2222, 80, 443 } ct state new \ # ... on ajoute l'IP source au set des scanners... add @port_scanners { ip saddr } \ # ... et on rejette le paquet. drop # On bloque ensuite tout trafic venant de ces IPs ip saddr @port_scanners drop # ... } }
Section 4 : Journalisation (Logging) et Filtrage en Sortie
La visibilité et le contrôle du trafic sortant sont des aspects souvent négligés mais cruciaux.
- Journaliser les paquets rejetés : Pour savoir ce que votre pare-feu bloque, ajoutez une règle de log juste avant la politique `drop`.
# Dans la chaîne 'input', juste avant la fin log prefix "[nftables drop] " drop - Filtrage en Sortie (Egress Filtering) : C'est une mesure avancée. Elle consiste à bloquer tout le trafic sortant et à n'autoriser que les flux nécessaires (DNS, mises à jour, etc.). Cela empêche un serveur compromis de communiquer avec un serveur de C&C (Commande et Contrôle) ou de participer à des attaques.
# Dans la table 'inet filter' chain output { type filter hook output priority 0; policy drop; # TOUT BLOQUER PAR DÉFAUT # Autoriser le trafic sortant établi (réponses aux requêtes entrantes) ct state established,related accept # Autoriser le loopback oif lo accept # Autoriser les requêtes DNS (port 53 en TCP et UDP) udp dport 53 accept tcp dport 53 accept # Autoriser les requêtes HTTP/HTTPS (pour les mises à jour par exemple) tcp dport { 80, 443 } accept # ... ajoutez d'autres règles pour les flux sortants légitimes (NTP, mail, etc.) }