Aller au contenu
Sécurité medium

Configurer un pare-feu avec Firewalld

14 min de lecture

Firewalld est le pare-feu hôte par défaut sur Red Hat Enterprise Linux, Fedora, CentOS Stream, Rocky et AlmaLinux. Il expose un modèle déclaratif à deux niveaux — des zones associées aux interfaces, et des services préconfigurés autorisés par zone — par-dessus nftables (Linux moderne) ou iptables (Linux plus ancien). La promesse : configurer un filtrage riche sans écrire de chaîne de règles, et recharger à chaud sans couper les connexions établies. Ce guide pose les fondations (zones, services, règles riches), traite les deux pièges classiques (runtime vs permanent, oubli d'autoriser SSH), et termine par un plan de rollback.

  • Installer et activer Firewalld, vérifier son état
  • Comprendre les zones (public, internal, work…) et leur rôle
  • Distinguer runtime et permanent pour ne plus perdre vos règles au reload
  • Ouvrir des services et des ports par zone
  • Écrire une règle riche pour les cas que les services ne couvrent pas
  • Journaliser, dépanner et rollback proprement

Firewalld est la valeur par défaut quand vous êtes sur l'écosystème Red Hat (RHEL, Fedora, CentOS Stream, Rocky, AlmaLinux) ou sur openSUSE moderne. Vous le rencontrerez presque systématiquement sur un poste RHCSA, sur une VM cloud RHEL/Rocky, et sur tout serveur géré par firewalld.service.

Il s'utilise :

  • quand on veut un pare-feu hôte avec zones (laptop avec différents réseaux, serveur multi-interfaces)
  • quand on veut recharger sans couper les connexions TCP établies
  • quand on préfère déclarer des services nommés (http, ssh, samba…) plutôt que des numéros de port

Sur Debian/Ubuntu, la valeur par défaut est UFW — plus simple, suffisant pour un serveur mono-interface. Ne mélangez pas les deux sur la même machine.

  • Un serveur RHEL, Fedora, CentOS Stream, Rocky ou AlmaLinux (ou Debian/Ubuntu si vous avez un besoin explicite de Firewalld)
  • Un utilisateur avec droits sudo
  • Une session SSH par clé et un accès de secours (console cloud, IPMI, série) avant toute manipulation

Firewalld attache chaque interface réseau à une zone, et chaque zone porte ses propres règles. C'est ce qui permet à un laptop d'être strict sur le Wi-Fi public et permissif sur le Wi-Fi maison en basculant automatiquement de zone.

Les zones standard à connaître :

ZoneUsage typiquePolitique par défaut
dropHostile (réseau inconnu, scan intensif)Entrée bloquée sans notification
blockHostile avec rejet expliciteEntrée bloquée, ICMP reject
publicInternet, Wi-Fi public — défaut fréquentSSH autorisé, reste bloqué
externalSortie Internet avec masquerade (NAT)SSH autorisé, masquerade activé
workLAN de bureauSSH, DHCP, MDNS autorisés
homeLAN domestiqueSSH, MDNS, Samba, IPP client
internalLAN de confianceIdentique à home
trustedTout autoriséPas de filtrage

Vérifier la zone par défaut et les zones actives :

Fenêtre de terminal
sudo firewall-cmd --get-default-zone
sudo firewall-cmd --get-active-zones

Firewalld maintient deux configurations :

  • Runtime — les règles actuellement appliquées. Perdues au prochain reload ou reboot.
  • Permanent — les règles sauvegardées dans /etc/firewalld/. Appliquées après reload ou reboot.

Une commande sans --permanent touche uniquement le runtime. Une commande avec --permanent touche uniquement le permanent ; il faut alors un firewall-cmd --reload pour que ça prenne effet.

Firewalld est normalement installé et activé par défaut :

Fenêtre de terminal
sudo dnf install -y firewalld
sudo systemctl enable --now firewalld

Vérifier :

Fenêtre de terminal
sudo firewall-cmd --version
sudo firewall-cmd --state

firewall-cmd --state doit répondre running.

C'est l'étape à ne jamais sauter. Vous devez connaître la zone active de l'interface d'administration avant d'autoriser SSH — sinon vous ouvrez le port sur la mauvaise zone et vous verrouillez à la première déconnexion.

Repérer la zone active :

Fenêtre de terminal
sudo firewall-cmd --get-active-zones
# Sortie type :
# public
# interfaces: eth0
# internal
# interfaces: eth1

L'interface qui porte votre session SSH (souvent eth0) est associée à une zone — ici public. C'est sur cette zone-là qu'il faut autoriser SSH. Dans la suite de cette section, remplacez public par votre zone active.

Vérifier que ssh est déjà dans la zone (c'est le cas par défaut sur RHEL/Fedora) :

Fenêtre de terminal
sudo firewall-cmd --zone=public --list-services

Si ssh n'apparaît pas dans la sortie :

Fenêtre de terminal
# runtime
sudo firewall-cmd --zone=public --add-service=ssh
# permanent
sudo firewall-cmd --zone=public --add-service=ssh --permanent
sudo firewall-cmd --reload

Si SSH écoute sur un port non standard, ouvrez le port brut :

Fenêtre de terminal
sudo firewall-cmd --zone=public --add-port=2222/tcp --permanent
sudo firewall-cmd --reload

Lister toutes les zones disponibles :

Fenêtre de terminal
sudo firewall-cmd --get-zones

Voir le détail d'une zone (services, ports, sources, interfaces) :

Fenêtre de terminal
sudo firewall-cmd --zone=public --list-all

Associer une interface à une zone (persistant) :

Fenêtre de terminal
sudo firewall-cmd --zone=internal --change-interface=eth1 --permanent
sudo firewall-cmd --reload

Définir la zone par défaut :

Fenêtre de terminal
sudo firewall-cmd --set-default-zone=public

Créer une zone personnalisée — utile pour un segment réseau dédié :

Fenêtre de terminal
sudo firewall-cmd --new-zone=administration --permanent
sudo firewall-cmd --reload
sudo firewall-cmd --zone=administration --add-source=10.10.10.0/24 --permanent
sudo firewall-cmd --zone=administration --add-service=ssh --permanent
sudo firewall-cmd --reload

Firewalld embarque plus de 150 services préconfigurés (fichiers XML sous /usr/lib/firewalld/services/). Lister :

Fenêtre de terminal
sudo firewall-cmd --get-services | tr ' ' '\n' | head
Fenêtre de terminal
# runtime
sudo firewall-cmd --zone=public --add-service=https
# permanent + reload
sudo firewall-cmd --zone=public --add-service=https --permanent
sudo firewall-cmd --reload
Fenêtre de terminal
sudo firewall-cmd --zone=public --add-port=8080/tcp --permanent
sudo firewall-cmd --reload
Fenêtre de terminal
sudo firewall-cmd --zone=public --remove-service=https --permanent
sudo firewall-cmd --zone=public --remove-port=8080/tcp --permanent
sudo firewall-cmd --reload
Fenêtre de terminal
sudo firewall-cmd --zone=public --list-services
sudo firewall-cmd --zone=public --list-ports
sudo firewall-cmd --zone=public --list-all

Règles riches (rich rules) : quand les services ne suffisent pas

Section intitulée « Règles riches (rich rules) : quand les services ne suffisent pas »

Les règles riches (--add-rich-rule) expriment des critères que les services simples ne couvrent pas : source précise, action avancée, rate-limit, journalisation par règle. Syntaxe :

Fenêtre de terminal
# Autoriser HTTP uniquement depuis un sous-réseau interne
sudo firewall-cmd --zone=public --add-rich-rule='
rule family="ipv4"
source address="192.168.1.0/24"
service name="http"
accept
' --permanent
# Bloquer explicitement une IP qui martèle
sudo firewall-cmd --zone=public --add-rich-rule='
rule family="ipv4"
source address="203.0.113.42"
reject
' --permanent
# Rate-limiter les nouvelles connexions SSH
sudo firewall-cmd --zone=public --add-rich-rule='
rule service name="ssh"
accept
limit value="6/m"
' --permanent
sudo firewall-cmd --reload

Lister les règles riches actives :

Fenêtre de terminal
sudo firewall-cmd --zone=public --list-rich-rules

Supprimer : remplacer --add-rich-rule par --remove-rich-rule en reprenant exactement la même chaîne.

Activer la journalisation des paquets refusés :

Fenêtre de terminal
# valeurs : off | all | unicast | broadcast | multicast
sudo firewall-cmd --set-log-denied=unicast

La valeur unicast suffit pour le dépannage sans noyer le journal. Les événements apparaissent ensuite dans :

Fenêtre de terminal
sudo journalctl -u firewalld --since "10 min ago"
# ou plus bas niveau
sudo dmesg --follow | grep -i reject

État complet du service :

Fenêtre de terminal
sudo systemctl status firewalld
sudo firewall-cmd --state
sudo firewall-cmd --list-all-zones
  • Toujours tester en runtime avant de sauver en --permanent.
  • Associer les interfaces à une zone explicite plutôt que de dépendre de la zone par défaut — évite les surprises après ajout d'une nouvelle carte.
  • Préférer les services aux ports bruts — la maintenance devient lisible (--add-service=http plutôt que --add-port=80/tcp).
  • Créer un service custom si vous exposez une appli sur un port non standard : fichier XML sous /etc/firewalld/services/<nom>.xml, firewall-cmd --reload, puis --add-service=<nom>.
  • Journaliser (--set-log-denied=unicast) pendant la phase d'ouverture d'un service, désactiver ensuite pour garder le journal propre.
  • Sauvegarder /etc/firewalld/ — c'est la totalité de votre état permanent (fichiers XML, versionnables dans Git).

En cas d'erreur, trois niveaux de repli :

Fenêtre de terminal
# 1. Revenir au dernier permanent chargé (annule les modifs runtime)
sudo firewall-cmd --reload
# 2. Supprimer une règle runtime immédiatement
sudo firewall-cmd --zone=public --remove-service=<service>
sudo firewall-cmd --zone=public --remove-rich-rule='<règle exacte>'
# 3. Panic mode : bloque TOUT le trafic, entrant ET sortant
sudo firewall-cmd --panic-on
# une fois l'incident maîtrisé depuis la console de secours :
sudo firewall-cmd --panic-off

Pour un rollback complet de la configuration permanente, restaurez /etc/firewalld/ depuis votre sauvegarde (ou depuis /usr/lib/firewalld/ pour les zones officielles de la distribution) puis firewall-cmd --reload.

SymptômeCause probableAction
SSH coupé après --reloadService ssh retiré de la zone active, ou zone par défaut changéeConsole → firewall-cmd --zone=<active> --add-service=ssh puis --permanent
Règle visible mais inactiveAjoutée en --permanent sans --reloadfirewall-cmd --reload
Règle disparue au rebootAjoutée en runtime uniquementRejouer avec --permanent
Port ouvert mais service inaccessibleService écoute sur 127.0.0.1 ou mauvaise zone affectée à l'interfacess -tulpn côté serveur, firewall-cmd --get-active-zones
Paquets bloqués sans tracelog-denied désactivé (défaut)firewall-cmd --set-log-denied=unicast
Conflit avec UFW ou iptables manuelDeux gestionnaires actifs en même tempssystemctl disable --now ufw ; ne pas lancer de règles iptables directes
rich-rule non supprimée par --remove-rich-ruleLa chaîne doit correspondre exactement à celle ajoutéeCopier-coller depuis --list-rich-rules
  • Firewalld attache les interfaces à des zones, chaque zone porte ses propres services / ports / règles riches.
  • Runtime ≠ permanent. Sans --permanent, la règle est perdue au prochain --reload ou reboot.
  • firewall-cmd --reload rejoue la conf permanente ; il n'interrompt pas les connexions TCP établies.
  • Toujours autoriser SSH explicitement dans la zone active de l'interface d'admin avant tout changement profond.
  • Pour la plupart des besoins, --add-service=<nom> est plus lisible que --add-port=<n>/tcp.
  • Règles riches pour tout ce qui demande source, rate-limit ou journalisation par règle.
  • --set-log-denied=unicast est l'outil de dépannage n°1.
  • --panic-on existe pour l'incident ; jamais en config normale.
  • Sur Debian/Ubuntu, UFW suffit presque toujours ; Firewalld sur Red Hat, point.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn