🔥 iptables / nftables — Filtrage & NAT / DMZ

Bloc 3 Module 3.4 Séance 1/2 BTS SIO SLAM
FormationBTS SIO option SLAM — IRIS Mediaschool
BlocB3 — Cybersécurité des services informatiques
ModuleM3.4 — Disponibilité, intégrité et confidentialité
Durée3h30 (10 min accroche · 75 min théorie · 85 min TP · 10 min synthèse)
PrérequisNotions de protocoles TCP/IP, concepts de réseau (LAN, WAN, routage)
ContextePME InnovatTech SARL — Debian 12 pare-feu entre LAN (192.168.1.0/24) et DMZ (192.168.10.0/24)

🎯 Objectifs

  • Distinguer pare-feu stateless et stateful
  • Maîtriser l'architecture iptables (tables, chaînes, politiques)
  • Écrire des règles iptables avec suivi d'état conntrack
  • Comprendre le NAT (SNAT/Masquerade et DNAT/port forwarding)
  • Concevoir et implémenter un zonage DMZ/LAN sécurisé
  • Rédiger l'équivalent en nftables

🔥 Accroche — Capital One (2019)

En juillet 2019, une ancienne ingénieure d'AWS a exploité une règle WAF mal configurée pour effectuer des Server-Side Request Forgery (SSRF) et accéder à des instances EC2. Des données de 106 millions de clients ont été exfiltrées. Une règle autorisant des requêtes sortantes vers n'importe quelle adresse interne était le maillon faible. Si un zonage strict et des règles de pare-feu bien pensées avaient été en place, l'exfiltration aurait pu être empêchée.

📖 Section 1 — Architecture iptables et filtrage stateful

Pare-feu stateless vs stateful

CritèreStatelessStateful
MémoireAucune — chaque paquet examiné isolémentSuit l'état des connexions (NEW, ESTABLISHED, RELATED)
Règles de retourDoivent être écrites explicitementAutorisées automatiquement via conntrack
ComplexitéRègles verbeuses et sujettes aux erreursRègles plus simples et robustes
Exemple Linuxiptables sans conntrackiptables + -m conntrack --ctstate

Tables et chaînes iptables

  • filter — filtrage classique : chaînes INPUT, OUTPUT, FORWARD
  • nat — translation d'adresses : PREROUTING (DNAT), POSTROUTING (SNAT/MASQUERADE)
  • mangle — modification de paquets (TTL, marquage)
  • raw — bypass du suivi d'état pour cas particuliers

Flux d'un paquet (simplifié)

Paquet entrant
     │
     ▼
[PREROUTING] ─ nat
     │
     ├─ Destination = machine locale ? OUI → [INPUT] (filter)
     │                                NON → [FORWARD] (filter)
     ▼
[POSTROUTING] ─ nat → Paquet sortant

Commandes iptables essentielles

# Afficher les règles avec compteurs
sudo iptables -L -v -n --line-numbers

# Politique par défaut DROP (sécurisée)
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT

# Autoriser les connexions établies/liées (stateful — règle fondamentale)
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Autoriser SSH depuis le LAN
sudo iptables -A INPUT -s 192.168.1.0/24 -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT

# Autoriser HTTP/HTTPS
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# Autoriser loopback
sudo iptables -A INPUT -i lo -j ACCEPT

# Journaliser et bloquer le reste
sudo iptables -A INPUT -j LOG --log-prefix "IPT DROP: " --log-level 4
sudo iptables -A INPUT -j DROP

# NAT Masquerade (sortie vers Internet)
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

# Sauvegarder les règles
sudo iptables-save > /etc/iptables/rules.v4

nftables — syntaxe moderne

sudo nft add table inet filter
sudo nft add chain inet filter input { type filter hook input priority 0 ; policy drop ; }
sudo nft add rule inet filter input ct state established,related accept
sudo nft add rule inet filter input iif lo accept
sudo nft add rule inet filter input tcp dport 22 ip saddr 192.168.1.0/24 accept
sudo nft add rule inet filter input tcp dport { 80, 443 } accept

# Afficher la configuration complète
sudo nft list ruleset

📖 Section 2 — NAT et architecture DMZ

SNAT vs DNAT

  • SNAT / MASQUERADE — modifie l'adresse source : cache les adresses internes derrière une IP publique (sortie vers Internet)
  • DNAT (port forwarding) — modifie l'adresse destination : redirige les paquets entrants vers un serveur interne (publier un serveur web en DMZ)

Architecture DMZ InnovatTech

INTERNET (0.0.0.0/0)
     │
[Debian pare-feu / pfSense]
     │                    │
DMZ (192.168.10.0/24)   LAN (192.168.1.0/24)
┌─────────────────┐     ┌────────────────────┐
│ Serveur Web     │     │ Postes utilisateurs │
│ 192.168.10.10   │     │ AD 192.168.1.10     │
│ Serveur Mail    │     │ NAS 192.168.1.20    │
│ 192.168.10.20   │     └────────────────────┘
└─────────────────┘

Règles :
Internet → DMZ (80, 443) : AUTORISÉ
LAN → DMZ (tous ports)   : AUTORISÉ
DMZ → LAN                : BLOQUÉ (isolation)
Internet → LAN           : BLOQUÉ

🛠️ TP — Zonage DMZ/LAN sur Debian 12 (85 min)

Hypothèses : eth0 = WAN, eth1 = LAN (192.168.1.1), eth2 = DMZ (192.168.10.1), serveur web DMZ = 192.168.10.10.

Script iptables complet

#!/bin/bash
WAN_IF=eth0 ; LAN_IF=eth1 ; DMZ_IF=eth2
LAN_NET=192.168.1.0/24 ; DMZ_NET=192.168.10.0/24 ; WEB_DMZ=192.168.10.10

# 1) Flush et politiques par défaut
sudo iptables -F ; sudo iptables -t nat -F ; sudo iptables -X
sudo iptables -P INPUT DROP ; sudo iptables -P FORWARD DROP ; sudo iptables -P OUTPUT ACCEPT

# 2) Règles générales
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A INPUT -i ${LAN_IF} -p tcp --dport 22 -s ${LAN_NET} -m conntrack --ctstate NEW -j ACCEPT

# 3) Zonage DMZ
sudo iptables -A FORWARD -i ${LAN_IF} -o ${DMZ_IF} -s ${LAN_NET} -d ${DMZ_NET} -j ACCEPT
sudo iptables -t nat -A PREROUTING -i ${WAN_IF} -p tcp --dport 80 -j DNAT --to-destination ${WEB_DMZ}:80
sudo iptables -t nat -A PREROUTING -i ${WAN_IF} -p tcp --dport 443 -j DNAT --to-destination ${WEB_DMZ}:443
sudo iptables -A FORWARD -i ${WAN_IF} -o ${DMZ_IF} -p tcp -d ${WEB_DMZ} --dport 80 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT

# 4) Isolation DMZ → LAN (BLOQUÉ)
sudo iptables -A FORWARD -i ${DMZ_IF} -o ${LAN_IF} -j LOG --log-prefix "IPT DROP DMZ->LAN: " --log-level 4
sudo iptables -A FORWARD -i ${DMZ_IF} -o ${LAN_IF} -j DROP

# 5) NAT Masquerade
sudo iptables -t nat -A POSTROUTING -o ${WAN_IF} -j MASQUERADE

# 6) Sauvegarder
sudo apt install -y iptables-persistent && sudo netfilter-persistent save

Tests de validation

OrigineDestinationPortRésultat attendu
Internet (WAN)Serveur web DMZ (192.168.10.10)80✅ HTTP 200 OK (via DNAT)
LAN (192.168.1.20)Serveur web DMZ (192.168.10.10)80✅ Accès OK
DMZ (192.168.10.50)AD LAN (192.168.1.10)389🚫 BLOQUÉ (log IPT DROP)
# Vérifier les logs de blocage DMZ→LAN
sudo journalctl -k --since "5 minutes ago" | grep "IPT DROP" || true
sudo grep "IPT DROP" /var/log/syslog | tail -n 20 || true

# Vérifier les compteurs des règles FORWARD
sudo iptables -L FORWARD -v -n --line-numbers

💬 Synthèse — Question finale

Quelle est la différence entre -j DROP et -j REJECT ? Quand utiliser l'une ou l'autre ?

DROP élimine silencieusement le paquet ; l'expéditeur perçoit un timeout. REJECT envoie immédiatement une notification ICMP unreachable ou TCP RST. Utilisez DROP sur les interfaces exposées à Internet (limiter l'information fournie à un attaquant) et REJECT sur les réseaux internes de confiance (faciliter le diagnostic en PME).

📝 QCM — Testez vos connaissances

  1. Quelle table iptables est dédiée au filtrage des paquets (ACCEPT/DROP/REJECT) et contient les chaînes INPUT, FORWARD, OUTPUT ?
  2. Quel module conntrack permet d'autoriser automatiquement les paquets de réponse des connexions déjà établies ?
  3. Dans une architecture DMZ, quelle règle FORWARD est indispensable pour l'isolation de la DMZ vis-à-vis du LAN interne ?
  4. Vrai ou Faux — Un pare-feu stateless conserve l'état des connexions TCP et autorise automatiquement les paquets de réponse.
  5. Expliquez la différence entre SNAT (Masquerade) et DNAT (port forwarding) avec un exemple d'usage concret pour chacun.
📝 Afficher les corrections
  1. La table filter — c'est la table par défaut de filtrage iptables. Elle contient les chaînes INPUT (paquets destinés au système), FORWARD (paquets en transit) et OUTPUT (paquets générés par le système). C'est là que l'on écrit les règles ACCEPT/DROP/REJECT.
  2. --ctstate ESTABLISHED,RELATED — cette option du module conntrack autorise automatiquement les paquets appartenant à une connexion déjà établie ou liée. Elle est fondamentale dans un pare-feu stateful Linux pour éviter d'écrire des règles de retour manuelles.
  3. Bloquer DMZ → LAN (iptables -A FORWARD -i DMZ_IF -o LAN_IF -j DROP) — cette règle empêche les serveurs de la DMZ d'accéder directement au réseau interne en cas de compromission. C'est le principe d'isolation qui justifie l'existence même de la DMZ.
  4. Faux — un pare-feu stateless n'a aucune mémoire des connexions ; chaque paquet est examiné de façon indépendante. Seul le pare-feu stateful (avec conntrack) suit l'état des connexions TCP et autorise automatiquement les paquets de réponse.
  5. SNAT/Masquerade modifie l'adresse source (ex. les postes du LAN 192.168.1.0/24 sortent sur Internet avec l'IP publique du routeur). DNAT/port forwarding modifie l'adresse destination (ex. un paquet entrant sur le port 80 de l'IP publique est redirigé vers 192.168.10.10:80 en DMZ).
← C3.3.3 Séance 1 C3.4.1 Séance 2 →