Plan staged isolation of group service access
This commit is contained in:
1 parent
22abcd13ca
commit
bb02709be3
2 files changed
+222
No files matched your search
@@ -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-вызовы соблюдают ту же предметную политику.
|
||||
|
||||
Задача завершена только после реализации всех этапов и этой матрицы для каждого
|
||||
относящегося к ней сервиса. Сам этот документ не подтверждает устранение пробелов.
|
||||
@@ -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-устройство.
|
||||
|
||||
Reference in new issue
Block a user