Configurer le pare-feu UFW sans se bloquer l'accès SSH

Publié le 19 min de lecture

Le bon ordre des commandes pour monter UFW, les règles IPv6, nftables comme backend, la limitation de débit avec ufw limit et la voie de secours par la console quand cela tourne mal malgré tout.

Sur un serveur root, le filtrage de paquets n'est pas un luxe, c'est un équipement de base. UFW (Uncomplicated Firewall) rend l'exercice agréablement simple, mais possède une particularité qui enferme chaque année des milliers d'administrateurs hors de leur propre serveur : la commande qui arme le pare-feu est aussi celle qui peut couper la session SSH en cours. Ce guide montre l'ordre des opérations qui évite ce scénario et, presque plus important encore, le chemin du retour si cela arrive quand même.

Toutes les indications valent pour Debian 13 (trixie), Debian 12 (bookworm), Ubuntu 24.04 LTS et Ubuntu 22.04 LTS. Les commandes sont écrites pour une exécution en tant que root. Si vous travaillez avec un compte utilisateur normal, faites précéder chaque commande de sudo.

Pourquoi l'ordre des opérations décide de tout

L'erreur classique se déroule ainsi : on règle d'abord la politique par défaut sur « rejeter tout le trafic entrant », on active le pare-feu, puis on se dit qu'on ajoutera tranquillement la règle SSH ensuite. C'est exactement dans cet intervalle que le serveur cesse d'être joignable.

La raison pour laquelle cette erreur passe si souvent inaperçue est plus sournoise que l'erreur elle-même. UFW livre dans /etc/ufw/before.rules une règle qui laisse passer les connexions déjà établies :

-A ufw-before-input -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

Votre session SSH actuelle est justement une connexion établie. Elle survit donc à l'activation du pare-feu, même lorsqu'aucune règle SSH n'existe. L'invite reste là, tout semble en ordre. Seule la tentative de connexion suivante, typiquement votre login du lendemain matin, part en timeout. D'où la règle : tant que le pare-feu n'a pas été vérifié avec une seconde session nouvellement établie, ne quittez pas la première.

Règle empirique : d'abord autoriser, ensuite rejeter, ensuite activer, ensuite vérifier avec une seconde session, et seulement après fermer la première.

Avant la première commande : voie de secours et état des lieux

Avant de modifier quoi que ce soit au filtrage de paquets, clarifiez deux points.

1. Comment accéder au serveur sans SSH ?

Sur les serveurs root KVM et les serveurs dédiés de KernelHost, la console VNC est accessible directement dans l'espace client. Cette console ne dépend pas de la pile réseau du système invité, mais de la couche de virtualisation ou du raccordement réseau lui-même. Une règle de pare-feu à l'intérieur de l'invité ne peut donc pas la bloquer. Connectez-vous une fois avant via cette console et assurez-vous de connaître le mot de passe root. Une voie de secours que l'on essaie pour la première fois en pleine urgence n'est pas une voie de secours.

2. Qu'est-ce qui écoute réellement sur ce serveur ?

Des règles pour des services inexistants sont inoffensives. En revanche, un service que vous avez oublié vous coûte l'accès ou une panne. Commencez par faire l'inventaire :

ss -lntup

La colonne Local Address:Port distingue proprement 0.0.0.0:22 (IPv4 uniquement), [::]:22 (IPv6 et, via la socket dual-stack, le plus souvent IPv4 également) et 127.0.0.1:3306 (local uniquement, aucune règle de pare-feu nécessaire). Tout ce qui est lié à 127.0.0.1 ou ::1 n'a pas besoin d'être ouvert.

Le point le plus important reste le port SSH réellement utilisé. Ne le devinez pas, vérifiez-le. La commande a besoin des droits de lecture sur les clés d'hôte et s'exécute donc en tant que root ou avec sudo :

sudo sshd -T | grep -i "^port "

Un détail que beaucoup de tutoriels passent sous silence : sous Ubuntu 24.04, le service SSH est démarré par activation de socket via ssh.socket, et non via ssh.service. Sur ce système, systemctl is-enabled ssh.socket renvoie enabled et ssh.service renvoie disabled. Sur Debian 12, Debian 13 et Ubuntu 22.04, c'est exactement l'inverse : le service permanent classique s'applique.

La conséquence est ici désagréablement concrète : sous Ubuntu 24.04, le port annoncé par sshd -T n'est pas forcément celui sur lequel le système écoute vraiment. Ce qui fait foi, c'est ListenStream dans /lib/systemd/system/ssh.socket ou dans un fichier complémentaire sous /etc/systemd/system/ssh.socket.d/. Si vous avez changé votre port SSH et que vous vous fiez à sshd -T, vous ouvrez le mauvais numéro de port dans UFW et vous vous bloquez à la connexion suivante. Sur les quatre systèmes, seule l'observation du processus qui écoute réellement est fiable :

sudo ss -lntp | grep sshd

3. L'interrupteur homme mort

Au cas où quelque chose tournerait mal, mettez en place avant la modification risquée une minuterie qui désactive d'elle-même le pare-feu au bout de dix minutes :

nohup sh -c 'sleep 600; ufw disable' >/dev/null 2>&1 &

Si tout a fonctionné, annulez-la :

pkill -f 'sleep 600; ufw disable'

Le pkill ne touche que le processus shell englobant. Le sleep continue en orphelin et se termine sans conséquence, puisqu'il ne reste plus personne pour appeler ensuite ufw disable.

L'ordre des opérations qui ne vous enferme pas dehors

Sous Debian, UFW n'est en général pas préinstallé ; sous Ubuntu Server, il l'est le plus souvent. Lancer l'installation ne fait de mal dans aucun cas :

apt-get update
apt-get install -y ufw
ufw version

Voici maintenant l'ordre à respecter, exactement dans cette forme :

ufw allow 22/tcp comment 'SSH'
ufw default deny incoming
ufw default allow outgoing
ufw --force enable

Quatre remarques à ce sujet :

  • La règle d'autorisation vient avant tout le reste. UFW accepte les règles même à l'état inactif et les enregistre dans /etc/ufw/user.rules. Elles sont donc immédiatement en place au moment de l'activation.
  • À la place de 22/tcp, vous pouvez utiliser un profil applicatif, par exemple ufw allow OpenSSH. Ne vous y fiez toutefois pas aveuglément : les profils ne viennent pas d'UFW lui-même, mais des paquets installés. Sous Ubuntu, /etc/ufw/applications.d/ reste vide tant qu'aucun service n'est installé, et ufw app list n'affiche alors que l'en-tête Available applications:, sans la moindre entrée. Sous Debian, le paquet ufw fournit à lui seul environ 38 profils, et le profil SSH s'y appelle SSH. Le profil OpenSSH provient sur les deux distributions du paquet openssh-server, donc du cas normal sur un serveur. Avec un port SSH différent, le profil tombe de toute façon à côté. Pour savoir quels profils votre système connaît, utilisez ufw app list ; la notation par port ufw allow 22/tcp, elle, fonctionne de façon identique sur les quatre systèmes et constitue donc le choix le plus fiable.
  • ufw enable demande une confirmation interactive : Command may disrupt existing ssh connections. Proceed with operation (y|n)?. Dans les scripts et les rôles Ansible, utilisez ufw --force enable, sinon l'exécution reste bloquée.
  • Le texte placé derrière comment apparaît dans ufw status. Sans lui, dans six mois, vous ne saurez plus pourquoi le port 8443 est ouvert.

Les autres services s'ajoutent ensuite, par exemple un serveur web :

ufw allow 80/tcp comment 'HTTP'
ufw allow 443/tcp comment 'HTTPS'

Et c'est seulement maintenant que vous ouvrez un second terminal pour vous reconnecter. L'affaire n'est réglée que lorsque cette connexion aboutit.

IPv6 : la deuxième famille d'adresses que l'on oublie

Tout serveur moderne dispose d'IPv6, le plus souvent sans que personne ne l'ait configuré activement. Si vous ne pensez qu'à IPv4, vous obtenez au final un pare-feu qui règle exactement la moitié du trafic et laisse passer l'autre moitié. Vérifiez d'abord si des adresses IPv6 globales sont seulement configurées :

ip -6 addr show scope global

Bonne nouvelle : sur les quatre distributions traitées ici, /etc/default/ufw contient IPV6=yes d'origine. UFW maintient alors en parallèle une règle IPv6 pour chaque règle IPv4. Vérifiez plutôt que de faire confiance :

grep '^IPV6' /etc/default/ufw

Une deuxième preuve, plus solide, est la politique par défaut de la chaîne IPv6 elle-même :

ip6tables -L INPUT -n

La première ligne doit indiquer Chain INPUT (policy DROP). Si vous y lisez policy ACCEPT sans aucune chaîne ufw en dessous, votre serveur est entièrement ouvert en IPv6, quelle que soit la qualité de vos règles IPv4.

Deux pièges :

  • Une modification de IPV6 dans /etc/default/ufw ne prend pas effet avec ufw reload. Il faut ufw disable suivi de ufw enable. Pendant ce court intervalle, vous n'avez plus de pare-feu du tout : ne faites donc pas cela à la légère sur un système exposé.
  • Bloquer ICMPv6 en bloc revient à détruire sa propre connectivité. Neighbor Discovery et « Packet too big » ne sont pas optionnels en IPv6, ils font partie du protocole. UFW autorise déjà les types nécessaires dans /etc/ufw/before6.rules. Ne touchez à ce fichier que si vous savez précisément ce que vous faites.

Lorsqu'une règle par port a été correctement créée dans les deux familles d'adresses, UFW affiche deux lignes à l'ajout : Rule added et Rule added (v6). Si la seconde ligne manque, la moitié de la protection manque aussi. Les règles restreintes à une source font exception : avec ufw allow from 203.0.113.10 to any port 22 proto tcp, seul Rule added apparaît, et c'est normal, car une adresse source IPv4 n'a pas d'équivalent IPv6.

Ce qu'UFW écrit réellement : nftables comme backend

Le sujet charrie beaucoup d'idées reçues. La situation est pourtant uniforme sur Debian 12, Debian 13, Ubuntu 22.04 et Ubuntu 24.04 : UFW parle toujours la syntaxe iptables, mais la commande iptables est sur les quatre systèmes l'outil de compatibilité iptables-nft. Les règles atterrissent donc dans le sous-système nftables du noyau. La preuve en une ligne :

iptables -V

La sortie se termine par (nf_tables). Si vous y lisez (legacy), votre système travaille avec l'ancien backend. Cela fonctionne, mais des règles issues de deux mondes différents cohabitent alors dans le noyau et se masquent mutuellement. Pour savoir quelle variante est active, utilisez update-alternatives --display iptables.

Vu du côté nftables, cela donne ceci. Point important : ne regardez qu'après avoir activé le pare-feu :

apt-get install -y nftables
nft list tables

Tant qu'UFW n'est pas actif, la table n'existe tout simplement pas : iptables-nft ne la crée qu'au moment où des règles sont réellement chargées, donc au plus tôt avec ufw --force enable. Avant cela, nft list tables reste vide et un nft list table ip filter s'interrompt avec Error: No such file or directory. Ce n'est pas un défaut, c'est l'état attendu. Ce n'est qu'une fois table ip filter et table ip6 filter présentes dans la liste qu'il vaut la peine de regarder à l'intérieur :

nft list table ip filter

La sortie commence par la ligne Warning: table ip filter is managed by iptables-nft, do not touch!, et il faut la prendre au pied de la lettre : regarder oui, modifier à la main non. En dessous, vous trouverez des chaînes comme ufw-before-input, ufw-user-input et ufw-after-input. C'est ici qu'apparaît le conflit le plus important : ne mélangez pas UFW et des règles nft écrites à la main. Un nft flush ruleset supprime toutes les règles UFW du noyau sans qu'UFW s'en aperçoive. ufw status continue ensuite d'annoncer Status: active alors qu'en réalité plus aucune règle ne s'applique. C'est l'une des sources d'erreur les plus désagréables qui soient, car l'outil avec lequel vous vérifiez vous ment. Le chemin du retour :

ufw reload

Après chaque intervention touchant à d'autres outils de pare-feu (Docker, Kubernetes, logiciels VPN, iptables-persistent), ne vérifiez donc pas le statut UFW, mais le jeu de règles réellement chargé dans le noyau.

ufw limit contre le brute force, et là où il s'arrête

Pour SSH, UFW propose une limitation de débit :

ufw limit 22/tcp comment 'SSH rate limit'

La sémantique est clairement définie dans le manuel : les connexions sont autorisées normalement, mais rejetées dès qu'une même adresse IP source ouvre six nouvelles connexions ou plus en 30 secondes. Ces valeurs sont figées et ne se modifient pas depuis l'interface d'UFW. En coulisses, le mécanisme repose sur le module recent, visible dans iptables -S. Pour IPv6, UFW crée une règle équivalente si le module noyau est disponible, ce qui est le cas sur les quatre distributions.

Si vous aviez déjà posé ufw allow 22/tcp auparavant, une seconde règle vient s'ajouter. L'ancienne doit disparaître, sinon elle s'applique en premier et la limitation ne sert à rien :

ufw status numbered
ufw delete allow 22/tcp

Si vous préférez supprimer par numéro (ufw delete 3), retenez deux particularités. Premièrement, ufw status numbered numérote les règles IPv4 et IPv6 en continu dans une seule liste, et après chaque suppression, tous les numéros suivants se décalent. Ne supprimez donc jamais qu'une règle à la fois, réaffichez la liste ensuite, ou travaillez du numéro le plus élevé vers le plus bas. Deuxièmement, UFW demande à cette occasion une confirmation interactive : Proceed with operation (y|n)?.

Et maintenant, la mise en perspective honnête qui manque dans la plupart des tutoriels :

  • Cela ne sert à rien contre les attaques distribuées. Le comptage se fait par adresse IP source. Un botnet disposant de mille adresses effectue cinq tentatives par adresse et reste sous le seuil.
  • Cela touche vos propres automatismes. Un script de sauvegarde enchaînant de nombreux appels rsync, une exécution Ansible avec plusieurs forks ou un job CI peuvent heurter la même limite. Vous ne bloquez alors pas l'attaquant, mais votre propre pipeline de déploiement. Pour de telles sources, placez plutôt une exception explicite en amont, par exemple ufw allow from 203.0.113.10 to any port 22 proto tcp avec l'adresse réelle de votre serveur de build.
  • Cela ne remplace pas une configuration SSH propre. La mesure la plus efficace contre la devinette de mots de passe consiste à désactiver les mots de passe : PasswordAuthentication no dans /etc/ssh/sshd_config ou dans un fichier sous /etc/ssh/sshd_config.d/. Un serveur qui n'accepte aucun mot de passe n'en laisse deviner aucun. En complément, fail2ban a du sens : contrairement à ufw limit, il réagit aux entrées de journal et bannit plus longtemps.

Comment savoir que cela a vraiment fonctionné

« La commande s'est exécutée sans erreur » ne prouve rien. Quatre vérifications qui, elles, disent quelque chose :

Premièrement, l'état général.

ufw status verbose

La sortie attendue se présente sous cette forme :

Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22/tcp                     LIMIT IN    Anywhere
22/tcp (v6)                LIMIT IN    Anywhere (v6)

L'élément décisif est la deuxième ligne, avec la mention (v6). Sans elle, la couverture IPv6 manque.

Deuxièmement, le redémarrage. Un pare-feu qui ne survit pas à un redémarrage ne vaut rien.

systemctl is-enabled ufw

La réponse doit être enabled. Redémarrez ensuite réellement le serveur une fois et reconnectez-vous. C'est le seul test qui réponde vraiment à la question.

Troisièmement, le regard depuis l'extérieur. Depuis un autre hôte, vérifiez qu'un port volontairement laissé fermé l'est bien, par exemple avec nc -zv VOTRE-IP 3306. Important : un test depuis localhost ne prouve rien du tout, car UFW laisse par principe passer le trafic qui transite par l'interface loopback.

Quatrièmement, les journaux. Il existe ici une vraie différence entre les distributions. Dans son réglage par défaut low, UFW consigne les paquets bloqués via le journal du noyau. Sous Ubuntu 22.04 et 24.04, rsyslog est présent et les messages atterrissent en plus dans /var/log/ufw.log. Sous Debian 12 et tout particulièrement sous Debian 13, rsyslog manque dans les installations minimales et ce fichier n'existe tout simplement pas. La méthode qui fonctionne partout :

journalctl -k -n 50

Ce que vous cherchez, ce sont les lignes commençant par [UFW BLOCK]. Si vous voulez en voir davantage, montez le niveau (ufw logging medium), puis revenez ensuite à ufw logging low. Sur un serveur exposé au public, le niveau supérieur remplit le disque plus vite qu'on ne le croit.

Les messages d'erreur, mot pour mot

ERROR: problem running ufw-init : la cause la plus fréquente est un conflit avec un second outil de pare-feu, le plus souvent nftables.service ou iptables-persistent, ou encore un mélange des backends legacy et nft. Vérifiez iptables -V et désactivez les services concurrents. UFW fournit par ailleurs un script de test qui passe en revue les prérequis du noyau un par un et indique quelle exigence de module échoue.

ERROR: Could not find a profile matching 'OpenSSH' : le profil applicatif manque, parce qu'openssh-server n'est pas installé ou que le fichier sous /etc/ufw/applications.d/ a été supprimé. Sous Ubuntu, ce répertoire est de toute façon vide tant qu'aucun service n'est installé. Utilisez le numéro de port à la place.

ERROR: Bad port : le plus souvent une faute de frappe ou un nom de service que /etc/services ne connaît pas. Les numéros de port, eux, sont toujours sans ambiguïté.

Skipping adding existing rule ou Skipping adding existing rule (v6) : ce n'est pas un message d'erreur, mais l'indication que la règle existe déjà. Si vous croyez avoir modifié une règle et qu'elle reste inchangée, voilà la raison.

ERROR: Invalid position '0' : pour la suppression comme pour l'insertion, UFW compte à partir de 1, pas de 0. Les numéros proviennent de ufw status numbered et se décalent après chaque suppression. Supprimez donc toujours en partant du numéro le plus élevé.

WARN: Rules updated but not applied : la règle est bien dans la configuration, mais le pare-feu est inactif. Il manque un ufw enable.

Les différences entre distributions en un coup d'œil

  • Debian 13 (trixie) : UFW à installer soi-même. Backend nf_tables. IPV6=yes d'origine. rsyslog absent des installations minimales, journaux à consulter via journalctl -k. SSH via ssh.service.
  • Debian 12 (bookworm) : UFW à installer soi-même. Backend nf_tables. IPV6=yes d'origine. rsyslog présent selon la variante d'installation, /var/log/ufw.log n'est donc pas garanti. SSH via ssh.service.
  • Ubuntu 24.04 LTS : UFW présent sur les images serveur, mais inactif. Backend nf_tables. IPV6=yes d'origine. /var/log/ufw.log présent. SSH par activation de socket via ssh.socket : vérifiez donc toujours le port en écoute avec sudo ss -lntp | grep sshd et non avec sshd -T.
  • Ubuntu 22.04 LTS : UFW présent sur les images serveur, mais inactif. Backend nf_tables. IPV6=yes d'origine. /var/log/ufw.log présent. SSH via ssh.service.

Ce qui est identique sur les quatre systèmes : après l'installation, UFW est toujours inactif. Personne n'active le pare-feu à votre insu, et personne ne le désactive en douce.

Docker contourne UFW

Si Docker tourne sur le serveur, une restriction importante s'applique : les ports publiés des conteneurs (containers) ignorent vos règles UFW. Docker crée ses propres chaînes et travaille avec de la traduction d'adresse de destination, si bien que les paquets passent à côté des chaînes UFW dans INPUT. Un docker run -p 8080:80 est donc joignable depuis l'extérieur, alors même que ufw status affiche un propre « deny incoming ».

La contre-mesure la plus simple et la plus robuste consiste à ne pas publier sur toutes les adresses, mais uniquement en local, et à faire passer les accès par un reverse proxy :

docker run -d -p 127.0.0.1:8080:80 nginx

Dans un fichier Compose, cela correspond à l'indication de port "127.0.0.1:8080:80". Il existe aussi la possibilité d'accrocher ses propres règles UFW dans la chaîne DOCKER-USER réservée par Docker. C'est efficace, mais coûteux en maintenance et à revérifier à chaque mise à jour de Docker. La liaison sur 127.0.0.1 règle le problème à la racine.

Si vous êtes malgré tout enfermé dehors

C'est arrivé, SSH ne répond plus. Dans l'ordre :

  1. Ne redémarrez pas. Un redémarrage n'aide en rien, car UFW est activé comme service systemd et restaure ses règles au démarrage. Le serveur revient exactement aussi fermé qu'il s'est arrêté.
  2. Ouvrez la console VNC dans l'espace client et connectez-vous en tant que root.
  3. Désactivez le pare-feu : ufw disable. Vous revenez ainsi dans la partie, mais aussi sans protection.
  4. Cherchez la cause, ne la devinez pas. Regardez ufw status numbered ainsi que le port SSH réel donné par ss -lntup. Dans neuf cas sur dix, la cause est l'une de ces trois : il n'y a jamais eu de règle d'autorisation pour SSH, la règle porte sur le port 22 alors que sshd écoute sur un autre port, ou l'ouverture était limitée à une adresse IP que votre accès n'a plus (attribution dynamique d'adresse chez le fournisseur d'accès).
  5. Corrigez, puis réactivez, cette fois dans le bon ordre et avec l'interrupteur homme mort en place.

Si vous voulez remettre entièrement le jeu de règles à zéro, il existe ufw reset. À savoir : cette commande désactive le pare-feu et dépose des copies de sauvegarde des anciens fichiers de règles sous /etc/ufw/, avec un horodatage dans le nom de fichier. En cas de doute, vous pouvez donc relire ce qui s'appliquait avant. Ne l'exécutez jamais via une connexion SSH sans avoir la console ouverte à côté.

Une configuration de départ raisonnable

Pour un serveur web typique, la séquence complète ressemble à ceci :

apt-get update
apt-get install -y ufw
ufw default deny incoming
ufw default allow outgoing
ufw limit 22/tcp comment 'SSH rate limit'
ufw allow 80/tcp comment 'HTTP'
ufw allow 443/tcp comment 'HTTPS'
ufw --force enable
ufw status verbose

Notez qu'ici default deny incoming figure certes avant la règle SSH, mais que l'activation intervient tout à la fin. Tant qu'UFW est inactif, la politique par défaut ne fait aucun dégât. Seul compte l'état au moment du enable, et à cet instant la règle SSH est enregistrée depuis longtemps.

Si vous voulez en plus rendre les accès d'administration joignables uniquement depuis votre propre réseau, travaillez avec des règles restreintes à une source, sur le modèle ufw allow from 203.0.113.0/24 to any port 22 proto tcp. Plus propre encore : ne pas exposer du tout les services d'administration sur le réseau ouvert et les rendre accessibles via un VPN. Une instance WireGuard s'installe en quelques minutes sur chacun des quatre systèmes et remplace toute une pile d'exceptions de pare-feu par un unique port UDP ouvert.

Et pour finir, une mise en perspective qu'il faut avoir en tête : UFW filtre sur le serveur lui-même. Contre les attaques volumétriques qui saturent le raccordement, cela n'aide pas par principe, car les paquets ont déjà traversé la liaison au moment où votre noyau les rejette. Il faut pour cela un filtrage dans le réseau en amont. Chez KernelHost, c'est l'infrastructure en amont du datacenter maincubes à Francfort-sur-le-Main qui s'en charge, avec un filtrage Arbor en temps réel. Votre pare-feu local et la protection réseau résolvent deux problèmes différents, et vous avez besoin des deux.

Questions fréquentes

« ufw enable » me coupe-t-il aussitôt ma session SSH en cours ?
Non, et c'est précisément là qu'est le piège. Dans /etc/ufw/before.rules, UFW autorise les connexions déjà établies (état RELATED,ESTABLISHED). Votre session actuelle survit donc à l'activation, même si aucune règle SSH n'existe. Seule la tentative de connexion suivante échoue. Vérifiez donc toujours avec une seconde session nouvellement établie avant de fermer la première.
Dois-je activer IPv6 séparément dans UFW ?
Sur Debian 13, Debian 12, Ubuntu 24.04 et Ubuntu 22.04, IPV6=yes figure déjà d'origine dans /etc/default/ufw. UFW crée alors automatiquement un équivalent IPv6 pour chaque règle, reconnaissable au message « Rule added (v6) » et à la mention « (v6) » dans ufw status. Pour en avoir le cœur net, utilisez ip6tables -L INPUT -n : la sortie doit indiquer « policy DROP ». Une modification de IPV6 ne prend effet qu'après ufw disable suivi de ufw enable, un ufw reload ne suffit pas.
UFW utilise-t-il iptables ou nftables ?
Les deux, en un certain sens. UFW parle toujours la syntaxe iptables, mais la commande iptables est sur les quatre distributions la couche de compatibilité iptables-nft. Les règles atterrissent donc dans le sous-système nftables du noyau et sont visibles, pare-feu actif, avec nft list table ip filter. Tant qu'UFW n'est pas activé, cette table n'existe pas du tout et la commande renvoie « Error: No such file or directory ». Le backend se vérifie avec iptables -V, la sortie se termine par (nf_tables). Ne mélangez pas UFW et des règles nft écrites à la main : un nft flush ruleset supprime toutes les règles UFW, tandis que ufw status continue d'annoncer « active ».
Que fait exactement ufw limit ?
ufw limit autorise les connexions normalement, mais les rejette dès qu'une même adresse IP source ouvre six nouvelles connexions ou plus en 30 secondes. Ces valeurs sont figées et ne se modifient pas depuis l'interface d'UFW. Cela n'aide pas contre les attaques distribuées, puisque le comptage se fait par adresse IP source. Cela peut en outre toucher vos propres automatismes, par exemple des scripts de sauvegarde ou des jobs CI qui ouvrent de nombreuses connexions SSH en parallèle. Pour de telles sources, placez une exception explicite en amont.
Je n'arrive plus à joindre le serveur en SSH. Un redémarrage aide-t-il ?
Non. UFW est activé comme service systemd et restaure ses règles au démarrage, le serveur revient tout aussi fermé. Utilisez plutôt la console VNC dans l'espace client, connectez-vous en tant que root et exécutez ufw disable. Cherchez ensuite la cause : règle SSH manquante, mauvais port, ou restriction de source sur une adresse IP que votre accès n'a plus.
Pourquoi mes conteneurs Docker sont-ils joignables depuis l'extérieur malgré un pare-feu UFW actif ?
Docker crée ses propres chaînes et travaille avec de la traduction d'adresse de destination, si bien que les ports de conteneurs publiés passent à côté des chaînes UFW. Le « deny incoming » ne s'applique pas à ce trafic. La solution la plus robuste consiste à ne publier les ports qu'en local, donc -p 127.0.0.1:8080:80 au lieu de -p 8080:80, et à faire passer les accès par un reverse proxy.
Pourquoi /var/log/ufw.log n'existe-t-il pas sur mon serveur Debian ?
Parce que rsyslog n'y est pas installé. Debian 13 ne livre plus de démon syslog dans les installations minimales et s'appuie sur systemd-journald ; sur Debian 12, cela dépend également de la variante d'installation. Les messages sont malgré tout présents, vous les lisez avec journalctl -k en cherchant les lignes contenant [UFW BLOCK]. Sous Ubuntu 22.04 et 24.04, rsyslog est présent et le fichier existe.

UFW Firewall Linux Debian Ubuntu nftables IPv6 SSH Serversicherheit Root Server