Tout a l’air verrouillé. Votre scan IPv4 est propre. Le ticket de changement indique « pare‑feu activé ». Puis un client envoie une capture d’écran de votre invite de connexion — via IPv6. Ce n’est pas un manque théorique ; c’est réel, et ça se manifeste exactement quand vous ne le voulez pas : pendant des audits, des incidents ou une fenêtre de maintenance un dimanche matin.
Ubuntu 24.04 facilite l’état « demi‑protégé ». Pas parce que c’est cassé, mais parce que les paramètres par défaut, les couches d’outils et les réalités cloud créent le piège parfait du « je jure qu’on a bloqué ça ». Voici le guide pratique pour colmater la faille correctement — nftables, UFW, services et périphérie réseau — afin que dual‑stack signifie « sécurisé sur les deux stacks », et non « surprise, on a laissé une porte latérale ouverte ».
Ce qui cloche réellement : le motif d’« exposition fantôme » IPv6
Le mode de défaillance est ennuyeux et constant :
- Vous déployez des règles de pare‑feu qui bloquent clairement l’entrée IPv4.
- L’hôte possède une adresse IPv6 routable globalement (ou un /64 sur l’interface).
- Votre outil de pare‑feu n’applique soit pas les règles à IPv6, soit les applique différemment, soit est contourné par une autre couche.
- Un service se lie sur
::(toutes les interfaces IPv6), ce qui signifie souvent qu’il accepte aussi IPv4 via le mécanisme mapped IPv6 selon la configuration. - Vous testez depuis un point de vue IPv4 uniquement et déclarez victoire.
Ubuntu 24.04 est du « Linux moderne ». C’est bien. Mais cela veut aussi dire que netfilter est orienté nftables, UFW est une couche de compatibilité, iptables peut tourner via nft en coulisse, et les métadonnées cloud plus l’auto‑configuration peuvent ajouter des adresses inattendues. Si vous pensez seulement « iptables rules = pare‑feu », vous êtes déjà en retard.
Une petite plaisanterie rapide pour détendre : Un pare‑feu qui bloque IPv4 mais pas IPv6, c’est comme verrouiller la porte d’entrée et laisser le garage ouvert — sauf que le garage a un néon disant « nouveau protocole, qui es‑tu ».
Et : « désactiver IPv6 » n’est pas une stratégie. C’est un palliatif de dernier recours qui casse des choses réelles (mirroirs de paquets, CDN modernes, certains réseaux d’entreprise) et revient souvent plus tard avec un comportement encore plus étrange. Ce qu’il vous faut, c’est une politique : refuser par défaut l’entrée sur les deux stacks, autoriser explicitement ce dont vous avez besoin, valider depuis les deux stacks et appliquer à plus d’une couche.
Faits et contexte intéressants (parce que l’histoire se répète)
- IPv6 est standardisé depuis la fin des années 1990. Le protocole n’est pas nouveau ; ce sont les habitudes opérationnelles qui prennent du retard.
- Les premiers pare‑feu Linux ciblaient surtout iptables. Beaucoup d’équipes ont appris à travailler avec des tables IPv4 et ont traité IPv6 comme « plus tard ».
- IPv6 supprime NAT comme béquille par défaut. Avec l’adressage global, « c’est derrière du NAT donc c’est sûr » n’est plus une excuse.
- UFW s’appuyait historiquement sur iptables/ip6tables. À l’ère nftables, les couches de traduction peuvent surprendre si vous supposez « mêmes règles, même comportement ».
- Certaine outils de scan et contrôles de conformité ciblent encore par défaut IPv4. Vous pouvez réussir un rapport tout en étant largement exposé sur IPv6.
- La découverte de voisins IPv6 remplace ARP. Le trafic de plan de contrôle est différent, ce qui crée d’autres modes de défaillance si l’on bloque « l’ICMP bizarre ».
- ICMPv6 n’est pas optionnel. Le bloquer de façon indiscriminée casse la découverte de MTU de chemin et la connectivité de base de manières intermittentes et agréables.
- Dual‑stack est souvent « activé par accident ». Images cloud, routeurs qui annoncent des préfixes, ou DHCPv6 peuvent vous attribuer une adresse globalement joignable sans ticket.
- « Écouter sur :: » est un comportement par défaut courant. Beaucoup de démons se lient au wildcard IPv6 et deviennent accessibles en v6 même si vous n’avez testé que v4.
Un modèle mental correct : paquets, hooks et qui peut dire « deny »
Sur Ubuntu 24.04, « le pare‑feu » n’est pas une seule chose. C’est une chaîne :
- La périphérie réseau (security groups du cloud, ACL du routeur, pare‑feu on‑prem, écouteurs de load balancer).
- Le filtre de paquets du noyau hôte (jeu de règles nftables, potentiellement géré par UFW, firewalld, ou une automatisation personnalisée).
- L’acceptation locale (un service à l’écoute sur une socket, l’activation par systemd socket, et des ACL applicatives).
nftables est le moteur. UFW est un gestionnaire. Les commandes iptables peuvent être une façade de compatibilité qui écrit des règles nft. Vous pouvez avoir plusieurs gestionnaires, et ils peuvent se marcher sur les pieds. Si vous n’avez pas de chance, vous avez des règles pour IPv4, une politique vide pour IPv6, et un service sur ::. Voilà le film en entier.
Les gens fiabilité aiment citer une formule pour ça. En voici une qui tient la route, paraphrasée parce que la formulation exacte varie : paraphrased idea — « L’espérance n’est pas une stratégie. »
— souvent attribué aux cercles d’ingénierie et d’exploitation.
Appliquez cela au travail sur le pare‑feu : ne supposez pas que « UFW activé » implique « IPv6 bloqué ». Vérifiez le jeu de règles du noyau et faites une vérification avec un scan IPv6 externe.
Plan de diagnostic rapide
Si vous suspectez une exposition IPv6 sur Ubuntu 24.04, procédez dans cet ordre. Le but est de trouver rapidement le goulot d’étranglement (ou le contrôle manquant), pas de satisfaire la curiosité.
1) Confirmer que l’hôte est réellement joignable en IPv6
Première question : avez‑vous une adresse IPv6 globale ? Si oui, considérez‑la joignable sauf preuve du contraire. Si non, votre risque immédiat peut être moindre, mais ne vous relâchez pas — les interfaces et routes changent.
2) Identifier ce qui écoute sur IPv6
Trouvez les services liés à :: ou à des adresses v6 spécifiques. Les sockets en écoute sont le « pourquoi ». Les règles de pare‑feu sont le « comment ».
3) Inspecter le vrai jeu de règles (nftables), pas seulement l’état de l’outil
Le statut UFW est un indice. Le jeu de règles nftables est la vérité. Cherchez les chaînes et politiques ip6.
4) Vérifier l’application : compteurs, logs et une vraie sonde IPv6
Les compteurs vous disent si des règles correspondent. Une sonde depuis une autre machine vous dit si votre modèle mental est correct. « curl local » n’est pas un test de sécurité.
5) Vérifier les contrôles en périphérie (SG cloud / ACL routeur)
Si la périphérie autorise largement IPv6, votre pare‑feu hôte est votre dernier rempart. Si la périphérie bloque, le pare‑feu hôte reste nécessaire (mouvement latéral et trafic mal routé), mais votre exposition peut être contenue.
Tâches pratiques (commandes, sorties, décisions)
Ceci n’est pas « à lancer pour le plaisir ». Chaque tâche contient : une commande, un extrait de sortie réaliste, ce que ça signifie, et la décision à prendre. Exécutez‑les dans un terminal. Sauvegardez les sorties dans votre ticket d’incident. Le vous du futur vous remerciera.
Task 1 — Voir si IPv6 est activé et quelles adresses vous avez
cr0x@server:~$ ip -6 addr show
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
inet6 2001:db8:10:20::123/64 scope global dynamic
valid_lft 86390sec preferred_lft 14390sec
inet6 fe80::a00:27ff:fe4e:66a1/64 scope link
valid_lft forever preferred_lft forever
Ce que ça signifie : Vous avez une adresse IPv6 globale (2001:db8:...). Cet hôte est potentiellement joignable depuis Internet (selon le routage et les règles en périphérie).
Décision : Traitez l’exposition IPv6 comme réelle. Poursuivez avec les vérifications des écouteurs et du pare‑feu.
Task 2 — Vérifier si IPv6 est désactivé via sysctl (ne pas supposer)
cr0x@server:~$ sysctl net.ipv6.conf.all.disable_ipv6 net.ipv6.conf.default.disable_ipv6
net.ipv6.conf.all.disable_ipv6 = 0
net.ipv6.conf.default.disable_ipv6 = 0
Ce que ça signifie : IPv6 est activé au niveau noyau.
Décision : Gardez IPv6 activé ; corrigez le pare‑feu et les services au lieu d’essayer de « couper Internet ».
Task 3 — Lister les sockets en écoute, y compris IPv6
cr0x@server:~$ ss -lntup
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
tcp LISTEN 0 4096 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1123,fd=3))
tcp LISTEN 0 4096 [::]:22 [::]:* users:(("sshd",pid=1123,fd=4))
tcp LISTEN 0 4096 [::]:8080 [::]:* users:(("java",pid=2210,fd=99))
Ce que ça signifie : SSH et un service Java écoutent sur le wildcard IPv6. Même si votre pare‑feu IPv4 est strict, IPv6 peut toujours atteindre ces ports.
Décision : Vous devez soit (a) bloquer l’entrée IPv6 pour ces ports via nftables/UFW, soit (b) lier les services à des interfaces spécifiques, ou les deux.
Task 4 — Vérifier le réglage IPv6 d’UFW (c’est ici que les gens se font avoir)
cr0x@server:~$ sudo grep -n '^IPV6=' /etc/default/ufw
13:IPV6=no
Ce que ça signifie : UFW ne gérera pas les règles IPv6. Votre posture « UFW activé » ne s’applique qu’à IPv4.
Décision : Si vous utilisez UFW, mettez IPV6=yes et rechargez, puis validez le jeu de règles nftables. Si vous n’utilisez pas UFW, assurez‑vous que nftables a un filtrage explicite ip6.
Task 5 — Voir l’état d’UFW, mais traitez‑le comme un voyant
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 10.0.0.0/8
Ce que ça signifie : UFW est actif pour ce qu’il gère. Notez que rien ici n’indique que l’IPv6 est couvert.
Décision : Vérifiez nftables pour ip6. Si UFW IPv6 est désactivé, cette sortie peut être dangereusement rassurante.
Task 6 — Inspecter le vrai jeu de règles nftables
cr0x@server:~$ sudo nft list ruleset
table inet ufw {
chain input {
type filter hook input priority filter; policy drop;
ct state established,related accept
iif "lo" accept
ip protocol icmp accept
tcp dport 22 ip saddr 10.0.0.0/8 accept
counter packets 1840 bytes 220800 drop
}
}
Ce que ça signifie : Ce jeu de règles est dans une table inet, qui peut matcher IPv4 et IPv6. Mais regardez de près : il accepte ip protocol icmp (ICMP IPv4), et il autorise SSH seulement avec ip saddr (match source IPv4). Il n’y a pas d’autorisation explicite ICMPv6 ni d’autorisation SSH IPv6 explicite. Avec une politique drop par défaut, IPv6 peut être bloqué — ou bien il peut être traité ailleurs si d’autres tables/chaînes existent en dehors de l’extrait.
Décision : Confirmez qu’il existe une chaîne d’entrée autoritaire unique accrochée pour inet et qu’elle inclut les éléments essentiels IPv6 (découverte de voisins ICMPv6) et des autorisations explicites.
Task 7 — Confirmer quels hooks existent (filtrez‑vous du tout l’entrée IPv6 ?)
cr0x@server:~$ sudo nft list chains
table inet ufw
chain input
chain forward
chain output
Ce que ça signifie : Vous avez des chaînes, mais il faut encore confirmer qu’elles sont réellement accrochées avec type filter hook input pour la bonne famille.
Décision : Si vous ne voyez pas une chaîne d’entrée accrochée dans une table inet/ip6, vous pourriez fonctionner sans pare‑feu IPv6 malgré les affirmations des outils.
Task 8 — Vérifier que la découverte de voisins IPv6 n’est pas étouffée
cr0x@server:~$ ip -6 neigh show dev enp0s3
fe80::1 lladdr 52:54:00:12:34:56 router REACHABLE
Ce que ça signifie : La découverte de voisins fonctionne au moins jusqu’au routeur. Si ND casse, vous pouvez avoir « le pare‑feu est sûr » et « le réseau est mystérieusement instable » en même temps.
Décision : Quand vous durcissez IPv6, autorisez explicitement les types ICMPv6 requis (ou autorisez globalement ICMPv6 entrant si vous n’avez pas de raison forte de l’interdire).
Task 9 — Vérifier la confusion legacy iptables (backend nft vs legacy)
cr0x@server:~$ sudo update-alternatives --display iptables | sed -n '1,12p'
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
Ce que ça signifie : Les commandes iptables utilisent le backend nft. C’est acceptable, mais cela signifie que la sortie de « iptables-save » peut ne pas correspondre à ce que vos anciens playbooks attendent.
Décision : Standardisez : gérez les règles avec nftables directement ou avec un seul outil (UFW) et cessez de mélanger des scripts iptables avec des règles nft sauf si vous aimez le débogage à 2 h du matin.
Task 10 — Confirmer qu’il n’y a pas de second gestionnaire de pare‑feu (firewalld) en concurrence
cr0x@server:~$ systemctl is-active firewalld; systemctl is-active ufw
inactive
active
Ce que ça signifie : Bien. Un seul gestionnaire est actif.
Décision : Si les deux sont actifs, choisissez‑en un. Désactivez l’autre. La propriété mixte crée des trous et des pertes « aléatoires » de règles.
Task 11 — Identifier si systemd socket activation a ouvert quelque chose que vous avez oublié
cr0x@server:~$ systemctl list-sockets --all | sed -n '1,12p'
LISTEN UNIT ACTIVATES DESCRIPTION
[::]:22 ssh.socket ssh.service OpenSSH Server Socket
[::]:631 cups.socket cups.service CUPS Scheduler
Ce que ça signifie : systemd écoute sur des adresses IPv6 pour des services. Même si vous « avez arrêté le service », la socket peut encore accepter des connexions et le lancer.
Décision : Désactivez les sockets inutiles (systemctl disable --now cups.socket) et assurez‑vous que les règles de pare‑feu couvrent tout de même le port.
Task 12 — Vérifier explicitement le comportement de liaison du daemon SSH
cr0x@server:~$ sudo sshd -T | egrep '^(addressfamily|listenaddress|port)'
addressfamily any
port 22
Ce que ça signifie : SSH écoute à la fois sur IPv4 et IPv6 (« any ») sauf contrainte.
Décision : Si vous voulez SSH seulement sur un sous‑réseau de gestion, appliquez‑le dans les règles du pare‑feu pour les deux familles et envisagez de lier SSH à cette interface/adresse.
Task 13 — Confirmer le chemin entrant en sondant depuis une autre machine (IPv6)
cr0x@server:~$ nc -6vz 2001:db8:10:20::123 22
Connection to 2001:db8:10:20::123 22 port [tcp/ssh] succeeded!
Ce que ça signifie : Le port est joignable en IPv6. C’est la « vraie faille » en clair.
Décision : Bloquez‑le à la périphérie et sur l’hôte, ou restreignez‑le aux plages sources appropriées, puis retestez jusqu’à ce qu’il échoue pour les sources non autorisées.
Task 14 — Surveillez les compteurs nft pendant les tests (prouve quelle règle a matché)
cr0x@server:~$ sudo nft -a list chain inet ufw input
table inet ufw {
chain input { # handle 3
type filter hook input priority filter; policy drop;
ct state established,related accept # handle 10
iif "lo" accept # handle 11
ip protocol icmp accept # handle 12
tcp dport 22 ip saddr 10.0.0.0/8 accept # handle 13
counter packets 1901 bytes 228120 drop # handle 14
}
}
Ce que ça signifie : Vous pouvez voir les compteurs évoluer lorsque du trafic arrive. Si votre sonde IPv6 réussit mais que les compteurs ne changent pas ici, votre trafic IPv6 n’est pas filtré par cette chaîne. C’est l’évidence irréfutable.
Décision : Trouvez la chaîne qui hooke réellement l’entrée IPv6, ou créez une chaîne d’entrée inet correcte couvrant les deux familles.
UFW sur Ubuntu 24.04 : ce que ça fait réellement pour IPv6
UFW est populaire parce qu’il est lisible. Ce n’est pas la même chose que « complet ». Le plus grand piège opérationnel est que le support IPv6 est un simple interrupteur dans /etc/default/ufw. S’il est désactivé, vous pouvez avoir une politique IPv4 propre et un monde IPv6 intact.
Activer correctement IPv6 dans UFW (si vous utilisez UFW)
Éditez /etc/default/ufw et mettez IPV6=yes. Puis rechargez.
cr0x@server:~$ sudo sed -i 's/^IPV6=.*/IPV6=yes/' /etc/default/ufw
cr0x@server:~$ sudo ufw reload
Firewall reloaded
Ce que ça signifie : UFW va maintenant générer et appliquer des règles IPv6 aussi.
Décision : Vérifiez immédiatement avec sudo nft list ruleset et une sonde IPv6 externe. Ne vous fiez pas au seul message de reload.
Définir des valeurs par défaut sensées pour le dual‑stack
cr0x@server:~$ sudo ufw default deny incoming
Default incoming policy changed to 'deny'
(be sure to update your rules accordingly)
cr0x@server:~$ sudo ufw default allow outgoing
Default outgoing policy changed to 'allow'
(be sure to update your rules accordingly)
Ce que ça signifie : Vous refusez par défaut l’entrée pour les deux stacks (une fois IPv6 activé) et autorisez la sortie. C’est la base pour des serveurs.
Décision : Ajoutez des autorisations explicites pour les ports entrants requis, limitées par source lorsque possible, en termes IPv4 et IPv6.
Autoriser SSH depuis un préfixe de gestion en IPv6 (exemple)
cr0x@server:~$ sudo ufw allow from 2001:db8:100::/56 to any port 22 proto tcp
Rule added
Rule added (v6)
Ce que ça signifie : Vous avez maintenant une règle d’autorisation spécifique v6 en plus des règles v4. La ligne « (v6) » est ce que vous voulez voir.
Décision : Si vous ne voyez pas « (v6) », votre interrupteur IPv6 ou la syntaxe de règle ne font pas ce que vous pensez.
Deux avis qui vous feront gagner du temps
- Ne comptez pas sur « allow 22/tcp » sans limiter la source sur des machines exposées à Internet. Sur IPv6, l’espace d’adressage n’empêche pas les attaques par force brute. Les attaquants se moquent que le scan soit « plus difficile » quand ils connaissent déjà votre adresse via DNS ou des logs.
- Ne bloquez pas trop ICMPv6. Vous casserez IPv6 de façons qui ressemblent à une perte de paquets aléatoire. Restez simple : autorisez les types ICMPv6 essentiels entrants, puis durcissez si vous avez des preuves et des tests.
Vérification de la réalité nftables : tables, chaînes, priorités
Si vous voulez moins de surprises, gérez nftables directement et tenez UFW à l’écart — ou engagez‑vous pleinement à laisser UFW gérer et vérifiez ses règles nft générées. Ce qu’il ne faut surtout pas faire, c’est avoir trois systèmes « qui aident ». C’est comme ça qu’on obtient un serveur à la fois ouvert et intermittemment brisé.
Utiliser une table inet pour le filtrage dual‑stack
La famille inet permet à une seule chaîne de matcher IPv4 et IPv6. C’est généralement la manière la plus simple d’éviter « on a oublié ip6 ». Un schéma minimal :
- Drop par défaut sur input
- Autoriser established/related
- Autoriser loopback
- Autoriser ICMP + ICMPv6 (ou au moins les types ICMPv6 nécessaires)
- Autoriser des services spécifiques depuis des plages sources spécifiques
Exemple : créer une chaîne d’entrée dual‑stack simple (illustratif — adaptez à votre environnement, ne copiez pas bêtement en production) :
cr0x@server:~$ sudo nft add table inet filter
cr0x@server:~$ sudo nft 'add chain inet filter input { type filter hook input priority 0; policy drop; }'
cr0x@server:~$ sudo nft add rule inet filter input ct state established,related accept
cr0x@server:~$ sudo nft add rule inet filter input iif "lo" accept
cr0x@server:~$ sudo nft add rule inet filter input ip protocol icmp accept
cr0x@server:~$ sudo nft add rule inet filter input ip6 nexthdr ipv6-icmp accept
cr0x@server:~$ sudo nft add rule inet filter input tcp dport 22 ip saddr 10.0.0.0/8 accept
cr0x@server:~$ sudo nft add rule inet filter input tcp dport 22 ip6 saddr 2001:db8:100::/56 accept
Ce que ça signifie : Une seule chaîne couvre les deux stacks. Vous autorisez explicitement l’ICMP IPv4 et l’ICMP IPv6, et vous limitez SSH par source pour chaque famille.
Décision : Décidez si vous voulez gérer les règles avec nft directement. Si oui, désactivez UFW pour éviter des chaînes concurrentes, puis persistez les règles via votre méthode de gestion de configuration.
Persister les règles nftables : soyez explicite sur la propriété
Les systèmes Ubuntu varient sur la manière dont la persistance nftables est gérée. L’important n’est pas le mécanisme ; c’est qu’il soit unique et audité. Si vous écrivez des règles en interactif et oubliez de les persister, vous « corrigerez » le problème jusqu’au prochain reboot — classique film papier.
Si vous utilisez UFW : laissez UFW les persister. Si vous utilisez nftables directement : persistez via la méthode choisie et testez au reboot dans le cadre de la validation du changement.
Deuxième petite plaisanterie, puis retour au travail : l’exposition IPv6 est le type de bug qui se cache si bien que vous commencez à croire que c’est une fonctionnalité — jusqu’à ce que l’auditeur la trouve et que soudain ce soit du « comportement legacy ».
Ce n’est pas qu’un pare‑feu : services qui écoutent IPv6 par défaut
Même avec un pare‑feu parfait, n’autorisez pas les services à écouter largement sauf si nécessaire. La défense en profondeur n’est pas qu’un slogan ; c’est comment vous survivez aux mauvaises configurations, aux changements futurs, et à la fameuse règle « temporaire » que quelqu’un oublie d’enlever.
Lier à des adresses spécifiques quand c’est pratique
Certaines applications peuvent être configurées pour se lier à une interface de gestion uniquement, ou à localhost derrière un reverse proxy. Exemples :
- Les tableaux de bord d’administration doivent se lier à
127.0.0.1et::1, et être accessibles via un tunnel SSH ou un VPN. - Les APIs internes doivent se lier à une interface VLAN interne, pas à l’interface publique.
- Tout ce qui est « temporaire » devrait par défaut se lier à localhost.
Méfiez‑vous des sockets systemd
systemd peut garder des ports ouverts même quand vous pensez qu’un service est arrêté. Ce n’est pas un bug ; c’est une fonctionnalité pour les services à la demande. C’est aussi un piège si vous ne vérifiez pas les sockets.
Si vous trouvez une socket écoutant en IPv6 que vous ne voulez pas, désactivez‑la :
cr0x@server:~$ sudo systemctl disable --now cups.socket
Removed "/etc/systemd/system/sockets.target.wants/cups.socket".
Ce que ça signifie : L’unité socket n’écoutera plus après cela, et ne sera pas démarrée au boot.
Décision : Faites cela pour toute socket activée par défaut non désirée, puis confirmez avec ss -lntup.
IPv6 et « localhost » ne sont pas identiques
Les ingénieurs lient parfois une appli à « localhost » et supposent que c’est local. Mais « localhost » peut signifier IPv4 seulement (127.0.0.1), IPv6 seulement (::1), ou les deux selon la configuration. Soyez explicite dans les configurations de service. Écrivez les deux adresses si vous voulez les deux. Testez les deux.
Cloud et périphérie : security groups, NACLs, load balancers, et pourquoi le pare‑feu hôte n’est pas suffisant
Dans les systèmes d’entreprise, la défaillance IPv6 la plus courante est une politique en mode split‑brain :
- L’équipe réseau verrouille soigneusement les security groups IPv4.
- L’IPv6 est activé plus tard (« nécessaire pour conformité » / « modernisation » / « parce que la checkbox du provider existe »).
- Les règles entrantes IPv6 restent permissives ou en permissif par défaut à un endroit que personne ne vérifie quotidiennement.
- Le pare‑feu hôte est supposé le bloquer, mais UFW IPv6 est désactivé ou les règles nft ne sont pas hookées.
Le pare‑feu hôte est nécessaire, mais pas suffisant. Si vous pouvez bloquer IPv6 en périphérie, faites‑le. Puis appliquez quand même la politique sur l’hôte. Les deux couches attrapent différentes classes d’erreurs :
- Les contrôles en périphérie protègent contre le bruit direct d’Internet et réduisent la surface d’exposition.
- Le pare‑feu hôte protège contre le mouvement latéral, le trafic mal routé, les menaces internes, et les moments « quelqu’un a ouvert un port sur l’instance ».
Souvenez‑vous aussi des load balancers : vous pouvez avoir un écouteur IPv6 sur le LB qui fait du forwarding vers des instances en IPv4. Ou l’inverse. Le dual‑stack en périphérie ne garantit pas le dual‑stack sur l’hôte. Ce décalage est où la surveillance vous trompe.
Trois mini‑histoires d’entreprise tirées du terrain
1) Incident causé par une mauvaise hypothèse : « UFW est activé, donc on est sûrs »
Une entreprise de taille moyenne a déployé des images Ubuntu 24.04 pour des outils internes. Ils avaient un script d’hardening cohérent : installer UFW, définir deny par défaut sur l’entrée, autoriser SSH depuis les plages IPv4 de l’entreprise, activer le logging. Ça a passé leur étape standard de « scan de ports », qui — prévisible — était lancée depuis un runner CI IPv4‑only.
Trois mois plus tard, un exercice red‑team a signalé plusieurs hôtes avec SSH joignable en IPv6. La première réaction de l’équipe fut le déni, puis la confusion, puis une avalanche de captures d’écran « mais UFW est actif ». L’indice était sous leurs yeux : IPV6=no dans /etc/default/ufw. Ce réglage venait d’un baseline plus ancien créé quand leur environnement n’avait pas de routage IPv6. Il a persisté comme un fossile.
Les hôtes avaient acquis des adresses IPv6 globales à la suite d’un changement réseau qui n’était pas présenté comme « ça change l’exposition ». Les annonces de routeur ont fait apparaître des adresses automatiquement. Personne n’a pensé à traiter ça comme un changement de périmètre de sécurité. C’est la mauvaise hypothèse : « l’attribution d’adresse est un détail réseau ». En dual‑stack, c’est un événement de politique.
Le correctif n’a pas été seulement de passer IPV6=yes. Ils ont dû ajouter des autorisations ICMPv6 appropriées, sinon la connectivité cassait de façons étranges. Ils ont aussi découvert que certains hôtes avaient des services liés à :: « temporairement ». Une fois qu’ils ont forcé le binding des services et appliqué des règles dual‑stack, les résultats du red‑team sont devenus ennuyeux. L’ennui, c’est bien.
2) Optimisation qui s’est retournée contre eux : « Drop all ICMP pour réduire le bruit »
Une autre organisation exploitait une plateforme API à fort volume et était fière d’avoir une « surface d’attaque minimale ». Un ingénieur a remarqué beaucoup de trafic ICMP dans les logs et a décidé que c’était « inutile ». Ils ont resserré les règles pour drop ICMP de façon globale, y compris ICMPv6, parce que « ping n’est pas nécessaire en production ». Ceci a été présenté comme une optimisation : moins de paquets, moins de logs, moins de distractions.
En quelques jours, la plateforme a développé des timeouts intermittents. Pas une panne claire — pire. Certains clients voient des requêtes volumineuses échouer, d’autres non. Les retries aidaient parfois. La latence semblait correcte jusqu’à ce qu’elle ne le soit plus. L’équipe on‑call a commencé à accumuler des superstitions. Quelqu’un a accusé le CDN. Quelqu’un a accusé TLS.
La vraie cause était la découverte de MTU de chemin IPv6 cassée. Les messages ICMPv6 « Packet Too Big » ne revenaient pas. Les connexions sont retombées sur un comportement de fragmentation inattendu, et certains chemins ont mis les paquets en échec. L’optimisation s’est retournée contre eux en créant un cauchemar de fiabilité et une taxe de débogage.
Ils ont réparé cela en autorisant l’ICMPv6 nécessaire et en ajustant le logging pour que le bruit soit gérable. La leçon : ICMPv6 n’est pas « ping ». C’est la plomberie. Enlever le témoin d’huile parce qu’il est agaçant ne résout pas le problème.
3) La pratique ennuyeuse mais correcte qui a sauvé la mise : gates de validation dual‑stack
Une entreprise du secteur financier avait été brûlée par une exposition IPv6 précédente, alors ils ont institutionnalisé une pratique que personne n’aimait : chaque nouveau service et chaque nouvelle image de base devait passer des tests de joignabilité dual‑stack. Pas « on a lancé nmap une fois », mais une petite suite automatisée : vérifier les sockets en écoute, vérifier les hooks nftables, sonder depuis un runner IPv6, et affirmer « seuls ces ports sont joignables ».
C’était ennuyeux. Les ingénieurs se plaignaient que ça ralentissait les provisionnements. La sécurité aimait ça. Les SREs le toléraient. Le payoff est arrivé discrètement : pendant une migration cloud, un changement réseau a ajouté IPv6 aux subnets par défaut. Beaucoup d’équipes ne l’ont même pas remarqué, parce que rien ne cassait. Mais la gate de validation l’a fait : soudain les builds tombaient parce que les tests de joignabilité IPv6 trouvaient des ports ouverts.
Au lieu de découvrir le souci via un incident, ils l’ont découvert en CI. Les correctifs étaient petits et répétables : activer UFW IPv6 (ou corriger les règles nftables inet), restreindre SSH par préfixe v6, et désactiver les sockets systemd inutiles. La migration est restée sur son planning. Personne n’a écrit de postmortem. C’est le rêve.
Erreurs courantes : symptômes → cause racine → correction
1) « Le scan IPv4 est propre, mais les auditeurs disent que des ports sont ouverts »
Symptôme : Un rapport externe montre SSH/HTTP joignable ; votre scan interne montre fermé.
Cause racine : L’auditeur a scanné IPv6 ; vous n’avez validé que l’IPv4.
Correction : Effectuez des scans dual‑stack. Confirmez ip -6 addr, puis sondez avec nc -6vz ou équivalent depuis un hôte IPv6. Activez les règles IPv6 dans UFW ou nftables.
2) « UFW est actif, mais des connexions IPv6 réussissent quand même »
Symptôme : ufw status semble correct ; des connexions IPv6 atteignent les services quand même.
Cause racine : IPV6=no dans /etc/default/ufw, ou les règles UFW ne sont pas hookées dans nftables pour les chemins inet/ip6.
Correction : Mettez IPV6=yes, rechargez UFW, vérifiez avec nft list ruleset, et retestez depuis une source IPv6 externe.
3) « IPv6 plante aléatoirement après durcissement »
Symptôme : Certaines connexions bloquent, gros transferts échouent, pertes intermittentes étranges.
Cause racine : ICMPv6 bloqué trop agressivement (PMTUD et découverte de voisins impactés).
Correction : Autorisez ICMPv6 (ip6 nexthdr ipv6-icmp accept) ou au moins les types requis. Testez avec de vrais workloads, pas juste un ping.
4) « Le service est arrêté, mais le port est toujours ouvert »
Symptôme : Vous arrêtez un daemon ; ss montre encore une écoute.
Cause racine : systemd socket activation garde le port ouvert via une unité .socket.
Correction : Désactivez l’unité socket (systemctl disable --now name.socket) et revérifiez les écouteurs.
5) « Des règles existent, mais le trafic IPv6 n’atteint pas les compteurs »
Symptôme : Les connexions IPv6 réussissent ; vos compteurs de chaîne nft attendus ne bougent pas.
Cause racine : Votre chaîne n’est pas hookée pour l’entrée, ou une autre table/chaîne a priorité, ou vous filtrez seulement la famille ip.
Correction : Assurez‑vous d’avoir une chaîne d’entrée inet ou ip6 avec un hook et la bonne priorité. Simplifiez la propriété : un seul gestionnaire.
6) « Nous avons autorisé SSH depuis IPv4 corp, mais IPv6 autorise toujours le monde »
Symptôme : SSH est restreint par sources IPv4 ; IPv6 est ouvert.
Cause racine : La règle matche seulement ip saddr, pas ip6 saddr.
Correction : Ajoutez des règles limitées en source pour IPv6 (UFW allow from 2001:.../... ou nft ip6 saddr).
7) « Nous avons désactivé IPv6, mais il revient / les applis cassent »
Symptôme : Quelqu’un bascule un sysctl pour désactiver IPv6 ; plus tard il réapparaît ou des services plantent.
Cause racine : Désactiver IPv6 est fragile selon les environnements et peut casser des dépendances ; ou les réglages sont appliqués de façon incohérente par interface.
Correction : Réactivez IPv6 et mettez en place une politique correcte de pare‑feu et de bindings. Si vous devez le désactiver, faites‑le de manière cohérente et documentez pourquoi, puis planifiez un travail de révision.
Listes de contrôle / plan étape par étape
Étape par étape : colmater la vraie faille sur un hôte Ubuntu 24.04
- Découvrir les adresses et routes IPv6. Si vous avez une adresse globale, supposez l’exposition et poursuivez.
- Inventorier les écouteurs. Identifiez ce qui se lie à
::et ce qui ne devrait pas. - Choisir un gestionnaire de pare‑feu. UFW ou nftables. Pas les deux. Pas « iptables scripts plus UFW ».
- Assurer deny par défaut pour les deux stacks. Dans UFW, mettre
IPV6=yes. Dans nftables, utiliser une chaîne d’entréeinetavecpolicy drop. - Autoriser l’ICMPv6 requis. Gardez IPv6 fonctionnel tout en le sécurisant.
- Ajouter des autorisations explicites pour les services requis. Préférez le scoped source : préfixes de gestion pour SSH, subnets de LB pour les ports applicatifs.
- Réduire les écouteurs. Liez les services internes/admin à localhost ou à des interfaces internes. Désactivez les sockets systemd inutiles.
- Valider depuis l’extérieur en IPv6. Si vous ne pouvez pas tester depuis l’extérieur, votre changement n’est pas vérifié.
- Vérifier compteurs/logs. Confirmez que vos règles sont réellement utilisées.
- Persister la configuration. Assurez‑vous que les règles survivent au reboot et à la dérive de la gestion de configuration.
Checklist Ops : que capturer dans le ticket (rend les audits gérables)
- Sortie de
ip -6 addretip -6 route(prouve l’adressage et la route par défaut). - Sortie de
ss -lntup(prouve ce qui peut être atteint). - Sortie de
nft list ruleset(prouve l’application effective). - État UFW + le toggle IPv6 dans
/etc/default/ufw(prouve la portée du gestionnaire). - Résultats de la sonde IPv6 externe avant/après (prouve la fermeture).
FAQ
1) Pourquoi cela est‑il apparu spécifiquement sur Ubuntu 24.04 ?
Ubuntu 24.04 est solidement ancré dans l’ère nftables et le dual‑stack est courant par défaut dans de nombreux environnements. Le « piège » n’est pas unique à 24.04, mais le mélange des couches d’outils et des paramètres modernes rend les demi‑configurations plus probables.
2) Si mon serveur n’a pas d’enregistrement AAAA DNS, suis‑je à l’abri d’une exposition IPv6 ?
Non. DNS est un mécanisme de découverte, pas un contrôle d’accès. Les adresses IPv6 fuitent via les logs, configurations, certificats, télémétrie et inventaires cloud. De plus, un attaquant interne n’a pas besoin du DNS.
3) « Le scan IPv6 est difficile » est‑ce une défense valable ?
Pas vraiment. Les attaquants n’ont pas besoin de scanner tout un /64 s’ils connaissent déjà votre adresse, ce qui arrive souvent. Et beaucoup de services utilisent des adresses prévisibles en cloud.
4) Puis‑je simplement désactiver IPv6 pour faire disparaître le problème ?
Vous pouvez, mais c’est généralement un pansement à court terme avec des dommages collatéraux. Ça casse certains réseaux, complique le dépannage, et a tendance à être annulé plus tard. Un pare‑feu dual‑stack correct est la solution durable.
5) Ai‑je besoin de règles séparées pour IPv4 et IPv6 ?
Vous devez couvrir les deux familles. Avec nftables, une table inet peut appliquer une chaîne aux deux familles. Avec UFW, vous devez activer IPv6 et confirmer que des règles sont générées pour v6.
6) Quels ICMPv6 dois‑je autoriser ?
Au minimum, autorisez le trafic ICMPv6 requis pour la découverte de voisins et la PMTUD. Si vous n’avez pas le temps d’être astucieux, autorisez ICMPv6 entrant puis resserrez ensuite avec des tests réels et une justification.
7) Pourquoi je vois des services écoutant sur [::]:port alors que je n’ai configuré que IPv4 ?
Beaucoup de démons se lient par défaut au wildcard IPv6 parce que cela couvre les deux stacks, ou parce que les paramètres de distribution le favorisent. C’est normal ; cela signifie juste que vous devez appliquer la politique pare‑feu pour IPv6 aussi.
8) Comment savoir si UFW applique réellement IPv6 ?
Vérifiez /etc/default/ufw pour IPV6=yes, puis inspectez le jeu de règles nftables et testez depuis un hôte IPv6 externe. Le simple état de l’outil n’est pas une preuve.
9) Quelle est la manière la plus rapide de prouver que nous avons corrigé le problème ?
Depuis un hôte extérieur à vos plages autorisées, tentez une connexion IPv6 sur le port auparavant exposé (par exemple nc -6vz). Elle doit échouer. Ensuite confirmez que les compteurs nft montrent des drops pour ce trafic.
10) Si nous avons des security groups cloud, pourquoi s’embêter avec un pare‑feu sur l’hôte ?
Parce que les politiques en périphérie dérivent, le trafic interne existe, et des erreurs de routage arrivent. Le pare‑feu hôte vous protège quand le périmètre n’est pas parfait — et il ne l’est jamais.
Conclusion : prochaines étapes que vous pouvez planifier
Colmatez la faille comme vous colmatez tout vrai écart opérationnel : prouvez qu’elle existe, corrigez‑la dans un endroit auteuritif, puis ajoutez un garde‑fou pour qu’elle ne revienne pas.
- Aujourd’hui : exécutez
ip -6 addr,ss -lntupetsudo nft list rulesetsur un hôte représentatif. Si vous voyez IPv6 global + écouteurs ouverts + règles faibles, vous avez trouvé le problème. - Cette semaine : choisissez un modèle de responsabilité pour le pare‑feu (UFW avec IPv6 activé, ou nftables natif). Imposer deny par défaut sur les deux stacks. Autoriser ICMPv6 correctement. Scoper les autorisations entrantes par source.
- Ce mois‑ci : ajoutez une gate de validation dual‑stack : sonde IPv6 externe + inventaire des écouteurs + vérification des hooks nft. Rendez‑la ennuyeuse. Automatisez‑la.
Le dual‑stack n’est plus optionnel. La bonne nouvelle : le corriger est simple une fois que vous arrêtez de faire semblant que IPv6 est « plus tard ».