
vcheck v1.6.3
Copy FailおよびDirty Fragのバグ(CVE-2026-31431、CVE-2026-43284、CVE-2026-43500)に対する脆弱性検出・緩和ツール
vcheck
SSH経由でリモートLinuxホストを監査し、Copy FailおよびDirty Fragカーネルモジュールの脆弱性を確認し、必要に応じて緩和策を適用します。
| CVE | 名前 | 影響を受けるモジュール |
|---|---|---|
| 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 |
影響を受ける各モジュールについて、vcheckは現在ロードされているか、実行中のカーネルに組み込まれているか、カーネルログに過去のトレースがあるか、AF_ALGソケットがライブで存在するか(Copy Failのみ)、および/etc/modprobe.d/下で既にブラックリストに登録されているかを報告します。
-fixを指定すると、vcheckは初期状態を報告し、まだブラックリストに登録されていないモジュールに対してcve-XXXX-XXXXX-disable.confスニペットを作成し、その後チェックを再実行して最終状態を報告します。-fix -unloadを指定すると、vcheckは修正前にロードされていた影響を受けるモジュールのアンロードも試み、最終スキャンでまだロードされているかどうかを確認します。-fix -rebuild-initramfsを指定すると、vcheckはスニペット作成後、現在実行中のカーネルのみのinitramfsを再構築し、次回ブートイメージにブラックリストを組み込みます。古いカーネルエントリは、フォールバックとして元のinitramfsを保持します。
チェックのみの実行後にのみ-fixを使用してください
常に最初に-fixなしでvcheckを実行してください。 レポートを読み、このホストで影響を受けるモジュールを無効にしても安全であることを確認してから、-fixを付けて再実行してください。正規のワークロードが依存するカーネルモジュールを無効にすると、ユーザーに影響を与えたり、アプリケーションを壊したりする可能性があります。
特に:
-fixは、影響を受けるモジュールのいずれも現在ロードされていない場合にのみ安全と見なしてください。つまり、すべてのモジュールがmitigatedまたはmodule not blacklistedとして報告されている場合です(VULNERABLEまたはblacklisted but currently loadedの行がないこと)。ロードされたモジュールはほとんどの場合、何かがホストで積極的に使用していることを意味します。ブラックリストに登録する前に確認してください。- IPsecモジュール(
esp4,esp6,ipcomp4,ipcomp6,xfrm_user)は、IPsec/strongSwan/WireGuard-over-IPsec/IKEデプロイメントに必要です。ipcomp4/ipcomp6モジュールはIPCompペイロード圧縮を実装し、明示的に設定されていなくてもIPsec SAの一部として自動ネゴシエーションされる可能性があります。VPNゲートウェイ、IPsecエンドポイント、またはip xfrm policyがルールを返す場所では、これらをブラックリストに登録しないでください。xfrm_algoフレームワークモジュールは意図的にこのリストに含まれていないことに注意してください。ベンダーガイダンス(Red Hat、Ubuntu、AWS)によると、ESPおよびIPCompプロトコルモジュールに加えてxfrm_usernetlink設定インターフェースをブロックすれば十分であり、xfrm_algoをブラックリストに登録すると、他のすべてのxfrm変換機能が壊れるだけで、追加のメリットはありません。 - RxRPCモジュール(
rxrpc,kafs)は、AFSファイルシステムをマウントするホストに必要です。無効にすると、次回ブート時にそれらのマウントが壊れます。 algif_aeadは、AF_ALGソケットファミリーを介してカーネル暗号を公開します。アプリケーションコードで直接使用されることはほとんどありませんが、ライブソケットをリスト(ss -p --af-alg)し、ブラックリストに登録する前にユーザースペースのコンシューマを確認してください。
vcheckが書き込むブラックリストスニペットは、モジュールロード時にのみ有効になります(通常は次回ブート時、またはシステムがアイドル状態のときにmodprobe -r <module>を実行)。すでにロードされているモジュールは-fix後も動作を続けます。vcheckはこれをblacklisted but currently loaded; run 'modprobe -r' or rebootとして報告します。-fixとともに-unloadを渡すと、vcheckはブラックリストスニペットの書き込み後、ロードされている影響を受けるモジュールに対してmodprobe -rを実行します。これは、モジュールを実行中のカーネルから安全に削除できることを確認した場合にのみ使用してください。
-fixとともに-rebuild-initramfsを渡すと、現在実行中のカーネルのみのinitramfsが再生成されます(Debian/Ubuntuではupdate-initramfs -u -k $(uname -r)、RHEL/Fedoraではdracut -f --kver $(uname -r))。他のインストール済みカーネルは既存のinitramfsを変更せずに残します。そのため、再起動後に問題が発生した場合は、ブートメニューから古いカーネルエントリを選択して回復できます。将来のカーネルインストールでは、現在の/etc/modprobe.d/の状態から独自のinitramfsを再構築するため、再実行しなくてもブラックリストは自動的に伝播します。update-initramfsもdracutも存在しない場合(例: Arch, Alpine, 不変イメージ)、vcheckは警告を出して続行します。再起動前に、ディストリビューションのツールを使用して手動で再構築してください。
再構築には数分かかる場合があり(特に多くのドライバがあるホストでのdracut)、診断用の-command-timeoutを超える可能性があります。これは独自の-initramfs-timeout(デフォルト10m)の下で実行されるため、再構築に必要な時間が確保され、高速チェックは厳しい制限を維持します。低速ハードウェアの場合は-initramfs-timeoutを増やすか、0を渡してタイムアウトを完全に無効にします。長時間のリモートコマンド中、vcheckはデフォルトで30秒ごとにSSHキープアライブリクエストを送信し、NAT/ファイアウォールのアイドルタイマーによる接続切断を防ぎます。-ssh-keepaliveで調整するか、0を渡して無効にします。
インストール
Homebrew (macOS):
brew install --cask krisiasty/tap/vcheck
プリビルドバイナリ(Linux、macOS、Windows用)はリリースページで公開されています。
ソースから(Go 1.26+が必要):
go install github.com/krisiasty/vcheck@latest
使い方
vcheck -host HOST [flags]
| フラグ | デフォルト | 説明 |
|---|---|---|
-host | (必須) | リモートホスト |
-user | $USER | リモートユーザー |
-port | 22 | リモートSSHポート |
-agent | true | 認証にSSHエージェントを使用 |
-identity | (空) | 秘密鍵ファイルへのパス(暗号化されている場合はパスフレーズを要求) |
-password | false | SSHパスワードを要求 |
-insecure | false | known_hostsにまだ記録されていないホスト鍵を受け入れる;記録された鍵との不一致は依然として失敗 |
-fix | false | まだブラックリストに登録されていないモジュールに対して/etc/modprobe.dスニペットを作成 |
-unload | false | -fixとともに、ブラックリスト登録後に影響を受けるモジュールをアンロード |
-rebuild-initramfs | false | -fixとともに、実行中のカーネルのみのinitramfsを再構築(update-initramfsまたはdracut) |
-skip-logs | false | カーネルログ履歴チェックをスキップ |
-timeout | 15s | SSH接続タイムアウト |
-ssh-keepalive | 30s | SSHキープアライブ間隔(0で無効) |
-command-timeout | 30s | リモートコマンドのタイムアウト(0で無効) |
-initramfs-timeout | 10m | initramfs再構築ステップのタイムアウト(0で無効);-rebuild-initramfsとのみ使用 |
-debug | false | ログの詳細度を上げる |
-version | false | バージョンを表示して終了 |
-agent、-identity、-passwordのうち少なくとも1つが使用可能な認証方法を生成する必要があります。メソッドはリストされた順序で試行されます。
ターゲットではsudoが必要です。パスワードなしのsudoが設定されている場合、ツールは静かに進みます。それ以外の場合は、パスワードを1回要求し(入力は非表示)、以降のすべてのコマンドでsudo -S経由で渡します。
終了コード
| コード | 意味 |
|---|---|
0 | すべての影響を受けるモジュールがブラックリストに登録され、アンロードされ、組み込まれておらず、非アクティブ |
1 | 使用法エラー |
2 | SSH接続失敗 |
3 | Sudo認証失敗 |
4 | 1つ以上のモジュールがブラックリストに登録されていない(現在の露出なし) |
5 | 1つ以上のモジュールが現在ロードされている、カーネルに組み込まれている、またはアクティブに使用中 |
99 | 内部/チェック失敗 |
出力例
完全に緩和されたホスト
$ 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 — 初回実行
$ 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
ブラックリストは適用されていますが、スニペット作成前にesp4がカーネルにロードされていました。完全にクリアするには、ターゲットで再起動するかsudo modprobe -r esp4を実行してください。
2回目の実行 — esp4がまだロードされている
$ 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
3回目の実行 — 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
...
実行中のカーネルのinitramfsのみが再構築されます。他のインストール済みカーネルは既存のinitramfsを保持するため、ブートメニューの古いエントリは、新しいinitramfsで問題が発生した場合のフォールバックとして機能します。update-initramfsもdracutも存在しないホストでは、vcheckはWRN no supported initramfs tool found ...をログに記録して続行します。
初回ホスト — -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は、known_hostsにまだ存在しないホストを受け入れます。ただし、ホストがすでに記録されており、別の鍵を提示した場合、接続は依然として失敗します。このフラグは「初回接続」のオーバーライドのみであり、既知のホストで中間者攻撃の警告を抑制する方法ではありません。
検出の詳細
- ロード済み:
lsmodを1回取得し、モジュール名を最初の列と照合します。 - 組み込み:
/lib/modules/$(uname -r)/modules.builtinと/sys/moduleをチェックします。modprobeスニペットでは、実行中のカーネルにコンパイルされたコードを無効にできないためです。 - ブラックリスト:
/etc/modprobe.d/下のすべてのファイルを検索し(grep -rE)、install <module> /bin/falseディレクティブがあるか確認します。これはvcheckが-fixで書き込む形式と同じです。他の無効化形式(例:blacklist)は認識されません。 - 過去のアクティビティ: 最初に
journalctl -kを参照し、フォールバックとして/var/log/kern.logを使用します。モジュールごとに最後の5行の一致行を保持します。この手順をスキップするには-skip-logsを渡します。 - アクティブなソケット(
algif_aeadのみ):ss -p --af-algで開いているAF_ALGソケットをリストします。ヘッダー以外の出力は、ライブでの使用と見なされます。
すべてのコマンドはsudo経由で実行され、-command-timeoutで制限されます。/var/log/kern.logの読み取り、AF_ALGソケットのリスト、/etc/modprobe.d/下への書き込みには特権アクセスが必要です。-unloadを使用する場合、modprobe -rの実行にも特権アクセスが必要です。-rebuild-initramfsを使用する場合、vcheckはupdate-initramfs -u -k $(uname -r)(Debian/Ubuntu)またはdracut -f --kver $(uname -r)(RHEL/Fedora)を実行します。これらもrootが必要です。