Credit : Logo officiel
Comprendre et configurer iptables sous Linux
iptables, le pare-feu qu'on ne peut plus ignorer
Jeudi dernier, intervention urgente : un VPS Debian 12 chez un client devenu inaccessible apres qu'un freelance ait "securise le firewall". Resultat : le serveur etait joignable depuis Mars mais pas depuis le bureau. Politique INPUT a DROP par defaut, aucune regle d'autorisation, console KVM en sauvetage. C'est pour ce genre de catastrophe qu'il faut vraiment comprendre iptables avant de toucher la moindre chain.
Netfilter (le module noyau) et iptables (l'outil userspace) c'est le pare-feu integre a Linux depuis 2.4. Oui, nftables le remplace doucement depuis Debian 11 et reste compatible via la couche iptables-nft, mais en pratique iptables est encore omnipresent en prod, dans les playbooks Ansible, dans les images Docker, et dans la tete de 90% des sysadmins. Je vous montre tout ce qu'il faut savoir pour ne pas vous enfermer dehors.
L'architecture : tables, chains, rules
iptables s'organise en tables, chaque table contient des chains, chaque chain contient des rules evaluees dans l'ordre.
Les tables principales
- filter : la table par defaut, c'est elle qui filtre les paquets
- nat : pour le Network Address Translation (masquerading, port forwarding)
- mangle : pour modifier les paquets (TOS, TTL, marquage)
- raw : pour exempter des paquets du suivi de connexion
Les chains de la table filter
- INPUT : trafic destine au serveur lui-meme
- OUTPUT : trafic emis par le serveur
- FORWARD : trafic qui traverse le serveur (utile uniquement si votre machine fait routeur)
Les paquets traversent ces chains selon leur destination. Comprendre ce flux c'est 80% du job.
Cibles (targets) communes
- ACCEPT : laisser passer
- DROP : detruire silencieusement (l'expediteur croit a une perte reseau)
- REJECT : detruire avec un message ICMP (plus poli, mais revele que vous filtrez)
- LOG : journaliser sans bloquer ni accepter (continue l'evaluation)
DROP vs REJECT : DROP est preferable face a un attaquant (il ne sait pas si le port existe), REJECT est preferable en interne (le client comprend tout de suite que c'est ferme).
Commandes de base
Lister les regles avec details :
sudo iptables -L -v -n --line-numbers
sudo iptables -t nat -L -v -n --line-numbers
Les flags : -L liste, -v verbeux (compteurs paquets/octets), -n ne resout pas DNS, --line-numbers affiche les numeros de regle (utile pour les supprimer par numero).
Vider une chain :
sudo iptables -F INPUT # Vider la chain INPUT
sudo iptables -F # Vider toutes les chains de filter
sudo iptables -X # Supprimer les chains custom
Attention : iptables -F sans avoir au prealable mis la politique par defaut a ACCEPT vous enferme dehors si la politique est DROP. Toujours dans cet ordre :
sudo iptables -P INPUT ACCEPT
sudo iptables -F
# Puis on reconstruit
Politique par defaut : DROP everything
La bonne pratique : on bloque tout par defaut, puis on autorise uniquement ce qui est legitime. Si vous aimez souffrir, faites l'inverse et essayez de blacklister chaque attaquant.
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT
Important : avant de mettre INPUT a DROP, autorisez d'abord le trafic essentiel sinon votre session SSH se coupe immediatement.
Autoriser le trafic essentiel
Le loopback (communication interne) et les connexions deja etablies (essentiel pour que les reponses passent) :
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
Sans la regle conntrack, vos connexions sortantes ne recoivent plus de reponses. C'est l'erreur numero un des debutants.
SSH, HTTP, HTTPS :
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
ICMP (ping) - utile pour le diagnostic :
sudo iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT
Le --limit 1/s evite qu'un attaquant fasse un DoS avec des floods de ping.
Rate limiting anti brute-force
Limiter SSH a 4 tentatives par minute par IP. Ca n'arrete pas un attaquant determine mais ca ralentit tellement les bots qu'ils passent au suivant :
sudo iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --set --name SSH
sudo iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 4 --name SSH -j DROP
Le module recent maintient une liste d'IPs avec timestamps. La premiere regle marque chaque nouvelle connexion, la seconde DROP si plus de 4 nouvelles connexions en 60 secondes.
Pour quelque chose de plus solide, utilisez fail2ban ou CrowdSec par-dessus. iptables fait le filtrage de base, ces outils ajoutent une intelligence comportementale.
Bloquer une IP ou un sous-reseau
Un scanner vous spam ? Hop :
sudo iptables -I INPUT 1 -s 203.0.113.50 -j DROP
sudo iptables -I INPUT 1 -s 203.0.113.0/24 -j DROP
Le -I INPUT 1 insere en premiere position, donc evalue avant tout le reste. Important sinon votre regle ACCEPT du dessus avalera l'attaquant.
Whitelist d'IPs admin (a placer en debut de chain) :
sudo iptables -I INPUT 1 -s 10.0.0.0/8 -j ACCEPT
sudo iptables -I INPUT 2 -s 192.168.1.0/24 -j ACCEPT
NAT et redirection de port
La table nat ouvre un autre monde. Masquerading, redirection, source NAT...
Activer le forwarding noyau
sudo sysctl -w net.ipv4.ip_forward=1
echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.d/99-router.conf
Masquerade pour une box maison
Votre serveur fait routeur pour un sous-reseau interne :
sudo iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o eth1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
Rediriger un port vers un service interne
Votre serveur public expose 8080 et redirige vers un app server interne sur 8000 :
sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.100:8000
sudo iptables -A FORWARD -p tcp -d 192.168.1.100 --dport 8000 -j ACCEPT
N'oubliez pas la regle FORWARD : sans elle, le DNAT redirige le paquet mais la chain FORWARD le drop.
Sauvegarder et persister les regles
Les regles iptables disparaissent au reboot. J'ai appris ca a la dure un dimanche soir apres avoir passe 2h a configurer un firewall parfait, fait reboot, et tout perdu. Donc on persiste :
Methode manuelle
sudo iptables-save > /etc/iptables/rules.v4
sudo ip6tables-save > /etc/iptables/rules.v6
Restauration :
sudo iptables-restore < /etc/iptables/rules.v4
Avec iptables-persistent (Debian/Ubuntu)
sudo apt install iptables-persistent
sudo netfilter-persistent save
sudo netfilter-persistent reload
Le paquet recharge automatiquement les regles au boot via systemd.
Avec un script systemd custom
Pour un controle plus fin :
[Unit]
Description=Restore iptables rules
Before=network-pre.target
Wants=network-pre.target
[Service]
Type=oneshot
ExecStart=/sbin/iptables-restore /etc/iptables/rules.v4
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
A placer dans /etc/systemd/system/iptables-restore.service, puis systemctl enable --now iptables-restore.
Journaliser ce qu'on bloque
Avant la regle DROP finale, ajoutez une regle LOG. Ca aide enormement pour debugger pourquoi un service ne repond pas :
sudo iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "IPT-DROP: " --log-level 4
sudo iptables -A INPUT -j DROP
Le --limit 5/min evite que vos logs explosent en cas de scan massif. Les logs atterrissent dans /var/log/kern.log (Debian) ou via journalctl -k -f.
sudo journalctl -k -f | grep IPT-DROP
Script complet de demarrage
Voila un script pret a l'emploi pour un serveur web standard. Adaptez les ports selon vos besoins :
#!/bin/bash
set -e
# Reset
iptables -F && iptables -X
iptables -t nat -F && iptables -t nat -X
# Politique par defaut
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# Loopback et connexions etablies
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
# Whitelist admin (adaptez)
iptables -A INPUT -s 10.0.0.0/8 -j ACCEPT
# SSH avec rate limiting
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --set --name SSH
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 4 --name SSH -j DROP
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Web
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# ICMP limite
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT
# Log + drop final
iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "IPT-DROP: "
iptables -A INPUT -j DROP
# Persister
iptables-save > /etc/iptables/rules.v4
echo "Firewall applique avec succes"
Erreurs courantes et leur fix
Vous etes enferme dehors apres une regle
Gardez TOUJOURS une session SSH active a cote pendant les tests, et utilisez la console KVM IONOS comme filet. Astuce qui sauve : avant de tester une nouvelle regle, planifier un reset auto :
# Programme un reset dans 5 min, A LANCER AVANT la modification
sudo bash -c "sleep 300 && iptables -P INPUT ACCEPT && iptables -F" &
Si vous etes enferme, attendez 5 min, sinon kill %1 une fois la conf validee.
Mes regles disparaissent au reboot
Vous n'avez pas iptables-persistent installe. Reportez-vous a la section persistance ci-dessus.
Le DNAT ne fonctionne pas
Verifiez net.ipv4.ip_forward = 1, et n'oubliez pas la regle FORWARD correspondante.
Mes connexions sortantes ne marchent plus
Vous avez oublie la regle ESTABLISHED,RELATED sur INPUT. Sans elle, les reponses aux requetes sortantes sont droppees.
Conflit avec ufw ou firewalld
iptables / ufw / firewalld manipulent les memes chains. N'utilisez qu'un seul outil. Sur Debian je conseille iptables-persistent direct ou nftables, sur Ubuntu desktop ufw, sur CentOS firewalld.
Pour aller plus loin
- Securiser SSH avec sshd_config
- Fail2ban : proteger un serveur du brute force
- Configurer CrowdSec sur un serveur Linux
- Hardening Linux : durcir un serveur
- Configurer un pare-feu applicatif WAF avec Nginx
Le pare-feu, ca se configure pas a la legere
iptables c'est puissant mais impardonnable. Une virgule mal placee et c'est le service down. Mes trois regles d'or : (1) toujours testez avec une console de secours ouverte (le KVM IONOS est votre ami), (2) versionnez votre script de regles dans git avec un changelog des modifications, (3) automatisez la persistance des le premier essai pour ne pas tout reperdre au reboot.
Et si vous demarrez un nouveau serveur en 2026, jetez quand meme un oeil a nftables : la syntaxe est plus moderne, les performances sont meilleures sur les grosses regles, et c'est l'avenir officiel cote noyau Linux. Mais comprendre iptables reste une competence fondamentale qui se transferera de toute facon, surtout si vous reprenez du legacy ou que vous lisez du code Ansible/Docker existant. Investissez les 2 heures necessaires pour vraiment internaliser le flux des paquets : le retour sur investissement est immense.