Files
kaskad/docs/webui.md
Андрей Бобырев a2182d0b91 fix(webui): cookie session login/logout (replace Basic Auth)
Browsers cannot clear HTTP Basic credentials; logout never worked reliably.
Use Flask signed session + /login form + GET /logout + POST /api/logout.
Optional KASKAD_SECRET_KEY or auto /etc/kaskad/.session_secret.
Fetch API uses credentials: same-origin; 401 redirects to /login.

Docs + README updated.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 20:04:03 +03:00

84 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Web UI
Flask-приложение, бежит рядом с TG-ботом (на одном из ам. серверов). Использует **те же** скрипты и тот же `ru-servers.json`, что и бот.
## Возможности
- **Дашборд** — состояние туннелей всех ам. серверов: куда подключены, возраст handshake
- **Force-переключение** на любой RU-сервер одной кнопкой
- **CRUD RU-серверов** — добавление/удаление с веб-формы (бот сам пробрасывает SSH ключи и поднимает WG)
- **CRUD ам. серверов** — то же
- **CRUD доменов** — добавить/удалить с автоматическим резолвом
- **CRUD IP/CIDR** — добавить/удалить любые подсети
- **Просмотр базовых подсетей** — read-only
- **Фильтры по доменам и IP** — для удобства поиска
## API
Все endpoint'ы под `/api/` требуют **куки-сессии** (страница входа `/login`), не HTTP Basic — иначе в браузере нельзя сделать надёжный «выход».
Из скрипта / curl — сначала POST на `/login` (как форма), потом запросы с сохранённой кукой:
```bash
curl -c jar.txt -b jar.txt -X POST 'http://127.0.0.1:8088/login' \
-d 'username=admin&password=ВАШ_ПАРОЛЬ&next=/'
curl -b jar.txt 'http://127.0.0.1:8088/api/state' | jq .
```
| Метод | Путь | Тело | Описание |
|---|---|---|---|
| GET | `/api/state` | — | Полное состояние JSON |
| POST | `/api/use` | `{"id":"primary"}` | Force-переключить все ам. на этот RU |
| POST | `/api/server` | `{host,id,user,ssh_port,priority,...}` | Добавить новый RU |
| DELETE | `/api/server/<id>` | — | Удалить RU |
| POST | `/api/ams` | `{host,id,user,ssh_port,xray_iface,...}` | Добавить новый ам. |
| DELETE | `/api/ams/<id>` | — | Удалить ам. |
| POST | `/api/domains` | `{"domains":["vk.com",...]}` | Добавить домены |
| DELETE | `/api/domains` | `{"domains":[...]}` | Удалить домены |
| POST | `/api/domains/refresh` | — | Перерезолвить |
| POST | `/api/ips` | `{"ips":["1.2.3.4/32",...]}` или `{"ips":"text with IPs"}` | Добавить |
| DELETE | `/api/ips` | то же | Удалить |
| POST | `/api/ips/clear` | — | Очистить все доп. IP |
## Безопасность
- Вход — форма `/login` + подписанная **cookie-сессия** (ключ `KASKAD_SECRET_KEY` или файл `/etc/kaskad/.session_secret`). Пароль админа — `KASKAD_WEB_PASS`, должен быть длинным и случайным.
- По умолчанию слушает на `0.0.0.0:8088`. **Рекомендуется** поставить за HTTPS reverse-proxy (nginx/caddy) с Let's Encrypt
- Если хочется привязать только к localhost — `KASKAD_HOST=127.0.0.1` и пользоваться через SSH-туннель: `ssh -L 8088:localhost:8088 root@ams1`
- Пароли SSH (`password=` при `/server-add`, `/ams-add`) передаются по HTTPS только если веб за reverse-proxy. Без HTTPS не передавай пароли через WebUI — используй ключи (см. `/bot-key`)
## Конфиг (env-переменные)
| Переменная | Дефолт | Описание |
|---|---|---|
| `KASKAD_WEB_USER` | `admin` | Логин для входа в WebUI |
| `KASKAD_WEB_PASS` | (нет) | Пароль; ОБЯЗАТЕЛЬНО задать |
| `KASKAD_SECRET_KEY` | (файл) | Секрет подписи сессии; иначе создаётся `/etc/kaskad/.session_secret` |
| `LOCAL_HOST` | `ams1` | Имя локального ам. сервера |
| `LOCAL_IP` | `127.0.0.1` | Локальный IP — определяет, какой ам. читать локально без SSH |
| `KASKAD_HOST` | `0.0.0.0` | Адрес для bind |
| `KASKAD_PORT` | `8088` | Порт |
| `KASKAD_SSH_KEY` | `/root/.ssh/id_ed25519` | SSH-ключ для управления другими серверами |
| `KASKAD_SERVERS_JSON` | `/etc/wireguard/ru-servers.json` | Путь к конфигу |
## nginx reverse-proxy (пример)
```nginx
server {
listen 443 ssl http2;
server_name kaskad.example.com;
ssl_certificate /etc/letsencrypt/live/kaskad.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/kaskad.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8088;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 600s; # для долгих /add-domain пачкой
}
}
```
И в WebUI поставить `KASKAD_HOST=127.0.0.1`, не открывать 8088 наружу.