From 63a7e0f3732d683c0ad13b08584a4807f5d6eb50 Mon Sep 17 00:00:00 2001 From: jestivald Date: Sun, 6 Sep 2026 00:52:26 +0300 Subject: [PATCH 1/6] fix: leave distribution nftables boot service under operator control --- CHANGELOG.md | 16 ++++++++++++++++ scripts/protect.sh | 5 ++++- tests/apply-smoke.sh | 14 ++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e16108f..23c7f1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # Changelog +## Unreleased + +### Firewall boot service ownership + +`protect` no longer enables the distribution's `nftables.service`. NA already +persists its table through `na-firewall.service`; the distribution's default +`/etc/nftables.conf` starts with `flush ruleset`, which can erase NA, CrowdSec and +Docker tables when boot services run in a different order. Existing operator +service settings remain unchanged. The apply test records service operations and +checks that only the NA boot service is enabled. + +Existing installations should inspect `nftables.service` and its configuration. +If it only loads the unused distribution template, disable its boot activation +with `systemctl disable nftables.service` (without `--now` or `stop`, which can +flush the running ruleset). Keep a deliberately managed distribution service. + ## v4.1.1 — 2026-09-02 Два хвоста того же аудита, заведённые уже после сборки v4.1 diff --git a/scripts/protect.sh b/scripts/protect.sh index 4241fab..aa32b0e 100755 --- a/scripts/protect.sh +++ b/scripts/protect.sh @@ -1084,7 +1084,10 @@ else fi systemctl daemon-reload systemctl enable na-firewall.service >/dev/null 2>&1 || true -systemctl enable nftables >/dev/null 2>&1 || true +# The distro service owns /etc/nftables.conf, whose default configuration starts +# with `flush ruleset`. Enabling it alongside our service races at boot with +# na_filter, CrowdSec and Docker. Only our own unit provides NA persistence; +# leave the operator's nftables.service state unchanged, including on re-runs. ok "na-firewall.service включён (правила переживут reboot — если не сработает сейфти-таймер: он теперь снимает и автозагрузку)" fi # ═══ конец блока файрвола (FW_MODE=skip его пропускает) ═══ diff --git a/tests/apply-smoke.sh b/tests/apply-smoke.sh index ad3ecb4..6cc9436 100755 --- a/tests/apply-smoke.sh +++ b/tests/apply-smoke.sh @@ -27,6 +27,14 @@ sed -e "s#/etc/systemd/system/#$T/sys/#g" \ for c in systemctl modprobe nft systemd-run sysctl conntrack; do printf '#!/bin/sh\nexit 0\n' > "$T/bin/$c"; chmod +x "$T/bin/$c" done +# Record service operations: protect owns na-firewall.service. Enabling the +# distro nftables.service can flush every table at the next boot. +export NA_TEST_SYSTEMCTL_LOG="$T/systemctl.log" +cat > "$T/bin/systemctl" <<'SYSTEMCTL' +#!/bin/sh +printf '%s\n' "$*" >> "$NA_TEST_SYSTEMCTL_LOG" +exit 0 +SYSTEMCTL # curl падает → сетевые fetch (crowdsec/blocklist/fleet) деградируют мягко, не висят. printf '#!/bin/sh\nexit 1\n' > "$T/bin/curl"; chmod +x "$T/bin/curl" # docker падает → детект node-порта детерминированно идёт по .env/ss-веткам @@ -71,6 +79,12 @@ rc=$? set -e fail=0 +grep -qx 'enable na-firewall.service' "$NA_TEST_SYSTEMCTL_LOG" \ + || { echo "[x] protect did not enable its own boot service"; fail=1; } +if grep -Eq '^(enable|start|restart|reload|stop|disable|mask)( [^ ]+)* nftables(\.service)?( |$)' "$NA_TEST_SYSTEMCTL_LOG"; then + echo "[x] protect changed the unrelated nftables.service (global ruleset risk)" + fail=1 +fi if [ "$rc" -ne 0 ]; then echo "[x] apply упал (exit $rc)"; fail=1; fi if grep -qiE 'unbound variable|bad substitution' "$LOG"; then echo "[x] найдена unbound-переменная:"; grep -iE 'unbound variable|bad substitution' "$LOG"; fail=1; fi # ключевые блоки должны были отработать From 12067071c120a5fdc182074f63c6f105885d0f84 Mon Sep 17 00:00:00 2001 From: jestivald Date: Sun, 6 Sep 2026 00:53:09 +0300 Subject: [PATCH 2/6] release: sign updated protection module --- scripts/protect.sh.minisig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/protect.sh.minisig b/scripts/protect.sh.minisig index 42a0aa0..6398ac2 100644 --- a/scripts/protect.sh.minisig +++ b/scripts/protect.sh.minisig @@ -1,4 +1,4 @@ -untrusted comment: node-accelerator v4.1.1 -RUQrJghT9nkdBCM9IR9iMEwQS6sDcwVTfzg4UV7E98JvNxD41mLD2QfmRf0TyPypOeHE83iUW2N3726gl0RL3SkQH1Sem0cEKwY= -trusted comment: timestamp:1788349350 file:protect.sh hashed -bF0SKfnBtn/+pe7g2Ti46F2QL1yc3RPBMYaeVV1YWrk3MMXXfiIxlWnAZgzpjRnEfswFkWtoigZfJ3snz+gOAA== +untrusted comment: node-accelerator: nftables boot ownership fix +RUQrJghT9nkdBCnzm86r8pvBf71BoFaOUiGzDiv7dwhaSDdCYidusMDERhfsaDi5uoNOu7JV6FdV5BJjRkqdaH9MdGxgoW26ywk= +trusted comment: timestamp:1788645146 file:protect.sh hashed +0zwX8eJdUyMibp52s0sqkGmIWuXPOoqpfpPyuiSPiuqwr8QVHuSED02mwRx3QUYYtjT6Bw/C/Kwjq+DpipTaAw== From 301b012c3683626db1b8378e12a79a73e37b28c6 Mon Sep 17 00:00:00 2001 From: jestivald Date: Sun, 6 Sep 2026 01:09:36 +0300 Subject: [PATCH 3/6] fix: apply RPS settings when rerunning an active oneshot --- CHANGELOG.md | 9 +++++++++ scripts/optimize.sh | 11 +++++++++-- tests/rps-unit.sh | 47 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23c7f1d..9d35a94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ ## Unreleased +### Apply RPS changes to an already-active unit + +`optimize` now restarts its RPS setup unit after updating the helper. Previously, +`enable --now` left an already-active `Type=oneshot` / `RemainAfterExit=yes` unit +untouched: upgrading the boot-race fix could still leave `rps_cpus=0` until a +manual restart or reboot, while the installer claimed success. Failed activation +now produces a warning. A behavioral regression test models an active oneshot, +checks the resulting CPU mask, and covers failed activation. + ### Firewall boot service ownership `protect` no longer enables the distribution's `nftables.service`. NA already diff --git a/scripts/optimize.sh b/scripts/optimize.sh index 214bc0f..e09bcfe 100755 --- a/scripts/optimize.sh +++ b/scripts/optimize.sh @@ -619,8 +619,15 @@ RestartSec=5 WantedBy=multi-user.target EOF systemctl daemon-reload -systemctl enable --now na-rps.service >/dev/null 2>&1 || true -ok "RPS/RFS/XPS включены ($(nproc) ядер, NIC=${NIC:-автодетект на буте})" +# An active oneshot with RemainAfterExit=yes is not run again by enable --now. +# Re-apply the updated helper on every optimize run, including after a previous +# boot raced with route setup and left the old unit active with rps_cpus=0. +systemctl enable na-rps.service >/dev/null 2>&1 || true +if systemctl restart na-rps.service >/dev/null 2>&1; then + ok "RPS/RFS/XPS включены ($(nproc) ядер, NIC=${NIC:-автодетект на буте})" +else + warn "na-rps.service: не удалось применить RPS — проверь journalctl -u na-rps.service" +fi # ─── 6. NIC tuning ─────────────────────────────────────────────────────────── title "NIC tuning (ring buffer, offloads)" diff --git a/tests/rps-unit.sh b/tests/rps-unit.sh index 11c49dd..f26310b 100755 --- a/tests/rps-unit.sh +++ b/tests/rps-unit.sh @@ -162,6 +162,53 @@ expect "NIC детектится ДО генерации юнита" \ test "$(grep -n 'NIC="\$(default_iface || true)"' "$REPO_ROOT/scripts/optimize.sh" | cut -d: -f1)" \ -lt "$(grep -n 'ExecStart=/usr/local/sbin/na-rps-setup' "$REPO_ROOT/scripts/optimize.sh" | cut -d: -f1)" +# An active oneshot is not executed again by `enable --now`. Exercise the +# installation section with that state, rather than calling the helper directly. +echo "== re-run while na-rps.service is already active ==" +extract_activation() { + awk ' + /^cat > \/etc\/systemd\/system\/na-rps.service < "$2" +} +extract_activation "$REPO_ROOT/scripts/optimize.sh" "$T/activation.sh" +cat > "$T/activation-driver.sh" <<'DRIVER' +. "$REPO_ROOT/scripts/lib/common.sh" +systemctl() { + case "$1" in + enable) + # A systemd oneshot with RemainAfterExit=yes is already active. + # Enabling it, with or without --now, does not run ExecStart again. + return 0;; + restart) + [ "${RPS_FORCE_FAILURE:-0}" = 1 ] && return 1 + "$WBASH" "$RPS" "$NIC";; + *) return 0;; + esac +} +. "$ACTIVATION" +DRIVER +run_activation() { + REPO_ROOT="$REPO_ROOT" WBASH="$WBASH" RPS="$RPS" NIC=ens18 \ + ACTIVATION="$1" "$WBASH" "$T/activation-driver.sh" > "$T/activation.out" 2>&1 +} +reset_net; mk_net ens18 1 +run_activation "$T/activation.sh" +expect "re-run applies RPS even when the old oneshot is active" test "$(mask_of ens18)" = 7 +reset_net; mk_net ens18 1 +RPS_FORCE_FAILURE=1 run_activation "$T/activation.sh" +expect "failed activation is reported" grep -q 'не удалось применить RPS' "$T/activation.out" +expect_not "failed activation must not claim RPS is enabled" grep -q 'RPS/RFS/XPS включены' "$T/activation.out" +if git -C "$REPO_ROOT" show v4.1.1:scripts/optimize.sh > "$T/v411-optimize.sh" 2>/dev/null; then + extract_activation "$T/v411-optimize.sh" "$T/v411-activation.sh" + reset_net; mk_net ens18 1 + run_activation "$T/v411-activation.sh" + expect "v4.1.1 left an already-active oneshot unapplied" test -z "$(mask_of ens18)" + expect "v4.1.1 nevertheless reported success" grep -q 'RPS/RFS/XPS включены' "$T/activation.out" +fi + # ── #28: ничего «курсорного» в не-терминал ────────────────────────────────────── echo "== курсорный вывод только в терминал (#28) ==" expect_not "голых 'tput ' в коде optimize.sh не осталось" bare_tput "$REPO_ROOT/scripts/optimize.sh" From 98667efabd501c7bc55baeaa8820c3731b06d2d1 Mon Sep 17 00:00:00 2001 From: jestivald Date: Sun, 6 Sep 2026 01:09:36 +0300 Subject: [PATCH 4/6] release: sign updated optimization module --- scripts/optimize.sh.minisig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/optimize.sh.minisig b/scripts/optimize.sh.minisig index b76315c..6ea5e50 100644 --- a/scripts/optimize.sh.minisig +++ b/scripts/optimize.sh.minisig @@ -1,4 +1,4 @@ -untrusted comment: node-accelerator v4.1.1 -RUQrJghT9nkdBFzx1P7p5JoJ79BCF7lkOYOkx8yobz7G1kvaOM7gT7Hk/iUIzrPMfYXe/Mq/BRshJyPUnp3BVc41zXTWz5gSxAE= -trusted comment: timestamp:1788349350 file:optimize.sh hashed -6/gfjc4FoY6moWYtPxteYrF7qI8QudC1R2PNtirQZSs+6JnwE0mPGi48iPOtPUKMJg1VjTK+IBEDEAkgatyeAA== +untrusted comment: node-accelerator: apply RPS on re-run +RUQrJghT9nkdBHNkft75Z4UjzKrUhQ2hfV+FA7zd6wdYt78VqBawBPg2/1sQ+jP/Lx1INpPy2PqAsPYRcwonvqF9Ve1QuyZugA8= +trusted comment: timestamp:1788646176 file:optimize.sh hashed +5pTdRXF/5yeA1jEZVAyXt2FF8gPWYpz0Z/8lX/p5+MU9VmBnqu3regQN61lZelBx4+wkhxjeivmzJKxv0G5eCw== From de1b15c2e8370ed10fd18db0726f9c976aa10a2e Mon Sep 17 00:00:00 2001 From: jestivald Date: Sun, 6 Sep 2026 01:31:28 +0300 Subject: [PATCH 5/6] =?UTF-8?q?v4.1.2:=20protect=20=D0=BD=D0=B5=20=D0=B2?= =?UTF-8?q?=D0=BA=D0=BB=D1=8E=D1=87=D0=B0=D0=B5=D1=82=20=D1=87=D1=83=D0=B6?= =?UTF-8?q?=D0=BE=D0=B9=20nftables.service=20(=D0=BF=D0=B5=D1=80=D1=81?= =?UTF-8?q?=D0=B8=D1=81=D1=82=20=D1=82=D0=BE=D0=BB=D1=8C=D0=BA=D0=BE=20?= =?UTF-8?q?=D1=87=D0=B5=D1=80=D0=B5=D0=B7=20na-firewall.service);=20optimi?= =?UTF-8?q?ze=20=D0=BD=D0=B0=20=D1=80=D0=B5-=D1=80=D0=B0=D0=BD=D0=B5=20?= =?UTF-8?q?=D1=8F=D0=B2=D0=BD=D0=BE=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B7=D0=B0?= =?UTF-8?q?=D0=BF=D1=83=D1=81=D0=BA=D0=B0=D0=B5=D1=82=20na-rps=20(RPS=20?= =?UTF-8?q?=D1=80=D0=B5=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=20=D0=BF=D1=80=D0=B8?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D1=8F=D0=B5=D1=82=D1=81=D1=8F,=20=D0=BE?= =?UTF-8?q?=D1=82=D0=BA=D0=B0=D0=B7=20=3D=20warn);=20changelog=20v4.1.2,?= =?UTF-8?q?=20NA=5FREF-=D0=BF=D1=80=D0=B8=D0=BC=D0=B5=D1=80=D1=8B,=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BC=D0=BC=D0=B5=D0=BD=D1=82=D0=B0=D1=80=D0=B8?= =?UTF-8?q?=D0=B8=20=D0=B8=20=D1=82=D0=B5=D1=81=D1=82=D1=8B=20=E2=80=94=20?= =?UTF-8?q?=D0=BD=D0=B0=20=D1=8F=D0=B7=D1=8B=D0=BA=D0=B5=20=D1=80=D0=B5?= =?UTF-8?q?=D0=BF=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5.1 --- CHANGELOG.md | 74 +++++++++++++++++++++++++++++-------------- README.md | 4 +-- install.sh | 2 +- scripts/lib/common.sh | 2 +- scripts/optimize.sh | 6 ++-- scripts/protect.sh | 10 +++--- scripts/rollback.sh | 4 +-- tests/apply-smoke.sh | 8 ++--- tests/rps-unit.sh | 20 ++++++------ 9 files changed, 79 insertions(+), 51 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d35a94..fda6fed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,29 +1,55 @@ # Changelog -## Unreleased - -### Apply RPS changes to an already-active unit - -`optimize` now restarts its RPS setup unit after updating the helper. Previously, -`enable --now` left an already-active `Type=oneshot` / `RemainAfterExit=yes` unit -untouched: upgrading the boot-race fix could still leave `rps_cpus=0` until a -manual restart or reboot, while the installer claimed success. Failed activation -now produces a warning. A behavioral regression test models an active oneshot, -checks the resulting CPU mask, and covers failed activation. - -### Firewall boot service ownership - -`protect` no longer enables the distribution's `nftables.service`. NA already -persists its table through `na-firewall.service`; the distribution's default -`/etc/nftables.conf` starts with `flush ruleset`, which can erase NA, CrowdSec and -Docker tables when boot services run in a different order. Existing operator -service settings remain unchanged. The apply test records service operations and -checks that only the NA boot service is enabled. - -Existing installations should inspect `nftables.service` and its configuration. -If it only loads the unused distribution template, disable its boot activation -with `systemctl disable nftables.service` (without `--now` or `stop`, which can -flush the running ruleset). Keep a deliberately managed distribution service. +## v4.1.2 — 2026-09-06 + +Два дефекта ре-рана, из-за которых состояние ноды расходилось с тем, что печатал установщик +([#44](https://github.com/jestivald/node-accelerator/pull/44)). Дефолты не менялись, новых ручек +нет — правки только в поведении `protect` и `optimize` при повторном прогоне. + +### 🟠 `protect` включал в автозагрузку чужой `nftables.service` + +Персист правил через ребут у тулкита свой: `na-firewall.service` грузит `na_filter.nft` и никогда +не трогает `/etc/nftables.conf`. Но рядом `protect` включал и дистрибутивный `nftables.service`, +конфиг которого не писал. У этого юнита `ExecStop=nft flush ruleset`, а его дефолтный +`/etc/nftables.conf` начинается с `flush ruleset` — то есть любой `stop`, `restart` или `reload` +юнита, который оператор считал «нашим», сносит **все** таблицы: `na_filter`, CrowdSec, Docker. +На самой загрузке порядок детерминирован (дистрибутивный юнит стартует в `sysinit.target`, наш — +после `network-pre.target`), так что штатный бут не страдал; риск был в жизненном цикле юнита, +за который никто не отвечал. + +Теперь `protect` включает только `na-firewall.service`, а состояние `nftables.service` не меняет +ни на первом прогоне, ни на повторных: если оператор включил его сам и ведёт свой +`/etc/nftables.conf` — это его решение. + +**Миграция существующих нод.** `nftables.service` там уже включён прошлыми версиями. Если +`/etc/nftables.conf` — нетронутый шаблон дистрибутива, снимите юнит с автозагрузки: + +```bash +systemctl disable nftables.service # БЕЗ --now и БЕЗ stop: ExecStop = flush ruleset +``` + +Если конфиг ведётся осознанно — оставьте как есть. + +### 🟠 `optimize` на ре-ране не применял обновлённый RPS, но рапортовал успех + +`na-rps.service` — `Type=oneshot` с `RemainAfterExit=yes`. Для уже активного такого юнита +`systemctl enable --now` ничем не отличается от `enable`: `ExecStart` повторно не запускается. +Поэтому ре-ран `optimize` переписывал хелпер `na-rps-setup` (в v4.1 — фикс гонки с маршрутом +на буте, #30), а применить его не мог: на трёхъядерной ноде после апгрейда `rps_cpus` так и +оставался `0`, при этом установщик печатал «RPS/RFS/XPS включены». + +Теперь после перезаписи хелпера юнит явно перезапускается (`enable` + `restart`), и результат +честный: `ok` только при успешном применении, иначе `warn` с отсылкой к +`journalctl -u na-rps.service`. Перезапуск меняет только настройки очередей NIC — процесс +VPN-ноды не трогается. + +### 🧪 Тесты + +`tests/rps-unit.sh`: секция активации `optimize` исполняется против модели уже активного +oneshot — маска `rps_cpus` реально выставляется, отказ применения даёт `warn` без `ok`; +регрессия против тега `v4.1.1` (маска пуста при рапорте об успехе). `tests/apply-smoke.sh`: +стаб `systemctl` пишет журнал вызовов — `protect` включает `na-firewall.service` и не трогает +`nftables.service` ни одной операцией. ## v4.1.1 — 2026-09-02 diff --git a/README.md b/README.md index 639722f..0264488 100644 --- a/README.md +++ b/README.md @@ -121,11 +121,11 @@ curl -fsSL https://raw.githubusercontent.com/jestivald/node-accelerator/main/ins # прод-режим: пиньте тег через NA_REF — компрометация ветки main тогда не утечёт # сразу на весь флот (скрипты тянутся из того же тега): -export NA_REF=v4.1.1 +export NA_REF=v4.1.2 curl -fsSL "https://raw.githubusercontent.com/jestivald/node-accelerator/$NA_REF/install.sh" | sudo -E bash -s all # максимум: + проверка minisign-подписей модулей (подписи лежат в дереве с v3.6): -export NA_REF=v4.1.1 NA_REQUIRE_SIG=1 \ +export NA_REF=v4.1.2 NA_REQUIRE_SIG=1 \ NA_MINISIGN_PUBKEY="RWQrJghT9nkdBC3ntiEXF29zrS8o429WhObHKq6I7CKoftVDhQBrBscu" curl -fsSL "https://raw.githubusercontent.com/jestivald/node-accelerator/$NA_REF/install.sh" | sudo -E bash -s all ``` diff --git a/install.sh b/install.sh index c41f605..f9aba25 100755 --- a/install.sh +++ b/install.sh @@ -13,7 +13,7 @@ # curl-bash: # curl -fsSL https://raw.githubusercontent.com/jestivald/node-accelerator/main/install.sh | sudo bash -s all # # прод: пиньте тег (компрометация ветки main тогда не утечёт сразу на весь флот): -# export NA_REF=v4.1.1; curl -fsSL "https://raw.githubusercontent.com/jestivald/node-accelerator/$NA_REF/install.sh" | sudo -E bash -s all +# export NA_REF=v4.1.2; curl -fsSL "https://raw.githubusercontent.com/jestivald/node-accelerator/$NA_REF/install.sh" | sudo -E bash -s all # # + подписи модулей: NA_REQUIRE_SIG=1 NA_MINISIGN_PUBKEY=<ключ из README> # # ENV: NA_REF=<ветка|тег> NA_REPO_URL=<база raw-URL, для форка/зеркала> diff --git a/scripts/lib/common.sh b/scripts/lib/common.sh index 1221a01..da01e0d 100755 --- a/scripts/lib/common.sh +++ b/scripts/lib/common.sh @@ -6,7 +6,7 @@ # Версия тулкита — ЕДИНСТВЕННЫЙ источник. Пишется в installed-маркеры и отдаётся # в na-diagnose/na-report --json, чтобы флот-мониторинг видел version-drift по нодам. # shellcheck disable=SC2034 -NA_VERSION="4.1.1" +NA_VERSION="4.1.2" # shellcheck disable=SC2034 RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m' diff --git a/scripts/optimize.sh b/scripts/optimize.sh index e09bcfe..fdc8793 100755 --- a/scripts/optimize.sh +++ b/scripts/optimize.sh @@ -619,9 +619,9 @@ RestartSec=5 WantedBy=multi-user.target EOF systemctl daemon-reload -# An active oneshot with RemainAfterExit=yes is not run again by enable --now. -# Re-apply the updated helper on every optimize run, including after a previous -# boot raced with route setup and left the old unit active with rps_cpus=0. +# Уже активный oneshot с RemainAfterExit=yes `enable --now` повторно НЕ запускает — +# ре-ран переписывал хелпер, а rps_cpus оставался старым (после гонки с маршрутом на +# буте — нулём), при этом печатался ok. Поэтому: enable + явный restart на каждом прогоне. systemctl enable na-rps.service >/dev/null 2>&1 || true if systemctl restart na-rps.service >/dev/null 2>&1; then ok "RPS/RFS/XPS включены ($(nproc) ядер, NIC=${NIC:-автодетект на буте})" diff --git a/scripts/protect.sh b/scripts/protect.sh index aa32b0e..3bec78f 100755 --- a/scripts/protect.sh +++ b/scripts/protect.sh @@ -1084,10 +1084,12 @@ else fi systemctl daemon-reload systemctl enable na-firewall.service >/dev/null 2>&1 || true -# The distro service owns /etc/nftables.conf, whose default configuration starts -# with `flush ruleset`. Enabling it alongside our service races at boot with -# na_filter, CrowdSec and Docker. Only our own unit provides NA persistence; -# leave the operator's nftables.service state unchanged, including on re-runs. +# Дистрибутивный nftables.service НЕ включаем (до v4.1.2 включали «для персиста»): +# его конфиг /etc/nftables.conf тулкит не пишет, а дефолтный шаблон начинается с +# `flush ruleset` и ExecStop у юнита = `nft flush ruleset` — любой stop/restart/reload +# такого «ничейного» юнита снёс бы na_filter, таблицы CrowdSec и Docker. Персист даёт +# только na-firewall.service; состояние nftables.service — решение оператора, не трогаем +# ни на первом прогоне, ни на ре-ране. ok "na-firewall.service включён (правила переживут reboot — если не сработает сейфти-таймер: он теперь снимает и автозагрузку)" fi # ═══ конец блока файрвола (FW_MODE=skip его пропускает) ═══ diff --git a/scripts/rollback.sh b/scripts/rollback.sh index 56d5113..0f8ff67 100755 --- a/scripts/rollback.sh +++ b/scripts/rollback.sh @@ -123,8 +123,8 @@ rollback_protect() { /usr/local/sbin/na-fleet-sync /usr/local/sbin/na-blocklist-update /usr/local/sbin/na-ctguard \ /usr/local/sbin/na-fw-safety-revert rm -f "$STATE_DIR/safety-fired.last" "$STATE_DIR/protect.lock" - # nftables.service мы включали (boot-persist), но выключать не будем: он лишь грузит - # /etc/nftables.conf, который тулкит никогда не писал — трогать чужой конфиг нельзя. + # nftables.service до v4.1.2 включал сам protect (boot-persist), но выключать не будем: он + # лишь грузит /etc/nftables.conf, который тулкит никогда не писал — трогать чужой конфиг нельзя. systemctl is-enabled --quiet nftables 2>/dev/null && info "nftables.service оставлен включённым (грузит ваш /etc/nftables.conf, наших правил там нет)" rm -f /etc/modules-load.d/na-synproxy.conf "$STATE_DIR/.synproxy-degraded" # конфиги: persisted protect.conf, ctguard.conf, токен панели fleet.env (custom-blocklist.txt — данные оператора, оставляем) diff --git a/tests/apply-smoke.sh b/tests/apply-smoke.sh index 6cc9436..5089d28 100755 --- a/tests/apply-smoke.sh +++ b/tests/apply-smoke.sh @@ -27,8 +27,8 @@ sed -e "s#/etc/systemd/system/#$T/sys/#g" \ for c in systemctl modprobe nft systemd-run sysctl conntrack; do printf '#!/bin/sh\nexit 0\n' > "$T/bin/$c"; chmod +x "$T/bin/$c" done -# Record service operations: protect owns na-firewall.service. Enabling the -# distro nftables.service can flush every table at the next boot. +# Стаб systemctl пишет журнал вызовов: protect включает СВОЙ na-firewall.service и не +# трогает дистрибутивный nftables.service (его stop/restart/reload = flush ruleset). export NA_TEST_SYSTEMCTL_LOG="$T/systemctl.log" cat > "$T/bin/systemctl" <<'SYSTEMCTL' #!/bin/sh @@ -80,9 +80,9 @@ set -e fail=0 grep -qx 'enable na-firewall.service' "$NA_TEST_SYSTEMCTL_LOG" \ - || { echo "[x] protect did not enable its own boot service"; fail=1; } + || { echo "[x] protect не включил свой na-firewall.service"; fail=1; } if grep -Eq '^(enable|start|restart|reload|stop|disable|mask)( [^ ]+)* nftables(\.service)?( |$)' "$NA_TEST_SYSTEMCTL_LOG"; then - echo "[x] protect changed the unrelated nftables.service (global ruleset risk)" + echo "[x] protect тронул чужой nftables.service (риск flush ruleset)" fail=1 fi if [ "$rc" -ne 0 ]; then echo "[x] apply упал (exit $rc)"; fail=1; fi diff --git a/tests/rps-unit.sh b/tests/rps-unit.sh index f26310b..1535399 100755 --- a/tests/rps-unit.sh +++ b/tests/rps-unit.sh @@ -162,9 +162,9 @@ expect "NIC детектится ДО генерации юнита" \ test "$(grep -n 'NIC="\$(default_iface || true)"' "$REPO_ROOT/scripts/optimize.sh" | cut -d: -f1)" \ -lt "$(grep -n 'ExecStart=/usr/local/sbin/na-rps-setup' "$REPO_ROOT/scripts/optimize.sh" | cut -d: -f1)" -# An active oneshot is not executed again by `enable --now`. Exercise the -# installation section with that state, rather than calling the helper directly. -echo "== re-run while na-rps.service is already active ==" +# Активный oneshot `enable --now` повторно не исполняет. Гоняем саму секцию активации +# optimize.sh в этом состоянии, а не хелпер напрямую. +echo "== ре-ран при уже активном na-rps.service ==" extract_activation() { awk ' /^cat > \/etc\/systemd\/system\/na-rps.service < "$T/activation-driver.sh" <<'DRIVER' systemctl() { case "$1" in enable) - # A systemd oneshot with RemainAfterExit=yes is already active. - # Enabling it, with or without --now, does not run ExecStart again. + # oneshot с RemainAfterExit=yes уже активен: enable (с --now или без) + # ExecStart повторно не запускает. return 0;; restart) [ "${RPS_FORCE_FAILURE:-0}" = 1 ] && return 1 @@ -196,17 +196,17 @@ run_activation() { } reset_net; mk_net ens18 1 run_activation "$T/activation.sh" -expect "re-run applies RPS even when the old oneshot is active" test "$(mask_of ens18)" = 7 +expect "ре-ран применяет RPS даже при активном старом oneshot" test "$(mask_of ens18)" = 7 reset_net; mk_net ens18 1 RPS_FORCE_FAILURE=1 run_activation "$T/activation.sh" -expect "failed activation is reported" grep -q 'не удалось применить RPS' "$T/activation.out" -expect_not "failed activation must not claim RPS is enabled" grep -q 'RPS/RFS/XPS включены' "$T/activation.out" +expect "отказ применения — warn" grep -q 'не удалось применить RPS' "$T/activation.out" +expect_not "при отказе нет рапорта об успехе" grep -q 'RPS/RFS/XPS включены' "$T/activation.out" if git -C "$REPO_ROOT" show v4.1.1:scripts/optimize.sh > "$T/v411-optimize.sh" 2>/dev/null; then extract_activation "$T/v411-optimize.sh" "$T/v411-activation.sh" reset_net; mk_net ens18 1 run_activation "$T/v411-activation.sh" - expect "v4.1.1 left an already-active oneshot unapplied" test -z "$(mask_of ens18)" - expect "v4.1.1 nevertheless reported success" grep -q 'RPS/RFS/XPS включены' "$T/activation.out" + expect "регрессия v4.1.1: активный oneshot не применён (маска пуста)" test -z "$(mask_of ens18)" + expect "регрессия v4.1.1: при этом рапортовал успех" grep -q 'RPS/RFS/XPS включены' "$T/activation.out" fi # ── #28: ничего «курсорного» в не-терминал ────────────────────────────────────── From cf048ad9b0c45aa7f18ab56a58c08b93e0875a4a Mon Sep 17 00:00:00 2001 From: jestivald Date: Sun, 6 Sep 2026 01:31:28 +0300 Subject: [PATCH 6/6] release: sign 6 modules with minisign (v4.1.2) Co-Authored-By: Claude Fable 5.1 --- scripts/diagnose.sh.minisig | 6 +++--- scripts/lib/common.sh.minisig | 8 ++++---- scripts/na-report.sh.minisig | 6 +++--- scripts/optimize.sh.minisig | 8 ++++---- scripts/protect.sh.minisig | 8 ++++---- scripts/rollback.sh.minisig | 8 ++++---- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/scripts/diagnose.sh.minisig b/scripts/diagnose.sh.minisig index bd8ecb0..37b3b0a 100644 --- a/scripts/diagnose.sh.minisig +++ b/scripts/diagnose.sh.minisig @@ -1,4 +1,4 @@ -untrusted comment: node-accelerator v4.1.1 +untrusted comment: node-accelerator v4.1.2 RUQrJghT9nkdBENoxhnU9rwsJzsLv3J7D9SkM1oe+0YmmPdKLZWtjkaSKCLIQJyFN6bIsc+I6+50gMTg6NHare9Bwo6SMiIB9AY= -trusted comment: timestamp:1788349350 file:diagnose.sh hashed -Kn3mUHqRXJ3TrbY2sTWuRegSUPxmAGUiC58AhBamEvfgFWFxmfcHS6pXKwfG5xCPdSznjgxXGwC5OFtLbCXlCw== +trusted comment: timestamp:1788647488 file:diagnose.sh hashed +vD5w6tc+/j+lAHtgd4marGeKQL+6LIMeYjVB/BA2N+oQm+9s24iSz9md+jdy8U1O6xnh4xMdS9Tyj6QLfCj0Bg== diff --git a/scripts/lib/common.sh.minisig b/scripts/lib/common.sh.minisig index 51585b9..bdf99c3 100644 --- a/scripts/lib/common.sh.minisig +++ b/scripts/lib/common.sh.minisig @@ -1,4 +1,4 @@ -untrusted comment: node-accelerator v4.1.1 -RUQrJghT9nkdBPMjRYxTeyDRPHNs+d5y7lErzQAsoal8gZpryUTA0Ad09waeYLWIWZWthxvOsUaocoZ/qPl1PPhUPoRKACUfPwo= -trusted comment: timestamp:1788349350 file:common.sh hashed -l4F98FXGpy8Umba+MEjtxykaeq298rquHNSNvaJLxaZGqT33SYSK8WlY4IGmT997kPLSBZHWA1KFM74UU8gTBw== +untrusted comment: node-accelerator v4.1.2 +RUQrJghT9nkdBL9iAGv1f9+ZiVf16X9beZhz659G4TXQS+g5bw0e8RQHeluighIIV7kWOSE1PkubOQ4CbWBrsX8vNQZfVr/78A4= +trusted comment: timestamp:1788647488 file:common.sh hashed +zcWQlx5JcCMnl4bxHUPCFV60li61IHyh95+obuk9BUH4CsixVLy4HejZ7qcufzajDQUMLLppiIGJBLMW53LyDA== diff --git a/scripts/na-report.sh.minisig b/scripts/na-report.sh.minisig index 3c49499..ea0f71c 100644 --- a/scripts/na-report.sh.minisig +++ b/scripts/na-report.sh.minisig @@ -1,4 +1,4 @@ -untrusted comment: node-accelerator v4.1.1 +untrusted comment: node-accelerator v4.1.2 RUQrJghT9nkdBOrdxdxfyqJUywTv/RLU7ZreVDZAtLeliMCTEsY5M0vWhsR1gF5MEbykzE8/QRKRqFN3Odck90tt1E7RC8oxow8= -trusted comment: timestamp:1788349350 file:na-report.sh hashed -YAktBFahm+IuuKRNinUKv9J3BcJl7TZCMGxC9s4dxl0kOsmWTV09BLbSb11ln/Yt5DmgNZ71xxnwjIXaIk8NCQ== +trusted comment: timestamp:1788647488 file:na-report.sh hashed +Q4FyevSLXC7c7wgxf7XHYHYBS2S/z6fZaL/xNM6vMBLToDX/UtMaCNABbpWWYzGqMvj+oe/EGdja+GRlQYOICQ== diff --git a/scripts/optimize.sh.minisig b/scripts/optimize.sh.minisig index 6ea5e50..9ea93ee 100644 --- a/scripts/optimize.sh.minisig +++ b/scripts/optimize.sh.minisig @@ -1,4 +1,4 @@ -untrusted comment: node-accelerator: apply RPS on re-run -RUQrJghT9nkdBHNkft75Z4UjzKrUhQ2hfV+FA7zd6wdYt78VqBawBPg2/1sQ+jP/Lx1INpPy2PqAsPYRcwonvqF9Ve1QuyZugA8= -trusted comment: timestamp:1788646176 file:optimize.sh hashed -5pTdRXF/5yeA1jEZVAyXt2FF8gPWYpz0Z/8lX/p5+MU9VmBnqu3regQN61lZelBx4+wkhxjeivmzJKxv0G5eCw== +untrusted comment: node-accelerator v4.1.2 +RUQrJghT9nkdBGrIA8t3qUQSL2vbCsTwMaj68kto3cF+M9kaELTIV7p3rC3tHaM2hK3IKdIAp1mrk4z0A3GyasaldaUxstpXzAo= +trusted comment: timestamp:1788647488 file:optimize.sh hashed +Bgtevmgdu7iPsHegOuE+DOg3nmauiXmQwG19F8Dt+/GE09Oa6RLJO1xHq7/MS6zSoeBXKvPfHjdfHwoixf0UCw== diff --git a/scripts/protect.sh.minisig b/scripts/protect.sh.minisig index 6398ac2..e53b9f8 100644 --- a/scripts/protect.sh.minisig +++ b/scripts/protect.sh.minisig @@ -1,4 +1,4 @@ -untrusted comment: node-accelerator: nftables boot ownership fix -RUQrJghT9nkdBCnzm86r8pvBf71BoFaOUiGzDiv7dwhaSDdCYidusMDERhfsaDi5uoNOu7JV6FdV5BJjRkqdaH9MdGxgoW26ywk= -trusted comment: timestamp:1788645146 file:protect.sh hashed -0zwX8eJdUyMibp52s0sqkGmIWuXPOoqpfpPyuiSPiuqwr8QVHuSED02mwRx3QUYYtjT6Bw/C/Kwjq+DpipTaAw== +untrusted comment: node-accelerator v4.1.2 +RUQrJghT9nkdBJqIVt61VwZTKJhdE0N9X+OAtg5EGgMFJOI+zHuMzLKXLkvnGEc2SC+dinSfa29iiA2zRt3rrVQ9BPFg6iEREg4= +trusted comment: timestamp:1788647488 file:protect.sh hashed +9w+0564+2LwgBKvoPS/n+a7UP4qccb7K/MVtieSjv1TFDw6vjLJbVUuSRRyVDLw8RVUcsvvkeQQLmUyi/pPbAA== diff --git a/scripts/rollback.sh.minisig b/scripts/rollback.sh.minisig index a25bf77..6657608 100644 --- a/scripts/rollback.sh.minisig +++ b/scripts/rollback.sh.minisig @@ -1,4 +1,4 @@ -untrusted comment: node-accelerator v4.1.1 -RUQrJghT9nkdBB27AWybm39DtJ+7UApLPni5ByAeqgET7Ghc3BDFfn5Idz5Cc9n5WK99g5bU/FN1ZvxW8NaK7oLw+MMpBCXNcws= -trusted comment: timestamp:1788349350 file:rollback.sh hashed -LMN68xED+5PySBeLNUgVIFf1y7T8VTMLZ0JpHeUYLs92MACXIF4ZvFWe7PxvCq9RwM9Tmjh7En/Adbb6tdQDCQ== +untrusted comment: node-accelerator v4.1.2 +RUQrJghT9nkdBMsr5fhI1fYTi7I7wBpqvnimavufi/5cvOoomiqN/XsfcRtJWW4VVRfH6Kzhw5S/0psSDogosrTIfeISuCnI0AY= +trusted comment: timestamp:1788647488 file:rollback.sh hashed +IE75JmhRbtIM0cM4OsXG8F1LiDLTblJ8S+7/onPT727coriGziz0R7w45E66LdAbvlnO9Hotky+RbjHd4zPOBA==