Add Windows SSH monitoring MVP #1
4 changed files with 257 additions and 134 deletions
|
|
@ -1,51 +1,64 @@
|
||||||
# Архитектура Server Monitor Manager
|
# Архитектура Server Monitor Manager
|
||||||
|
|
||||||
## 1. Компоненты
|
## 1. Выбранная топология
|
||||||
|
|
||||||
Для первого тестирования используется переходный режим **SSH pull**: Windows-клиент вызывает на сервере ограниченный forced-command и получает snapshot. Постоянный агент и control node ниже описывают следующий этап после проверки UX на трёх серверах.
|
Первый рабочий вариант использует один **Mesh Hub** на Linux-сервере с белым IP. Остальные узлы не требуют входящего публичного порта и устанавливают исходящее WireGuard-соединение с Hub.
|
||||||
|
|
||||||
### Desktop client
|
```text
|
||||||
|
Windows client -- ограниченный SSH --> Mesh Hub (публичный UDP)
|
||||||
|
^
|
||||||
|
|
|
||||||
|
исходящие WireGuard-туннели
|
||||||
|
|
|
||||||
|
AI-agent / Home / Server2 / ...
|
||||||
|
```
|
||||||
|
|
||||||
Windows-first приложение на WinUI 3. Оно показывает состояние всех серверов, графики, события, терминалы и связи. Клиент хранит пользовательские секреты в Windows Credential Locker/DPAPI и не передаёт приватные SSH-ключи control node.
|
Hub выполняет две разные функции:
|
||||||
|
|
||||||
### Control node
|
- control plane первого MVP: список узлов, политики Links и команды управления через ограниченный SSH forced-command;
|
||||||
|
- data plane первого MVP: маршрутизация WireGuard-трафика с обязательной фильтрацией nftables.
|
||||||
|
|
||||||
Небольшой координационный сервис, который можно установить на одном из своих серверов. Он принимает исходящие mTLS-соединения агентов, хранит инвентарь, короткую историю метрик, правила оповещений, команды и аудит. Для одного пользователя достаточно SQLite; внешний PostgreSQL не является требованием MVP.
|
Это осознанная звёздная топология. Прямые peer-to-peer соединения, relay и отказоустойчивый второй Hub не входят в первый MVP.
|
||||||
|
|
||||||
Control node не становится обязательным маршрутизатором трафика между серверами. При возможности соединение идёт напрямую. Relay добавляется позже как явно включаемый режим для узлов за NAT.
|
## 2. Текущий переходный режим
|
||||||
|
|
||||||
### Linux agent
|
### Windows client
|
||||||
|
|
||||||
Один статически собранный бинарный файл. Агент читает `/proc`, `/sys` и разрешённые systemd-состояния, агрегирует метрики локально и отправляет их наружу. По умолчанию он запускается непривилегированным пользователем и не открывает входящих портов.
|
Packaged WinUI 3 приложение хранит профили серверов локально, создаёт отдельную Ed25519 identity мониторинга и вызывает только разрешённые SSH-команды. Клиент показывает snapshot метрик, узлы Mesh и направленные Links.
|
||||||
|
|
||||||
Привилегированные операции выносятся в маленький отдельный helper с белым списком действий. Агент мониторинга не должен постоянно иметь `root` или `CAP_NET_ADMIN`.
|
### SSH monitoring endpoint
|
||||||
|
|
||||||
## 2. Потоки данных
|
На Hub и Node создаётся непривилегированный пользователь `ochenstarik-monitor`. Его ключ привязан к root-owned forced-command и не даёт shell, PTY или forwarding. В текущем протоколе доступны `metrics` и ограниченные команды `mesh` на Hub.
|
||||||
|
|
||||||
### Метрики
|
### Mesh Hub
|
||||||
|
|
||||||
Агент отправляет компактный snapshot каждые 5–15 секунд. Control node сохраняет сырые точки недолго, затем выполняет downsampling. При потере сети агент держит ограниченный дисковый буфер и не заполняет диск.
|
Hub хранит:
|
||||||
|
|
||||||
Минимальный snapshot:
|
- публичные WireGuard identities узлов;
|
||||||
|
- выданные внутренние адреса;
|
||||||
|
- желаемое и фактическое состояние Links;
|
||||||
|
- политики CIDR, протокола, порта и TTL;
|
||||||
|
- журнал управляющих операций.
|
||||||
|
|
||||||
- load average и использование CPU;
|
Приватный WireGuard-ключ каждого Node создаётся на самом Node и никогда не передаётся Hub. Временный enrollment token не является ключом узла.
|
||||||
- использованная/доступная память и swap;
|
|
||||||
- заполнение и inode выбранных файловых систем;
|
|
||||||
- сетевые счётчики интерфейсов;
|
|
||||||
- uptime, температура при наличии датчиков;
|
|
||||||
- состояние выбранных systemd units;
|
|
||||||
- только метаданные процессов, разрешённые политикой.
|
|
||||||
|
|
||||||
### Команды и терминал
|
### Node
|
||||||
|
|
||||||
Произвольная shell-команда не является обычной командой агента. Для безопасных операций используются типизированные действия: перезапуск разрешённой службы, чтение журнала с ограничением, получение списка процессов. Полный терминал создаётся как отдельная SSH-сессия от desktop client.
|
Node устанавливает исходящее WireGuard-соединение с Hub. Входящий публичный порт не нужен. Node применяет выданную конфигурацию, подтверждает её версию и хранит приватный ключ с правами `0600`.
|
||||||
|
|
||||||
### Links между серверами
|
## 3. Метрики
|
||||||
|
|
||||||
Link — отдельный ресурс, а не свойство группы серверов:
|
Текущий SSH snapshot содержит CPU/load, память, корневой диск, uptime и задержку. Следующая версия добавляет swap, inode, сетевые счётчики и выбранные systemd units.
|
||||||
|
|
||||||
|
Постоянный Linux agent появится после стабилизации трёхсерверного сценария. Он будет отправлять метрики исходящим mTLS-соединением, вести ограниченный локальный буфер и не открывать публичный API.
|
||||||
|
|
||||||
|
## 4. Links между серверами
|
||||||
|
|
||||||
|
Link — направленный ресурс:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
Draft -> Connecting -> Active -> Disconnecting -> Disabled
|
Draft -> Connecting -> Active -> Disconnecting -> Disabled
|
||||||
|
\-> Partial
|
||||||
\-> Failed
|
\-> Failed
|
||||||
Active -> Expired -> Disabled
|
Active -> Expired -> Disabled
|
||||||
```
|
```
|
||||||
|
|
@ -53,33 +66,42 @@ Active -> Expired -> Disabled
|
||||||
Каждый Link содержит:
|
Каждый Link содержит:
|
||||||
|
|
||||||
- source и destination;
|
- source и destination;
|
||||||
- разрешённые IP/CIDR и TCP/UDP-порты;
|
- разрешённый IP или CIDR;
|
||||||
- режим `manual` или TTL;
|
- протокол TCP/UDP и список портов;
|
||||||
- WireGuard peer identities;
|
- ручной режим или TTL;
|
||||||
- владельца, причину и запись аудита;
|
- причину, владельца и запись аудита;
|
||||||
- фактическое состояние обоих узлов.
|
- версию политики и подтверждение применения.
|
||||||
|
|
||||||
Control node передаёт каждому узлу только его часть конфигурации. Приватный WireGuard-ключ никогда не покидает узел. `Disconnect` удаляет peer и маршруты с обеих сторон; при недоступности одного узла команда остаётся обязательной и применяется при его следующем подключении.
|
Пустая политика не означает `allow all`. Ответный трафик существующего соединения разрешается stateful-правилом, обратное новое соединение требует отдельного Link.
|
||||||
|
|
||||||
## 3. Сценарий AI-агента
|
При `Disconnect` Hub сначала блокирует направление в nftables, затем фиксирует `Disabled`. Если подтверждение узла недоступно, интерфейс показывает `Partial`, а обязательное состояние применяется после reconnect.
|
||||||
|
|
||||||
1. На домашнем сервере создаётся отдельный пользователь, например `ai-agent-dev`, без root-доступа.
|
## 5. Сценарий AI-агента
|
||||||
2. Рабочие каталоги и разрешённые команды ограничиваются Unix-правами, группами, контейнером или sandbox-профилем.
|
|
||||||
3. В Server Monitor Manager создаётся Link от сервера с AI-агентом к домашнему серверу только для адреса домашнего узла и SSH-порта.
|
|
||||||
4. AI-агент использует собственный SSH-ключ или короткоживущий SSH-сертификат.
|
|
||||||
5. Пользователь нажимает `Connect`; после разработки — `Disconnect`.
|
|
||||||
6. Отключение Link разрывает сетевую достижимость, а отзыв SSH-сертификата/ключа остаётся вторым независимым барьером.
|
|
||||||
|
|
||||||
## 4. Режимы развёртывания
|
1. На целевом сервере создаётся отдельный Unix-пользователь, например `ai-agent-dev`, без root-доступа.
|
||||||
|
2. Рабочие каталоги и команды ограничиваются Unix-правами, группами, контейнером или sandbox-профилем.
|
||||||
|
3. Создаётся Link от узла с AI-агентом к целевому адресу и только необходимому SSH-порту.
|
||||||
|
4. AI-агент использует отдельную SSH identity, не ключ мониторинга приложения.
|
||||||
|
5. Пользователь включает Link на ограниченное время и после работы отключает его.
|
||||||
|
|
||||||
- **Single owner:** один control node, один пользователь, SQLite. Основной MVP.
|
## 6. Следующий control layer
|
||||||
- **Family/team:** несколько пользователей, роли и подтверждения. После MVP.
|
|
||||||
- **Direct local:** desktop подключается к агентам внутри одной сети без публичного control node. Возможен позже, но использует тот же протокол идентичности.
|
|
||||||
|
|
||||||
## 5. Целевые ограничения MVP
|
После проверки текущей топологии SSH-команды управления заменяются небольшим control service:
|
||||||
|
|
||||||
- агент: один бинарник, idle RAM до 50 МБ, CPU в простое менее 1%;
|
- SQLite для инвентаря, политик, истории и аудита;
|
||||||
- control node: запуск без Kubernetes и обязательного Docker;
|
- одноразовая enrollment-регистрация;
|
||||||
- отсутствие открытого agent API в интернет;
|
- исходящие mTLS-сессии агентов;
|
||||||
- работа при 50–100 серверах на одном небольшом control node;
|
- WebSocket/stream событий для desktop client;
|
||||||
- деградация без потери управления: графики могут иметь пробелы, но команды не выполняются повторно без idempotency key.
|
- idempotency key и защита от replay.
|
||||||
|
|
||||||
|
Hub остаётся маршрутизатором Mesh первого поколения. Разделение control plane и data plane возможно позже без изменения модели направленных Links.
|
||||||
|
|
||||||
|
## 7. Целевые ограничения MVP
|
||||||
|
|
||||||
|
- без Kubernetes и обязательного Docker;
|
||||||
|
- отсутствие публичного agent API;
|
||||||
|
- вторичные серверы работают без белого IP;
|
||||||
|
- 50–100 узлов на одном небольшом Hub;
|
||||||
|
- Node agent: idle RAM до 50 МБ и CPU менее 1%;
|
||||||
|
- команды не повторяются без idempotency key;
|
||||||
|
- потеря истории метрик не должна приводить к потере управления Links.
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,74 @@
|
||||||
# Контракт Linux-установщика
|
# Контракт Linux-установщика
|
||||||
|
|
||||||
Файл `ochenstarik-server-monitor-manager.sh` находится в `ochenstarik-ui/lightweight-server`; синхронная копия хранится в `deploy/` этого репозитория.
|
Единственный исходный файл `ochenstarik-server-monitor-manager.sh` хранится в `ochenstarik-ui/lightweight-server`. В репозитории desktop client не должна находиться устаревающая копия.
|
||||||
|
|
||||||
## Первый тестовый этап: SSH pull
|
## Поддерживаемые роли
|
||||||
|
|
||||||
До появления постоянного агента Windows-клиент получает метрики через OpenSSH. Установщик:
|
### Monitor only
|
||||||
|
|
||||||
- поддерживает Ubuntu/Debian с systemd;
|
Режим `install` устанавливает SSH monitoring endpoint без WireGuard:
|
||||||
- запрашивает публичный ключ `ssh-ed25519`, созданный Windows-клиентом;
|
|
||||||
- читает интерактивный ключ из `/dev/tty`, поэтому поддерживает установку через `curl | sudo bash`;
|
|
||||||
- поддерживает повторяемый режим через `SERVER_MONITOR_PUBLIC_KEY`;
|
|
||||||
- проверяет синтаксис ключа через `ssh-keygen`;
|
|
||||||
- устанавливает и включает OpenSSH Server, не меняя текущий SSH-порт;
|
|
||||||
- создаёт отдельного системного пользователя `ochenstarik-monitor` без пароля;
|
|
||||||
- устанавливает root-owned metrics command;
|
|
||||||
- записывает ключ как `restrict,command="..."`;
|
|
||||||
- не создаёт UFW-правил и не открывает дополнительных портов;
|
|
||||||
- поддерживает `install`, `status` и `uninstall`;
|
|
||||||
- допускает безопасный повторный запуск для замены ключа мониторинга.
|
|
||||||
|
|
||||||
Forced-command отдаёт только строки `KEY=VALUE`:
|
- Ubuntu/Debian с systemd;
|
||||||
|
- публичный ключ `ssh-ed25519` из Windows-клиента;
|
||||||
|
- отдельный системный пользователь `ochenstarik-monitor` без пароля;
|
||||||
|
- root-owned forced-command;
|
||||||
|
- сохранение существующего SSH-порта;
|
||||||
|
- отсутствие нового публичного API.
|
||||||
|
|
||||||
|
### Hub
|
||||||
|
|
||||||
|
Режим `hub` дополнительно:
|
||||||
|
|
||||||
|
- устанавливает WireGuard и nftables;
|
||||||
|
- запрашивает публичный IPv4/домен и UDP-порт;
|
||||||
|
- создаёт `smm0` с адресом `10.77.0.1/24`;
|
||||||
|
- включает IPv4 forwarding;
|
||||||
|
- устанавливает минимальный root helper и systemd restore unit;
|
||||||
|
- хранит публичные identities Node и политики Links;
|
||||||
|
- разрешает транзит только по явной политике.
|
||||||
|
|
||||||
|
### Node
|
||||||
|
|
||||||
|
Режим `node`:
|
||||||
|
|
||||||
|
- локально генерирует WireGuard keypair;
|
||||||
|
- принимает одноразовый enrollment token;
|
||||||
|
- отправляет Hub только публичный ключ;
|
||||||
|
- получает внутренний адрес и подписанную конфигурацию;
|
||||||
|
- создаёт только исходящее WireGuard-соединение;
|
||||||
|
- не требует белого IP или входящего публичного порта.
|
||||||
|
|
||||||
|
## Команды жизненного цикла
|
||||||
|
|
||||||
|
Целевой интерфейс:
|
||||||
|
|
||||||
|
```text
|
||||||
|
install-monitor
|
||||||
|
install-hub
|
||||||
|
install-node
|
||||||
|
status
|
||||||
|
update
|
||||||
|
rollback
|
||||||
|
uninstall-monitor
|
||||||
|
uninstall-node
|
||||||
|
uninstall-hub
|
||||||
|
```
|
||||||
|
|
||||||
|
Каждая установка и обновление должны быть идемпотентными. Перед изменением рабочей конфигурации создаётся root-only backup. Ошибка проверки или запуска автоматически восстанавливает последнюю рабочую версию.
|
||||||
|
|
||||||
|
Удаление роли должно убрать только принадлежащие ей файлы, units, интерфейсы и правила. Удаление Hub требует отдельного подтверждения и не должно молча оставлять включённый forwarding или nftables ACL.
|
||||||
|
|
||||||
|
## Forced-command
|
||||||
|
|
||||||
|
Ключ мониторинга допускает только:
|
||||||
|
|
||||||
|
- `metrics`;
|
||||||
|
- read-only `mesh nodes`, `mesh links`, `mesh status` на Hub;
|
||||||
|
- строго типизированные изменения Link с проверкой параметров.
|
||||||
|
|
||||||
|
Он не должен позволять shell, PTY, agent forwarding, TCP forwarding или произвольную команду. Полный SSH-терминал использует отдельную identity.
|
||||||
|
|
||||||
|
## Минимальный metrics snapshot
|
||||||
|
|
||||||
```text
|
```text
|
||||||
PROTOCOL=1
|
PROTOCOL=1
|
||||||
|
|
@ -29,13 +78,23 @@ LOAD1=0.42
|
||||||
CPU_COUNT=4
|
CPU_COUNT=4
|
||||||
MEM_TOTAL_KB=...
|
MEM_TOTAL_KB=...
|
||||||
MEM_AVAILABLE_KB=...
|
MEM_AVAILABLE_KB=...
|
||||||
|
SWAP_TOTAL_KB=...
|
||||||
|
SWAP_FREE_KB=...
|
||||||
DISK_TOTAL_KB=...
|
DISK_TOTAL_KB=...
|
||||||
DISK_AVAILABLE_KB=...
|
DISK_AVAILABLE_KB=...
|
||||||
|
DISK_INODES_TOTAL=...
|
||||||
|
DISK_INODES_FREE=...
|
||||||
|
NETWORK_RX_BYTES=...
|
||||||
|
NETWORK_TX_BYTES=...
|
||||||
KERNEL=...
|
KERNEL=...
|
||||||
```
|
```
|
||||||
|
|
||||||
Ключ мониторинга не должен позволять shell, PTY, agent forwarding, TCP forwarding или выполнение переданной клиентом команды. Полноценный SSH-терминал использует отдельную пользовательскую identity и не входит в этот ключ.
|
## Проверки перед применением
|
||||||
|
|
||||||
## Будущий этап: постоянный агент
|
- `bash -n` и ShellCheck;
|
||||||
|
- проверка SSH-ключа через `ssh-keygen`;
|
||||||
После проверки UX на нескольких серверах SSH pull будет дополнен статическим агентом для потоковых метрик, systemd events, короткого локального буфера и управляемых WireGuard Links. Агент будет регистрироваться одноразовым token и работать по исходящему mTLS-соединению без входящего API.
|
- `sshd -t` перед reload;
|
||||||
|
- `wg-quick strip` и пробный запуск конфигурации;
|
||||||
|
- `nft --check` перед заменой таблицы;
|
||||||
|
- проверка systemd unit;
|
||||||
|
- сохранение активной SSH-сессии до подтверждения нового доступа.
|
||||||
|
|
|
||||||
103
docs/roadmap.md
103
docs/roadmap.md
|
|
@ -1,52 +1,85 @@
|
||||||
# План разработки
|
# План разработки
|
||||||
|
|
||||||
## Этап 0 — фундамент
|
## Этап 0 — репозиторий и контракт
|
||||||
|
|
||||||
- [x] переименовать проект в Server Monitor Manager;
|
- [x] переименовать проект в Server Monitor Manager;
|
||||||
- [x] разделить мониторинг, терминал и Links в архитектуре;
|
- [x] выбрать звёздную архитектуру Hub/Node для первого Mesh;
|
||||||
- [x] определить безопасный контракт установки агента;
|
- [x] разделить monitoring identity, terminal identity и AI-agent identity;
|
||||||
|
- [x] описать направленные Links и kill switch;
|
||||||
- [ ] выбрать лицензию;
|
- [ ] выбрать лицензию;
|
||||||
- [ ] настроить CI, форматирование, тесты и релизные checksum.
|
- [ ] добавить CI, форматирование, тесты и release checksum;
|
||||||
|
- [ ] объединить PR приложения и установщика в `main`.
|
||||||
|
|
||||||
## Этап 1 — Windows MVP
|
## Этап 1 — Windows SSH MVP
|
||||||
|
|
||||||
- [x] установить .NET SDK и официальный WinUI 3 toolchain;
|
- [x] создать packaged WinUI 3 приложение;
|
||||||
- [x] создать packaged WinUI 3 приложение с воспроизводимым CLI-запуском через WinApp;
|
- [x] добавить адаптивный Overview и профили нескольких серверов;
|
||||||
- [x] реализовать shell: Overview, Servers, Links, Sessions, Settings;
|
- [x] генерировать отдельный Ed25519 SSH-ключ;
|
||||||
- [x] добавить локальные demo-данные и адаптивный dashboard;
|
- [x] сохранять профили локально без паролей;
|
||||||
- [x] генерировать отдельный Ed25519 SSH-ключ и хранить его в локальном каталоге packaged-приложения;
|
- [x] получать CPU/load, RAM, disk, uptime и latency;
|
||||||
- [x] сохранять профили серверов локально без паролей;
|
- [x] собрать и реально запустить x64-приложение;
|
||||||
- [x] собрать и реально запустить x64-приложение.
|
- [ ] редактирование и удаление серверов;
|
||||||
|
- [ ] единственный изменяемый Hub;
|
||||||
|
- [ ] настоящие страницы Servers, Links, Sessions и Settings.
|
||||||
|
|
||||||
## Этап 2 — мониторинг одного сервера
|
## Этап 2 — установщик Hub/Node
|
||||||
|
|
||||||
- [x] первый бездемонный Linux endpoint через SSH forced-command;
|
- [x] SSH forced-command для Ubuntu/Debian;
|
||||||
- [ ] статический постоянный Linux agent для amd64/arm64;
|
- [x] роли `hub` и `node`;
|
||||||
- [ ] control node с SQLite, mTLS enrollment и WebSocket событиями;
|
- [x] WireGuard Hub и исходящие Node-соединения;
|
||||||
- [ ] CPU, RAM, disk, network, uptime и systemd units;
|
- [x] постоянный nftables ACL на Hub;
|
||||||
- [ ] ограниченный локальный буфер и downsampling;
|
- [x] список узлов и handshake-состояние;
|
||||||
- [ ] installer, update, rollback и uninstall;
|
- [ ] явные зависимости `sudo`, `visudo` и `ping` для минимального Debian;
|
||||||
- [ ] предупреждения о диске, памяти и недоступности.
|
- [ ] безопасные `update` и `rollback`;
|
||||||
|
- [ ] полный `uninstall-monitor`, `uninstall-node` и `uninstall-hub`;
|
||||||
|
- [ ] интеграционный тест повторной установки и reboot.
|
||||||
|
|
||||||
## Этап 3 — несколько серверов и терминал
|
## Этап 3 — безопасная регистрация
|
||||||
|
|
||||||
- [ ] группы, теги, поиск и сводные статусы;
|
- [ ] локальная генерация WireGuard-ключа на Node;
|
||||||
- [ ] прямой SSH из Windows-клиента;
|
- [ ] одноразовый enrollment token;
|
||||||
- [ ] known_hosts pinning и отдельные profiles;
|
- [ ] срок действия не более 10 минут;
|
||||||
- [ ] типизированные безопасные действия с аудитом;
|
- [ ] атомарное погашение token;
|
||||||
- [ ] экспорт диагностики без секретов.
|
- [ ] отзыв и повторная регистрация Node;
|
||||||
|
- [ ] подтверждение fingerprint Hub;
|
||||||
|
- [ ] защита desktop SSH-ключа через DPAPI.
|
||||||
|
|
||||||
## Этап 4 — Links и AI-агенты
|
## Этап 4 — управляемые Links
|
||||||
|
|
||||||
- [ ] WireGuard peer helper с минимальными привилегиями;
|
- [x] направленные пары source → destination;
|
||||||
- [ ] policies по CIDR, протоколу, порту и TTL;
|
- [x] ручное добавление и удаление nftables ACL из Windows-клиента;
|
||||||
- [ ] connect/disconnect с подтверждением обоих узлов;
|
- [ ] политики по CIDR, TCP/UDP и порту;
|
||||||
|
- [ ] TTL и автоматическое истечение;
|
||||||
|
- [ ] состояния Connecting, Active, Disconnecting, Partial, Disabled и Failed;
|
||||||
|
- [ ] версия политики и подтверждение применения;
|
||||||
- [ ] обязательное отключение после reconnect;
|
- [ ] обязательное отключение после reconnect;
|
||||||
- [ ] отдельная automation identity для AI-агента;
|
- [ ] append-only аудит;
|
||||||
- [ ] интеграционные тесты kill switch и частичных отказов.
|
- [ ] интеграционные тесты kill switch и частичных отказов.
|
||||||
|
|
||||||
## Этап 5 — другие платформы
|
## Этап 5 — мониторинг и терминал
|
||||||
|
|
||||||
- [ ] macOS и Linux desktop clients после стабилизации Core/API;
|
- [ ] swap, inode, network и выбранные systemd units;
|
||||||
- [ ] Android/iOS как companion-клиенты;
|
- [ ] предупреждения по диску, памяти и недоступности;
|
||||||
- [ ] push-уведомления без передачи административных секретов стороннему push-провайдеру.
|
- [ ] автоматическое обновление и короткая локальная история;
|
||||||
|
- [ ] графики и экспорт диагностики без секретов;
|
||||||
|
- [ ] отдельный прямой SSH-терминал;
|
||||||
|
- [ ] отдельная terminal identity и подтверждение пользователя;
|
||||||
|
- [ ] отдельная automation identity для AI-агента.
|
||||||
|
|
||||||
|
## Этап 6 — постоянный control layer
|
||||||
|
|
||||||
|
- [ ] статический Linux agent для amd64/arm64;
|
||||||
|
- [ ] SQLite inventory, policies, history и audit;
|
||||||
|
- [ ] исходящие mTLS agent sessions;
|
||||||
|
- [ ] WebSocket/stream событий для desktop client;
|
||||||
|
- [ ] ограниченный локальный буфер и downsampling;
|
||||||
|
- [ ] idempotency key и защита от replay;
|
||||||
|
- [ ] тест нагрузки 50–100 Node на одном Hub.
|
||||||
|
|
||||||
|
## Этап 7 — релиз и другие платформы
|
||||||
|
|
||||||
|
- [ ] подписанный Windows installer и GitHub Release;
|
||||||
|
- [ ] checksum Linux-установщика и бинарников;
|
||||||
|
- [ ] macOS и Linux desktop после стабилизации Core/API;
|
||||||
|
- [ ] Android/iOS companion clients;
|
||||||
|
- [ ] push-уведомления без административных секретов у push-провайдера.
|
||||||
|
|
|
||||||
|
|
@ -2,55 +2,64 @@
|
||||||
|
|
||||||
## Защищаемые данные
|
## Защищаемые данные
|
||||||
|
|
||||||
- учётные записи и сессии пользователей;
|
- SSH, WireGuard, device и agent identities;
|
||||||
- device, agent, SSH и WireGuard identities;
|
- topology, внутренние адреса, метрики и состояния Links;
|
||||||
- команды, терминальные сессии и аудит;
|
- команды, терминальные сессии и аудит;
|
||||||
- topology серверов, адреса и метрики;
|
- права пользователей и AI-агентов.
|
||||||
- права автоматизаций, включая AI-агентов.
|
|
||||||
|
|
||||||
## Границы доверия
|
## Границы доверия
|
||||||
|
|
||||||
Desktop client, control node и каждый agent считаются отдельными субъектами. Компрометация одного агента не должна выдавать ключи других узлов или право создавать новые Links. Control node координирует публичные параметры и политики, но не хранит приватные WireGuard/SSH-ключи узлов.
|
Windows client, Hub и каждый Node считаются отдельными субъектами. Компрометация одного Node не должна выдавать ключи других узлов или право создавать новые Links.
|
||||||
|
|
||||||
В первом SSH-MVP control node отсутствует. Windows-клиент генерирует отдельный Ed25519-ключ, а сервер привязывает его к `restrict,command`. Этот ключ предназначен только для чтения ограниченного snapshot метрик и не используется для интерактивного терминала или AI-агента.
|
Hub хранит только публичные WireGuard-ключи Node. Приватный ключ Node генерируется локально, не включается в enrollment token и не записывается на Hub.
|
||||||
|
|
||||||
## Регистрация агента
|
## SSH monitoring MVP
|
||||||
|
|
||||||
1. Пользователь создаёт одноразовый enrollment token со сроком жизни не более 10 минут.
|
Windows-клиент использует отдельный Ed25519-ключ только для forced-command. Этот ключ не используется для интерактивного терминала или AI-агента. Первый host key требует явного подтверждения fingerprint; последующие подключения проверяют сохранённый `known_hosts`.
|
||||||
2. Агент генерирует ключевую пару локально.
|
|
||||||
3. По TLS агент предъявляет token и публичный ключ.
|
|
||||||
4. Control node выдаёт agent certificate и помечает token использованным.
|
|
||||||
5. Последующие соединения требуют mTLS. Повторное использование token отклоняется.
|
|
||||||
|
|
||||||
## Авторизация
|
Приватный ключ клиента защищается Windows DPAPI и доступом текущего пользователя. Профили серверов не содержат паролей.
|
||||||
|
|
||||||
- read-only мониторинг отделён от управления;
|
## Регистрация Node
|
||||||
- команды проверяются по типу ресурса и действию;
|
|
||||||
- полный терминал требует свежего подтверждения пользователя;
|
1. На Hub создаётся случайный enrollment token со сроком жизни не более 10 минут.
|
||||||
- создание Link требует точного набора маршрутов/портов, пустой набор не означает `allow all`;
|
2. Node локально генерирует WireGuard-ключ.
|
||||||
|
3. Node предъявляет token и публичный ключ по защищённому каналу.
|
||||||
|
4. Hub атомарно помечает token использованным, назначает адрес и возвращает подписанную конфигурацию.
|
||||||
|
5. Повторное использование, просроченный token и смена публичного ключа отклоняются.
|
||||||
|
|
||||||
|
До появления mTLS enrollment выполняется через отдельную ограниченную SSH-команду. Token не должен содержать приватный WireGuard-ключ.
|
||||||
|
|
||||||
|
## Авторизация Links
|
||||||
|
|
||||||
|
- мониторинг read-only отделён от управления;
|
||||||
|
- Link всегда содержит source, destination, CIDR, протокол и порт;
|
||||||
|
- пустой список портов не означает разрешение всех портов;
|
||||||
- automation identity не наследует интерактивные права владельца;
|
- automation identity не наследует интерактивные права владельца;
|
||||||
- команды имеют срок действия, nonce/idempotency key и защиту от replay.
|
- команды имеют TTL, nonce/idempotency key и версию политики;
|
||||||
|
- Hub проверяет имена и параметры повторно, независимо от проверки desktop client.
|
||||||
|
|
||||||
## Аудит
|
## Аудит
|
||||||
|
|
||||||
Записываются входы, регистрация устройств, изменение прав, команды, начало и завершение терминала, создание/подключение/отключение Link. Секреты и полный ввод терминала по умолчанию не журналируются. Аудит экспортируется во внешний append-only storage; локальный администратор control node всё равно считается способным изменить локальную БД.
|
Записываются регистрация и удаление узла, изменение прав, создание, включение, истечение и отключение Link, а также ошибки применения. Секреты, приватные ключи и полный ввод терминала не журналируются.
|
||||||
|
|
||||||
|
Для первого MVP используется append-only JSONL с ограниченными правами и ротацией. После появления control service аудит переносится в SQLite с возможностью внешнего экспорта.
|
||||||
|
|
||||||
## Kill switch
|
## Kill switch
|
||||||
|
|
||||||
Отключение Link должно:
|
Отключение Link должно:
|
||||||
|
|
||||||
1. перевести желаемое состояние в `Disabled`;
|
1. немедленно удалить разрешающее правило на Hub;
|
||||||
2. удалить peer и маршруты на доступных узлах;
|
2. записать желаемое состояние `Disabled` до отправки дополнительных команд;
|
||||||
3. заблокировать повторное автоматическое включение;
|
3. запретить автоматическое восстановление после reboot/reconnect;
|
||||||
4. сохранить обязательную команду для временно недоступного узла;
|
4. получить подтверждение применённой версии политики;
|
||||||
5. показать пользователю разницу между желаемым и фактическим состоянием.
|
5. показывать `Partial`, если подтверждение одного из узлов отсутствует;
|
||||||
|
6. сохранить обязательную операцию для временно недоступного Node.
|
||||||
Кнопка не должна сообщать «отключено», пока оба узла не подтвердили применение или интерфейс явно не показывает частичное отключение.
|
|
||||||
|
|
||||||
## Не входит в первый MVP
|
## Не входит в первый MVP
|
||||||
|
|
||||||
- выполнение произвольных root-команд из веб/API;
|
- выполнение произвольных root-команд;
|
||||||
- хранение пользовательских приватных SSH-ключей на control node;
|
- хранение пользовательских приватных SSH-ключей на Hub;
|
||||||
- автоматическое соединение всех серверов группы в одну flat network;
|
- автоматическое объединение всех серверов в flat network;
|
||||||
- публичный входящий порт агента;
|
- публичный входящий API на Node;
|
||||||
- собственная криптография вместо TLS, SSH и WireGuard.
|
- собственная криптография вместо SSH, TLS и WireGuard;
|
||||||
|
- автоматический failover между несколькими Hub.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue