Назад к обновлениям
New releaseAug 17, 2026

vcheck v1.6.3

Инструмент обнаружения и устранения уязвимостей для ошибок Copy Fail и Dirty Frag (CVE-2026-31431, CVE-2026-43284, CVE-2026-43500)

Поделиться

vcheck

Проверка удалённого Linux-хоста по SSH на уязвимости ядерных модулей Copy Fail и Dirty Frag и, при необходимости, применение мер по устранению:

CVEНазваниеЗатронутые модули
CVE-2026-31431Copy Failalgif_aead
CVE-2026-43284Dirty Frag (IPsec)esp4, esp6, ipcomp4, ipcomp6, xfrm_user
CVE-2026-43500Dirty 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 только после проверочного запуска

Всегда сначала запускайте vcheck без -fix. Изучите отчёт и убедитесь, что затронутые модули можно безопасно отключить на этом хосте, прежде чем повторно запускать с -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 плюс интерфейса конфигурации netlink xfrm_user достаточно, а внесение 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. Передача -unload вместе с -fix предписывает vcheck выполнить modprobe -r для загруженных затронутых модулей после записи фрагментов чёрного списка. Используйте это только после того, как подтвердили, что модули можно безопасно удалить из работающего ядра.

Передача -rebuild-initramfs вместе с -fix пересоздаёт initramfs только для текущего работающего ядра (update-initramfs -u -k $(uname -r) на Debian/Ubuntu, dracut -f --kver $(uname -r) на RHEL/Fedora). Остальные установленные ядра сохраняют свой initramfs нетронутым, поэтому если после перезагрузки что-то пойдёт не так, вы сможете выбрать более старую запись ядра из меню загрузки и восстановиться. Будущие установки ядра пересобирают собственный initramfs на основе текущего состояния /etc/modprobe.d/, поэтому чёрный список распространяется автоматически без повторного запуска vcheck. Если ни update-initramfs, ни dracut не установлены (например, Arch, Alpine, неизменяемые образы), vcheck выводит предупреждение и продолжает работу — пересоберите вручную инструментом вашего дистрибутива перед перезагрузкой.

Пересборка может занять несколько минут (особенно dracut на хостах с большим количеством драйверов), что превысило бы диагностический -command-timeout. Она выполняется под собственным -initramfs-timeout (по умолчанию 10m), поэтому пересборка получает необходимое время, а быстрые проверки сохраняют свой жёсткий бюджет. Увеличьте -initramfs-timeout для медленного оборудования или укажите 0, чтобы полностью отключить тайм-аут. Во время длительных удалённых команд vcheck по умолчанию отправляет SSH keepalive-запросы каждые 30s, чтобы таймеры простоя 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Удалённый пользователь
-port22Удалённый SSH-порт
-agenttrueИспользовать SSH-агент для аутентификации
-identity(пусто)Путь к файлу закрытого ключа (запросит парольную фразу, если ключ зашифрован)
-passwordfalseЗапросить SSH-пароль
-insecurefalseПринимать ключи хостов, ещё не записанные в known_hosts; несовпадения с записанным ключом по-прежнему приводят к ошибке
-fixfalseЗаписать фрагменты в /etc/modprobe.d для модулей, которые ещё не внесены в чёрный список
-unloadfalseВместе с -fix выгрузить затронутые модули после внесения их в чёрный список
-rebuild-initramfsfalseВместе с -fix пересобрать initramfs только для работающего ядра (update-initramfs или dracut)
-skip-logsfalseПропустить проверки истории журналов ядра
-timeout15sТайм-аут SSH-подключения
-ssh-keepalive30sИнтервал SSH keepalive (0 отключает)
-command-timeout30sТайм-аут удалённой команды (0 отключает)
-initramfs-timeout10mТайм-аут для шага пересборки initramfs (0 отключает); используется только с -rebuild-initramfs
-debugfalseПовысить подробность журналирования
-versionfalseПоказать версию и выйти

По крайней мере один из -agent, -identity или -password должен обеспечить рабочий метод аутентификации. Методы перебираются в указанном порядке.

На целевом хосте требуется sudo. Если настроен sudo без пароля, инструмент продолжает работу без запросов; в противном случае он один раз запрашивает пароль (ввод скрыт) и передаёт его через sudo -S для каждой последующей команды.

Коды выхода

КодЗначение
0Все затронутые модули внесены в чёрный список, выгружены, не встроены в ядро и неактивны
1Ошибка использования
2Не удалось установить SSH-подключение
3Ошибка аутентификации sudo
4Один или несколько модулей не внесены в чёрный список (текущей угрозы нет)
5Один или несколько модулей в данный момент загружены, встроены в ядро или активно используются
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 на целевом хосте, чтобы полностью его выгрузить.

Второй запуск — 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

Третий запуск — после 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 выполняется один раз, а имена модулей сопоставляются с первой колонкой.
  • Встроен в ядро: проверяются /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; для каждого модуля сохраняются последние пять подходящих строк. Передайте -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.

Категории