54 lines
6.2 KiB
Markdown
54 lines
6.2 KiB
Markdown
---
|
||
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` (вся клиентская база).
|