- allowlist read-tools + exec-policy allowlist/on-miss: чтение свободно, write блокируется - 2 вопроса (Telegram-кнопка approval не проверена; allowlist лишает гибкости) -> yolo - механизм и allowlist-записи задокументированы для финализации в Этап 9 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
146 lines
15 KiB
Markdown
146 lines
15 KiB
Markdown
---
|
||
date: 2026-05-31
|
||
type: project
|
||
tags: [ai-assistant, alexandr, umnybot, credentials, secrets, openclaw, omniroute]
|
||
status: active
|
||
---
|
||
|
||
# 🔐 AI-ассистент «umnybot» — инфра и креды (пилот Александра)
|
||
|
||
> ⚠️ **КОНФИДЕНЦИАЛЬНО.** Продукт «консьерж в коробке». См. [[PROMPT]] (тех-задание) и память `project_alexandr_assistant`.
|
||
> Все секреты также лежат на коробке в `/opt/assistant/.env` (chmod 600).
|
||
|
||
## Коробка (хост + контейнер)
|
||
|
||
| Параметр | Значение |
|
||
|---|---|
|
||
| Хост | Proxmox `pve` (pve-147), **10.0.0.147**, root / `1qaz!QAZ` |
|
||
| Контейнер | **LXC 102 «assistant»**, Debian 12, IP **10.0.0.163** |
|
||
| root LXC 102 | `j5DS1JSPKewKQw6i7mTK` (уникальный; Mac-ключ `ai@mac-20260112` в authorized_keys) |
|
||
| Стек | Docker (overlayfs) + Node 22; openclaw 2026.5.27; OmniRoute 3.8.7; Postgres16/pgvector |
|
||
| Доступ | `sshpass -p '1qaz!QAZ' ssh root@10.0.0.147` → `pct exec 102 -- bash` (или `ssh root@10.0.0.163` по Mac-ключу) |
|
||
|
||
## OmniRoute (LLM-роутер)
|
||
|
||
| Параметр | Значение |
|
||
|---|---|
|
||
| Сервис | systemd `omniroute.service`, слушает **0.0.0.0:20128** |
|
||
| Дашборд | **https://omni.umnybot.ru** (через NPM, LE) или `http://10.0.0.163:20128` |
|
||
| Пароль дашборда | **`A30Y7aan8dCKf9`** (Settings → Security можно сменить) |
|
||
| API-ключ (для openclaw) | **`ork_VQo75huaEVGzhdfD4QlrL2XaxTmNKPTD`** |
|
||
| Конфиг/секреты | `/root/.omniroute/.env` (STORAGE_ENCRYPTION_KEY + СВЕЖИЕ JWT_SECRET/API_KEY_SECRET — перегенерены перед выходом наружу), `storage.sqlite` |
|
||
| Старт сервера | `node /usr/lib/node_modules/omniroute/app/server.js` (PORT=20128, HOSTNAME=0.0.0.0) |
|
||
| Провайдеры | **Kiro** подключён (GitHub device-flow, аккаунт `kiro1@umnybot.ru`) — но **новый аккаунт троттлит (429 AWS CodeWhisperer)**. Олег добавляет 2-й провайдер через дашборд-GUI |
|
||
| Сброс пароля | `omniroute-reset-password` (интерактивный, нужен `expect` для pipe) |
|
||
|
||
## openclaw (мозг + каналы)
|
||
|
||
| Параметр | Значение |
|
||
|---|---|
|
||
| Версия | 2026.5.27 (глоб. npm), конфиг `/root/.openclaw/openclaw.json` |
|
||
| Gateway | systemd **`openclaw-gateway.service`** (`openclaw gateway run`), loopback 127.0.0.1:18789 |
|
||
| Канал | Telegram `@alex_umny_bot` (connected, polling) |
|
||
| Дефолт-модель | пока `openai/gpt-5.5` (без провайдера) → переключить на `omniroute/<provider>/<model>` |
|
||
| Провайдер omniroute | `openclaw models auth paste-api-key` (baseUrl `http://127.0.0.1:20128/v1`, key `ork_VQo…`) |
|
||
|
||
## Telegram
|
||
|
||
| Параметр | Значение |
|
||
|---|---|
|
||
| Бот | **@alex_umny_bot** «Консьерж Бот», id 8601326674 |
|
||
| Токен | `8601326674:AAEJwbyXGEgEEiIwmfZVdYbG2SxpyMkmDiA` |
|
||
| Audit chat_id | **1292155421** (Олег, @it5870) |
|
||
|
||
## Postgres + pgvector
|
||
|
||
`127.0.0.1:5432` (Docker `assistant-postgres`, pgvector/pgvector:pg16) — user `assistant` / `c2e193fb341120471917f720a1c6eeea` / db `assistant`. Compose: `/opt/assistant/docker-compose.yml`.
|
||
|
||
## Домен umnybot.ru (Spaceweb)
|
||
|
||
| Параметр | Значение |
|
||
|---|---|
|
||
| Регистратор/DNS | **Spaceweb**, панель `vps.sweb.ru`, логин `it5870yand` / `1qaz!QAZ` |
|
||
| API | `POST https://api.sweb.ru/domains/dns` (методы `editMain`/`editMx`/`editTxt`, `action:add`) |
|
||
| ⚠️ Проверка DNS | **только через DoH** (`curl https://1.1.1.1/dns-query?name=...&type=...`) — `dig` из dttb-сети режется домашним :53-перехватом (ложно-пусто). `action:add` РАБОТАЕТ |
|
||
| Записи | `omni` A→**176.62.183.186**; `@` MX→`mail.dttb.ru` (10); `@` TXT SPF `v=spf1 ip4:176.62.183.186 ~all`; `dkim._domainkey` (2048); `_dmarc` |
|
||
| Поддомены план | `omni.` = дашборд OmniRoute; `alex.` = веб ассистента Александра; `<client>.` на будущих |
|
||
|
||
## Почта (на Mailcow dttb, VM 107)
|
||
|
||
| Параметр | Значение |
|
||
|---|---|
|
||
| Ящик ассистента | **`assistant@umnybot.ru`** / **`KQcZnxkB5sMNiVYo`** |
|
||
| Catch-all | `@umnybot.ru` → `assistant@umnybot.ru` (любой адрес, удобно под регистрацию аккаунтов) |
|
||
| Вебмейл | **https://mail.dttb.ru** (SOGo) |
|
||
| IMAP/SMTP | `mail.dttb.ru:993` / `mail.dttb.ru:587` |
|
||
| Mailcow | 10.0.0.107, admin `admin`/`1qaz!QAZ`, API `dttb-mailcow-api-2026` (с 10.0.0.0/24) |
|
||
| rspamd whitelist | `github.com`, `sgmail.github.com`, `sendgrid.net` для umnybot.ru (новый домен резался, для приёма GitHub-кодов) |
|
||
|
||
## Codex/OpenAI ящики (мульти-аккаунт, 2026-05-31)
|
||
|
||
8 ящиков на umnybot.ru, **общий пароль `1BU5zqB9NxC84h`**: `codex1@umnybot.ru` … `codex8@umnybot.ru` (quota 512MB, real-боксы, не catch-all). Вебмейл https://mail.dttb.ru (логин любым `codexN@umnybot.ru` / пароль). Коды можно тянуть по IMAP `mail.dttb.ru:993`. ⚠️ OpenAI требует телефон при регистрации — реальный потолок числа аккаунтов.
|
||
|
||
## Аккаунты провайдеров
|
||
|
||
| Сервис | Логин | Заметка |
|
||
|---|---|---|
|
||
| GitHub (для Kiro) | `kiro1@umnybot.ru` | пароль задал Олег — **здесь не записан, спросить у Олега**. Зарегистрирован через catch-all (код пришёл в assistant@) |
|
||
| Kiro (AWS) | через GitHub-логин выше | device-flow, профиль `arn:aws:codewhisperer:us-east-1:...`. Новый аккаунт троттлит |
|
||
|
||
## NetBird (доступ коробки к сети Александра)
|
||
|
||
| Параметр | Значение |
|
||
|---|---|
|
||
| **Setup-key (Benelux)** | `26C84D9A-B71B-474D-BC41-8FAC2C4C6399` (reusable, до 2027-05-31) |
|
||
| Группа | **Benelux** `d8e5s1jl0ubs73f3g7vg` (туда добавлен Cudy «OpenWrt Benilux»), политика «Benelux Access» |
|
||
| Коробка в NetBird | `alex-assistant` = **100.70.186.192** (userspace-режим, без TUN — работает; TUN прописан в `/etc/pve/lxc/102.conf`, активируется при `pct reboot 102`) |
|
||
| Цель | достать Cudy Александра **100.70.207.97** (ping ✅ ~62мс) → jump на Mac (`aleksandrgrigorev`/`gav1971@`)/устройства |
|
||
| Управление NetBird | `api.netbird.io`, токен `nbp_…` в `projects/dttb/credentials.md` |
|
||
| ⚠️ Безопасность | Default-политика NetBird = `All↔All` → коробка достаёт и др. сети Олега. **Для продукта — Александра в ОТДЕЛЬНЫЙ NetBird** (изоляция + автономность). |
|
||
|
||
## Инструменты Алекса — управление устройствами Александра (2026-05-31)
|
||
|
||
Алекс ходит в сеть Александра: коробка → NetBird → Cudy (`100.70.207.97`) → LAN. Прямой роут в `192.168.1.0/24` нельзя (коллизия с Знаменское/НИИКН в NetBird) → всё джампом через Cudy. Обёрнуто в скрипты на коробке (`/opt/assistant/`), Алекс зовёт их через exec (`exec-policy` = yolo). Проверено в живом диалоге (TG): «какие точки wifi по комнатам» → Алекс сам зовёт `alex-unifi.sh`.
|
||
|
||
**Подтверждение write-действий (Этап 4):** гейт = ЖЕЛЕЗНОЕ ПРАВИЛО в `SOUL.md` (двухшаговый протокол: на «перезапусти» Алекс сначала описывает+спрашивает «да?», выполняет только после ОТДЕЛЬНОГО «да»). Проверено: первый прогон без правила — выполнил молча; после усиления SOUL — спрашивает. Бэкстоп = авто-аудит каждого write-действия Олегу. **Настоящий хард-гейт для продукта** = allowlist + `exec-policy set --security allowlist --ask on-miss --ask-fallback deny`. Механизм: `openclaw approvals allowlist add "/opt/assistant/alex-router.sh*"` (glob; хранится в `exec-approvals.json` → `agents."*".allowlist[].pattern`). **Протестировано 2026-05-31:** чтение под allowlist работает свободно ✅, write (`alex-fix.sh`, не в allowlist) реально БЛОКИРУЕТСЯ (podkop не перезапустился) ✅. ДВА открытых вопроса → **откатил на yolo:** (1) не проверено, рисует ли Telegram интерактивную кнопку approval (в CLI headless — пусто/deny; **если кнопки нет → write вообще невыполним**, хуже мягкого гейта); (2) `security=allowlist` лишает агента гибкости (только 5 helper'ов, не импровизирует диагностику новых проблем). **Финализация:** живой тест в TG (Олег пишет боту «перезапусти» → есть ли кнопка?). Если да — вернуть allowlist (read-tools + alex-print), alex-fix НЕ в allowlist. allowlist-записи уже лежат в `exec-approvals.json` (неактивны при yolo). Отложено в Этап 9.
|
||
|
||
| Скрипт | Что делает |
|
||
|---|---|
|
||
| `alex-router.sh [status\|devices\|printer\|dns]` | Cudy: статус обхода (`awg show awg0`), DHCP-аренды, пинг принтера, FakeIP-DNS. read-only |
|
||
| `alex-unifi.sh [list\|check <ip>]` | UniFi: точки/свитчи по комнатам + онлайн-проверка пингом. read-only |
|
||
| `alex-print.sh` (текст на stdin) | Печать на HP M775, кириллица через `paps`→CUPS |
|
||
| `alex-fix.sh [restart-podkop\|reboot-ap <ip>\|test]` | **write-действия** (перезапуск обхода / перезагрузка Wi-Fi точки). Авто-аудит Олегу в TG на каждое. reboot-ap через device-SSH `ktf8b@<ip>` пароль `TlbbdJoVADiXGDrcpnNq3q` |
|
||
| `alex-security.sh` | аудит безопасности сети (см. ниже «Защита сети») |
|
||
|
||
### UniFi (Cloud Key Gen2+ `192.168.1.199`)
|
||
- Доступ: **SSH через Cudy** — `DROPBEAR_PASSWORD='1qaz!QAZ!QAZ' dbclient -y root@192.168.1.199` (sshpass на Cudy нет; dropbear `dbclient` берёт пароль из env).
|
||
- ⚠️ Локальный UniFi-API **залочен SSO** (`/api/auth/login` = 403). Данные тянем из **MongoDB контроллера**: `mongo --quiet --port 27117 ace --eval "db.device.find({},{name:1,ip:1,model:1,_id:0}).forEach(printjson)"`. Поле `state` пустое → онлайн проверяем пингом точки с Cudy.
|
||
- 13×UAP6MP по комнатам + 7 свитчей, см. [[benelux-topology]].
|
||
|
||
### Принтер (HP LaserJet M775 `192.168.1.148`)
|
||
- 9100/515 закрыты, открыт только **IPP/631** (+AirPrint).
|
||
- Печать: **CUPS на коробке** (`apt: cups cups-client cups-filters paps`), очередь `alex` = `ipp://100.70.207.97:6310/ipp/print` (IPP Everywhere, `lpadmin -m everywhere`).
|
||
- Коробка достаёт принтер через **DNAT на Cudy**: `100.70.207.97:6310` (NetBird) → `192.168.1.148:631`. Персистентно: `/etc/nftables.d/30-alex-printer.nft` (dstnat + masquerade только для `saddr 100.70.186.192`; `fw4 check` ОК, `fw4 reload` применён).
|
||
- Кириллица: `paps --font='DejaVu Sans Mono 11'` → PostScript → CUPS. Хелпер `/opt/assistant/alex-print.sh`. Тест-лист напечатан (job completed).
|
||
|
||
## Защита сети — Алекс-сторож (2026-05-31)
|
||
|
||
Алекс защищает сеть Александра от повторения инцидента [[../../decisions/2026-05-20-benelux-compromise]] (WAN-SSH брут → спам-релей). Детект + алерт (превенция уже стоит: nft `incident-20260520` + key-only).
|
||
|
||
- **Аудит:** `/opt/assistant/alex-security.sh` (на коробке) → `/root/.alex-seccheck.sh` (на Cudy, read-only). Чек-лист под вектор инцидента: WAN-SSH закрыт (правило `incident-20260520-no-ssh-from-wan`), нет `Allow-SSH-WAN`, `PasswordAuth=off`, чужие SSH-сессии (не `100.70.`/`192.168.1.`), исходящий SMTP 25/465/587, посторонний cron, скрытые **executable** в /tmp, левые SSH-ключи (белый список: `mac-20260112` / `claude-code@code-server` / `alex-assistant`), LA≥3.
|
||
- **Сторож:** `/opt/assistant/alex-secwatch.sh` + cron коробки `*/15` → при FLAG алерт Олегу в TG (`TELEGRAM_AUDIT_CHAT_ID=1292155421` из `.env`), дедуп по md5 набора угроз, «отбой» когда чисто. Канал проверен (`tg=200`, «🛡️ Алекс-сторож на посту»).
|
||
- **Авто-лечение:** если флаг = открытый WAN-SSH, сторож САМ возвращает nft-блок (`nft insert ... input iifname eth0 dport 22 drop`) до алерта + помечает «закрыл автоматически». Проверено боевым тестом (удалил handle из `incident_block_in` → сторож восстановил → `count=1`). Расширять авто-heal на cron/ключи НЕ стоит (риск ложного авто-удаления) — там только алерт.
|
||
- ⚠️ **ssh в скриптах — с `-n`** (или запуск из cron/файла, не pipe): `ssh` без `-n` в скрипте, поданном в `bash` через pipe, съедает остаток скрипта со stdin.
|
||
- On-demand в TG: «нас не ломают?» → Алекс сам зовёт проверку, объясняет спокойно. Проверено.
|
||
- Статус: всё чисто, ~150 WAN-SSH брутов отбито (nft counter растёт — защита держит вектор).
|
||
|
||
## NPM (reverse proxy)
|
||
|
||
| Параметр | Значение |
|
||
|---|---|
|
||
| Текущий | основной NPM **10.0.0.195** (it5870@yandex.ru/`1qaz!QAZ`): proxyhost **id30** `omni.umnybot.ru`→`10.0.0.163:20128`, cert **id115** (LE до 2026-08-29), websocket-upgrade вкл |
|
||
| План | перенести на **NPM коробки** (LXC 101 pve-147, 10.0.0.207) для автономности; ограничение — публичный 443 один на дом, при передаче коробки к клиенту его роутер сразу на NPM коробки |
|
||
|
||
## Статус (2026-05-31)
|
||
Этап 1 почти закрыт. Тракт TG→openclaw→OmniRoute→Kiro-роутинг проверен (429 = достучались). Блокер: рабочая модель (новый Kiro троттлит → Олег подключает 2-й провайдер). Дальше: openclaw model=omniroute/* + fallback → тест «привет» в TG.
|