mirror of
https://github.com/maeneko/forgetting.git
synced 2026-08-25 15:24:26 +00:00
Add README documentation for Forgetting VPN project
Added detailed documentation for the Forgetting VPN project, including architecture, requirements, installation, management, and API usage.
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user