Временная защита: окна, закрытые досками

Временная мера против CVE-2026-98432 уже развернута на 26 серверах. Ниже — порядок применения nftables‑фильтра: от проверки пакета ядра до отката и загрузки правила после перезапуска.

Команды рассчитаны на Ubuntu с nftables и systemd, для входящего трафика самого хоста. Для трафика, пересылаемого контейнерам или другим узлам, нужно отдельно выбрать цепочку фильтрации.

1. Проверьте статус исправления

Узнайте запущенное ядро:

uname -r

На странице Canonical найдите свой релиз и пакет ядра. Work in progress означает, что исправление готовится; указанная рядом версия — плановая, пакет еще не выпущен.

Если исправление уже доступно для вашей ветки, запланируйте обновление и загрузку в исправленное ядро. Временный фильтр нужен на период ожидания. Red Hat предлагает отбрасывать IPv4 TCP‑пакеты с IP‑options: это снижает экспозицию, но не заменяет исправление ядра.

2. Подготовьте один сервер и откат

Начните с одного узла. Сохраните действующие правила и подготовьте доступ к консоли хостера на случай потери SSH.

Посмотрите текущую конфигурацию:

(umask 077; sudo nft list ruleset > "$HOME/nft-before.txt")
sudo nft list table inet cve_2026_98432

Ошибка об отсутствии таблицы на этом шаге ожидаема. Если таблица cve_2026_98432 уже существует, сначала разберитесь, кто ее установил. Повторно создавать ее и удалять чужое правило не нужно.

Подготовьте команду отката; выполняйте ее только при необходимости снять новую таблицу:

sudo nft delete table inet cve_2026_98432

Она снимает только добавленный фильтр.

3. Подготовьте правило

Сохраните пример из бюллетеня Red Hat в файл cve-2026-98432.nft:

table inet cve_2026_98432 {
    chain input {
        type filter hook input priority -310; policy accept;
        ip protocol tcp ip hdrlength > 5 counter drop
    }
}

Условие ip hdrlength > 5 относится к заголовку IPv4. Обычные TCP‑options, например MSS и timestamps, находятся в TCP‑заголовке и под это условие не попадают.

Проверьте синтаксис:

sudo nft --check --file cve-2026-98432.nft

Исправьте ошибки до применения. Не очищайте существующие таблицы через flush ruleset.

4. Взведите автооткат и примените фильтр

До загрузки правила поставьте таймер на пять минут. Сначала убедитесь, что command -v nft возвращает полный путь к программе:

nft_bin=$(command -v nft)
sudo systemd-run --collect --unit=cve-98432-rollback --on-active=5m \
  "$nft_bin" delete table inet cve_2026_98432
sudo systemctl is-active cve-98432-rollback.timer

Продолжайте, только если таймер успешно создан и находится в состоянии active. Если имя службы занято или путь к программе не найден, сначала устраните причину.

Загрузите правило и проверьте его наличие:

sudo nft --file cve-2026-98432.nft
sudo nft list table inet cve_2026_98432

5. Проверьте доступ и сервисы

Откройте новое SSH‑подключение с другой машины. Затем проверьте прикладной трафик: HTTPS, API или реальное подключение клиентом вашего сервиса. Сравните прежние правила с сохраненной конфигурацией.

После успешной проверки отмените таймер и еще раз убедитесь, что таблица остается на месте:

sudo systemctl stop cve-98432-rollback.timer cve-98432-rollback.service
sudo nft list table inet cve_2026_98432
  • Если таблицы уже нет, автооткат мог сработать.

  • Если связь нарушилась, дайте таймеру сработать либо удалите только эту таблицу через консоль.

  • После любого отката остановите таймер и его службу командой из предыдущего блока. Затем повторите процедуру с шага 4, заново взведя таймер.

6. Настройте загрузку и повторите на остальных узлах

Добавьте применение отдельной таблицы в действующую схему запуска firewall. Загрузчик фильтра должен добавлять только свою таблицу, сохраняя правила основного firewall. Если ими управляют ufw, Docker или другой менеджер, не включайте ради этой таблицы nftables.service с flush ruleset в конфигурации. Проверьте и обратный порядок: основной firewall при загрузке не должен стирать фильтр.

Перед перезагрузкой проверьте все измененные файлы загрузки через nft --check --file. Например, для штатной конфигурации:

sudo nft --check --file /etc/nftables.conf

В согласованное окно перезагрузите пилот. После загрузки проверьте успешный запуск службы основного firewall, наличие новой таблицы и сохранность прежних таблиц, цепочек и правил по снимку ~/nft-before.txt; счетчики пакетов и динамические элементы наборов могут измениться. Затем откройте новое SSH‑подключение и проверьте сервис. После приемки пилота повторяйте процедуру на остальных узлах, с отдельным автооткатом для каждого.

После выпуска исправления обновите ядро и загрузитесь в него. Сопоставьте запущенную версию с исправленным пакетом своей ветки. Затем уберите загрузку временной таблицы из конфигурации и снова проверьте измененные файлы через nft --check --file. После этого удалите саму таблицу.

Комментарии (20)


  1. korn3r
    02.11.2026 23:27

    охренеть, целый systemd-unit для добавления одного единственного правила nftables, которое блочит только те пакеты, которые и так нахер не нужны ~99.9% серверов


    1. dewil Автор
      02.11.2026 23:27

      Для постоянной загрузки правило можно добавить в существующую конфигурацию firewall, согласен. systemd-run здесь ставит временный таймер отката: через пять минут он удалит новую таблицу, если таймер не отменить вручную. Это страховка на случай потери SSH. После проверки таймер и служба останавливаются.


    1. poige
      02.11.2026 23:27

      которые и так нахер не нужны ~99.9% серверов

      Я бы не советовал оценивать долю открытых сервисов на Go в 0.1 %.

      По уровню залёта этот баг делает даже недавний PHP2Shell.

      Смешное, что даже мой вариант заголовка:

      CVE…432 — Go: Дистанционный root в Linux

      не очень эффективно поджигает нужные нейрончики у основной массы прочитавших — люди, замученные нарзаном кликбейтом, читают это всё равно без должного уровня понимания опасности. Видимо пора переделать на что-то в духе «открыт порт сервиса на Go? — открыт и Linux root shell»


      1. korn3r
        02.11.2026 23:27

        а я бы вам советовал все таки сначала читать на что вы отвечаете, а потом отвечать.
        я писал про IP пакеты с Options. которые во-первых все таки нахер не нужны большинству (подавляющему) сервисов и приложений, и во-вторых и без того рекомендуются к дропу на сетевом оборудовании (многие из них по крайней мере).

        и вопрос: вы же понимаете что cve вообще не про Go?


        1. poige
          02.11.2026 23:27

          и вопрос: вы же понимаете что cve вообще не про Go?

          полагаю, прочитай вы ту новость, которую я написал — вопрос бы не возникал.

          а я бы вам советовал все таки сначала читать на что вы отвечаете, а потом отвечать.

          то есть вы считаете, что ваша короткая фраза «охренеть, целый systemd-unit для добавления одного единственного правила nftables, которое блочит только те пакеты, которые и так нахер не нужны ~99.9% серверов» не допускает того прочтения, которое сделал я? Ну так вы себе льстите, должен заметить.


          1. korn3r
            02.11.2026 23:27

            если вы все таки прочитали, то може объясните мне каким образом вы приравняли крайне специфически ip пакеты к go сервисам вот тут

            Я бы не советовал оценивать долю открытых сервисов на Go в 0.1 %.

            и я сам cve читал.зачем мне ваша новость? https://nvd.nist.gov/vuln/detail/cve-2026-98432


            1. poige
              02.11.2026 23:27

              сорян, чё-то как-то агрессивно звучит. Я же не настаиваю. Простите, не хотел никак задеть, если что. В смысле — я уже пояснил, что вполне допускаю, что неправильно прочитал вашу краткую фразу. Предложил просто не считать, что она сама по себе не оставляет возможности трактовать её так, как я сделал. Но нет, так нет.


              1. korn3r
                02.11.2026 23:27

                ок. но все таки в посте про правило nftables где даже нет ни одного упоминания (в тексте поста) Go или хотя бы mptcp считать по-умолчанию что человек в первом комментарии под словом "пакет" имеет в виду Go приложение, это надо ну очень сильно хотеть самому так трактовать.

                И у вас в новости почему-то в заголовке номер CVE обрезан.


                1. poige
                  02.11.2026 23:27

                  И у вас в новости почему-то в заголовке номер CVE обрезан.

                  да, замысел в том, что человек обратит внимание на «432» больше (и лучше запомнит), чем на некоторый индекс, который будет полным, но бесполезным как само сообщение. Это такой «хороший клик-бейт», если угодно. — Механизм отчасти мнемонический: 432 становится «лёгким» идентификатором в контексте статьи, а полный CVE остаётся в тексте и доступен по ссылке.


  1. nojecom
    02.11.2026 23:27

    echo 'net.mptcp.enabled = 0' | sudo tee /etc/sysctl.d/99-mptcp.conf && sudo sysctl --system


    1. korn3r
      02.11.2026 23:27

      лучше уж пакеты с ip options резать. отключение mptcp помогает от конкретно того что было реализовано в демонстрационных целях, а не от самого cve.


    1. poige
      02.11.2026 23:27

      — выключит только в одном net ns, в любом «контейнере» будет "on" — потому, что 1 — дефолт инициализации. Я писал об этом в новости от 30 октября.


    1. olegtsss
      02.11.2026 23:27

      Вот я за этот же способ sysctl net.mptcp.enabled. Во-первых на старых ядрах он и так скорее всего не входит в ядро, а для более свежих отключить его, делов... Отвечу на свой же комментарий, что если модуль все-таки есть в ядре, то этого не хватит, так как контейнеры пойдут с другим namespace и другим дефолтом для этого. Можно запретить загрузку модуля:

      # /etc/modprobe.d/blacklist-mptcp.conf
      
      blacklist mptcp
      install mptcp /bin/true

      Тратить ресурсы firewall на анализ tcp стека по мне так расточительно, хотя для new-connections может и не сильно.


      1. Dimmirslr
        02.11.2026 23:27

        Не думаю, что проверка длины заголовка прям сожрет все ресурсы


        1. olegtsss
          02.11.2026 23:27

          Нет конечно, вопрос дизайна. Любое правило в L3 firewall должно быть понятно сетевому инженеру, и точно не сводится к закрытию CVE. Хотя как hotfix пойдет. С другой стороны, нет ничего постояннее чем временное.


          1. korn3r
            02.11.2026 23:27

            через фаервол зато прикрываемся от дыры в ядре, а не от частного случая ее применения, который был продемонстрирован.


      1. dewil Автор
        02.11.2026 23:27

        В Linux 6.8 CONFIG_MPTCP имеет тип bool: при CONFIG_MPTCP=y поддержка встроена в ядро. Поэтому blacklist mptcp в modprobe.d ее не отключит.


        1. olegtsss
          02.11.2026 23:27

          У меня ядро 6.1, там тоже самое:

          CONFIG_MPTCP=y
          CONFIG_MPTCP_IPV6=y

          Увы, мой комментарий не рабочий.


      1. olegtsss
        02.11.2026 23:27

        Мой комментарий выше не рабочий. Тогда так:

        apt update
        apt --only-upgrade install linux-image-amd64
        uname -r
        reboot
        uname -r            6.1.0-54-amd64    Пакет: linux-image-6.1.0-54-amd64 (6.1.190-1) [security]


  1. Dimmirslr
    02.11.2026 23:27

    На самом деле отключение mptcp через sysctl не универсальное средство если крутится много контейнеров со своими неймспейсами