
vcheck v1.6.3
Strumento di rilevamento e mitigazione delle vulnerabilità per i bug Copy Fail e Dirty Frag (CVE-2026-31431, CVE-2026-43284, CVE-2026-43500)
vcheck
Controlla un host Linux remoto via SSH per le vulnerabilità dei moduli del kernel Copy Fail e Dirty Frag e, opzionalmente, applica le mitigazioni:
| CVE | Name | Moduli interessati |
|---|---|---|
| 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 |
Per ogni modulo interessato, vcheck segnala se è attualmente caricato, se è compilato nel kernel in esecuzione, se ci sono tracce passate nei log del kernel, se ci sono socket AF_ALG attivi (solo per Copy Fail) e se è già in blacklist in /etc/modprobe.d/.
Con -fix, vcheck riporta lo stato iniziale, scrive un file cve-XXXX-XXXXX-disable.conf per ogni modulo non ancora in blacklist, quindi riesegue i controlli e riporta lo stato finale. Con
-fix -unload, vcheck tenta anche di scaricare i moduli interessati già caricati prima della correzione, quindi usa la scansione finale per verificare se sono ancora caricati. Con -fix -rebuild-initramfs, vcheck
ricostruisce l'initramfs per il kernel attualmente in esecuzione (solo) dopo la scrittura di un file, in modo che la blacklist venga inclusa nella prossima immagine di avvio. Le voci del kernel meno recenti mantengono il loro initramfs originale come ripiego.
Usa -fix solo dopo un'esecuzione di solo controllo
Esegui sempre vcheck prima senza -fix. Leggi il rapporto e conferma che i moduli interessati possano essere disabilitati in sicurezza su questo host prima di rieseguire con -fix. Disabilitare moduli del kernel da cui dipendono workload legittimi può avere impatto sugli utenti e rompere le applicazioni.
In particolare:
- Considera
-fixsicuro solo quando nessuno dei moduli interessati è attualmente caricato — cioè ogni modulo è segnalato comemitigatedomodule not blacklisted(nessuna rigaVULNERABLEoblacklisted but currently loaded). Un modulo caricato significa quasi sempre che qualcosa sull'host lo sta usando attivamente; verificalo prima di metterlo in blacklist. - I moduli IPsec (
esp4,esp6,ipcomp4,ipcomp6,xfrm_user) sono necessari per qualsiasi implementazione IPsec/strongSwan/WireGuard-over-IPsec/IKE. I moduliipcomp4/ipcomp6implementano la compressione del payload IPComp e possono essere negoziati automaticamente come parte di una SA IPsec anche se non configurati esplicitamente. Non metterli in blacklist su un gateway VPN, un endpoint IPsec o ovunqueip xfrm policyrestituisca regole. Nota che il modulo frameworkxfrm_algoè volutamente non in questo elenco — secondo le indicazioni dei vendor (Red Hat, Ubuntu, AWS), bloccare i moduli dei protocolli ESP e IPComp più l'interfaccia di configurazione netlinkxfrm_userè sufficiente, e mettere in blacklistxfrm_algoromperebbe ogni altra trasformazione xfrm senza alcun beneficio aggiuntivo. - I moduli RxRPC (
rxrpc,kafs) sono necessari per qualsiasi host che monta filesystem AFS. Disabilitarli romperà quei mount al prossimo avvio. algif_aeadespone la crittografia del kernel tramite la famiglia di socketAF_ALG. È usato raramente direttamente dal codice delle applicazioni, ma verifica elencando i socket attivi (ss -p --af-alg) e controllando i consumatori in spazio utente prima di metterlo in blacklist.
I file di blacklist scritti da vcheck hanno effetto solo al momento del caricamento del modulo (in genere al riavvio successivo, oppure con modprobe -r <module> a sistema inattivo). Un modulo già caricato continuerà a funzionare
anche dopo -fix — vcheck lo segnalerà come blacklisted but currently loaded; run 'modprobe -r' or reboot. Passare -unload insieme a -fix chiede a vcheck di eseguire modprobe -r per i moduli interessati caricati
dopo la scrittura dei file di blacklist. Usalo solo quando hai confermato che i moduli possono essere rimossi in sicurezza dal kernel in esecuzione.
Passare -rebuild-initramfs insieme a -fix rigenera l'initramfs solo per il kernel attualmente in esecuzione (update-initramfs -u -k $(uname -r) su Debian/Ubuntu, dracut -f --kver $(uname -r) su
RHEL/Fedora). Gli altri kernel installati mantengono intatto il proprio initramfs, quindi se qualcosa va storto dopo il riavvio puoi scegliere una voce kernel meno recente dal menu di avvio e recuperare. Le future installazioni
del kernel ricostruiscono il proprio initramfs a partire dallo stato corrente di /etc/modprobe.d/, quindi la blacklist si propaga automaticamente senza dover rieseguire vcheck. Se non sono presenti né update-initramfs né dracut
(ad es. Arch, Alpine, immagini immutabili), vcheck avvisa e continua — ricostruisci manualmente con lo strumento della distribuzione prima di riavviare.
La ricostruzione può richiedere alcuni minuti (soprattutto dracut su host con molti driver), il che supererebbe il timeout diagnostico -command-timeout. Viene eseguita con un proprio -initramfs-timeout (default 10m),
così la ricostruzione ha tutto il tempo necessario mentre i controlli rapidi mantengono il loro budget ridotto. Aumenta -initramfs-timeout per hardware lento, oppure passa 0 per disabilitare completamente il timeout. Durante i comandi remoti
di lunga durata, vcheck invia richieste keepalive SSH ogni 30s di default per evitare che i timer di inattività NAT/firewall interrompano la connessione. Regola questo valore con -ssh-keepalive, oppure passa 0 per disabilitarlo.
Installazione
Homebrew (macOS):
brew install --cask krisiasty/tap/vcheck
Binari precompilati per Linux, macOS e Windows sono pubblicati nella pagina delle release.
Dal sorgente (richiede Go 1.26+):
go install github.com/krisiasty/vcheck@latest
Utilizzo
vcheck -host HOST [flags]
| Flag | Predefinito | Descrizione |
|---|---|---|
-host | (obbligatorio) | Host remoto |
-user | $USER | Utente remoto |
-port | 22 | Porta SSH remota |
-agent | true | Usa l'agente SSH per l'autenticazione |
-identity | (vuoto) | Percorso di un file di chiave privata (chiede la passphrase se cifrato) |
-password | false | Chiede una password SSH |
-insecure | false | Accetta host key non ancora registrate in known_hosts; le discrepanze con una chiave registrata falliscono comunque |
-fix | false | Scrive i file in /etc/modprobe.d per i moduli non ancora in blacklist |
-unload | false | Con -fix, scarica i moduli interessati dopo averli messi in blacklist |
-rebuild-initramfs | false | Con -fix, ricostruisce l'initramfs solo per il kernel in esecuzione (update-initramfs o dracut) |
-skip-logs | false | Salta i controlli sulla cronologia dei log del kernel |
-timeout | 15s | Timeout di connessione SSH |
-ssh-keepalive | 30s | Intervallo keepalive SSH (0 lo disabilita) |
-command-timeout | 30s | Timeout dei comandi remoti (0 lo disabilita) |
-initramfs-timeout | 10m | Timeout per il passaggio di ricostruzione dell'initramfs (0 lo disabilita); usato solo con -rebuild-initramfs |
-debug | false | Aumenta la verbosità dei log |
-version | false | Mostra la versione ed esce |
Almeno uno tra -agent, -identity o -password deve produrre un metodo di autenticazione utilizzabile. I metodi vengono provati nell'ordine elencato.
Sudo è richiesto sull'host di destinazione. Se è configurato sudo senza password, lo strumento procede silenziosamente; altrimenti chiede una volta la password (l'input è nascosto) e la fornisce tramite sudo -S per ogni
comando successivo.
Codici di uscita
| Codice | Significato |
|---|---|
0 | Tutti i moduli interessati in blacklist, scaricati, non compilati nel kernel e inattivi |
1 | Errore di utilizzo |
2 | Connessione SSH fallita |
3 | Autenticazione sudo fallita |
4 | Uno o più moduli non in blacklist (nessuna esposizione attuale) |
5 | Uno o più moduli attualmente caricati, compilati nel kernel o in uso attivo |
99 | Errore interno/di controllo |
Esempio di output
Host completamente mitigato
$ 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
Non mitigato e parzialmente caricato — controllo semplice
$ 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
Stesso host con -fix — prima esecuzione
$ 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 blacklist è in atto, ma esp4 era già caricato nel kernel prima della scrittura del file. Riavvia o esegui sudo modprobe -r esp4 sull'host per eliminarlo completamente.
Seconda esecuzione — esp4 ancora caricato
$ 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
Terza esecuzione — dopo 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
Con -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
...
Viene ricostruito solo l'initramfs del kernel in esecuzione. Gli altri kernel installati mantengono il proprio initramfs, quindi una voce meno recente nel menu di avvio resta un ripiego funzionante se il nuovo initramfs causa
problemi. Su un host senza né update-initramfs né dracut, vcheck registra WRN no supported initramfs tool found ... e continua.
Primo contatto con l'host — -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 accetta host non ancora presenti in known_hosts. Se un host è già registrato e presenta una chiave diversa, la connessione fallisce comunque — il flag è solo una deroga per il "primo contatto", non
un modo per sopprimere gli avvisi man-in-the-middle su un host noto.
Dettagli del rilevamento
- Caricato:
lsmodviene recuperato una volta e i nomi dei moduli vengono confrontati con la prima colonna. - Compilato nel kernel: vengono controllati
/lib/modules/$(uname -r)/modules.builtine/sys/module, perché i file di modprobe non possono disabilitare codice compilato nel kernel in esecuzione. - In blacklist: viene cercato in ogni file sotto
/etc/modprobe.d/(grep -rE) una direttivainstall <module> /bin/false— la stessa forma che vcheck scrive con-fix. Altre forme di disabilitazione (ad es.blacklist) non vengono riconosciute. - Attività passata: viene consultato prima
journalctl -k, con ripiego su/var/log/kern.log; vengono conservate le ultime cinque righe corrispondenti per ogni modulo. Passa-skip-logsper saltare questo passaggio. - Socket attivi (solo
algif_aead):ss -p --af-algelenca i socketAF_ALGaperti; qualsiasi output diverso dall'intestazione conta come utilizzo attivo.
Tutti i comandi vengono eseguiti tramite sudo e sono limitati da -command-timeout — l'accesso privilegiato è necessario per leggere /var/log/kern.log, elencare i socket AF_ALG e scrivere in /etc/modprobe.d/. Con
-unload, l'accesso privilegiato è necessario anche per eseguire modprobe -r. Con -rebuild-initramfs, vcheck esegue update-initramfs -u -k $(uname -r) (Debian/Ubuntu) o dracut -f --kver $(uname -r)
(RHEL/Fedora), che richiedono anch'essi i permessi di root.