Aller au contenu
Réseaux high

Pare-feu — Qui peut parler à qui ?

28 min de lecture

Votre service est accessible en local mais pas depuis Internet ? Le pare-feu bloque probablement le trafic entrant. Ce module vous apprend à comprendre le filtrage réseau, lire les règles iptables et diagnostiquer les blocages — compétences essentielles pour déployer des applications accessibles.

  • Pare-feu = filtre qui décide quel trafic passe (par IP, port, protocole)
  • Timeout = pare-feu DROP (silencieux), Refused = pare-feu REJECT ou port fermé
  • Cloud : double filtrage (Security Group + pare-feu OS)
  • Stateful = les réponses aux connexions sortantes passent automatiquement
  1. Blocage par défaut : un pare-feu bien configuré bloque tout sauf ce qui est explicitement autorisé
  2. Stateful : si vous autorisez une connexion sortante, les réponses rentrent automatiquement
  3. Timeout ≠ Refused : timeout = DROP (silencieux), refused = service absent ou REJECT
  • Je sais distinguer timeout (filtré) de refused (port fermé)
  • sudo iptables -L -n me montre les règles actives
  • Je pense à vérifier le Security Group en plus du pare-feu OS (cloud)
Fenêtre de terminal
# 1. Voir les règles iptables
sudo iptables -L -n --line-numbers
# 2. Tester si un port est filtré ou fermé
nc -zv -w 3 serveur 22
# 3. Voir les connexions suivies (stateful)
sudo conntrack -L 2>/dev/null | head -10
  • Module 6 complété : vous comprenez TCP/UDP et les ports
  • Module 8 complété : vous savez comment une machine obtient son IP (DHCP)
  • Accès root sur une machine Linux
SymptômeHypothèse #1Hypothèse #2Commandes
TimeoutDROP / Security Group / routeService downtcpdump, ss -tlnp, nc -zv -w 5
Connection refusedService absentREJECT —reject-with tcp-resetss -tlnp, iptables -S
Marche en local, pas remoteBinding sur 127.0.0.1Pare-feu/SGss -tlnp, docker ps, iptables -L
ICMP unreachableREJECT avec ICMPRoute manquantetraceroute, iptables -S
  • Le rôle d’un pare-feu : filtrer qui peut parler à qui
  • Ingress vs egress : trafic entrant vs sortant
  • Stateful vs stateless : pare-feu à mémoire de connexion
  • Iptables/nftables : les chaînes INPUT, OUTPUT, FORWARD
  • Symptômes de blocage : timeout, connection refused, ICMP unreachable
  • Diagnostic pratique : tester si un port est filtré

Un pare-feu est un gardien qui décide quel trafic réseau peut passer et lequel est bloqué. Il applique des règles basées sur :

  • L’adresse IP source/destination
  • Le port source/destination
  • Le protocole (TCP, UDP, ICMP)
  • La direction (entrant ou sortant)

Principe de base : tout bloquer par défaut, autoriser seulement ce qui est nécessaire.

Sans pare-feuAvec pare-feu
Tous les ports accessiblesSeuls les ports autorisés
Vulnérable aux scansProtection contre les intrusions
Pas de contrôleJournalisation des tentatives

Le pare-feu distingue deux directions de trafic :

Schéma ingress/egress : Internet vers serveur (ingress) et serveur vers Internet (egress)

Le trafic qui arrive vers votre serveur depuis l’extérieur.

Exemples :

  • Un client qui accède à votre site web (port 443)
  • Une requête SSH depuis votre poste (port 22)
  • Un scan de port malveillant

Le trafic qui part de votre serveur vers l’extérieur.

Exemples :

  • Votre serveur qui télécharge une mise à jour
  • Une requête vers une API externe
  • L’envoi d’emails (port 25/587)

Chaque paquet est évalué indépendamment. Le pare-feu ne sait pas si un paquet fait partie d’une connexion établie.

Problème : vous devez créer des règles pour les deux sens (requête ET réponse).

Le pare-feu mémorise les connexions établies. Si vous autorisez une connexion sortante, les réponses entrantes sont automatiquement autorisées.

Avantage : règles plus simples et plus sécurisées.

┌─────────────────────────────────────────────────────────────┐
│ PARE-FEU STATEFUL │
├─────────────────────────────────────────────────────────────┤
│ Connexion sortante autorisée (port 443) │
│ └── Réponse entrante : AUTOMATIQUEMENT acceptée │
│ │
│ Connexion entrante non sollicitée : BLOQUÉE │
└─────────────────────────────────────────────────────────────┘

Le comportement stateful repose sur conntrack (connection tracking). Pour voir les connexions suivies :

Fenêtre de terminal
# Avec conntrack-tools installé
sudo conntrack -L | head -20
# Sans conntrack-tools
sudo cat /proc/net/nf_conntrack | head -20
# Compter les connexions actives
sudo conntrack -C

Exemple de sortie :

tcp 6 431999 ESTABLISHED src=192.168.1.10 dst=93.184.216.34 sport=54321 dport=443
src=93.184.216.34 dst=192.168.1.10 sport=443 dport=54321

Cette ligne montre une connexion HTTPS établie : le pare-feu sait que les paquets retour (443 → 54321) font partie de cette connexion.

Linux dispose de deux outils de pare-feu :

  • iptables : l’outil historique, encore très répandu
  • nftables : le successeur moderne (depuis kernel 3.13)

Les deux utilisent le même sous-système kernel (netfilter).

En production, beaucoup d’administrateurs n’utilisent pas iptables/nftables directement mais une surcouche :

DistributionOutil par défautBackend
Ubuntu/Debianufwiptables ou nftables
RHEL/Fedora/Rockyfirewalldnftables

Commandes UFW (Ubuntu/Debian) :

Fenêtre de terminal
# État et règles
sudo ufw status verbose
# Autoriser un port
sudo ufw allow 22/tcp
# Voir les règles numérotées
sudo ufw status numbered

Commandes firewalld (RHEL/Fedora) :

Fenêtre de terminal
# État du service
sudo firewall-cmd --state
# Lister toutes les règles de la zone active
sudo firewall-cmd --list-all
# Lister les services autorisés
sudo firewall-cmd --list-services
# Ouvrir un port (temporaire)
sudo firewall-cmd --add-port=8080/tcp
# Ouvrir un port (permanent)
sudo firewall-cmd --add-port=8080/tcp --permanent
sudo firewall-cmd --reload

Un paquet traverse différentes chaînes selon sa destination :

Les trois chaînes iptables : INPUT, FORWARD, OUTPUT

ChaîneS’applique àExemple
INPUTTrafic destiné à cette machineConnexion SSH vers ce serveur
OUTPUTTrafic généré par cette machineRequête curl vers une API
FORWARDTrafic qui traverse (routage)Paquet relayé par un routeur
ActionComportementSymptôme côté client
ACCEPTPaquet autoriséConnexion établie
DROPPaquet jeté silencieusementTimeout (pas de réponse)
REJECTPaquet refusé avec notification”Connection refused” ou ICMP
Fenêtre de terminal
# Lister toutes les règles (format lisible)
sudo iptables -L -n -v
# Lister avec numéros de ligne
sudo iptables -L -n --line-numbers
# Voir les règles brutes (format exact)
sudo iptables -S

Exemple de sortie :

Chain INPUT (policy DROP)
num pkts bytes target prot opt in out source destination
1 1234 56K ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
2 5678 890K ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
3 123 12K ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
4 45 2K ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
5 89 8K ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:443

Lecture :

  • policy DROP : tout ce qui n’est pas explicitement autorisé est bloqué
  • Règle 1 : tout trafic sur loopback (lo) est accepté
  • Règle 2 : les connexions établies sont acceptées (stateful)
  • Règles 3-5 : ports SSH, HTTP et HTTPS autorisés
Fenêtre de terminal
# Lister tout le ruleset
sudo nft list ruleset
# Lister une chaîne spécifique
sudo nft list chain inet filter input

Exemple de sortie nftables :

table inet filter {
chain input {
type filter hook input priority 0; policy drop;
iif "lo" accept
ct state established,related accept
tcp dport 22 accept
tcp dport { 80, 443 } accept
}
}

Lecture nftables :

  • table inet filter : table filter pour IPv4 et IPv6
  • chain input : équivalent de la chaîne INPUT iptables
  • policy drop : tout bloquer par défaut
  • ct state established,related : connexions établies (stateful)
  • tcp dport { 80, 443 } : syntaxe concise pour plusieurs ports

Quand un pare-feu bloque votre connexion, le symptôme dépend de la règle :

Fenêtre de terminal
nc -zv 192.168.1.100 22
# Aucune réponse... attend indéfiniment

Le paquet est jeté silencieusement. Le client attend une réponse qui ne viendra jamais (jusqu’au timeout, souvent 30-60 secondes).

Fenêtre de terminal
nc -zv 192.168.1.100 22
# Connection refused

Le serveur envoie un paquet TCP RST (Reset). Cela signifie :

  • Aucun service n’écoute sur ce port (RST envoyé par la stack TCP), OU
  • Le pare-feu a une règle REJECT --reject-with tcp-reset

Exemple de règle REJECT avec RST :

Fenêtre de terminal
# Cette règle envoie un RST au lieu de DROP silencieux
iptables -A INPUT -p tcp --dport 8080 -j REJECT --reject-with tcp-reset
Fenêtre de terminal
nc -zv 192.168.1.100 22
# Message selon l'outil et l'OS :
# - "No route to host"
# - "Host unreachable"
# - "Network unreachable"
# - "Administratively prohibited"

Le pare-feu a explicitement rejeté avec un message ICMP. Le message exact dépend du type d’ICMP envoyé et de l’outil utilisé.

Types de REJECT ICMP courants :

Fenêtre de terminal
# ICMP port-unreachable (défaut)
iptables -A INPUT -p tcp --dport 8080 -j REJECT
# ICMP host-unreachable
iptables -A INPUT -p tcp --dport 8080 -j REJECT --reject-with icmp-host-unreachable
# ICMP admin-prohibited
iptables -A INPUT -p tcp --dport 8080 -j REJECT --reject-with icmp-admin-prohibited
SymptômePaquet TCPCause probableVérification
TimeoutRienDROP par pare-feutcpdump pour voir si SYN arrive
Connection refusedRSTPas de service OU REJECT tcp-resetss -tlnp sur le serveur
ICMP unreachableICMPREJECT avec ICMPiptables -S, nft list ruleset
Connexion lente puis échecSYN sans SYN-ACKPare-feu intermédiairetraceroute, tcpdump
  1. Vérifiez que le service écoute localement

    Sur le serveur, vérifiez que votre service tourne :

    Fenêtre de terminal
    # Le service écoute-t-il ?
    ss -tlnp | grep :80
    # LISTEN 0 128 0.0.0.0:80 *:* users:(("nginx",pid=1234,fd=6))

    Si rien ne s’affiche, le problème n’est pas le pare-feu mais le service.

  2. Testez localement

    Fenêtre de terminal
    curl http://localhost
    # Si ça marche en local, le service fonctionne
  3. Testez depuis l’extérieur

    Depuis une autre machine :

    Fenêtre de terminal
    nc -zv <ip-serveur> 80
    # Timeout ? → Probablement le pare-feu
  4. Vérifiez les règles pare-feu

    Fenêtre de terminal
    sudo iptables -L -n | grep 80
    # Le port 80 est-il autorisé en INPUT ?
  5. Capturez le trafic avec tcpdump

    Sur le serveur, vérifiez si les paquets arrivent :

    Fenêtre de terminal
    sudo tcpdump -i eth0 port 80 -n
    • Paquets visibles : ils arrivent, le pare-feu local les bloque
    • Aucun paquet : bloqué avant (routeur, cloud, etc.)

Pour un diagnostic précis, capturez les flags TCP :

Fenêtre de terminal
# Voir uniquement SYN et SYN-ACK
sudo tcpdump -ni eth0 'tcp port 80 and (tcp[tcpflags] & (tcp-syn|tcp-ack) != 0)'

Interprétation :

Vous voyezSignificationAction
SYN entrant, pas de SYN-ACKPare-feu local DROP ou service ne répond passs -tlnp, iptables -L
SYN entrant, SYN-ACK sortantServeur répond ! Problème sur le chemin retourSG egress, NACL, route asymétrique
Aucun SYNBloqué avant d’arriverSecurity Group, NACL, routeur
SYN + RSTREJECT ou service absentss -tlnp, `iptables -S

Plusieurs outils permettent de vérifier si un port est accessible :

Fenêtre de terminal
# Test rapide d'un port TCP
nc -zv <ip> <port>
# Avec timeout de 5 secondes
nc -zv -w 5 <ip> <port>
  • -z : mode scan (pas de données envoyées)
  • -v : verbose
  • -w : timeout

Dans le cloud, le pare-feu s’appelle Security Group. C’est un pare-feu stateful qui s’applique aux instances.

Exemple AWS :

  • Par défaut : tout l’egress autorisé, tout l’ingress bloqué
  • Vous devez ajouter des règles pour chaque port à ouvrir
Inbound Rules:
Type Protocol Port Source
SSH TCP 22 Mon IP
HTTP TCP 80 0.0.0.0/0
HTTPS TCP 443 0.0.0.0/0
CloudComposantComportementPiège courant
AWSSecurity GroupStateful
AWSNetwork ACL (NACL)StatelessRetour bloqué si egress non configuré
AzureNSGStateful
GCPVPC Firewall RulesStateful

Docker manipule automatiquement iptables pour le port mapping (-p 8080:80).

Voir les règles Docker :

Fenêtre de terminal
# Table nat (port mapping)
sudo iptables -t nat -S | grep -E "(DOCKER|PREROUTING|POSTROUTING)"
# Table filter (FORWARD, DOCKER-USER)
sudo iptables -S DOCKER-USER 2>/dev/null
sudo iptables -S FORWARD | head -10

Problème courant : vous ajoutez une règle iptables, Docker la contourne avec ses propres règles.

Solution : utilisez la chaîne DOCKER-USER pour ajouter vos règles :

Fenêtre de terminal
# Bloquer un IP spécifique vers les conteneurs
sudo iptables -I DOCKER-USER -s 192.168.1.100 -j DROP

Problème fréquent : un port est publié (-p 8080:80) mais inaccessible depuis l’extérieur.

Checklist diagnostic :

Fenêtre de terminal
# 1. Vérifier le binding (127.0.0.1 vs 0.0.0.0)
docker ps --format "table {{.Names}}\t{{.Ports}}"
# Si vous voyez 127.0.0.1:8080->80/tcp, c'est bindé sur localhost uniquement !
# 2. Vérifier que le service dans le conteneur écoute
docker exec <container> ss -tlnp | grep :80
# Si le process écoute sur 127.0.0.1 dans le conteneur, il ne sera pas accessible
# 3. Vérifier les règles iptables Docker
sudo iptables -L DOCKER -n -v | grep 8080

Causes fréquentes :

SymptômeCauseSolution
127.0.0.1:8080->80Binding localhostUtiliser -p 8080:80 sans IP
Service écoute sur 127.0.0.1Config appConfigurer l’app pour écouter sur 0.0.0.0
Pas de règle DOCKERDocker pas démarrésystemctl status docker

Quand votre serveur ne peut pas joindre un service externe, suivez ce runbook :

Scénarios courants :

  • Serveur ne peut pas télécharger depuis un registry Docker
  • Application ne peut pas joindre une API externe
  • Connexion à une base de données managée qui échoue

Runbook egress :

Fenêtre de terminal
# 1. Tester la résolution DNS
dig api.externe.com
# 2. Tester la connectivité TCP
nc -zv -w 5 api.externe.com 443
# 3. Tester HTTP
curl -I --connect-timeout 5 https://api.externe.com
# 4. Vérifier les règles OUTPUT
sudo iptables -L OUTPUT -n -v
# 5. Capturer le trafic sortant
sudo tcpdump -ni eth0 'host api.externe.com and tcp port 443'

Causes fréquentes :

SymptômeCause probableSolution
DNS timeoutEgress UDP 53 bloquéAutoriser DNS sortant
nc timeoutEgress TCP bloquéAutoriser le port de destination
curl SSL errorProxy interceptantVérifier les variables proxy

Dans Kubernetes, les NetworkPolicies sont l’équivalent des règles pare-feu entre pods.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-nginx
spec:
podSelector:
matchLabels:
app: nginx
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 80

Cette policy autorise uniquement les pods labellisés app: frontend à accéder au port 80 des pods app: nginx.

  1. Affichez les règles actuelles

    Fenêtre de terminal
    sudo iptables -L -n -v
  2. Identifiez

    • Quelle est la policy par défaut de INPUT ?
    • Quels ports sont autorisés ?
    • Y a-t-il une règle pour les connexions établies ?
  3. Affichez le format brut

    Fenêtre de terminal
    sudo iptables -S

    Comparez avec la sortie précédente.

  1. Lancez un serveur de test

    Fenêtre de terminal
    # Terminal 1 : serveur sur port 9999
    python3 -m http.server 9999
  2. Testez localement

    Fenêtre de terminal
    # Terminal 2
    curl http://localhost:9999
    # Doit fonctionner
  3. Testez depuis une autre machine

    Fenêtre de terminal
    nc -zv <ip-serveur> 9999
    # Timeout si pare-feu bloque
  4. Vérifiez avec tcpdump

    Fenêtre de terminal
    # Sur le serveur
    sudo tcpdump -i eth0 port 9999 -n

    Les paquets arrivent-ils ?

  1. Testez un port DROP (timeout)

    Fenêtre de terminal
    time nc -zv -w 5 <ip> 12345
    # Attend 5 secondes puis timeout
  2. Testez un port sans service (refused)

    Fenêtre de terminal
    time nc -zv -w 5 localhost 12345
    # Immediate "Connection refused"
  3. Comparez les temps

    • DROP : attend le timeout
    • Pas de service : réponse immédiate

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

10 questions
10 min.
80% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

  • Pare-feu : filtre le trafic selon des règles (IP, port, protocole)
  • Ingress : trafic entrant (vers votre serveur)
  • Egress : trafic sortant (depuis votre serveur) — souvent négligé mais critique
  • Stateful : le pare-feu mémorise les connexions (conntrack) ; ESTABLISHED,RELATED accepte les réponses
  • iptables vs nftables : sur les distros récentes, iptables est souvent un frontend vers nftables
  • UFW/firewalld : surcouches courantes, vérifiez laquelle est active
  • Timeout = DROP : paquet jeté silencieusement (pas de RST, pas d’ICMP)
  • Connection refused = RST : le paquet arrive, mais pas de service OU règle REJECT tcp-reset
  • Cloud = multi-couches : Security Group (stateful) + NACL (stateless sur AWS) + iptables sur l’instance
  • Docker DOCKER-USER : seule chaîne pour ajouter vos règles sans être contourné