footer-logofooter-logo
Des règles de pare-feu par défaut raisonnables pour un serveur LinuxRetour

Des règles de pare-feu par défaut raisonnables pour un serveur Linux

Un serveur Linux fraîchement installé ne possède aucune règle de pare-feu. Chaque listener que vous démarrez devient instantanément accessible depuis l'ensemble d'Internet. La solution est une base courte et bien comprise : default-deny en entrée, autoriser le trafic established, et une allow-list explicite pour les services que vous faites réellement tourner. Ce guide construit cette base dans nftables règle par règle, explique les points que tout le monde rate (ICMP et IPv6), montre la même politique dans ufw et firewalld, et explique comment éviter de vous verrouiller vous-même dehors, ainsi que le piège de la publication de ports Docker.

08 juillet 2026

par Jesse Schokker

Firewall

nftables

Security

Linux

Loading...

La réponse d'abord : la philosophie des trois règles

Tout bon pare-feu de serveur repose sur les trois mêmes décisions ; une fois que vous les avez intégrées, le reste n'est que détail :

  1. Default-deny en entrée. La politique pour le trafic entrant est drop. Tout ce qui n'est pas explicitement autorisé n'atteint jamais un service, y compris le service que vous aviez oublié faire tourner.
  2. Autorisez le trafic established et related. Les réponses aux connexions initiées par votre serveur, ainsi que la moitié retour des connexions que vous avez acceptées, circulent librement. Cette seule règle avec état est ce qui rend le default-deny praticable.
  3. Placez explicitement vos services sur l'allow-list. SSH, vos ports web, et rien d'autre, jusqu'à ce qu'autre chose ait véritablement besoin d'être joignable.

Le trafic sortant reste default-allow sur la plupart des serveurs ; le filtrage sortant a de réels usages, mais c'est une étape de durcissement facultative, pas un élément d'une configuration par défaut raisonnable (nous y reviendrons vers la fin).

C'est important, car une installation neuve ne vous donne rien de tout cela. Debian et Ubuntu sont livrées sans aucune règle de pare-feu active ; chaque daemon qui se lie à 0.0.0.0 est exposé à Internet dès son démarrage, et des études sur les honeypots montrent que les premières sondes arrivent quelques minutes seulement après la mise en ligne d'une IP. Un pare-feu de base est l'affaire de dix minutes. Le voici.

Le jeu de règles de base, en nftables

nftables est le framework de pare-feu natif de toutes les grandes distributions actuelles (la commande iptables sur un système moderne est en réalité une couche de compatibilité au-dessus de nftables), et une seule table inet couvre IPv4 et IPv6 ensemble, ce qui élimine d'emblée l'erreur de pare-feu la plus courante. Enregistrez ceci sous /etc/nftables.conf :

#!/usr/sbin/nft -f
flush ruleset

table inet filter {
  chain input {
    type filter hook input priority filter; policy drop;

    # 1. Loopback is always fine
    iif "lo" accept

    # 2. The stateful core: replies and related traffic
    ct state established,related accept
    ct state invalid drop

    # 3. ICMP — the minimum the internet needs to work
    icmp type { echo-request, destination-unreachable, time-exceeded, parameter-problem } accept
    icmpv6 type { echo-request, destination-unreachable, packet-too-big, time-exceeded, parameter-problem,
                  nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept

    # 4. Your services — the explicit allow-list
    tcp dport 22 accept comment "SSH"
    tcp dport { 80, 443 } accept comment "HTTP/HTTPS"
    udp dport 443 accept comment "HTTP/3 (remove if unused)"

    # 5. Optional: see what you're dropping, without flooding the log
    limit rate 5/minute log prefix "input drop: "
  }

  chain forward {
    type filter hook forward priority filter; policy drop;
  }

  chain output {
    type filter hook output priority filter; policy accept;
  }
}

Appliquez-le avec nft -f /etc/nftables.conf et rendez-le persistant avec systemctl enable nftables. (Sur Debian et Ubuntu, le paquet nftables relie exactement ce fichier à ce service.)

Voici maintenant le raisonnement, règle par règle.

Règle 1 : le loopback

D'innombrables composants d'un système Linux se parlent à eux-mêmes via 127.0.0.1 et ::1 : résolveurs, bases de données, agents de métriques. Accepter lo sans condition est sûr (le trafic loopback ne vient jamais du câble), et l'oublier produit, sous une politique drop, des pannes déconcertantes.

Règle 2 : le cœur avec état

ct state established,related accept est la règle qui fait l'essentiel du travail. Le connection tracking (conntrack) se souvient de chaque flux que le pare-feu a approuvé ; cette règle laisse passer le reste de chaque conversation approuvée sans réévaluer l'allow-list à chaque paquet. related couvre les protocoles qui génèrent légitimement des flux secondaires (une erreur ICMP au sujet de votre connexion, les canaux de données FTP).

ct state invalid drop élimine les paquets qui n'appartiennent à aucun flux connu et ne peuvent pas non plus démarrer un nouveau flux valide : ACK égarés hors fenêtre, trafic parasite de scanners en plein milieu d'une connexion, restes d'attaques. Les rejeter tôt est une hygiène gratuite.

Une réserve honnête s'impose : conntrack lui-même constitue un état, et un état peut s'épuiser ; c'est exactement ce que ciblent les attaques DDoS par famille de protocole. Pour un serveur normal, les valeurs par défaut plus les SYN cookies suffisent ; si vous faites tourner un service à très fort taux de connexions, augmenter net.netfilter.nf_conntrack_max a sa place sur votre liste de réglages.

Règle 3 : ICMP, bien fait

Le morceau de folklore du pare-feu le plus tenace est « bloquez le ping, bloquez ICMP, c'est plus sûr ». Ce n'est pas le cas ; cela casse le plan de contrôle d'Internet :

  • destination-unreachable (et, à l'intérieur, le fragmentation-needed d'IPv4) est ce qui fait fonctionner Path MTU Discovery. Rejetez-le, et les connexions passant par un chemin à MTU plus petit (VPN, tunnels, certains transits) se bloquent mystérieusement lors de gros transferts, le classique bug « SSH fonctionne mais SCP se bloque ».
  • packet-too-big est l'équivalent IPv6, et IPv6 est plus strict : les routeurs ne fragmentent jamais en IPv6, donc PMTUD est obligatoire. Rejeter ICMPv6 en bloc casse IPv6, un point c'est tout.
  • Le neighbour discovery (nd-neighbor-solicit, nd-neighbor-advert, nd-router-advert) est l'ARP d'IPv6. Rejetez-le, et votre serveur perd sa passerelle par défaut dès que le cache de voisinage expire.
  • echo-request (le ping) mérite d'être autorisé sur un serveur : cela ne coûte pratiquement rien (votre adresse est de toute façon détectable par les scanners) et vous voudrez pinguer votre propre machine en plein débogage. Si les inondations de ping vous inquiètent, limitez leur débit (icmp type echo-request limit rate 10/second accept) plutôt que de les rejeter.

La base ci-dessus autorise exactement les messages de contrôle dont les protocoles ont besoin, et rien d'autre : pas de timestamps, pas de redirects, pas de router solicitations dont vous n'avez pas besoin en entrée.

Règle 4 : l'allow-list

Cette section devrait être un inventaire précis de ce à quoi le serveur sert. Deux habitudes la maintiennent honnête :

  • Ajoutez un comment à chaque règle. Dans six mois, tcp dport 8472 accept comment "flannel VXLAN" est de la documentation ; un simple numéro de port est de l'archéologie.
  • Quand un service est interne, dites-le dans la règle. Si PostgreSQL ne doit être joignable que depuis vos serveurs applicatifs sur un réseau privé, codez-le : ip saddr 10.0.0.0/24 tcp dport 5432 accept, pas un simple allow sur le port 5432. (Les adresses ici et plus bas sont des plages de documentation ; remplacez-les par les vôtres.)

Règle 5 : journaliser les rejets

Journaliser tous les rejets sur un serveur exposé à Internet remplit le disque en continu ; les scans en arrière-plan sont permanents. L'échantillon limit rate 5/minute vous donne assez dans journalctl -k pour repérer des motifs (et déboguer les moments « pourquoi je ne peux pas joindre mon nouveau service » : si vous voyez le rejet journalisé, le pare-feu est votre problème) sans le bruit.

La moitié oubliée : la parité IPv6

Le mode d'échec historique : un jeu de règles iptables soigné pour IPv4, et ip6tables jamais touché, laissant chaque service grand ouvert en IPv6 sur les machines dual-stack. Les études de cette époque trouvaient régulièrement une exposition v6 dont les gens ignoraient l'existence.

La base ci-dessus est immunisée par construction : une table nftables de type inet applique chaque règle aux deux familles à la fois, et les règles ICMPv6 donnent à v6 exactement les messages de contrôle dont il a besoin. Si vous utilisez ufw ou firewalld à la place, les deux gèrent aussi v6 aux côtés de v4 par défaut. La règle empirique survit à tout choix d'outillage : chaque décision de pare-feu que vous prenez doit valoir pour les deux familles d'adresses. Si votre serveur possède un enregistrement AAAA, testez vos services en v6 après avoir appliqué les règles, pas seulement en v4.

Limiter le débit de SSH (et la place de fail2ban)

Le port 22 recevra des tentatives de brute-force indéfiniment ; avec une authentification par clé uniquement, ces tentatives ne sont que du bruit, mais les limiter à peu de frais reste utile. nftables peut faire de la limitation de débit par source nativement grâce à un set dynamique. Remplacez la règle SSH simple par :

    set ssh_ratelimit {
      type ipv4_addr
      flags dynamic
      timeout 10m
    }
    set ssh_ratelimit6 {
      type ipv6_addr
      flags dynamic
      timeout 10m
    }

    tcp dport 22 ct state new add @ssh_ratelimit { ip saddr limit rate 4/minute } accept comment "SSH v4, per-IP throttle"
    tcp dport 22 ct state new add @ssh_ratelimit6 { ip6 saddr limit rate 4/minute } accept comment "SSH v6, per-IP throttle"

Chaque adresse source obtient quatre nouvelles connexions SSH par minute ; la cinquième est rejetée silencieusement jusqu'à ce que son débit redescende. Ceci ignore l'intention (impossible de distinguer une connexion échouée d'une réussie), c'est pourquoi fail2ban reste complémentaire : il lit le journal d'authentification et bannit les adresses qui échouent réellement à s'authentifier. Limiter le débit dans le pare-feu, bannir sur preuve avec fail2ban, et exiger des clés ; cette combinaison met fin au problème de bruit SSH.

La même base dans ufw et firewalld

Si la convention de votre distribution est un frontend, utilisez ce frontend ; mélanger des règles écrites à la main avec les règles d'un frontend est exactement ce qui transforme les pare-feu en archéologie. La même politique :

ufw (le frontend par défaut d'Ubuntu ; il pilote iptables sous le capot, ce qui aboutit à nftables via la couche de compatibilité) :

ufw default deny incoming
ufw default allow outgoing
ufw limit 22/tcp comment 'SSH, rate-limited'
ufw allow 80/tcp
ufw allow 443
ufw enable

ufw limit applique une limitation anti-brute-force intégrée (six connexions en trente secondes par source). ufw gère pour vous le loopback, conntrack et des valeurs ICMP par défaut sensées.

firewalld (le défaut de la famille RHEL, basé sur nftables depuis 2018) :

firewall-cmd --set-default-zone=public
firewall-cmd --permanent --zone=public --add-service=ssh
firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
firewall-cmd --reload

firewalld raisonne en zones et en services plutôt qu'en règles ; la zone public est en default-deny avec les services listés ouverts, et ICMP est géré intelligemment dès l'installation.

Comment éviter de vous verrouiller dehors

Les changements de pare-feu sur un serveur distant sont la panne auto-infligée classique. Les habitudes qui les rendent ennuyeux :

  • Vérifiez la syntaxe avant d'appliquer : nft -c -f /etc/nftables.conf valide le fichier sans le charger.
  • Planifiez un rollback automatique avant tout changement risqué, puis annulez-le une fois que vous avez confirmé que vous avez toujours accès :
# revert to the known-good ruleset in 3 minutes unless cancelled
systemd-run --on-active=3m --unit=fw-rollback nft -f /etc/nftables.known-good
# ...apply your change, confirm SSH still works, then cancel the rollback:
systemctl stop fw-rollback.timer

Et gardez une deuxième session SSH ouverte pendant toute l'opération ; n'enregistrez le nouveau jeu de règles comme known-good qu'après la réussite d'une connexion fraîche.

  • Ne testez jamais un changement de politique default-drop sans accès out-of-band. Sur un serveur dédié, cela signifie un accès console KVM-over-IP/IPMI (inclus sur nos serveurs), ce qui transforme un verrouillage d'un incident en une correction de deux minutes.
  • L'ordre compte moins dans nftables que vous ne le craignez, mais la règle accept-established doit précéder vos rejets, et tout le fichier est appliqué atomiquement par nft -f, si bien qu'un jeu de règles à moitié chargé ne peut pas vous bloquer comme le pouvaient historiquement des commandes iptables séquentielles.

Docker contourne ufw et votre chaîne input

Si vous faites tourner Docker avec des ports publiés (-p 8080:80), sachez ceci : Docker programme directement les règles NAT et de forwarding du noyau, et les ports publiés contournent entièrement ufw et votre chaîne input. Votre pare-feu soigneusement configuré en default-deny ne s'applique pas aux conteneurs publiés via -p ; le trafic est redirigé avant même que votre chaîne input ne le voie. C'est un comportement documenté de longue date, pas un bug qui sera corrigé dans la prochaine version (le backend nftables natif de Docker Engine 29 est expérimental et ne change rien à la sémantique).

Les solutions reconnues :

  • Liez les ports que vous ne voulez pas publics à localhost ou à une adresse privée : -p 127.0.0.1:8080:80 ou -p 10.0.0.5:5432:5432.
  • Placez vos restrictions dans la chaîne DOCKER-USER, que Docker garantit d'évaluer avant ses propres règles : c'est le point d'accroche officiellement pris en charge pour « mettre un pare-feu sur mes conteneurs ».
  • Traitez tout -p avec un port nu comme si « c'est désormais sur Internet », car c'est exactement le cas.

Filtrage sortant : quand cela en vaut la peine

Une politique de sortie default-accept est le bon réglage par défaut : les serveurs parlent légitimement en sortie à des miroirs de paquets, au DNS, au NTP, à des API et à la supervision. Le filtrage sortant justifie sa complexité dans des situations précises : régimes de conformité exigeant un contrôle de l'egress, serveurs traitant des entrées non fiables où vous voulez limiter les reverse shells et l'exfiltration de données, et machines à usage unique dont le profil de trafic complet est connaissable (un serveur de base de données n'a aucune raison d'ouvrir des connexions vers des hôtes Internet arbitraires).

Si vous l'adoptez, procédez comme pour l'entrée : recensez ce dont le serveur a besoin (DNS vers vos résolveurs, 80/443 vers des miroirs, votre endpoint de supervision), autorisez-les, mettez le reste en default-drop, et journalisez les rejets pendant une semaine avant de les appliquer ; le journal vous apprendra ce que vous avez oublié.

Questions fréquentes

Faut-il utiliser nftables directement, ou plutôt ufw ou firewalld ?

Suivez la convention de votre distribution et les habitudes de votre parc. Sur Debian, nftables natif est propre et parfaitement pris en charge ; sur Ubuntu, ufw est la voie éprouvée ; sur RHEL/AlmaLinux/Rocky, firewalld est l'interface prise en charge et la documentation le suppose. Les trois produisent au final des règles nftables dans le noyau. Le seul véritable anti-pattern consiste à mélanger les couches : ajouter des règles nft à la main sur une machine gérée par firewalld aboutit à des règles qui disparaissent au rechargement.

Bloquer le ping est-il une bonne mesure de sécurité ?

Non. L'existence de votre serveur n'est pas cachée par le rejet des echo requests (les scanners trouvent les hôtes actifs par bien d'autres moyens), et vous perdez un outil de diagnostic de base dont vous aurez vous-même besoin. Pire, ceux qui cherchent à « bloquer le ping » bloquent en général tout ICMP et cassent au passage Path MTU Discovery et le neighbour discovery IPv6. Autorisez echo-request (avec limitation de débit si vous préférez) ainsi que les messages d'erreur et de contrôle ; rejetez le reste.

Ces règles me protègent-elles des attaques DDoS ?

Partiellement, et il est important de préciser quelle partie. Un jeu de règles default-deny réduit la surface d'attaque (le trafic parasite visant des ports fermés meurt à faible coût) et les limitations de débit atténuent les petites inondations de connexions. Mais aucune règle sur l'hôte n'aide une fois qu'une attaque sature votre lien montant ; les paquets ont déjà traversé le lien derrière lequel vos règles s'exécutent. Les attaques volumétriques sont arrêtées en amont, ou pas du tout, ce pourquoi notre réseau place une mitigation DDoS permanente et un pare-feu de périphérie en libre-service devant votre port.

J'ai appliqué un pare-feu et quelque chose s'est cassé. Comment déboguer ?

Vérifiez d'abord le journal des rejets : journalctl -k | grep "input drop" (avec la règle de journalisation de la base). Si le trafic cassé y apparaît, il vous manque une règle allow. Notez le port et le protocole depuis la ligne de journal. S'il n'apparaît pas, le pare-feu n'est pas votre problème ; regardez le binding du service (ss -tlnp) et, pour les hôtes joignables en IPv6, vérifiez que vous avez testé la même famille d'adresses que celle qui échoue.

Déploiement chez Serverside

Sur nos serveurs dédiés, le jeu de règles sur l'hôte présenté dans ce guide n'est que l'une des deux couches de pare-feu : chaque serveur reçoit aussi un pare-feu en libre-service en périphérie du réseau, si bien que le trafic vers des ports que vous ne servez jamais est rejeté en amont avant même de toucher votre machine, en plus d'une mitigation DDoS permanente sur notre réseau ASN 55285. Et si un changement de pare-feu venait un jour à vous verrouiller dehors, l'accès console KVM-over-IP inclus signifie que la récupération prend des minutes, pas un ticket de support. Le provisioning prend moins d'une minute pour Ubuntu, Debian, AlmaLinux/Rocky, RHEL et plus.

À suivre dans cette série : le choix de votre outillage de règles dans iptables vs nftables, le tableau de la menace au sens large dans les attaques DDoS expliquées, et comment identifier ce qui frappe réellement votre serveur dans capturer et analyser un DDoS avec Wireshark.

Jesse Schokker

Écrit par

Jesse Schokker

Co-founder & CTO, Serverside.com

Jesse is the co-founder and CTO of Serverside.com, where he leads the engineering behind the company's bare-metal cloud: from the ASN 55285 backbone to the core automation that drives day-to-day operation. He writes about dedicated servers, operating systems, and running production workloads on bare metal.

Continuer la lecture

Voir tous les articles