diff --git a/README.md b/README.md new file mode 100644 index 0000000..dd91fdf --- /dev/null +++ b/README.md @@ -0,0 +1,144 @@ +# Forgetting +Панель управления и API для VPN на базе [AmneziaWG](https://github.com/amnezia-vpn/amneziawg-linux-kernel-module) +> [!WARNING] +> Данный проект предназначен только для использования в законных целях. +## Архитектура + +Три компонента, устанавливаются в `/opt/awg-control/`: + +| Компонент | Роль | +|---|---| +| **awg-ctrl** | Привилегированный REST-бэкенд. Управляет пирами через `awg`/`awg-quick`, ведёт SQLite-базу, генерирует `vpn://` ключи. Слушает только loopback. | +| **awg-ui** | Express + React. Веб-панель, аутентификация (JWT), внешний API (`/api/v1`), прокси к awg-ctrl. Единственный сервис, доступный по сети. | +| **cli** | Менеджер процессов: `start`/`stop`/`restart`/`status`, смена логина/пароля панели, интерактивное TUI-меню. | + +Внутренняя связь awg-ui → awg-ctrl подписывается асимметрично (Ed25519): приватный ключ только у awg-ui, awg-ctrl проверяет подпись публичным. + +## Требования +- **ОС**: Ubuntu 24.04+ (Тесты проходили на Ubuntu 24.04.4 LTS) +- **Права**: root. +- **Ядро**: kvm (не OpenVZ/LXC/Docker/WSL — нужен загружаемый kernel-модуль AmneziaWG). +- **Заголовки ядра** под текущее ядро (для сборки DKMS-модуля). +- **Node.js 20.x** (ставится установщиком автоматически). + +Совместимость установщик проверяет сам перед любыми изменениями. + +## Установка + +На сервере, от root: + +```bash +sudo bash <(curl -Ls https://amnesia.ma7neko.ru/forgeting/install.sh) +``` +## Управление + +```bash +awg-ctrl +``` + +Через systemd (автозапуск на загрузке): + +```bash +systemctl start|stop|restart awg-control +``` + +## 1. Публичный API (`/api/v1`) + +Авторизация по API-ключу. Ответы содержат только публичные поля — приватные +ключи и PSK наружу не отдаются. + +### Авторизация + +Каждый запрос обязан содержать заголовок: + +``` +X-Api-Key: awgk_<...> +``` + +Ключ создаётся в панели (вкладка «API-ключи») или через `POST /ui/apikeys` +(раздел 3). Открытое значение ключа показывается **один раз** при создании — +сохрани его сразу, дальше доступен только хэш. + +Ответы при проблемах с ключом: + +| Код | Когда | +|---|---| +| `401 {"error":"API key required"}` | заголовок отсутствует или не начинается с `awgk_` | +| `401 {"error":"Invalid API key"}` | ключ не найден (удалён/неверный) | + +> Ключ привязан к серверу (`server_id`). Сейчас сервер один — поле всегда `0` + +### `POST /api/v1/users` — создать пользователя + +Создаёт VPN-пира и возвращает готовый `vpn://` ключ. + +**Тело:** `{ "name": "<имя>" }` +Имя: `a–z A–Z 0–9 _ -`, 1–32 символа. + +**`201 Created`:** +```json +{ + "name": "alice", + "ip": "10.9.0.2", + "vpn_key": "vpn://AAAI..." +} +``` +| Код ошибки | Причина | +|---|---| +| `400` | имя не прошло валидацию | +| `409` | пользователь с таким именем уже есть | +```bash +curl -X POST http://HOST:PORT/api/v1/users \ + -H "X-Api-Key: awgk_xxx" \ + -H "Content-Type: application/json" \ + -d '{"name":"alice"}' +``` +### `GET /api/v1/users` — список пользователей +Пиры с трафиком и статусом онлайн. +**`200 OK`:** +```json +{ + "users": [ + { "name": "alice", "ip": "10.9.0.2", "online": true, "lastHandshake": 1718800000, "rx": 142400000, "tx": 9800000 }, + { "name": "bob", "ip": "10.9.0.3", "online": false, "lastHandshake": 0, "rx": 0, "tx": 0 } + ] +} +``` +- `lastHandshake` — unix-секунды последнего рукопожатия (`0` — не было). +- `rx`/`tx` — байты принято/отдано. + +```bash +curl http://HOST:PORT/api/v1/users -H "X-Api-Key: awgk_xxx" +``` + +### `GET /api/v1/users/:name` — получить ключ пользователя + +**`200 OK`:** +```json +{ "name": "alice", "ip": "10.9.0.2", "vpn_key": "vpn://AAAI..." } +``` + +| Код ошибки | Причина | +|---|---| +| `404` | пользователь не найден | + +```bash +curl http://HOST:PORT/api/v1/users/alice -H "X-Api-Key: awgk_xxx" +``` + +> Имея `vpn_key`, конфиг `.conf` можно получить локально: убрать префикс +> `vpn://`, base64url-декодировать, отбросить первые 4 байта (длина), распаковать +> `zlib inflate` → JSON; текст конфига лежит в `last_config.config`. + +### `DELETE /api/v1/users/:name` — удалить пользователя + +**`200 OK`:** +```json +{ "success": true, "name": "alice" } +``` + +```bash +curl -X DELETE http://HOST:PORT/api/v1/users/alice -H "X-Api-Key: awgk_xxx" +``` +## Лицензия +[MIT](LICENSE) © 2026 Ivan Vasilev