
Tool zur Erkennung und Minderung von Schwachstellen für die Copy-Fail- und Dirty-Frag-Bugs (CVE-2026-31431, CVE-2026-43284, CVE-2026-43500)
# vcheck Überprüft einen entfernten Linux-Host per SSH auf die Kernel-Modul-Sicherheitslücken Copy Fail und Dirty Frag und wendet optional Gegenmaßnahmen an: | CVE | Name | Betroffene Module | | -------------- | ------------------ | ------------------------------------------------- | | 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` | Für jedes betroffene Modul meldet vcheck, ob es derzeit geladen, in den laufenden Kernel eingebaut ist, ob es in der Vergangenheit im Kernel-Log aufgetaucht ist, ob live `AF_ALG`-Sockets vorhanden sind (nur Copy Fail) und ob es bereits unter `/etc/modprobe.d/` auf der Blacklist steht. Mit `-fix` meldet vcheck den Anfangszustand, schreibt für jedes noch nicht auf der Blacklist stehende Modul einen `cve-XXXX-XXXXX-disable.conf`-Snippet, führt dann die Prüfungen erneut durch und meldet den Endzustand. Mit `-fix -unload` versucht vcheck zusätzlich, betroffene Module, die vor der Reparatur geladen waren, zu entladen, und überprüft dann mit dem endgültigen Scan, ob sie noch geladen sind. Mit `-fix -rebuild-initramfs` baut vcheck (nur) für den aktuell laufenden Kernel die Initramfs neu auf, nachdem ein Snippet geschrieben wurde, sodass die Blacklist in das nächste Startabbild eingebaut wird. Ältere Kernel-Einträge behalten ihre ursprüngliche Initramfs als Fallback. ## Verwenden Sie `-fix` erst nach einem reinen Prüflauf **Führen Sie vcheck immer zuerst ohne `-fix` aus.** Lesen Sie den Bericht und bestätigen Sie, dass die betroffenen Module auf diesem Host sicher deaktiviert werden können, bevor Sie mit `-fix` erneut ausführen. Das Deaktivieren von Kernel-Modulen, von denen legitime Arbeitslasten abhängen, kann Benutzer beeinträchtigen und Anwendungen zum Absturz bringen. Insbesondere: - Betrachten Sie `-fix` nur dann als sicher, wenn **keines** der betroffenen Module derzeit geladen ist – d. h. jedes Modul wird entweder als `mitigated` oder `module not blacklisted` gemeldet (keine `VULNERABLE`- oder `blacklisted but currently loaded`-Zeilen). Ein geladenes Modul bedeutet fast immer, dass _etwas auf dem Host es aktiv nutzt_; überprüfen Sie das, bevor Sie es auf die Blacklist setzen. - Die IPsec-Module (`esp4`, `esp6`, `ipcomp4`, `ipcomp6`, `xfrm_user`) werden für jede IPsec/strongSwan/WireGuard-over-IPsec/IKE-Bereitstellung benötigt. Die Module `ipcomp4`/`ipcomp6` implementieren die IPComp-Nutzdatenkomprimierung und können im Rahmen einer IPsec-SA automatisch ausgehandelt werden, auch wenn sie nicht explizit konfiguriert sind. Setzen Sie keines davon auf einem VPN-Gateway, IPsec-Endpunkt oder irgendwo, wo `ip xfrm policy` Regeln zurückgibt, auf die Blacklist. Beachten Sie, dass das Framework-Modul `xfrm_algo` absichtlich **nicht** in dieser Liste enthalten ist – gemäß den Anleitungen der Hersteller (Red Hat, Ubuntu, AWS) reicht es aus, die ESP- und IPComp-Protokollmodule sowie die Netlink-Konfigurationsschnittstelle `xfrm_user` zu blockieren, und das Blacklisten von `xfrm_algo` würde jede andere xfrm-Transformation ohne zusätzlichen Nutzen zerstören. - Die RxRPC-Module (`rxrpc`, `kafs`) werden für jeden Host benötigt, der AFS-Dateisysteme einbindet. Das Deaktivieren wird diese Mounts beim nächsten Neustart zerstören. - `algif_aead` macht Kernel-Kryptografie über die `AF_ALG`-Socket-Familie verfügbar. Es wird selten direkt von Anwendungscode verwendet; überprüfen Sie dies jedoch durch Auflisten der Live-Sockets (`ss -p --af-alg`) und der Userspace-Konsumenten, bevor Sie es auf die Blacklist setzen. Die von vcheck geschriebenen Blacklist-Snippets werden erst zum Zeitpunkt des Modulladens wirksam (normalerweise beim nächsten Neustart oder durch `modprobe -r <module>`, während das System im Leerlauf ist). Ein Modul, das _bereits geladen_ ist, läuft auch nach `-fix` weiter – vcheck meldet dies als `blacklisted but currently loaded; run 'modprobe -r' or reboot`. Durch Hinzufügen von `-unload` zu `-fix` wird vcheck angewiesen, nach dem Schreiben der Blacklist-Snippets `modprobe -r` für geladene betroffene Module auszuführen. Verwenden Sie dies nur, wenn Sie bestätigt haben, dass die Module sicher aus dem laufenden Kernel entfernt werden können. Wenn Sie `-rebuild-initramfs` mit `-fix` übergeben, wird die Initramfs **nur für den derzeit laufenden Kernel** neu generiert (`update-initramfs -u -k $(uname -r)` unter Debian/Ubuntu, `dracut -f --kver $(uname -r)` unter RHEL/Fedora). Andere installierte Kernel behalten ihre vorhandene Initramfs unberührt, sodass Sie nach einem Neustart bei Problemen einen älteren Kernel-Eintrag aus dem Boot-Menü auswählen und das System wiederherstellen können. Zukünftige Kernel-Installationen bauen ihre eigene Initramfs aus dem aktuellen Zustand von `/etc/modprobe.d/` neu auf, sodass die Blacklist automatisch propagiert wird, ohne vcheck erneut ausführen zu müssen. Wenn weder `update-initramfs` noch `dracut` vorhanden sind (z. B. Arch, Alpine, unveränderliche Images), warnt vcheck und fährt fort – bauen Sie die Initramfs vor dem Neustart manuell mit dem Tool Ihrer Distribution neu auf. Der Neubau kann mehrere Minuten dauern (insbesondere `dracut` auf Hosts mit vielen Treibern), was das diagnostische `-command-timeout` überschreiten würde. Er läuft unter seinem eigenen `-initramfs-timeout` (Standard `10m`), sodass der Neubau den benötigten Spielraum erhält, während die schnellen Prüfungen ihr knappes Budget behalten. Erhöhen Sie `-initramfs-timeout` für langsame Hardware, oder übergeben Sie `0`, um das Timeout vollständig zu deaktivieren. Während langlebiger Remote-Befehle sendet vcheck standardmäßig alle `30s` SSH-Keepalive-Anfragen, um zu verhindern, dass NAT/Firewall-Idle-Timer die Verbindung trennen. Passen Sie dies mit `-ssh-keepalive` an, oder übergeben Sie `0`, um es zu deaktivieren. ## Installation **Homebrew (macOS):** ```bash brew install --cask krisiasty/tap/vcheck ``` **Vorkompilierte Binärdateien** für Linux, macOS und Windows werden auf der [Releases-Seite](https://github.com/krisiasty/vcheck/releases) veröffentlicht. **Aus dem Quellcode** (erfordert Go 1.26+): ```bash go install github.com/krisiasty/vcheck@latest ``` ## Verwendung ```text vcheck -host HOST [flags] ``` | Flag | Standard | Beschreibung | | -------------------- | ------------ | --------------------------------------------------------------------------------------------- | | `-host` | _(erforderlich)_ | Entfernter Host | | `-user` | `$USER` | Entfernter Benutzer | | `-port` | `22` | Entfernter SSH-Port | | `-agent` | `true` | SSH-Agent zur Authentifizierung verwenden | | `-identity` | _(leer)_ | Pfad zu einer privaten Schlüsseldatei (fragt nach Passphrase, falls verschlüsselt) | | `-password` | `false` | Nach einem SSH-Passwort fragen | | `-insecure` | `false` | Host-Schlüssel akzeptieren, die noch nicht in `known_hosts` aufgezeichnet sind; Abweichungen von einem aufgezeichneten Schlüssel schlagen weiterhin fehl | | `-fix` | `false` | `/etc/modprobe.d`-Snippets für Module schreiben, die noch nicht auf der Blacklist stehen | | `-unload` | `false` | Mit `-fix` betroffene Module nach dem Blacklisting entladen | | `-rebuild-initramfs` | `false` | Mit `-fix` Initramfs nur für den laufenden Kernel neu bauen (`update-initramfs` oder `dracut`) | | `-skip-logs` | `false` | Kernel-Log-Verlaufsprüfungen überspringen | | `-timeout` | `15s` | SSH-Verbindungs-Timeout | | `-ssh-keepalive` | `30s` | SSH-Keepalive-Intervall (`0` deaktiviert) | | `-command-timeout` | `30s` | Timeout für entfernte Befehle (`0` deaktiviert) | | `-initramfs-timeout` | `10m` | Timeout für den Initramfs-Neubauschritt (`0` deaktiviert); wird nur mit `-rebuild-initramfs` verwendet | | `-debug` | `false` | Erhöhen Sie die Ausführlichkeit der Protokolle | | `-version` | `false` | Version anzeigen und beenden | Mindestens eine der Methoden `-agent`, `-identity` oder `-password` muss eine verwendbare Authentifizierungsmethode ergeben. Die Methoden werden in der angegebenen Reihenfolge ausprobiert. Sudo ist auf dem Ziel erforderlich. Wenn passwortloses Sudo konfiguriert ist, arbeitet das Tool still; andernfalls fragt es einmal nach einem Passwort (Eingabe wird ausgeblendet) und übergibt es über `sudo -S` für jeden nachfolgenden Befehl. ## Exit-Codes | Code | Bedeutung | | ---- | ------------------------------------------------------------------------------- | | `0` | Alle betroffenen Module auf der Blacklist, entladen, nicht eingebaut und inaktiv | | `1` | Verwendungsfehler | | `2` | SSH-Verbindung fehlgeschlagen | | `3` | Sudo-Authentifizierung fehlgeschlagen | | `4` | Ein oder mehrere Module nicht auf der Blacklist (keine aktuelle Gefährdung) | | `5` | Ein oder mehrere Module derzeit geladen, in den Kernel eingebaut oder aktiv in Verwendung | | `99` | Interner/Prüffehler | ## Beispielausgabe ### Vollständig entschärfter Host ```console $ 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 ``` ### Nicht entschärft und teilweise geladen – reine Prüfung ```console $ 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 ``` ### Gleicher Host mit `-fix` – erster Lauf ```console $ 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 ``` Die Blacklist ist vorhanden, aber `esp4` wurde bereits in den Kernel geladen, bevor der Snippet geschrieben wurde. Starten Sie neu oder führen Sie `sudo modprobe -r esp4` auf dem Ziel aus, um es vollständig zu entfernen. ### Zweiter Lauf – esp4 immer noch geladen ```console $ 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 ``` ### Dritter Lauf – nach `modprobe -r esp4` ```console $ 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 ``` ### Mit `-rebuild-initramfs` ```console $ 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 ... ``` Nur die Initramfs des laufenden Kernels wird neu gebaut. Andere installierte Kernel behalten ihre vorhandene Initramfs, sodass ein älterer Eintrag im Boot-Menü ein funktionierender Fallback bleibt, wenn die neue Initramfs Probleme verursacht. Auf einem Host, der weder `update-initramfs` noch `dracut` hat, protokolliert vcheck `WRN no supported initramfs tool found ...` und fährt fort. ### Erstmaliger Host – `-insecure` ```console $ 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` akzeptiert Hosts, die noch nicht in `known_hosts` vorhanden sind. Wenn ein Host _bereits_ aufgezeichnet ist und einen anderen Schlüssel präsentiert, schlägt die Verbindung dennoch fehl – das Flag ist nur eine „Erstkontakt“-Überbrückung, keine Möglichkeit, Man-in-the-Middle-Warnungen für einen bekannten Host zu unterdrücken. ## Erkennungsdetails - **Geladen:** `lsmod` wird einmal abgerufen und Modulnamen werden mit der ersten Spalte abgeglichen. - **Eingebaut:** `/lib/modules/$(uname -r)/modules.builtin` und `/sys/module` werden geprüft, da modprobe-Snippets keinen in den laufenden Kernel kompilierten Code deaktivieren können. - **Auf der Blacklist:** Jede Datei unter `/etc/modprobe.d/` wird durchsucht (`grep -rE`) nach einer `install <module> /bin/false`-Direktive – dieselbe Form, die vcheck mit `-fix` schreibt. Andere Formen der Deaktivierung (z. B. `blacklist`) werden nicht erkannt. - **Vergangene Aktivität:** Zuerst wird `journalctl -k` konsultiert, mit einem Fallback auf `/var/log/kern.log`; die letzten fünf übereinstimmenden Zeilen pro Modul werden gespeichert. Übergeben Sie `-skip-logs`, um diesen Schritt zu überspringen. - **Aktive Sockets (nur `algif_aead`):** `ss -p --af-alg` listet offene `AF_ALG`-Sockets auf; jede Ausgabe außer der Kopfzeile gilt als aktive Nutzung. Alle Befehle werden über `sudo` ausgeführt und sind durch `-command-timeout` begrenzt – privilegierter Zugriff ist erforderlich, um `/var/log/kern.log` zu lesen, `AF_ALG`-Sockets aufzulisten und unter `/etc/modprobe.d/` zu schreiben. Mit `-unload` ist auch privilegierter Zugriff für die Ausführung von `modprobe -r` erforderlich. Mit `-rebuild-initramfs` führt vcheck `update-initramfs -u -k $(uname -r)` (Debian/Ubuntu) oder `dracut -f --kver $(uname -r)` (RHEL/Fedora) aus, die ebenfalls Root-Rechte benötigen.