VPN sur Ubuntu/Debian : erreurs UFW/nftables qui vous verrouillent (et correctifs)

Cet article vous a aidé ?

Vous activez un VPN, votre session SSH se fige, et votre serveur de production devient un presse-papier très coûteux.
Quelque part entre les abstractions « utiles » d’UFW et le filtrage sans fard de nftables, vous venez de
couper votre propre ligne de vie avec le pare-feu.

C’est un guide de terrain pour les vrais modes de défaillance : surprises de routage, erreurs de suivi d’état, lacunes sur le trafic
routé, et le classique « j’ai autorisé le port VPN, alors pourquoi rien ne marche ? ». Nous diagnostiquerons rapidement,
corrigerons précisément, et vous éviterons d’apprendre ces leçons à 3h du matin.

Le modèle mental : ce qui change quand un VPN se lève

Un VPN n’est pas « une application qui chiffre le trafic ». Sur Linux, c’est un ensemble d’interfaces réseau, de routes, de règles de pare-feu,
et souvent de modifications de DNS. Quand il se connecte, il fait généralement trois choses qui peuvent vous planter :

  1. Il crée une nouvelle interface (par exemple wg0, tun0) qui devient le nouveau chemin pour une partie ou la totalité du trafic.
    Si votre pare-feu est spécifique à une interface (nombreux le sont), vous venez de déplacer le trafic sous vos règles existantes.
  2. Il modifie le routage (route par défaut, routage par politique, ou routes par préfixe). Vos paquets de réponse peuvent sortir par une interface différente
    de celle par laquelle la requête est arrivée. Conntrack ne vous sauvera pas d’un routage asymétrique si vous vous shootez volontairement dans le genou.
  3. Il change les besoins en traduction d’adresses (NAT/masquerade) lorsque le trafic est routé via la machine ou quand le VPN attribue
    des adresses inconnues des routeurs en amont.

UFW et nftables ne « comprennent » pas les VPN. Ils comprennent les paquets, les interfaces, les états et les routes. Si vous
configurez un VPN puis espérez que le pare-feu « s’en charge », vous jouez l’accès à vos machines sur de l’optimisme.

Vérité sèche : la plupart des verrouillages ne sont pas causés par une règle unique fautive. Ils résultent d’une règle correcte appliquée à
la mauvaise interface ou à la mauvaise direction (INPUT vs OUTPUT vs FORWARD), combinée à une route que vous n’avez pas remarqué être remplacée.

Faits intéressants et contexte historique (pour que les bizarreries aient du sens)

  • iptables était la valeur par défaut pendant des années, mais nftables en est le remplaçant moderne ; de nombreux systèmes Ubuntu/Debian exécutent désormais
    des commandes iptables via le backend nft sans que vous le réalisiez.
  • UFW est une interface conçue à l’origine pour rendre iptables accessible ; elle n’expose pas toutes les subtilités du filtrage de paquets,
    notamment autour du routage par politique et du forwarding complexe.
  • Conntrack (suivi d’état) est un sous-système du noyau qui se souvient des flux. Si vous oubliez d’autoriser ESTABLISHED,RELATED,
    vous bloquerez les réponses même si le paquet entrant initial était permis.
  • WireGuard n’est « que du UDP » avec une interface noyau et un routage basé sur les clés. Il n’utilise pas de canal de contrôle séparé comme
    beaucoup de VPNs plus anciens, ce qui change l’aspect de ce qui est « trafic autorisé ».
  • OpenVPN utilise souvent un dispositif tun/tap et peut pousser des routes et du DNS. Si vous acceptez la route par défaut poussée, vous pouvez facilement
    faire sortir les réponses SSH dans le tunnel par erreur.
  • Le filtrage par chemin inverse (rp_filter) est une fonctionnalité anti-usurpation du noyau qui peut abandonner des paquets quand les routes paraissent asymétriques —
    exactement ce que certains montages VPN créent intentionnellement.
  • Le routage par politique Linux (ip rule) existe depuis des décennies. Les clients VPN l’utilisent de plus en plus pour le split tunneling, ce qui signifie
    que votre « route par défaut » ne raconte peut-être pas toute l’histoire.
  • Le comportement « kill switch » (bloquer le trafic hors VPN) est essentiellement une décision de politique de pare-feu, pas une fonctionnalité VPN. Beaucoup de clients
    l’implémentent avec des règles faciles à malconfigurer.

Playbook de diagnostic rapide

Quand vous perdez la connectivité après l’activation d’un VPN (ou que le trafic s’arrête mystérieusement), vous n’avez pas de temps pour un
débat philosophique sur les pare-feux. Vérifiez ces éléments dans l’ordre, car chaque étape réduit rapidement le périmètre du problème.

Première étape : le routage a-t-il changé sous vos pieds ?

  • Consultez la route par défaut et les règles de politique (ip route, ip rule).
  • Confirmez quelle interface votre IP source SSH utilise pour vous atteindre (ip route get).
  • Décidez : problème de routage ou de pare-feu ? Si les réponses sortent par la mauvaise interface, corrigez le routage en premier.

Deuxième étape : bloquez-vous sur INPUT/OUTPUT ou FORWARD ?

  • Vérifiez le statut d’UFW et les politiques par défaut (ufw status verbose).
  • Vérifiez le jeu de règles nftables et les compteurs de chaînes (nft list ruleset).
  • Décidez : le verrouillage est généralement sur INPUT/OUTPUT ; « le VPN fonctionne mais le LAN derrière le serveur ne fonctionne pas » est généralement FORWARD/NAT.

Troisième étape : la gestion de l’état/conntrack est-elle correcte ?

  • Vérifiez que l’acceptation established/related existe dans les bonnes chaînes.
  • Recherchez des règles « drop invalid » trop agressives.
  • Décidez : si les réponses sont bloquées, vous verrez des SYN arriver mais pas de SYN-ACK partir.

Quatrième étape : rp_filter ou sysctl bloque-t-il des chemins asymétriques ?

  • Vérifiez les paramètres rp_filter et ajustez-les pour les cas d’usage VPN.
  • Décidez : si des paquets arrivent mais sont abandonnés avant que les compteurs du pare-feu n’augmentent, suspectez rp_filter.

Cinquième étape : confirmez avec une capture de paquets, pas des impressions

  • Exécutez tcpdump sur la NIC physique et sur l’interface VPN simultanément.
  • Décidez : si les paquets entrent mais ne sortent pas, c’est le pare-feu/routage. S’ils n’entrent jamais, problème en amont/réseau.

Tâches pratiques (commandes, sorties, décisions)

Voici les exercices exacts que j’exécute sur Ubuntu/Debian quand quelqu’un dit « le VPN a tué la machine ». Chaque tâche inclut
ce que la sortie signifie habituellement et la décision à en tirer. Exécutez-les depuis la console, un accès hors-bande,
ou une session SSH existante avant de toucher quoi que ce soit d’autre.

Tâche 1 : Identifier les interfaces et ce qui est apparu avec le VPN

cr0x@server:~$ ip -brief link
lo               UNKNOWN        00:00:00:00:00:00 <LOOPBACK,UP,LOWER_UP>
ens3             UP             52:54:00:12:34:56 <BROADCAST,MULTICAST,UP,LOWER_UP>
wg0              UNKNOWN        3a:2b:1c:0d:ee:ff <POINTOPOINT,NOARP,UP,LOWER_UP>

Signification : Vous avez une NIC physique (ens3) et une interface WireGuard (wg0).
Beaucoup de verrouillages arrivent parce que les règles s’appliquent uniquement à ens3.
Décision : Si une nouvelle interface existe, auditez les règles du pare-feu pour le périmètre d’interface (iifname/oifname, règles de route UFW).

Tâche 2 : Vérifier les adresses IP pour voir quels réseaux sont impliqués

cr0x@server:~$ ip -brief addr
lo               UNKNOWN        127.0.0.1/8 ::1/128
ens3             UP             203.0.113.10/24 2001:db8:10::10/64
wg0              UNKNOWN        10.6.0.2/32

Signification : IP publique sur ens3, adresse VPN sur wg0.
Notez le /32 sur WireGuard — courant et acceptable, mais cela change les attentes de routage/NAT.
Décision : Si vous prévoyez de router d’autres sous-réseaux via cet hôte, vous aurez besoin de routes explicites et souvent de NAT.

Tâche 3 : Trouver la route par défaut et si elle a basculé dans le VPN

cr0x@server:~$ ip route show
default dev wg0 scope link
203.0.113.0/24 dev ens3 proto kernel scope link src 203.0.113.10
10.6.0.0/24 dev wg0 proto kernel scope link src 10.6.0.2

Signification : La route par défaut passe maintenant par wg0. C’est une configuration full-tunnel.
Si votre client SSH se connecte à 203.0.113.10, la requête arrive via ens3, mais vos réponses peuvent tenter de sortir via wg0.
Décision : Si c’est un serveur administré à distance, n’acceptez pas le routage full-tunnel sauf si vous avez explicitement épinglé les réponses SSH
ou autorisé le chemin. Envisagez le split tunnel ou le routage par politique pour le trafic de gestion.

Tâche 4 : Vérifier les règles de routage par politique (le split tunnel se trouve souvent ici)

cr0x@server:~$ ip rule show
0:      from all lookup local
32764:  from all fwmark 0xca6c lookup 51820
32766:  from all lookup main
32767:  from all lookup default

Signification : Certains paquets sont marqués (fwmark 0xca6c) et utilisent une table de routage spéciale. C’est typique des setups WireGuard « wg-quick »
pour le routage par politique ou les modes kill switch.
Décision : Si vous voyez des marques/règles que vous n’avez pas ajoutées, inspectez les hooks PostUp/PreDown du client VPN ou les unités systemd.
Votre pare-feu doit autoriser le trafic marqué à sortir par la bonne interface, sinon vous créez des trous noirs.

Tâche 5 : Confirmer quelle route le noyau utilisera pour votre IP d’administration

cr0x@server:~$ ip route get 198.51.100.25
198.51.100.25 dev wg0 src 10.6.0.2 uid 0
    cache

Signification : Les réponses vers l’IP de votre poste d’administration sortiraient via wg0 avec la source 10.6.0.2.
C’est la signature classique de « SSH meurt après activation du VPN ».
Décision : Ajoutez une route vers l’hôte ou une règle de politique pour que le trafic de gestion retourne via ens3, ou évitez le full-tunnel sur les serveurs.

Tâche 6 : Vérifier le statut d’UFW, les valeurs par défaut et si le forwarding est autorisé

cr0x@server:~$ sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip

To                         Action      From
22/tcp                     ALLOW IN    198.51.100.0/24
51820/udp                  ALLOW IN    Anywhere

Signification : Le routage/routé est désactivé. Cela casse les configurations « le serveur route le LAN via le VPN ».
Aussi, SSH n’est autorisé que depuis un sous-réseau spécifique ; si votre IP source change quand vous vous connectez via un VPN ou un bastion, vous pouvez vous retrouver verrouillé.
Décision : Si vous avez besoin de forwarding, activez la politique routée et ajoutez des règles ufw route allow explicites. Si vous avez besoin d’un accès admin résilient,
gardez au moins un chemin de gestion sûr (console, IP secondaire, ou une allowlist plus large avec MFA).

Tâche 7 : Voir ce qu’UFW a réellement généré (les « before rules » sont là où la magie opère)

cr0x@server:~$ sudo grep -nE 'DEFAULT_FORWARD_POLICY|ufw-before-input|ufw-before-output|wg0|tun0' /etc/default/ufw /etc/ufw/before.rules
/etc/default/ufw:9:DEFAULT_FORWARD_POLICY="DROP"
/etc/ufw/before.rules:20:*filter
/etc/ufw/before.rules:28:-A ufw-before-input -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

Signification : La politique de forwarding est DROP. Conntrack established est présent (bon point).
Décision : Si vous comptez router du trafic via cet hôte, changez DEFAULT_FORWARD_POLICY et ajoutez des règles de route étroites
plutôt que de tout rendre permissif.

Tâche 8 : Vérifier le jeu de règles nftables et les politiques de chaînes (Ubuntu peut utiliser nft en dessous)

cr0x@server:~$ sudo nft list ruleset
table inet filter {
  chain input {
    type filter hook input priority filter; policy drop;
    ct state established,related accept
    iifname "lo" accept
    tcp dport 22 ip saddr 198.51.100.0/24 accept
    udp dport 51820 accept
    counter drop
  }
  chain forward {
    type filter hook forward priority filter; policy drop;
  }
  chain output {
    type filter hook output priority filter; policy accept;
  }
}

Signification : La politique d’entrée est DROP, la sortie est ACCEPT. Le forward est DROP. Si votre VPN nécessite du forwarding entre interfaces, cela échouera.
Notez aussi que SSH est restreint par IP source ; le VPN peut modifier ce que « source » signifie.
Décision : Ne modifiez pas les règles à l’aveugle. Confirmez d’abord si le flux cassé est INPUT, OUTPUT ou FORWARD, puis ajoutez l’acceptation la plus ciblée possible.

Tâche 9 : Regarder les compteurs de règles pour voir ce qui est droppé

cr0x@server:~$ sudo nft -a list chain inet filter input
table inet filter {
  chain input {
    type filter hook input priority filter; policy drop;
    ct state established,related accept
    iifname "lo" accept
    tcp dport 22 ip saddr 198.51.100.0/24 accept
    udp dport 51820 accept
    counter packets 41 bytes 2460 drop # handle 12
  }
}

Signification : Le compteur de drop augmente. Des paquets arrivent et sont écartés par la politique par défaut ou la règle finale de drop.
Décision : Ajoutez un journal temporaire pour les drops, ou autorisez temporairement depuis votre source actuelle pour reprendre l’accès, puis resserrez.

Tâche 10 : Confirmer si rp_filter abandonne les paquets avant qu’ils n’atteignent le pare-feu

cr0x@server:~$ sysctl net.ipv4.conf.all.rp_filter net.ipv4.conf.ens3.rp_filter net.ipv4.conf.wg0.rp_filter
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.ens3.rp_filter = 1
net.ipv4.conf.wg0.rp_filter = 1

Signification : Un filtrage inverse strict est activé. Avec un routage asymétrique (commun avec VPN + accès public), Linux peut abandonner
des paquets parce que le « meilleur chemin de retour » ne correspond pas à l’interface d’arrivée.
Décision : Pour des passerelles multi-homed/VPN, définissez rp_filter à 2 (mode loose) sur les interfaces pertinentes, ou désactivez-le prudemment là où nécessaire.
Faites-le intentionnellement ; ne désactivez pas aveuglément les contrôles de sécurité sans comprendre la topologie.

Tâche 11 : Vérifier que le forwarding IP est activé quand vous attendez du routage

cr0x@server:~$ sysctl net.ipv4.ip_forward net.ipv6.conf.all.forwarding
net.ipv4.ip_forward = 0
net.ipv6.conf.all.forwarding = 0

Signification : L’hôte ne forwardera pas les paquets IPv4 ou IPv6. Même des règles de pare-feu parfaites ne le feront pas router.
Décision : Si cet hôte doit être une passerelle (LAN→VPN, site-à-site, etc.), activez le forwarding et persistez-le dans sysctl.

Tâche 12 : Vérifier s’il existe du NAT/masquerade pour le trafic sortant via le VPN

cr0x@server:~$ sudo nft list table ip nat
table ip nat {
  chain postrouting {
    type nat hook postrouting priority srcnat; policy accept;
  }
}

Signification : La table NAT existe mais n’a pas de règle de masquerade. Si vous routez un LAN privé via le VPN, l’autre côté peut ne pas savoir comment répondre.
Décision : Ajoutez une masquerade ciblée pour le réseau source LAN sortant via wg0 (ou mieux : ajoutez des routes côté distant si vous le contrôlez).

Tâche 13 : Utiliser tcpdump pour voir où le flux meurt

cr0x@server:~$ sudo tcpdump -ni ens3 tcp port 22 -c 5
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on ens3, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:01:03.101234 IP 198.51.100.25.53122 > 203.0.113.10.22: Flags [S], seq 1234567890, win 64240, options [mss 1460], length 0
12:01:04.104567 IP 198.51.100.25.53122 > 203.0.113.10.22: Flags [S], seq 1234567890, win 64240, options [mss 1460], length 0

Signification : Des SYN arrivent sur ens3. Si vous ne voyez pas de SYN-ACK sortir sur ens3, soit le pare-feu droppe en INPUT,
soit les réponses sont routées ailleurs.
Décision : Lancez tcpdump sur wg0 aussi. Si le SYN-ACK sort via wg0, vous avez un problème de routage/policy routing, pas un problème d’autorisation entrante.

Tâche 14 : Inspecter les unités systemd et les hooks PostUp du VPN qui modifient le pare-feu/routage

cr0x@server:~$ systemctl status wg-quick@wg0 --no-pager
● wg-quick@wg0.service - WireGuard via wg-quick(8) for wg0
     Loaded: loaded (/lib/systemd/system/wg-quick@.service; enabled; preset: enabled)
     Active: active (exited) since Fri 2025-12-27 11:59:12 UTC; 3min ago
       Docs: man:wg-quick(8)
             man:wg(8)
    Process: 1256 ExecStart=/usr/bin/wg-quick up wg0 (code=exited, status=0/SUCCESS)

Signification : wg-quick est en jeu. Il peut ajouter des routes, des ip rules, et des snippets nft/iptables selon votre config.
Décision : Revoyez /etc/wireguard/wg0.conf pour les commandes PostUp/PreDown et pour AllowedIPs qui pourraient détourner la route par défaut.

Tâche 15 : Valider la journalisation UFW et revoir les drops récents du noyau

cr0x@server:~$ sudo journalctl -k -g 'UFW BLOCK' -n 5 --no-pager
Dec 27 12:00:41 server kernel: [UFW BLOCK] IN=ens3 OUT= MAC=52:54:00:12:34:56 SRC=198.51.100.25 DST=203.0.113.10 LEN=60 TOS=0x00 PREC=0x00 TTL=51 ID=55233 DF PROTO=TCP SPT=53122 DPT=22 WINDOW=64240 SYN

Signification : UFW bloque explicitement l’SSH entrant depuis votre source actuelle. Ce n’est pas « le VPN qui a tout cassé » ; votre liste d’autorisation est désormais incorrecte.
Décision : Élargissez temporairement l’accès SSH depuis une plage sûre ou un jump host, reprenez le contrôle, puis repensez l’accès de gestion pour qu’il survive aux changements VPN.

Tâche 16 : Filet de sécurité d’urgence — planifier un rollback du pare-feu

cr0x@server:~$ echo "ufw disable" | sudo at now + 2 minutes
warning: commands will be executed using /bin/sh
job 7 at Fri Dec 27 12:04:00 2025

Signification : Vous avez programmé la désactivation automatique d’UFW dans 2 minutes. Si vous vous verrouillez, la machine finira par revenir.
Décision : Utilisez ceci avant d’appliquer des changements risqués sur des systèmes distants. Annulez le job une fois la connectivité vérifiée.

Blague #1 : Les pare-feux sont comme les ceintures de sécurité — jusqu’à ce que vous essayiez de sortir par la fenêtre pendant que la voiture roule.

Erreurs courantes : symptômes → cause racine → correctif

1) « SSH meurt immédiatement quand je monte le VPN »

Symptômes : La session SSH existante se fige ; nouvelles connexions SSH en timeout ; l’interface VPN s’active proprement.

Cause racine : La route par défaut a basculé vers wg0/tun0, donc les réponses SSH entrent dans le tunnel avec la mauvaise IP source ; ou rp_filter abandonne le trafic asymétrique.

Correctif : Épinglez les routes de gestion via l’interface publique ou utilisez le routage par politique pour que le trafic vers votre sous-réseau d’administration utilise ens3. Réglez rp_filter en mode loose là où c’est pertinent.

cr0x@server:~$ sudo ip route add 198.51.100.0/24 via 203.0.113.1 dev ens3
cr0x@server:~$ sudo sysctl -w net.ipv4.conf.ens3.rp_filter=2
net.ipv4.conf.ens3.rp_filter = 2

2) « Le VPN se connecte, mais rien n’atteint Internet »

Symptômes : Le tunnel est up ; le handshake fonctionne ; le DNS peut résoudre ; aucun trafic sortant ne passe.

Cause racine : Un kill switch ou une chaîne OUTPUT trop restrictive bloque tout sauf le port UDP du VPN. Commun avec des politiques « deny outgoing » par défaut qui n’ont pas listé le trafic wg0.

Correctif : Autorisez la sortie sur l’interface VPN, et gardez des règles OUTPUT stateful. Avec UFW, ajoutez des règles allow out explicites et vérifiez la sélection de la table de routage.

cr0x@server:~$ sudo ufw allow out on wg0
Rule added

3) « Le handshake WireGuard fonctionne, mais aucun trafic ne passe »

Symptômes : wg show affiche l’heure du dernier handshake mise à jour ; ping/ssh via le tunnel échouent.

Cause racine : Mismatch d’AllowedIPs, routes manquantes, ou pare-feu bloquant le FORWARD entre interfaces ; parfois problèmes MTU/PMTU mais commencez par les routes/règles.

Correctif : Vérifiez AllowedIPs et les routes ; autorisez le forwarding ; assurez-vous du NAT si nécessaire.

cr0x@server:~$ sudo wg show wg0
interface: wg0
  public key: 3m...redacted...9Q=
  listening port: 51820

peer: 8A...redacted...k=
  endpoint: 192.0.2.50:51820
  allowed ips: 10.6.0.0/24
  latest handshake: 1 minute, 4 seconds ago
  transfer: 92.14 KiB received, 88.22 KiB sent

4) « Mon serveur VPN fonctionne pour la machine elle-même, mais les clients n’atteignent pas le LAN derrière »

Symptômes : Le serveur peut ping via le tunnel ; les clients se connectent ; les clients ne peuvent pas atteindre les sous-réseaux internes.

Cause racine : Chaîne FORWARD par défaut en drop (UFW « routed disabled »), IP forwarding désactivé, masquerade manquant, ou routes manquantes côté LAN.

Correctif : Activez le forwarding IP ; définissez la politique de forwarding UFW ; ajoutez ufw route allow ; ajoutez NAT ciblé ou routes sur le routeur LAN.

5) « UFW dit qu’il autorise 51820/udp, mais le VPN ne se connecte toujours pas »

Symptômes : Le client ne peut pas handshake ; le serveur ne montre rien ; UFW a l’air « correct ».

Cause racine : La règle existe en IPv4 mais pas en IPv6 (ou l’inverse) ; le endpoint est en v6 ; ou nftables est actif avec un jeu de règles différent de ce que vous pensez.

Correctif : Vérifiez les adresses d’écoute ; contrôlez les deux familles ; confirmez le backend réel du pare-feu ; testez avec tcpdump sur la NIC.

6) « Tout fonctionne… jusqu’à ce que j’active UFW »

Symptômes : Le VPN va bien avec le pare-feu éteint ; casse quand le pare-feu est activé ; casse souvent le forwarding.

Cause racine : Valeurs par défaut d’UFW : le trafic routé est désactivé ; règles ufw route manquantes ; règles d’interface trop spécifiques ; absence d’autorisation pour l’interface VPN.

Correctif : Traitez le forwarding comme un produit séparé. Configurez DEFAULT_FORWARD_POLICY, ajoutez des règles de route explicites, et testez les flux de bout en bout.

7) « Le DNS casse uniquement quand le VPN est actif »

Symptômes : Vous pouvez pinguer des IP ; les noms d’hôtes ne se résolvent pas ; ou la résolution est lente/instable.

Cause racine : Le client VPN pousse du DNS ; systemd-resolved change l’amont ; le pare-feu bloque UDP/TCP 53 sur la mauvaise interface ; ou vous forcez tout dans le tunnel alors que le DNS est en dehors.

Correctif : Décidez où le DNS doit vivre (dans le VPN ou à l’extérieur). Autorisez-le explicitement et vérifiez resolvectl et le routage vers les serveurs DNS.

8) « Après avoir ajouté un ruleset nftables ‘simple’, UFW a cessé de fonctionner »

Symptômes : Les commandes UFW réussissent, mais le comportement ne correspond pas ; les compteurs ne bougent pas là où attendu.

Cause racine : Jeux de règles concurrents ou priorités de chaînes. UFW peut gérer ses propres tables/chains ; vos règles nft personnalisées peuvent les masquer ou s’appliquer plus tôt.

Correctif : Choisissez un seul contrôleur. Gérez nftables directement (et désactivez UFW), ou laissez UFW gérer le filtrage et n’ajoutez que des hooks pris en charge.

Trois mini-récits d’entreprise tirés du terrain

Mini-récit n°1 : L’incident causé par une mauvaise hypothèse

Une entreprise de taille moyenne exploitait une petite flotte de passerelles Ubuntu terminant des VPN site-à-site. Une équipe a ajouté WireGuard
pour remplacer un ancien OpenVPN. Le plan de migration semblait propre : monter wg0, autoriser UDP 51820 entrant,
et considérer l’affaire clos.

L’hypothèse erronée était subtile : « Si le handshake marche, le plan de données marchera. » Les handshakes fonctionnaient. Les
graphiques semblaient rassurants. Puis les utilisateurs internes ont commencé à se plaindre que seules certaines destinations étaient accessibles.
L’ingénieur d’astreinte a vu « latest handshake: 30 seconds ago » et a perdu du temps à chasser des fantômes MTU.

Le vrai problème était le forwarding. UFW avait routed désactivé. La machine elle-même pouvait atteindre les sous-réseaux distants parce que OUTPUT était autorisé,
mais les paquets du LAN étaient droppés en FORWARD. Le VPN n’était pas cassé ; la fonction de passerelle l’était.

Le correctif n’a pas été héroïque. Ils ont activé l’IP forwarding, mis à jour la politique de forwarding UFW, et ajouté des règles de route étroites :
uniquement le sous-réseau interne vers le sous-réseau VPN, uniquement via wg0. Soudain tout a fonctionné, et le récit « WireGuard est instable »
s’est éteint discrètement.

Mini-récit n°2 : L’optimisation qui s’est retournée contre eux

Une autre organisation a standardisé nftables et voulu des « règles propres et minimales ». Quelqu’un a réécrit le pare-feu du serveur comme un
unique ruleset policy drop avec seulement quelques acceptations : SSH, le port VPN, et established/related. Ils ont aussi
restreint OUTPUT à une whitelist parce que « les serveurs ne devraient pas parler à Internet ».

L’optimisation a été de supprimer ce qui semblait être des règles d’état redondantes et de compter sur le fait que « nous n’avons que peu de services ».
Cela a fonctionné en staging. En production, il y avait un petit twist : le client VPN utilisait le routage par politique et des fwmarks, et le résolveur DNS se situait en dehors du chemin VPN. Les drops en OUTPUT ont commencé à bloquer le DNS et les keepalives du VPN
d’une manière qui n’était pas évidente lors de la revue initiale des règles.

Le mode de défaillance n’était pas une panne totale ; c’était pire. Un comportement intermittent. Certaines requêtes réussissaient quand les caches
étaient chauds, puis échouaient quand les TTL expiraient. On a blâmé le fournisseur VPN, puis le DNS, puis « le réseau Linux ».
Classique.

Le correctif a été d’arrêter d’optimiser prématurément et de modéliser les flux. Ils ont créé des allowances OUTPUT explicites pour l’interface VPN,
pour le DNS vers les résolveurs sélectionnés, et pour NTP. Ils ont aussi ajouté des compteurs et de la journalisation pour le drop final, car un drop silencieux
est la recette d’un rapport d’incident d’une semaine.

Mini-récit n°3 : La pratique ennuyeuse mais correcte qui a sauvé la mise

Une équipe de services financiers maintenait des bastions Debian avec des politiques de pare-feu strictes et un VPN obligatoire pour l’accès admin.
Ils avaient une règle : tout changement de pare-feu/VPN doit inclure une minuterie de rollback automatisée et un plan d’accès hors-bande.
Personne n’aimait cette règle. Tout le monde en a profité.

Pendant une fenêtre de changement, un ingénieur a ajusté les règles UFW pour imposer un kill switch VPN. Le comportement attendu : autoriser
seulement le trafic sortant sur wg0, bloquer tout le reste. Ils ont appliqué le changement et ont immédiatement perdu leur session SSH.
Prévisible, mais toujours stressant.

Deux minutes plus tard, le rollback programmé s’est déclenché et UFW s’est désactivé. SSH est revenu. Pas d’appels paniqués au centre de données,
pas de « quelqu’un peut-il le redémarrer », pas d’éditions risquées via une session à moitié morte. Ils se sont reconnectés, ont corrigé l’exception
de routage pour le sous-réseau de gestion, et ont réessayé — cette fois avec des tests.

Pratique ennuyeuse, grosse récompense. Cela a aussi changé la culture d’équipe : les gens sont devenus plus disposés à améliorer la sécurité parce que
le plan de récupération supprimait la taxe de la peur.

Blague #2 : Le moyen le plus rapide de prouver que vous avez un pare-feu est de vous le démontrer accidentellement à vous-même.

Listes de contrôle / plan pas à pas (déploiements sûrs)

Checklist A : Avant d’activer un VPN sur un serveur distant

  1. Obtenez un chemin de récupération. Accès console, IPMI, console série cloud, ou au moins un second chemin SSH depuis un réseau différent.
  2. Programmez un rollback automatique. Utilisez at pour désactiver UFW ou restaurer nftables après 2–5 minutes.
  3. Snapshotter la configuration. Copiez /etc/ufw, les règles nft, et les configs VPN dans un endroit sûr.
  4. Notez vos IP sources de gestion. Si votre IP change à cause d’un VPN d’entreprise, votre allowlist vous trahira.
  5. Décidez full tunnel vs split tunnel. Les serveurs veulent rarement le full tunnel pour tout ; soyez explicite sur les exceptions.

Checklist B : Si vous avez besoin d’un kill switch VPN (et que vous avez toujours besoin de SSH)

  1. Autorisez l’SSH entrant sur l’interface physique depuis des plages de confiance.
  2. Autorisez les réponses de gestion sortantes via l’interface physique (routing par politique/routes hôtes).
  3. Autorisez la sortie sur l’interface VPN de façon large, puis restreignez les destinations si nécessaire.
  4. Gardez l’acceptation established,related dans INPUT/OUTPUT.
  5. Ajoutez journalisation/compteurs sur les drops finaux pour voir ce que vous avez cassé.

Checklist C : Si l’hôte est une passerelle VPN pour d’autres réseaux

  1. Activez net.ipv4.ip_forward=1 (et le forwarding IPv6 si utilisé).
  2. Décidez NAT vs sous-réseaux routés (privilégiez les routes si vous contrôlez les deux extrémités).
  3. Permettez explicitement les flux FORWARD (LAN → VPN, VPN → LAN selon besoin).
  4. Assurez-vous que le routage de retour existe des deux côtés (le NAT masque cela ; le routé le nécessite).
  5. Testez depuis un client derrière la passerelle, pas seulement depuis la passerelle elle-même.

Minuteur de rollback : annulez-le quand vous êtes sûr

cr0x@server:~$ atq
7	Fri Dec 27 12:04:00 2025 a root
cr0x@server:~$ sudo atrm 7

Signification : Vous supprimez le job de rollback programmé une fois que vous confirmez pouvoir vous reconnecter.
Décision : Ne l’annulez pas trop tôt. Attendez d’avoir testé depuis une session fraîche.

Schémas de travail : kill switch, split tunnel, routage côté serveur

Schéma 1 : Garder le trafic de gestion hors du VPN (recommandé pour les serveurs)

Si le serveur a une IP publique et que vous l’administrez par SSH, traitez la gestion comme un plan de contrôle séparé.
Ne la mettez pas dans un VPN full-tunnel sauf si vous êtes prêt à concevoir le routage précisément.

L’approche la plus simple et stable : le VPN gère le trafic applicatif ou des sous-réseaux spécifiques, mais les réponses SSH sortent toujours
par l’interface par laquelle SSH est entré.

Concrètement, cela signifie soit :
(a) ne changez pas la route par défaut quand le VPN monte ; ajoutez des routes spécifiques pour les destinations VPN ; ou
(b) utilisez le routage par politique pour que seul le trafic sélectionné utilise le VPN.

Schéma 2 : Un kill switch raisonnable qui ne tue pas votre accès

Un kill switch, c’est juste « dropper tout ce qui ne passe pas par wg0/tun0 ». Le point dangereux est que votre session SSH devient aussi « tout »
si vous n’extraire pas d’exceptions.

L’extraction correcte n’est pas « autoriser le port 22 ». C’est « garantir que les réponses à mes réseaux d’administration sont routées et passent via la bonne interface,
même quand la route par défaut est le VPN ». C’est routage plus filtrage, pas uniquement filtrage.

Schéma 3 : Passerelle VPN pour un LAN (forwarding + NAT ou routes)

C’est la zone où UFW surprend les gens. La posture par défaut d’UFW sur le trafic routé est conservatrice. C’est normal.
Mais si vous construisez une passerelle, vous devez configurer explicitement le forwarding.

Si vous ne contrôlez pas le routage de l’autre côté, le NAT est pragmatique. Si vous contrôlez les deux extrémités, les sous-réseaux routés sont plus propres.
Le NAT masque les IP sources ; le routé les préserve mais nécessite de vraies annonces/rentrées de route.

Activer le forwarding (de manière persistante)

cr0x@server:~$ sudo tee /etc/sysctl.d/99-vpn-forwarding.conf >/dev/null <<'EOF'
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
EOF
cr0x@server:~$ sudo sysctl --system
* Applying /etc/sysctl.d/99-vpn-forwarding.conf ...
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1

Signification : Le noyau forwardera désormais des paquets.
Décision : Ne faites cela que sur des hôtes destinés à router du trafic ; cela change la posture de sécurité.

UFW : autoriser le trafic routé entre LAN et VPN (exemple)

cr0x@server:~$ sudo ufw route allow in on ens3 out on wg0 from 192.168.50.0/24 to 0.0.0.0/0
Rule added
cr0x@server:~$ sudo ufw route allow in on wg0 out on ens3 from 0.0.0.0/0 to 192.168.50.0/24
Rule added

Signification : Vous avez permis le forwarding dans les deux sens pour ce sous-réseau LAN.
Décision : Resserrez les destinations si possible. « LAN vers n’importe où » convient pour la sortie Internet, mais pas pour le trafic est-ouest en réseau d’entreprise.

nftables : masquerade ciblé pour le LAN sortant sur wg0 (exemple)

cr0x@server:~$ sudo nft add table ip nat
cr0x@server:~$ sudo nft 'add chain ip nat postrouting { type nat hook postrouting priority srcnat; policy accept; }'
cr0x@server:~$ sudo nft add rule ip nat postrouting oifname "wg0" ip saddr 192.168.50.0/24 masquerade

Signification : Les clients LAN apparaîtront pour le côté distant comme l’IP de l’interface VPN, simplifiant le routage de retour.
Décision : Si vous avez besoin d’audit par hôte, préférez des sous-réseaux routés plutôt que le NAT.

Épingler le trafic de gestion avec le routage par politique (exemple)

Si le VPN insiste pour posséder la route par défaut, vous pouvez toujours garder la gestion stable en utilisant une table de routage séparée
pour le trafic vers vos réseaux d’administration.

cr0x@server:~$ echo "100 mgmt" | sudo tee -a /etc/iproute2/rt_tables
100 mgmt
cr0x@server:~$ sudo ip route add default via 203.0.113.1 dev ens3 table mgmt
cr0x@server:~$ sudo ip rule add to 198.51.100.0/24 lookup mgmt priority 1000

Signification : Le trafic destiné à votre sous-réseau d’administration utilise la passerelle physique, même si la table principale a une route par défaut pointant vers le VPN.
Décision : C’est l’approche adulte quand vous devez combiner full tunnel et administration distante.

Une citation fiabilité (idée paraphrasée)

« L’espoir n’est pas une stratégie. » — idée paraphrasée attribuée à la culture opérations/SRE (souvent utilisée en ingénierie de la fiabilité)

Cette phrase revient partout parce qu’elle s’applique douloureusement aux changements de pare-feu sur des machines distantes.

UFW vs nftables : choisissez votre poison, évitez de mélanger les métaphores

UFW : bien pour des politiques simples, dangereux si vous supposez qu’il couvre le forwarding par défaut

UFW est agréable quand vos besoins sont : autoriser SSH, autoriser quelques ports, refuser tout le reste. Il vous évite
d’écrire 200 lignes de règles pour une politique à 4 règles. C’est un gain.

Là où UFW brûle les ingénieurs, c’est sur le trafic routé et les chemins VPN basés sur interface. Si le système agit comme une passerelle,
vous devez raisonner sur FORWARD. UFW permet cela, mais ne vous oblige pas à y penser. C’est le piège.

nftables : pouvoir explicite, conséquences explicites

nftables est propre et expressif. Il fait aussi exactement ce que vous lui avez dit de faire, même si ce que vous lui avez dit provoque une panne auto-infligée. Avec nftables, vous devriez être à l’aise avec :

  • Les politiques de chaîne (policy drop signifie que vous avez besoin d’acceptations explicites).
  • La gestion d’état (ct state established,related n’est pas optionnelle dans la plupart des designs).
  • Le matching d’interface (iifname/oifname) — particulièrement avec des interfaces VPN.
  • Les compteurs et la journalisation (un drop silencieux est une usine à incidents).

Ne faites pas naviguer deux capitaines sur un même navire

Si UFW est actif et que vous chargez aussi un jeu de règles nftables personnalisé, vous pouvez vous retrouver avec des tables et priorités de chaînes qui se chevauchent.
Parfois cela fonctionne par accident. Ce n’est pas un design.

Choisissez-en un :
gardez UFW pour la politique, ou gérez nftables directement et désactivez UFW. Le mélange est la façon d’obtenir un jeu de règles qu’aucun astreint ne pourra expliquer.

Auditez qui possède réellement le filtrage de paquets sur votre hôte

cr0x@server:~$ sudo ufw status
Status: active
cr0x@server:~$ sudo systemctl is-active nftables
inactive
cr0x@server:~$ sudo update-alternatives --display iptables | sed -n '1,6p'
iptables - auto mode
  link best version is /usr/sbin/iptables-nft
  link currently points to /usr/sbin/iptables-nft
  link iptables is /usr/sbin/iptables

Signification : UFW est actif ; les commandes iptables pointent vers le backend nft. Même si nftables.service est inactive, nft peut être le moteur sous-jacent.
Décision : Lors du débogage, inspectez toujours nft list ruleset comme source de vérité sur les systèmes modernes.

FAQ

1) Pourquoi autoriser le port UDP du VPN n’a-t-il rien résolu ?

Parce que le port UDP ne couvre que le transport extérieur du tunnel. Votre vrai trafic passe par une interface différente
(wg0/tun0), touche des chaînes différentes (FORWARD/OUTPUT), et peut nécessiter NAT ou des routes.

2) Pourquoi SSH casse-t-il seulement après que le VPN change la route par défaut ?

Parce que les réponses suivent la table de routage. Si les réponses sortent via le VPN, l’IP source change et votre client ne l’accepte pas
(ou le chemin la droppe). Corrigez en épinglant les routes de gestion ou en utilisant le routage par politique.

3) Puis-je simplement définir UFW par défaut en autoriser la sortie et oublier ?

Sur un serveur de base, peut-être. Sur une passerelle VPN ou un setup kill-switch, non. Les restrictions OUTPUT interagissent avec le routage VPN,
le DNS et les keepalives d’une manière non triviale. Si vous restreignez OUTPUT, faites-le avec des allowances explicites et des compteurs.

4) Quelle est la manière la plus propre d’éviter les verrouillages pendant les changements de pare-feu ?

Programmez un timer de rollback (at now + 2 minutes), appliquez le changement, testez depuis une session fraîche, puis annulez le timer.
Gardez aussi un accès console si la machine est critique.

5) Pourquoi WireGuard montre des handshakes mais toujours pas de connectivité ?

Le succès du handshake prouve que les pairs peuvent échanger des clés via UDP. Cela ne prouve pas que vos routes, AllowedIPs, politique de forwarding,
ou NAT sont corrects. Traitez-le comme « le transport est vivant », pas comme « le réseau est fini ».

6) Ai-je besoin de NAT pour le trafic VPN ?

Si vous routez un LAN privé via le VPN et que l’autre côté n’a pas de route de retour vers ce LAN, le NAT est la solution pratique.
Si vous contrôlez les deux extrémités, préférez les routes et évitez le NAT pour une meilleure observabilité et moins de surprises.

7) Pourquoi l’IPv6 aggrave-t-il la situation ?

Parce que vous pouvez autoriser IPv4 et bloquer IPv6 (ou vice versa) par accident et le client choisira la famille qui « fonctionne ».
Ensuite ça casse. Auditez les sockets d’écoute et les règles de pare-feu pour les deux familles si IPv6 est activé.

8) Est-il sûr de désactiver rp_filter ?

rp_filter aide à prévenir l’usurpation. Le désactiver aveuglément est paresseux. Pour les passerelles VPN et le routage asymétrique, mettez-le en mode loose
(2) sur les interfaces concernées afin que le trafic asymétrique légitime ne soit pas abandonné.

9) Dois-je utiliser UFW ou nftables natif pour les systèmes VPN ?

Si le système est simple, UFW suffit. Si vous avez besoin de routage par politique, de forwarding complexe, de multiples VPNs ou de kill switches stricts,
nftables est généralement plus clair car vous pouvez exprimer l’intention précisément — à condition que votre équipe sache l’exploiter.

10) Quelle est l’erreur UFW la plus courante avec les passerelles VPN ?

Oublier que le trafic routé est désactivé par défaut. Vous pouvez autoriser le port VPN toute la journée ; le forwarding ne se produira toujours pas.
Corrigez en activant le forwarding et en ajoutant des règles ufw route allow.

Conclusion : prochaines étapes pour rester en ligne

Le thème récurrent est peu glamour : les VPN modifient le routage et les interfaces, et votre pare-feu se fiche de vos intentions.
Si vous traitez la « connectivité VPN » comme un problème d’ouverture de port, vous continuerez à vous verrouiller.

Prochaines étapes que je ferais réellement sur un hôte Ubuntu/Debian en production :

  1. Décidez si le serveur doit être full-tunnel ou split-tunnel. Si c’est un serveur administré à distance, partez par défaut sur le split-tunnel.
  2. Mettez en place l’habitude du timer de rollback pour chaque changement de pare-feu sur des systèmes distants.
  3. Auditez le routage (ip route, ip rule) et confirmez explicitement les chemins de retour de gestion.
  4. Choisissez une seule plane de contrôle du pare-feu (UFW ou nftables) et arrêtez de les mélanger à moins d’aimer l’archéologie.
  5. Ajoutez des compteurs/journaux à vos règles de drop pour que le débogage repose sur des preuves, pas sur des rituels.

Si vous ne faites qu’une seule chose : faites de ip route get votre réflexe avant et après le montage d’un VPN. Il vous dit où vos réponses iront.
C’est la différence entre « serveur sécurisé » et « serveur sécurisé mais injoignable ».

← Précédent
ZFS vs btrfs : où btrfs est agréable et où il pose problème
Suivant →
VPN + RDP/SSH : Accès distant sans ouvrir de ports sur Internet

Laisser un commentaire