Plan staged isolation of group service access

This commit is contained in:
evgeny committed 2026-11-03 19:33:45 +01:00
1 parent 22abcd13ca
commit bb02709be3
2 files changed
+222

No files matched your search

+218
View File
@@ -0,0 +1,218 @@
Межгрупповой доступ: план завершения изоляции
Дата: 03.11.2026
Статус: проект исправления; этапы ниже ещё не реализованы.
1. Цель и исходное состояние
На одном ядре могут существовать несколько CHAT-групп и UTUN. Узел, допущенный
только в A, не должен получать данные, менять состояние или запускать операции B.
Проверка должна работать на уже открытом общем ETCP и после отзыва членства.
Наличие транспорта, маршрута, TOPO_GROUP_NODE или записи в общем node_registry
не является разрешением на API группы.
MEDIA_DELIVERY уже использует обязательную криптографию router, проверку
topo_group_chat_allowed и закрытие запрещённых каналов через revalidate_group.
Для него есть негативный сетевой тест на двух группах общего ETCP.
Последний полный прогон после этого изменения: 239/239; это НЕ проверка изоляции
остальных протоколов. Новые замечания ниже пока основаны на чтении кода.
Основные подтверждённые места для исправления/проверки:
- radio_recv/broadcast_recv: выбор группы без проверки допуска входящего соседа;
- conn_mgr_router_recv_handler/cm_open: существование группы/узла вместо допуска;
- TCP/UDP/ICMP proxy и routing_pkt_from_etcp_cb: отсутствует входной фильтр группы;
- topo_group_peer_allowed: для не-CHAT возвращает разрешение;
- MEMBER_FILES/GROUP_AVATAR и ряд других сервисов: проверка данных внутри
callback не задаёт обязательную подпись router HELLO/ACK/CLOSE и других controls;
- multicast mc_report_recv: проверяет форму и дескриптор группы, но не членство
отправителя; raw mc_recv проверяет принятого соседа, но не свежий допуск из БД;
- ADMIN_KEY: канал берётся из payload без равенства router group; соответствие
приватных ключей ключам канала проверяется, поэтому произвольная подмена ключа
этим замечанием не доказана;
- NAT_DETECTION group_node: топология и подписанный снимок не заменяют членство;
- member_in_channel означает наличие любой строки. Его использование в DM,
mailbox и MEMBERS требует разбора по назначению; массовая замена недопустима.
2. Решение
Развивать существующие механизмы, без второго универсального слоя авторизации.
2.1. Групповые routed API
Использовать etcp_router_require_crypto и etcp_router_set_authorize. Для CHAT
базовый допуск уже реализован в topo_group_chat_allowed: живая группа и активное
локальное членство self и peer (source=0, deleted=0, admitted=1).
Криптографически проверяется конечный source из router, а не ETCP next hop.
SIGNED обязателен для данных и controls; существующие требования ENCRYPTED
сохраняются. Controls без payload подписываются без шифрования пустого тела.
Политика проверяется до создания состояния и вызова receive_ready/обработчика,
при отправке, повторе, доставке очередей и loopback. Ошибка чтения допуска означает
отказ. Callback политики остаётся чистым: чтение состояния, без мутаций/callbacks.
Проверки прав конкретной операции остаются в сервисах: owner файла, storage,
supernode, подпись автора, приглашение, адресат, идентификатор текущего запроса.
Если payload содержит канал, он обязан совпадать с авторизованным router group.
При регистрации проверять ошибки установки обеих политик и убирать частичную
инициализацию. Отдельный новый framework или реестр дублей SQL не требуется.
Не требовать READY как доказательство членства. Особенно это недопустимо для
CONN_MGR: он помогает создать соединение. Его локальный open и входящие команды
проверяют допуск до загрузки узла в группу, cm_ensure_entry, таймеров и NCD.
Повторная проверка нужна при выборе посредника, retry и публикации готового пути.
Для сервисов, работающих и с CHAT, и с UTUN, выбор политики определяется типом
реальной группы; неизвестный тип не получает автоматического разрешения.
2.2. Raw групповые пакеты
RADIO/BROADCAST/MULTICAST не проходят через router. Проверять входящий
аутентифицированный ETCP_CONN и текущий допуск его peer именно к группе пакета.
Для рассылки по соседям также нужна принятая живая сессия этой группы на этом conn.
Общий проверяющий код размещать рядом с топологией групп; не копировать SQL
в каждый протокол. Проверять до dedup, очередей, callbacks и пересылки.
Исходящие/отложенные отправки также фильтруют адресатов по текущему допуску.
Такая проверка закрывает доступ постороннего соседа. Она не превращает поле src
внутри raw RADIO/MULTICAST в сквозную подпись автора. Его нельзя использовать
как доказательство личности для привилегированной операции. Подмену src внешним
узлом проверять тестом вместе с отказом самому соседу. Защита от подделки автора
уже допущенным участником требует отдельного подписанного формата и не должна
выдаваться за результат простого фильтра членства.
STREAM имеет собственные сессии и проверки участников; применять к нему правило
допуска до побочных действий, сохраняя его транспортный жизненный цикл. Проверки
соседства RADIO нельзя автоматически навязать прямому STREAM поверх общего NCD.
2.3. UTUN
Проверки group_id == TOPO_GROUP_UTUN недостаточно: чужой CHAT-узел может указать
это значение. [allowed_keys] сейчас управляет входящим транспортом; allow_all=1
нужен, в частности, для новых CHAT-узлов и не должен открывать TUN/NAT/proxy.
Предлагаемая политика: отдельный список публичных ключей UTUN, например секция
[utun_allowed_keys]. По умолчанию внешний доступ закрыт; self допускается при
работающем UTUN-сервисе. Не импортировать автоматически транспортные allowed_keys,
все [client] или записи BGP. Список проверяется по проверенной идентичности узла,
одинаково для UDP/STCP/REALITY и routed источника за промежуточным узлом.
Явно открытый UTUN, если он нужен продукту, должен включаться отдельной настройкой
UTUN; транспортный allow_all не является этой настройкой.
Это изменение конфигурационного контракта: на каждом принимающем UTUN-узле
понадобится допуск конечных участников, а не только ближайшего сервера. Простой
список ключей выбран для первого исправления; подписанное распределённое членство
UTUN означало бы отдельный протокол управления и существенно больший объём.
Одной политикой UTUN закрыть BGP JOIN/обмен, CONN_MGR, NAT_DETECTION, DATA,
NAT и обе стороны TCP/UDP/ICMP proxy. У routed API обязательна проверенная подпись
source, иначе проверка списка ключей по подставленному node_id не имеет смысла.
NAT/proxy сохраняют собственные ограничения provider/via, ожидаемого peer и потока.
При изменении допуска закрывать соответствующие логические операции и сокеты,
сохраняя общий транспорт, необходимый CHAT. Учесть start/stop и применение конфига.
2.4. Bootstrap, синхронизация и личные данные
Routed JOIN обслуживает A-C, уже состоящих в канале; ему применим групповой допуск
и защита controls. Новый J входит через raw CHAT_SYNC/GROUP_INVITE. Исключения
разрешают только конкретную команду добавления с проверенным invite/add_key,
целевой идентичностью, каналом, attempt и сроком действия. Временного членства нет.
MEMBERS/Merkle может требоваться до admitted=1 для получения подписанного состава
и восстановления допуска. Сохранить отдельное разрешение синхронизации MEMBERS,
привязанное к проверенной идентичности и конкретному каналу/сценарию восстановления.
Не выдавать через него обычный DB_SYNC сообщений и другие групповые API. Простое
наличие строки, placeholder или tombstone нельзя молча объявить достаточным правом:
каждый разрешённый bootstrap/recovery случай должен иметь отдельный тест.
Для DM/CALL/DEVGROUP/FILE_TRANSFER разделять право пользоваться маршрутом группы
и право на личную беседу, вызов или объект. Сохранить проверки адресата и E2E,
снимка устройств/эпохи и истории. Смена общей группы для маршрута не должна менять
личность собеседника или права на вложение. Отзыв доступа к A останавливает A,
но допускает новое согласование через B, если оба участника допущены в B.
Ранее сохранённая локальная личная история не удаляется при отзыве маршрута.
2.5. Отзыв и владение
После commit изменения допуска использовать существующий revalidate_group.
Проверить все пути: deleted, admitted, source, изменение group_policy, удаление
self, остановка/удаление группы. Отмена сервиса адресуется по (group, peer, service)
и его идентификатору операции. Не закрывать общий ETCP или чужой NCD handle.
Убирать запрещённые router/service очереди, таймеры, ожидания, подписки и retries;
для отложенных callbacks и завершения workers повторно проверять актуальное право
до выдачи результата или записи. Уже переданные в транспорт/полученные данные
нельзя отозвать задним числом; проверяется прекращение новых действий после отзыва.
3. Этапы реализации
Этап 1. Стенд и общий контракт доступа
Расширить подход test_media_delivery_integration: реальные ядра, SQLite,
подписанные участники, две группы и один физический ETCP. Инъекция должна идти
ниже локального запрета отправителя, иначе тест проверит лишь клиентскую защиту.
Зафиксировать отрицательные воспроизведения RADIO/BROADCAST, CONN_MGR и proxy.
Добавить осмысленные логи отказа и очистки: service, group, source, next_hop,
команда/операция, фаза проверки, причина; без приватных ключей/содержимого файлов.
Критерий: в старом коде наблюдаем конкретный запрещённый эффект, после исправления
он отсутствует; нормальное действие в разрешённой группе проходит.
Этап 2. Routed CHAT и управление соединениями
Подключить политику у MEMBER_FILES, GROUP_AVATAR, RADIO_CALL, ATTACHMENT_KEYS,
ADMIN_KEY и routed JOIN. ADMIN_KEY дополнительно связывает канал с router group.
CONN_MGR проверяет вход, local open, кандидатов и отложенные переходы состояния.
NAT_DETECTION и MULTICAST_REPORT получают допуск конечного источника и подпись
controls; STREAM routed — согласованную с его действующими проверками политику.
MEDIA_DELIVERY остаётся контрольным образцом и регрессией.
Критерий: чужой/отозванный peer не создаёт сессий, файлов, запросов подключения,
NAT-проб и отчётов; unsigned HELLO/ACK/CLOSE не воздействуют на разрешённый канал.
Этап 3. Raw групповые обмены и отзыв
Общий фильтр группового соседа для RADIO/BROADCAST/MULTICAST; проверка перед
локальной доставкой, dedup, forwarding и возобновлением отложенной отправки.
Проверить STREAM raw и очистку его flows/relay при отзыве. Проверить BGP,
DB_SYNC, CHAT_SYNC и Merkle по отдельным bootstrap/обычным командам.
Критерий: подстановка чужого group/src не доставляет callback, не загрязняет
dedup и не порождает пересылку; удаление участника прекращает текущую передачу.
Этап 4. Независимый допуск UTUN
Реализовать отдельную конфигурацию доступа, отказ по умолчанию и применение
политики из п. 2.3 во всех входах UTUN, включая DATA/TUN и клиентские proxy replies.
Обновить sample, документацию и тестовые конфиги явным допуском нужных узлов.
Критерий: CHAT-only peer с валидным транспортом не использует UTUN даже указав
правильный UTUN group_id; разрешённый routed клиент работает через посредника.
Проверить UDP/STCP/REALITY и существующие proxy/NAT/load тесты, включая нагрузку
после введения подписи. Не заменять проверку членства наличием маршрута.
Этап 5. Личные сервисы, bootstrap и полная матрица
Проверить DM, DM_MAILBOX, DM_MEDIA, FILE_TRANSFER, CALL/CALL_AUDIO/CALL_VIDEO,
CALL_VIDEO_CONTROL и DEVGROUP; обязательные controls и групповые/предметные права.
Завершить тесты raw JOIN/invite, MEMBERS recovery и серверного add_key.
Сопоставить каждый ID из etcp_api.h с реализованной политикой и сетевым тестом.
NTP_TIME/NCD_CONTROL/SVC_ROUTE — общие транспортные службы: проверить их границы
отдельно. Не навязывать им фиктивное CHAT-членство. Проверить отсутствие обхода
через raw DATA/неизвестный ID и явно включаемую BLE_PROBE instrumentation.
Критерий: по каждому ID есть разрешённый сценарий, отказ либо документированный
транспортный/bootstrap контракт; без строки «не проверено» для групповых API.
После каждого этапа: целевые тесты и ./check.sh; изменения фиксировать отдельными
логически завершёнными коммитами. Этапы 2/3 не означают готовность этапов 4/5.
Успешный общий набор без новых отрицательных сценариев не закрывает задачу.
4. Обязательная матрица регрессий
1) Участник только A обращается к API B через существующий ETCP.
2) Тот же peer использует API A успешно на этом же транспорте.
3) Подмена group/source/service и несовпадение канала payload с router header.
4) Подписанный чужим peer пакет и unsigned/поддельные HELLO/CHALLENGE/CONFIRM,
ACK/BUSY/CLOSE: проверка не ограничивается флагом SIGNED без верификации.
5) Доступ отзывается только на принимающем узле после открытия сессии; отправитель
продолжает с прежней эпохой, передаёт новые пакеты и пробует открыть канал снова.
6) Отзыв при backpressure, reorder, retransmit, активном файле, worker и callback.
7) Удаление self, остановка/удаление B, последующее повторное добавление участника.
8) A остаётся рабочей; общий ETCP и NCD handle другого владельца остаются живы.
9) Разрешённый конечный отправитель через посредника: endpoint не принимает
next_hop за source; транзит не выполняет предметный API конечного узла.
10) Поздний пакет/результат старой операции не относится к новой группе/операции
при совпавшем числовом stream/transfer ID. Учесть существующие границы epochs.
11) Для запрета проверяется побочный эффект: callback/БД/файл/сокет/таймер/NCD,
а не только отсутствие ответа. Логи объясняют точную причину отказа.
12) Положительные JOIN, MEMBERS recovery, DM через другую общую группу и разрешённый
UTUN проходят. Локальные loopback-вызовы соблюдают ту же предметную политику.
Задача завершена только после реализации всех этапов и этой матрицы для каждого
относящегося к ней сервиса. Сам этот документ не подтверждает устранение пробелов.
+4
View File
@@ -13,6 +13,10 @@
но не задают обязательную подпись control-пакетов в router. Нужны отдельные воспроизведения на общем ETCP,
проверка подмены источника, отзыва доступа и соседней группы; правила JOIN/invite и личных DM учитывать отдельно.
На этом этапе перечисленные дополнительные сценарии проверены чтением кода, сетевые регрессии ещё не добавлены.
План исправления и критерии по пяти этапам: [group_isolation_plan.txt](group_isolation_plan.txt).
Дополнительно включены DATA/TUN, MULTICAST_REPORT, ADMIN_KEY, NAT_DETECTION и аудит допуска DM/mailbox;
отдельный доступ UTUN не должен наследовать transport allow_all. MEMBERS recovery и первичный JOIN требуют
отдельных правил. План зафиксирован; новые этапы ещё не реализованы, вывод о полной изоляции преждевременен.
[+] **Панель устройств групповой лички: свои и собеседника** — 03.11.2026.
Общий снимок текущего состава закреплённых сторон, включая offline и fallback-устройство.