
Outil de détection et d'atténuation des vulnérabilités pour les bugs Copy Fail et Dirty Frag (CVE-2026-31431, CVE-2026-43284, CVE-2026-43500)
Auditer un hôte Linux distant via SSH pour les vulnérabilités des modules noyau Copy Fail et Dirty Frag et, optionnellement, appliquer des atténuations :
| CVE | Nom | Modules affectés |
|---|---|---|
| CVE-2026-31431 | Copy Fail | algif_aead |
| CVE-2026-43284 | Dirty Frag (IPsec) | esp4, esp6, ipcomp4, ipcomp6, xfrm_user |
| CVE-2026-43500 | Dirty Frag (RxRPC) | rxrpc, kafs |
Pour chaque module affecté, vcheck indique s'il est actuellement chargé, intégré au noyau en cours d'exécution, s'il a des traces passées dans les journaux du noyau, s'il a des sockets AF_ALG actives (Copy Fail uniquement), et s'il est déjà mis sur liste noire dans /etc/modprobe.d/.
Avec -fix, vcheck signale l'état initial, écrit un fragment cve-XXXX-XXXXX-disable.conf pour tout module qui n'est pas encore sur liste noire, puis relance les vérifications et signale l'état final. Avec -fix -unload, vcheck tente également de décharger les modules affectés qui étaient chargés avant le correctif, puis utilise l'analyse finale pour vérifier s'ils sont toujours chargés. Avec -fix -rebuild-initramfs, vcheck reconstruit l'initramfs pour le noyau en cours d'exécution (uniquement) après avoir écrit un fragment, de sorte que la liste noire soit intégrée dans l'image de démarrage suivante. Les entrées de noyau plus anciennes conservent leur initramfs d'origine comme solution de repli.
-fix uniquement après une exécution sans correctionExécutez toujours vcheck sans -fix d'abord. Lisez le rapport et confirmez que les modules affectés peuvent être désactivés en toute sécurité sur cet hôte avant de relancer avec -fix. La désactivation de modules noyau dont dépendent des charges de travail légitimes peut affecter les utilisateurs et casser des applications.
En particulier :
-fix comme sûr uniquement lorsque aucun des modules affectés n'est actuellement chargé — c'est-à-dire que chaque module est signalé comme mitigé ou module non blacklisté (aucune ligne VULNÉRABLE ou blacklisté mais actuellement chargé). Un module chargé signifie presque toujours que quelque chose sur l'hôte l'utilise activement ; vérifiez cela avant de mettre sur liste noire.esp4, esp6, ipcomp4, ipcomp6, xfrm_user) sont nécessaires pour tout déploiement IPsec/strongSwan/WireGuard-over-IPsec/IKE. Les modules ipcomp4/ipcomp6 implémentent la compression de charge utile IPComp et peuvent être auto-négociés dans le cadre d'une SA IPsec même lorsqu'ils ne sont pas explicitement configurés. Ne mettez aucun d'entre eux sur liste noire sur une passerelle VPN, un point de terminaison IPsec ou partout où renvoie des règles. Notez que le module framework n'est intentionnellement dans cette liste — selon les directives des fournisseurs (Red Hat, Ubuntu, AWS), bloquer les modules de protocole ESP et IPComp ainsi que l'interface de configuration netlink est suffisant, et blacklister casserait toutes les autres transformations xfrm pour aucun bénéfice supplémentaire.Les fragments de liste noire écrits par vcheck ne prennent effet qu'au moment du chargement du module (généralement au prochain démarrage, ou avec modprobe -r <module> lorsque le système est inactif). Un module déjà chargé continuera de fonctionner même après -fix — vcheck le signalera comme blacklisté mais actuellement chargé ; exécutez 'modprobe -r' ou redémarrez. Passer -unload avec -fix demande à vcheck d'exécuter modprobe -r pour les modules affectés chargés après avoir écrit les fragments de liste noire. Utilisez-le uniquement lorsque vous avez confirmé que les modules peuvent être retirés du noyau en cours d'exécution en toute sécurité.
Passer -rebuild-initramfs avec -fix régénère l'initramfs pour le noyau en cours d'exécution uniquement (update-initramfs -u -k $(uname -r) sur Debian/Ubuntu, dracut -f --kver $(uname -r) sur RHEL/Fedora). Les autres noyaux installés conservent leur initramfs existant intact, donc si quelque chose se passe mal après le redémarrage, vous pouvez choisir une entrée de noyau plus ancienne dans le menu de démarrage et récupérer. Les futures installations de noyau reconstruisent leur propre initramfs à partir de l'état actuel de /etc/modprobe.d/, donc la liste noire se propage automatiquement sans relancer vcheck. Si ni update-initramfs ni dracut n'est présent (par exemple Arch, Alpine, images immuables), vcheck émet un avertissement et continue — reconstruisez manuellement avec l'outil de la distribution avant de redémarrer.
La reconstruction peut prendre plusieurs minutes (surtout dracut sur les hôtes avec de nombreux pilotes), ce qui dépasserait le -command-timeout de diagnostic. Elle s'exécute sous son propre -initramfs-timeout (par défaut 10m) de sorte que la reconstruction dispose de l'espace nécessaire tandis que les vérifications rapides conservent leur budget serré. Augmentez -initramfs-timeout pour le matériel lent, ou passez 0 pour désactiver complètement le délai d'attente. Pendant les commandes distantes de longue durée, vcheck envoie des requêtes keepalive SSH toutes les 30s par défaut pour éviter que les temporisateurs d'inactivité NAT/pare-feu ne coupent la connexion. Ajustez cela avec -ssh-keepalive, ou passez 0 pour le désactiver.
Homebrew (macOS) :
brew install --cask krisiasty/tap/vcheck
Binaires pré-compilés pour Linux, macOS et Windows sont publiés sur la page des versions.
Depuis les sources (nécessite Go 1.26+) :
go install github.com/krisiasty/vcheck@latest
vcheck -host HOST [flags]
Au moins l'un de -agent, -identity ou -password doit produire une méthode d'authentification utilisable. Les méthodes sont essayées dans l'ordre indiqué.
Sudo est requis sur la cible. Si sudo sans mot de passe est configuré, l'outil procède silencieusement ; sinon, il demande une fois un mot de passe (la saisie est masquée) et le transmet via sudo -S pour chaque commande suivante.
$ vcheck -host host.example.com -identity ~/.ssh/id_ed25519
INF connected user=ops host=host.example.com port=22
INF checking vulnerability cve=CVE-2026-31431 name="Copy Fail"
INF checking vulnerability cve=CVE-2026-43284 name="Dirty Frag (IPsec)"
INF checking vulnerability cve=CVE-2026-43500 name="Dirty Frag (RxRPC)"
INF mitigated cve=CVE-2026-31431 module=algif_aead
INF mitigated cve=CVE-2026-43284 module=esp4
INF mitigated cve=CVE-2026-43284 module=esp6
INF mitigated cve=CVE-2026-43284 module=ipcomp4
INF mitigated cve=CVE-2026-43284 module=ipcomp6
INF mitigated cve=CVE-2026-43284 module=xfrm_user
INF mitigated cve=CVE-2026-43500 module=rxrpc
INF mitigated cve=CVE-2026-43500 module=kafs
$ vcheck -host host.example.com -identity ~/.ssh/id_ed25519
INF connected user=ops host=host.example.com port=22
INF checking vulnerability cve=CVE-2026-31431 name="Copy Fail"
INF checking vulnerability cve=CVE-2026-43284 name="Dirty Frag (IPsec)"
INF checking vulnerability cve=CVE-2026-43500 name="Dirty Frag (RxRPC)"
INF mitigated cve=CVE-2026-31431 module=algif_aead
ERR VULNERABLE cve=CVE-2026-43284 module=esp4 loaded=true
ERR module not blacklisted cve=CVE-2026-43284 module=esp6
ERR module not blacklisted cve=CVE-2026-43284 module=ipcomp4
ERR module not blacklisted cve=CVE-2026-43284 module=ipcomp6
ERR module not blacklisted cve=CVE-2026-43284 module=xfrm_user
ERR module not blacklisted cve=CVE-2026-43500 module=rxrpc
ERR module not blacklisted cve=CVE-2026-43500 module=kafs
-fix — première exécution$ vcheck -fix -host host.example.com -identity ~/.ssh/id_ed25519
INF connected user=ops host=host.example.com port=22
INF checking vulnerability cve=CVE-2026-31431 name="Copy Fail"
INF checking vulnerability cve=CVE-2026-43284 name="Dirty Frag (IPsec)"
INF checking vulnerability cve=CVE-2026-43500 name="Dirty Frag (RxRPC)"
INF findings before fix
INF mitigated cve=CVE-2026-31431 module=algif_aead
ERR VULNERABLE cve=CVE-2026-43284 module=esp4 loaded=true
ERR module not blacklisted cve=CVE-2026-43284 module=esp6
ERR module not blacklisted cve=CVE-2026-43284 module=ipcomp4
ERR module not blacklisted cve=CVE-2026-43284 module=ipcomp6
ERR module not blacklisted cve=CVE-2026-43284 module=xfrm_user
ERR module not blacklisted cve=CVE-2026-43500 module=rxrpc
ERR module not blacklisted cve=CVE-2026-43500 module=kafs
INF writing modprobe.d snippet path=/etc/modprobe.d/cve-2026-43284-disable.conf modules="[esp4 esp6 ipcomp4 ipcomp6 xfrm_user]"
INF writing modprobe.d snippet path=/etc/modprobe.d/cve-2026-43500-disable.conf modules="[rxrpc kafs]"
INF re-scanning after fix snippets_written=2
INF checking vulnerability cve=CVE-2026-31431 name="Copy Fail"
INF checking vulnerability cve=CVE-2026-43284 name="Dirty Frag (IPsec)"
INF checking vulnerability cve=CVE-2026-43500 name="Dirty Frag (RxRPC)"
INF findings after fix
INF mitigated cve=CVE-2026-31431 module=algif_aead
ERR blacklisted but currently loaded; run 'modprobe -r' or reboot cve=CVE-2026-43284 module=esp4
INF mitigated cve=CVE-2026-43284 module=esp6
INF mitigated cve=CVE-2026-43284 module=ipcomp4
INF mitigated cve=CVE-2026-43284 module=ipcomp6
INF mitigated cve=CVE-2026-43284 module=xfrm_user
INF mitigated cve=CVE-2026-43500 module=rxrpc
INF mitigated cve=CVE-2026-43500 module=kafs
La liste noire est en place, mais esp4 était déjà chargé dans le noyau avant l'écriture du fragment. Redémarrez ou exécutez sudo modprobe -r esp4 sur la cible pour le vider entièrement.
$ vcheck -fix -host host.example.com -identity ~/.ssh/id_ed25519
INF connected user=ops host=host.example.com port=22
INF checking vulnerability cve=CVE-2026-31431 name="Copy Fail"
INF checking vulnerability cve=CVE-2026-43284 name="Dirty Frag (IPsec)"
INF checking vulnerability cve=CVE-2026-43500 name="Dirty Frag (RxRPC)"
INF findings before fix
INF mitigated cve=CVE-2026-31431 module=algif_aead
ERR blacklisted but currently loaded; run 'modprobe -r' or reboot cve=CVE-2026-43284 module=esp4
INF mitigated cve=CVE-2026-43284 module=esp6
INF mitigated cve=CVE-2026-43284 module=ipcomp4
INF mitigated cve=CVE-2026-43284 module=ipcomp6
INF mitigated cve=CVE-2026-43284 module=xfrm_user
INF mitigated cve=CVE-2026-43500 module=rxrpc
INF mitigated cve=CVE-2026-43500 module=kafs
INF fix: nothing to do — all affected modules already blacklisted
modprobe -r esp4$ vcheck -host host.example.com -identity ~/.ssh/id_ed25519
INF connected user=ops host=host.example.com port=22
INF checking vulnerability cve=CVE-2026-31431 name="Copy Fail"
INF checking vulnerability cve=CVE-2026-43284 name="Dirty Frag (IPsec)"
INF checking vulnerability cve=CVE-2026-43500 name="Dirty Frag (RxRPC)"
INF mitigated cve=CVE-2026-31431 module=algif_aead
INF mitigated cve=CVE-2026-43284 module=esp4
INF mitigated cve=CVE-2026-43284 module=esp6
INF mitigated cve=CVE-2026-43284 module=ipcomp4
INF mitigated cve=CVE-2026-43284 module=ipcomp6
INF mitigated cve=CVE-2026-43284 module=xfrm_user
INF mitigated cve=CVE-2026-43500 module=rxrpc
INF mitigated cve=CVE-2026-43500 module=kafs
-rebuild-initramfs$ vcheck -fix -rebuild-initramfs -host host.example.com -identity ~/.ssh/id_ed25519
...
INF writing modprobe.d snippet path=/etc/modprobe.d/cve-2026-43284-disable.conf modules="[esp4 esp6 ipcomp4 ipcomp6 xfrm_user]"
INF writing modprobe.d snippet path=/etc/modprobe.d/cve-2026-43500-disable.conf modules="[rxrpc kafs]"
INF rebuilding initramfs for running kernel timeout=10m0s
INF initramfs rebuilt for running kernel tool=update-initramfs
INF re-scanning after fix snippets_written=2
...
Seul l'initramfs du noyau en cours d'exécution est reconstruit. Les autres noyaux installés conservent leur initramfs existant, donc une entrée plus ancienne dans le menu de démarrage reste un repli fonctionnel si le nouvel initramfs pose problème. Sur un hôte sans update-initramfs ni dracut, vcheck enregistre WRN no supported initramfs tool found ... et continue.
-insecure$ vcheck -insecure -host host.example.com -identity ~/.ssh/id_ed25519
WRN host key not in known_hosts; accepting due to -insecure host=host.example.com:22 remote=192.0.2.42:22 fingerprint=SHA256:AAAAEXAMPLEfingerPrint000000000000000000000
INF connected user=ops host=host.example.com port=22
INF checking vulnerability cve=CVE-2026-31431 name="Copy Fail"
...
-insecure accepte les hôtes qui ne sont pas encore dans known_hosts. Si un hôte est déjà enregistré et présente une clé différente, la connexion échoue toujours — l'indicateur n'est qu'une dérogation de "premier contact", pas un moyen de supprimer les avertissements d'homme du milieu sur un hôte connu.
lsmod est récupéré une fois et les noms de modules sont comparés à la première colonne./lib/modules/$(uname -r)/modules.builtin et /sys/module sont vérifiés car les fragments modprobe ne peuvent pas désactiver le code compilé dans le noyau en cours d'exécution./etc/modprobe.d/ est recherché (grep -rE) pour une directive install <module> /bin/false — la même forme que vcheck écrit avec -fix. D'autres formes de désactivation (par exemple blacklist) ne sont pas reconnues.journalctl -k est consulté en premier, avec un repli vers /var/log/kern.log ; les cinq dernières lignes correspondantes par module sont conservées. Passez -skip-logs pour ignorer cette étape.Toutes les commandes sont exécutées via sudo et sont limitées par -command-timeout — un accès privilégié est requis pour lire /var/log/kern.log, lister les sockets AF_ALG et écrire sous /etc/modprobe.d/. Avec -unload, un accès privilégié est également requis pour exécuter modprobe -r. Avec -rebuild-initramfs, vcheck exécute update-initramfs -u -k $(uname -r) (Debian/Ubuntu) ou dracut -f --kver $(uname -r) (RHEL/Fedora), qui nécessitent aussi les droits root.
ip xfrm policyxfrm_algoxfrm_userxfrm_algorxrpc, kafs) sont nécessaires pour tout hôte qui monte des systèmes de fichiers AFS. Leur désactivation cassera ces montages au prochain démarrage.algif_aead expose la crypto du noyau via la famille de sockets AF_ALG. Il est rarement utilisé directement par le code applicatif, mais vérifiez en listant les sockets actives (ss -p --af-alg) et en consultant les consommateurs espace utilisateur avant de le blacklister.| Indicateur | Par défaut | Description |
|---|
-host | (requis) | Hôte distant |
-user | $USER | Utilisateur distant |
-port | 22 | Port SSH distant |
-agent | true | Utiliser l'agent SSH pour l'authentification |
-identity | (vide) | Chemin vers un fichier de clé privée (demande la phrase de passe si chiffrée) |
-password | false | Demander un mot de passe SSH |
-insecure | false | Accepter les clés d'hôte non encore enregistrées dans known_hosts ; les discordances avec une clé enregistrée échouent toujours |
-fix | false | Écrire des fragments dans /etc/modprobe.d pour les modules qui ne sont pas déjà sur liste noire |
-unload | false | Avec -fix, décharger les modules affectés après les avoir blacklistés |
-rebuild-initramfs | false | Avec -fix, reconstruire l'initramfs pour le noyau en cours d'exécution uniquement (update-initramfs ou dracut) |
-skip-logs | false | Ignorer les vérifications de l'historique des journaux du noyau |
-timeout | 15s | Délai d'attente de connexion SSH |
-ssh-keepalive | 30s | Intervalle keepalive SSH (0 désactive) |
-command-timeout | 30s | Délai d'attente des commandes distantes (0 désactive) |
-initramfs-timeout | 10m | Délai d'attente pour l'étape de reconstruction de l'initramfs (0 désactive) ; utilisé uniquement avec -rebuild-initramfs |
-debug | false | Augmenter la verbosité des journaux |
-version | false | Afficher la version et quitter |
| Code | Signification |
|---|
0 | Tous les modules affectés sont blacklistés, déchargés, non intégrés au noyau et inactifs |
1 | Erreur d'utilisation |
2 | Échec de la connexion SSH |
3 | Échec de l'authentification sudo |
4 | Un ou plusieurs modules non blacklistés (aucune exposition actuelle) |
5 | Un ou plusieurs modules actuellement chargés, intégrés au noyau ou activement utilisés |
99 | Échec interne/de vérification |
algif_aeadss -p --af-algAF_ALG