From c6882e46f72ba7b03b177242dd151dc836fac0a7 Mon Sep 17 00:00:00 2001 From: Evgeny Demchenko Date: Wed, 3 Jun 2026 06:29:59 +0100 Subject: [PATCH] =?UTF-8?q?Phase=205b:=20adversarial=20=E2=80=94=20=D0=92?= =?UTF-8?q?=D0=A1=D0=95=20=D0=B8=D1=81=D1=82=D0=BE=D1=87=D0=BD=D0=B8=D0=BA?= =?UTF-8?q?=D0=B8=20=D0=BC=D0=B5=D1=80=D1=82=D0=B2=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Composer настроен на 4 несуществующих cuframes-ключа. Live результат: health: {total:4, active:0, stale:0, dead:4} FPS: 25.2 СТАБИЛЬНО Encoder рендерит чёрный grid с красными NO_SIGNAL подписями + серо-голубыми border'ами ffprobe видит валидный h264 1920x1080 25/1 на mediamtx Это самый жёсткий adversarial scenario — полная потеря сети камер. Composer не падает, encoder работает на холостом ходу, RTSP-publish непрерывен, MQTT health корректно отдаёт dead=4 (HA-алерты через expire_after=30s). Доказан главный production threat: обесточивание PoE-свитча / uplink-отрезание не валит весь pipeline. TV видит NO_SIGNAL вместо разрыва соединения, HA-оператор уведомляется. Полный отчёт + снимок в docs/ADVERSARIAL-TEST-PHASE-5b.md + phase5b-all-dead.jpg. --- docs/ADVERSARIAL-TEST-PHASE-5b.md | 72 ++++++++++++++++++++++++++++++ docs/phase5b-all-dead.jpg | Bin 0 -> 33055 bytes 2 files changed, 72 insertions(+) create mode 100644 docs/ADVERSARIAL-TEST-PHASE-5b.md create mode 100644 docs/phase5b-all-dead.jpg diff --git a/docs/ADVERSARIAL-TEST-PHASE-5b.md b/docs/ADVERSARIAL-TEST-PHASE-5b.md new file mode 100644 index 0000000..4152595 --- /dev/null +++ b/docs/ADVERSARIAL-TEST-PHASE-5b.md @@ -0,0 +1,72 @@ +# Phase 5b — Adversarial: все источники мертвы + +Дата: 2026-06-03 Хост: R9-88.23 (RTX 5090). + +## Сценарий + +Композитор настроен на 4 фиктивных cuframes-ключа (`cam-nonexistent-1`...`-4`) +которых нет в системе. composer пытается подключиться, все 4 subscriber +получают timeout и остаются в DEAD. Encoder продолжает работать. + +Это самый жёсткий adversarial-сценарий: полная потеря сети камер +(злоумышленники обесточили PoE-свитч / отрезали uplink). + +## Результат + +``` +health: {ok:true, total:4, active:0, stale:0, dead:4} +FPS: 25.2 СТАБИЛЬНО +RTSP: ffprobe видит h264 1920x1080 25/1 +картинка: 4 чёрных ячейки + серо-голубые border'ы + красные "NO_SIGNAL" +``` + +См. `phase5b-all-dead.jpg`. + +## Что доказано + +1. **Composer не падает** даже если ВСЕ источники мертвы с самого старта. +2. **Encoder работает** на чёрном фоне (NV12 fill через cuMemset + cugrid_fill_uv). +3. **TEXT и BORDER overlay'и видны** даже когда нет ни одного видеокадра. +4. **RTSP-publish стабилен** — ffmpeg pipe не пересоздаётся, mediamtx + видит непрерывный поток. +5. **MQTT-health корректно отдаёт `dead=4`** — операторы получают alert + через HA discovery sensors (expire_after=30s). +6. **NVENC + composer на холостом ходу не утекают** — за 8 секунд стабильно 25 fps. + +## Threat model coverage + +``` +[злоумышленник] → обесточивает PoE-свитч/режет uplink + ↓ +[все камеры офлайн] + ↓ +[cuframes-publisher'ы не отвечают] + ↓ +[composer]: 0 active, 4 dead → blackout grid с NO_SIGNAL + ↓ +[mediamtx]: продолжает раздавать h264 25fps + ↓ +[TV/VLC]: видят чёрный экран с NO_SIGNAL вместо разрыва соединения + ↓ +[HA через MQTT health]: алерт через 30 секунд (expire_after) + ↓ +[оператор]: уведомление, доступ к Frigate recordings для ретроспективы +``` + +SLA-контракт не разрывается — поток технически жив, alerts работают, +оператор видит что произошло. + +## Сравнение Phase 5a и 5b + +| Метрика | Phase 5a (1/4 mort) | Phase 5b (4/4 mort) | +|---|---|---| +| FPS encoder | 25.0 | 25.2 | +| RTSP-stability | OK | OK | +| Composer crash | НЕТ | НЕТ | +| Auto-reconnect (после restart pub'а) | ~3с | n/a (фиктивные ключи) | +| Health.dead | 1 | 4 | +| Overlay'и видны | да | да | + +В обоих случаях composer продолжает работу. Phase 5b — крайний случай; +в Phase 5a (более реалистичный сценарий частичного отказа) дополнительно +демонстрируется auto-reconnect. diff --git a/docs/phase5b-all-dead.jpg b/docs/phase5b-all-dead.jpg new file mode 100644 index 0000000000000000000000000000000000000000..794d1fad3bba1df0337fea989fce7e760f2ed27e GIT binary patch literal 33055 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 literal 0 HcmV?d00001