Files
knowledge-base/projects/dttb/ai-assistant-pilot/architecture.md

193 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
date: 2026-06-17
type: reference
tags: [ai-assistant, alexandr, umnybot, architecture, topology, netbird, proxmox]
aliases: [архитектура коробки Александра, umnybot architecture, топология умного сервера]
---
# 🏗️ Архитектура «Умного сервера» Александра (umnybot)
> Авторитетная карта коробки после переезда к Александру (2026-06-17). Секреты — в [[credentials]]. Пилот/контекст — память `project_alexandr_assistant`, [[../../benilux/credentials|сеть Бенелюкса]].
## Кратко
«Консьерж в коробке» — Proxmox-нода у Александра (КП Бенелюкс), переехала из LAN Олега `10.0.0.0/24` в сеть Александра `192.168.1.0/24` (2026-06-17). Интерфейс клиента — **бот Алекс в Telegram** + **SwarmClaw на `https://umnybot.ru`**. Публичный доступ — через статичный VPS-шлюз по NetBird (WAN Александра динамический, на него вешать DNS нельзя).
## Топология
```mermaid
flowchart TB
user([Интернет]) -->|"https://umnybot.ru"| dns["DNS *.umnybot.ru → 158.255.0.139"]
user -->|"https://pve.umnybot.ru<br/>(Basic Auth oleg)"| dns
dns --> vps
subgraph VPSGW ["VPS-шлюз · vm-nano · 158.255.0.139 (статичный) · NetBird 100.70.127.23"]
vps["jc21 NPM :443 · LE-серты<br/>Basic Auth для pve"]
end
vps ==>|"NetBird → 100.70.90.103:80"| boxnpm
subgraph BOX ["Коробка Александра · Proxmox pve-147 (192.168.1.247) · LAN 192.168.1.0/24"]
boxnpm["LXC101 «npm» · 192.168.1.221<br/>NetBird 100.70.90.103 (alex-npm)"]
boxnpm ==>|"Host umnybot.ru"| swarm["LXC103 SwarmClaw<br/>192.168.1.71:3456"]
boxnpm ==>|"Host pve.umnybot.ru"| host["Proxmox UI<br/>host:8006"]
boxnpm -.->|"omni (internal)"| omni["LXC102 OmniRoute :20128<br/>NetBird 100.70.186.192"]
boxnpm -.->|"cloud (internal)"| fb["LXC105 filebrowser :8082"]
boxnpm -.->|"alex (internal)"| hp["LXC105 Homepage :3001"]
boxnpm -.->|"git (internal)"| git["LXC104 Gitea :3000"]
bot["LXC102 openclaw «Алекс»<br/>→ Telegram @alex_umny_bot"]
zima["VM100 ZimaOS — STOPPED<br/>(не используется)"]
end
oleg([Олег / админ]) -.->|"NetBird"| omni
classDef pub fill:#1f6f43,stroke:#0a3,color:#fff
classDef int fill:#333,stroke:#888,color:#ddd
classDef off fill:#5a1a1a,stroke:#a33,color:#fcc
class vps,boxnpm,swarm,host pub
class omni,fb,hp,git,bot int
class zima off
```
Сплошные стрелки (`==>`) — **публичный** путь (`umnybot.ru`; `pve.umnybot.ru` — за Basic Auth). Пунктир (`-.->`) — только **внутри** по NetBird.
## Хосты и сеть
| Узел | Адрес | NetBird | Роль |
|---|---|---|---|
| **Proxmox pve-147** (хост) | `192.168.1.247` static (+резерв Cudy), gw `.1` | нет (джамп через LXC102) | гипервизор, Web UI `:8006` |
| Cudy TR3000 (роутер Александра) | LAN `192.168.1.1`, WAN **`45.143.21.60` динамич. (dhcp)** | `100.70.207.97` | шлюз сети Александра |
| **VPS-шлюз vm-nano** | `158.255.0.139` (статичный, Ubuntu 22.04) | `100.70.127.23` | публичный фронт, jc21 NPM + LE |
## Контейнеры / VM
| ID | Имя | IP (LAN) | NetBird | Сервис | Порт |
|---|---|---|---|---|---|
| LXC 101 | npm | `192.168.1.221` | **`100.70.90.103`** (alex-npm) | jc21 NPM (внутр. роутер коробки) | 80/81/443 |
| LXC 102 | assistant | `192.168.1.154` | `100.70.186.192` (alex-assistant) | openclaw «Алекс» + OmniRoute + Postgres | TG, 20128, 5432 |
| LXC 103 | swarmclaw | `192.168.1.71` | — | **SwarmClaw** (UI на umnybot.ru) | 3456 |
| LXC 104 | gitea | `192.168.1.96` | — | Gitea | 3000 |
| LXC 105 | alex-apps | `192.168.1.14` (резерв) | — | Docker: filebrowser (облако) + Homepage (дашборд) | 8082, 3001 |
| VM 100 | Zima | — | — | ZimaOS — **stopped, не используется** (KVM/VT-x слетел, заменён Docker-апками на 105) | — |
Все контейнеры — `ip=dhcp` (резервации MAC→IP на Cudy для хоста .247 и apps .14). NetBird-агенты на 101/102 — autostart enabled.
## Домены и доступ
| Домен | Доступ | Бэкенд | Через |
|---|---|---|---|
| **`umnybot.ru`** | 🌐 ПУБЛИЧНО | SwarmClaw (103:3456) | VPS NPM → NetBird → NPM коробки (id9) |
| `omni.umnybot.ru` | 🔒 internal | OmniRoute (102:20128) | NetBird (напрямую `100.70.186.192:20128`) |
| `cloud.umnybot.ru` | 🔒 internal | filebrowser (105:8082) | NetBird → NPM коробки |
| `alex.umnybot.ru` | 🔒 internal | Homepage (105:3001) | NetBird → NPM коробки |
| `git.umnybot.ru` | 🔒 internal | Gitea (104:3000) | NetBird → NPM коробки |
| **`pve.umnybot.ru`** | 🌐 ПУБЛИЧНО + **Basic Auth** (`oleg`) | Proxmox UI (host:8006) | VPS NPM (LE id18, access-list `pve-basic-auth`) → NetBird → NPM коробки → Proxmox. ⚠️ root-пароль Proxmox слабый — сменить/2FA |
| ~~zima/tg/rustdesk/plex/ha/oc/qbit/term~~ | удалены | были апки ZimaOS | VM100 не используется |
| `ai.umnybot.ru` | — | домашний openclaw Олега (`10.0.0.239`) | не относится к коробке |
> На VPS NPM публично сейчас — **`umnybot.ru`** (SwarmClaw) и **`pve.umnybot.ru`** (Proxmox за Basic Auth). Остальные домены сняты с VPS; их бэкенды доступны по NetBird/LAN.
## Доступ для управления
```bash
# Хост Proxmox (нет своего NetBird → джамп через LXC102):
ssh -i ~/.ssh/id_ed25519 root@100.70.186.192 # LXC102 assistant (NetBird)
sshpass -p '1qaz!QAZ' ssh root@192.168.1.247 # → хост pve
# pct exec <id> -- ... для любого контейнера
# NPM коробки (внутр. роутер): http://192.168.1.221:81 или http://100.70.90.103:81
# VPS-шлюз: ssh root@158.255.0.139 ; NPM http://158.255.0.139:81
# OmniRoute (internal): http://100.70.186.192:20128
# Web UI Proxmox: ssh -L 8006:192.168.1.247:8006 root@100.70.186.192
```
Креды (root-пароли, NPM-логины, токены) — [[credentials]].
## Ключевые факты / грабли
- **WAN Александра динамический** (`dhcp`, аренда 24ч) → DNS на него вешать нельзя. Поэтому публичный доступ только через статичный VPS-шлюз. DDNS не нужен.
- **Хост без NetBird** → управление джампом через LXC102. Стоящий TODO: поставить NetBird на сам хост.
- **NetBird на NPM коробки (LXC101) = `100.70.90.103`** — единственная точка, куда бьёт VPS; NPM коробки роутит по Host-заголовку на внутренние бэкенды.
- **ZimaOS (VM100) убран** — заменён Docker-апками (filebrowser+Homepage) на LXC105; виртуализация (VT-x) больше не нужна.
- Сторож Антошки (LXC137) ходит к коробке по NetBird → LXC102 (см. [[credentials]]).
- Бэкап старого netconfig хоста: `/root/interfaces.bak-alexmove` на pve.
## История изменений (2026-06-17)
1. Переезд хоста `10.0.0.147``192.168.1.247`; контейнеры на DHCP сами переехали на `192.168.1.x`.
2. ZimaOS (VM100) выведен из работы; подняты filebrowser+Homepage на новом LXC105.
3. Публичный доступ переведён с прямого проброса Cudy (откатан) на VPS-шлюз `158.255.0.139` по NetBird.
4. NetBird добавлен на NPM коробки (LXC101 = `100.70.90.103`).
5. `umnybot.ru` → SwarmClaw публично; остальное (omni/cloud/alex/git) — internal; 8 ZimaOS-доменов + `ai` удалены с VPS.
6. `pve.umnybot.ru` → Proxmox UI публично **за Basic Auth** (`oleg`, access-list `pve-basic-auth`) + LE-серт id18. Креды — в [[credentials]].
## ⚠️ Факт-чек состояния 2026-06-30 (расхождение с картой выше)
Замер с code-server через джамп `LXC137(openclaw) → LXC102(alex-asst) → pve`. **Коробка ушла далеко вперёд от карты — на ней активно появляются новые LXC** (вероятно German-агент автономно / Олег вручную):
**`pct list` (факт 2026-06-30):**
| LXC | Имя | RAM | Что внутри (факт) | Статус |
|---|---|---|---|---|
| 101 | npm | 512 | jc21 NPM | 🟢 |
| 102 | assistant | 4096 | openclaw (Алекс) active, omniroute active, assistant-postgres | 🟢 |
| 103 | swarmclaw | — | swarmclaw (Up 11 дней) | 🟢 |
| 104 | gitea | — | Gitea | 🟢 |
| **106** | **authentik** | 2048 | authentik server+worker+pg16 (Up 11 дней, healthy) — **SSO УЖЕ ЕСТЬ** | 🟢 |
| **107** | **telegram** | 1024 | `webtop-telegram` (Telegram в браузере, Up 10 дней) | 🟢 |
| **108** | **cosmos-test** | 2048 | **Cosmos Cloud** (Up 10д) + **qBittorrent** (8д) + **Home-Assistant** (2д) + mongo:8 | 🟢 |
| **109** | **german-alex** | 3072 | Hermes установлен (`/usr/local/lib/hermes-agent`), но **gateway НЕ запущен**; Docker нет | 🟡 заготовка |
| ~~105~~ | ~~alex-apps~~ | — | **исчез** (был Homepage+filebrowser) | ❌ нет в pct list |
| ~~VM100~~ | ~~Zima~~ | — | удалена ранее | ❌ |
**Железо (факт):** хост ОЗУ 15906 МБ, **available ~10.4 ГБ** (used 5.5 ГБ) — бюджет лучше ожидаемого. `/mnt/pve/Work` 1.8 ТБ, занято 21 ГБ (2%). LXC102 свободно ~3.2 ГБ из 4.
**Cosmos (LXC108 `/var/lib/cosmos/cosmos.config.json`):**
- Hostname `cosmos.umnybot.ru`, HTTPS **SELFSIGNED** (не LE), AutoUpdate on, NewInstall false.
- Маршруты (2): `qbittorrent.cosmos.umnybot.ru → qBittorrent:8080`, `home-assistant.cosmos.umnybot.ru → Home-Assistant:8123`. **Оба `auth=False`** (SmartShield on, но без SSO!) — дыра, при паблик-доступе закрыть.
**Выводы для концепции `benilux/umny-server-concept`:** часть шагов уже частично выполнена (Cosmos=движок, qBittorrent, authentik=SSO, Hermes-заготовка, Telegram-webtop). План пересобрать из «ставить» в «навести порядок + доделать + закрыть безопасность». **Не дублировать существующее.**
### Проверка безопасности exposure (2026-06-30)
Публичный DNS (`dig`): наружу резолвятся **только** `umnybot.ru`, `cosmos.umnybot.ru`, `pve.umnybot.ru` → 158.255.0.139 (VPS-шлюз). `qbittorrent/home-assistant.cosmos.umnybot.ru`**НЕ резолвятся** (внутренние, из интернета недоступны) → дыра `auth=False` пока не открыта в интернет.
VPS-шлюз (openresty) публикует:
- `umnybot.ru` → HTTP 200, Next.js (SwarmClaw).
- `cosmos.umnybot.ru` → 307 → `/cosmos-ui/`**админка Cosmos торчит в паблик**. НО вход защищён: `/cosmos/api/servapps` = 401, `/cosmos/api/status` = «User not logged in», `newInstall` = 403 (setup закрыт). Не голая, но **рекомендуется убрать с паблика** (оставить по NetBird/за SSO).
- `pve.umnybot.ru` → Proxmox за Basic Auth (как и было).
**Хвосты безопасности (не пожар, в работу):** (1) убрать Cosmos-админку с публичного VPS; (2) перед любым публичным сервисом включить SSO (authentik уже стоит) вместо `auth=False`; (3) сменить общий `1qaz!QAZ` + 2FA на Proxmox.
### Hermes (LXC109) + GLM 5.2 — факты 2026-06-30
**109 «german-alex»:** Hermes/tirith **0.3.3** установлен (git-метод, бинарь `~/.hermes/bin/tirith` рабочий, есть `uv`), node v22, IP 192.168.1.46. Конфиг `~/.hermes/config.yaml` — копия шаблона German: `model.default: cc/claude-opus-4-8` через OmniRoute `http://192.168.1.154:20128/v1` (LXC102). **Gateway НЕ настроен и не запущен:** нет Telegram-токена, нет gateway-секции, нет allowlist, нет `.env`, нет systemd-юнита. Просто брошенная заготовка.
**GLM 5.2 — РАБОТАЕТ (проверено live 2026-06-30):**
- На **code-server OmniRoute (132)** провайдер `glm` подключён, в каталоге `glm/glm-5.2`, `glm-5.2-high`, `glm-5.2-max`. Live-тест `glm/glm-5.2` → ответ стримом OK (баланс жив). Старые 502/STREAM_EARLY_EOF от 21.06 были временные.
- На **коробке OmniRoute (LXC102, 96 моделей)** GLM 5.2 **НЕТ** — только `kr/glm-5`/`kiro/glm-5` (через Kiro-пул). Чтобы бот Александра думал на GLM 5.2: либо подключить провайдер `glm` в OmniRoute коробки (как на 132), либо ходить через OmniRoute 132 по NetBird.
**Решения (Олег 2026-06-30):** второй бот = новый через BotFather (токен ждём); модель = GLM 5.2.
### Безопасность: что блокировано доступом (2026-06-30)
Попытка закрыть хвосты с code-server упёрлась в отсутствие доступа:
- **VPS-шлюз (158.255.0.139 / NetBird 100.70.127.23)** — мой ключ не добавлен ни с code-server, ни с openclaw(137), ни через NetBird. Публичный :22 таймаутит (exit-node блок). → **убрать админку Cosmos с паблика без ключа к VPS нельзя.**
- **Cosmos-админ** — вход за логином (хорошо), mongo (COSMOS db) требует auth (хорошо). Включить auth на маршруты qbit/HA правильнее через UI/API Cosmos, но нужен **админ-логин Cosmos** (у Олега). Править cosmos.config.json руками — рискованно (Cosmos перезапишет), не делал.
- Cosmos-server (LXC108): `8088→80`, `8444→443`; mongo `cosmos-mongo-eN2`.
**Нужно от Олега для разблокировки безопасности:** (1) добавить ключ code-server на VPS-шлюз ИЛИ убрать `cosmos.umnybot.ru` с VPS самому; (2) дать админ-доступ к Cosmos UI (логин/пароль) для включения SSO на маршрутах.
**Второй бот «Мажордом» (имя выбрано 2026-06-30):** ждём токен из BotFather (личный «Герман» Олега не трогаем — отдельный бот). Бот на 109, модель GLM 5.2.
### Бот Мажордом + KB-изоляция — статус 2026-06-30 (продолжение)
**Мажордом (2-й бот):** токен получен — `@majordom_umny_bot` («Умный дом»), id 8844094095, getMe OK. На LXC109 — настоящий **Hermes Agent** (NousResearch, git e448b21), запуск `uv run hermes` (venv создан, 60 пакетов). `tirith` в ~/.hermes/bin — вспомогательная security-утилита Hermes, НЕ агент. Конфиг: токен → `~/.hermes/.env` `TELEGRAM_BOT_TOKEN`, allowlist → `TELEGRAM_ALLOWED_USERS` (CSV user-id; Олег=1292155421, нужен id Александра), модель → config.yaml `model.default`+`.env OPENAI_BASE_URL/KEY`.
**GLM 5.2 — решение: автономно через Zhipu-ключ (выбор Олега).** Ждём ключ z.ai/Zhipu (регион international, как на 132). План: подключить провайдер `glm` в OmniRoute коробки (102) → модель `glm/glm-5.2` локально. 109 НЕ в NetBird (132 недостижим) — поэтому через локальный OmniRoute 102. На 132 GLM-ключ зашифрован (enc:v1), перенести из БД нельзя.
**Бот Алекс (102):** active, OpenClaw 2026.5.27, модель `omniroute/cx/gpt-5.5`, 8 инструментов (/opt/assistant/alex-*.sh). **Память ПУСТАЯ** (~/.openclaw/memory/main.sqlite: 0 files). Нет kb-pull, нет общего vault, нет cron-синка → **уже полностью изолирован от инфры Олега**. Требование «KB только Бенелюкс» по факту выполнено (нет утечки); осталось НАПОЛНИТЬ KB про дом Александра.
**Gitea коробки (104):** уже есть репо `benelux/knowledge-base.git` (пустой, заготовка) + `/opt/kb-autocommit`. Основа для изолированной KB заложена.
**Ждём от Олега:** (1) Zhipu/z.ai GLM-ключ → запуск Мажордома на GLM 5.2; (2) Telegram user-id Александра → allowlist; (3) доступ к VPS/Cosmos-админу → безопасность.