--- date: 2026-06-23 type: decision tags: [dttb, vpn, amnezia, awg, netbird, control-plane] --- # Amnezia Web Panel — control-plane VPN-нод на home lab (LXC 143) ## Контекст Олег арендует HOSTKEY Finland (`151.241.234.241`, Ubuntu 22.04, 2 vCPU/3.9 GB) как **основной VPN-хаб для всех проектов**, старый финский VPS — горячий резерв. Управлять нодами решено через [Amnezia-Web-Panel](https://github.com/PRVTPRO/Amnezia-Web-Panel) (FastAPI/Python, paramiko-SSH; рулит AmneziaWG/WG/Xray-Reality/MTProxy на удалённых Ubuntu). ## Решение: панель — ДОМА, не на VPS Панель = control-plane с SSH-ключами **ко всем** нодам сразу. Держим её на home lab (LXC 143), VPS оставляем чистым data-plane. **Почему не на VPS:** 1. **Безопасность.** Финский VPS уже ломали через **RCE в amnezia-panel** (XorDDoS, чистили 2026-04-24). Панель на публичной коробке = ключи ко всему контуру под ударом. 2. Никакого публичного `:5000` + дефолт `admin/admin` + открытый Swagger `/docs`. 3. Переживает пересборку VPS — `data.json` (вся клиентская база) живёт дома. 4. Один пульт на все ноды (Finland + Paris/Singapore + будущие). ## Что развёрнуто (LXC 143, 10.0.0.143) - Debian 12, unprivileged + nesting/keyctl, rootfs на `work` (local-lvm забит на 94%), ns 1.1.1.1. - Docker 29.6 + compose, контейнер `prvtpro/amnezia-panel:1.4.4`, `-p 5000:5000`, restart=unless-stopped, onboot=1. - NetBird `100.70.9.163` / `amnezia-panel.netbird.cloud` (группа Claude-Diag, ключ `1558712D-…`, `--disable-dns`). - Доступ: LAN `10.0.0.143:5000` + NetBird `100.70.9.163:5000`. **Без NPM, без проброса портов — не публично.** - Логин `admin` / `AmnPanel!2026-fi` (дефолт сменён; проверено: old→401, new→200). ## Грабли - **Персистентность (важно).** Upstream `docker-compose.yml` монтирует `amnezia_data:/app/data`, но приложение пишет в **`/app/data.json`** и **`/app/tunnels_state.json`** (в WORKDIR `/app`). Т.е. дефолтный volume — пустышка, при пересоздании контейнера терялась бы вся база. Починено **bind-mount'ом конкретных файлов** в `/opt/amnezia-panel/`. - Базовый Debian-шаблон без `curl` — ставить перед get.docker.com. - Хеш пароля: `pbkdf2_hmac('sha256', pwd, salt_hex16, 100000)` → формат `salt$hex`. Смена пароля скриптом — воспроизвести этот алгоритм (`/opt/amnezia-panel/setpw.py`). ## Финский VPS заведён в панель (2026-06-23) Олег сам поднял сервер через **официальное приложение AmneziaVPN** (он = владелец/первый админ), затем сервер добавлен в панель — она **адаптировала существующую установку**: - Протокол **AmneziaWG 2.0** → контейнер `amnezia-awg2`, UDP **41624**, subnet `10.8.1.0/24`. - `/api/servers/0/check` → `awg2 running`, `clients_count: 1`. - Клиент Олега `Admin [macOS Tahoe (26.5.1)]` виден в панели (читается из `/opt/amnezia/awg/clientsTable`). - **Вывод подтверждён в коде + вживую:** `get_clients()` читает `clientsTable` с сервера и доп. парсит `[Peer]` («pick up peers created via native Amnezia app»). Панель = центральное управление поверх app-установки, не конфликтует. - ⚠️ root-пароль VPS хранится в `data.json` панели в открытом виде (так устроен SSH-доступ панели). При смене пароля VPS — обновить в карточке сервера (Servers → edit). ## Хардинг VPS сделан (2026-06-23) - **SSH key-only:** ed25519 `~/.ssh/awg_fi_key` (Mac, алиас `ssh awg-fi`), pubkey в `/root/.ssh/authorized_keys`. Пароль по SSH отключён (`PasswordAuthentication no` в `00-hardening.conf` — перебивает cloud-init `50-cloud-init.conf`, читается первым). `PermitRootLogin prohibit-password`. Бэкап `/root/sshd_config.bak.*`. - **Панель переведена на тот же ключ** (`/api/servers/0/edit` с `private_key`, пароль очищен; edit проверяет SSH до сохранения — не залочит). Проверено: `check 200` по ключу. - **ufw:** наружу только `22/tcp` + `41624/udp`. (Docker публикует 41624 в обход ufw — это ок, порт нужен открытым; ufw защищает хостовые службы.) - **fail2ban:** jail `sshd`, `backend=systemd` (на минимальной Ubuntu нет `/var/log/auth.log` → дефолтный backend падал). - Грабля cloud-init: `/etc/ssh/sshd_config.d/50-cloud-init.conf` держал `PasswordAuthentication yes` — перебито `00-hardening.conf` + закомментировано sed'ом. - Пароль `v_6hH9JuH_` остаётся валиден только для **веб-консоли HOSTKEY** (recovery). ## Дальше (TODO) - [ ] Резервный финский VPS: **переустановить ОС начисто** перед использованием, подцепить к панели. - [ ] Решить failover (AWG сам не переключается): второй endpoint в конфигах клиентов либо переключение через панель/DNS. - [ ] Проверить лимит трафика HOSTKEY (3 TB/мес) — под «все проекты» может быть тесно. - [ ] Бэкап `/opt/amnezia-panel/data.json` (вся клиентская база).