151 lines
9.8 KiB
Markdown
151 lines
9.8 KiB
Markdown
# Amnezia VPN Share Panel (Go)
|
||
|
||
Полный переезд панели совместного доступа к Amnezia VPN с PHP на Go
|
||
(модуль `amnezia-share`). Приложение — единый статически собранный бинарник:
|
||
HTTP-сервер, сессии, CSRF, шаблоны и вся бизнес-логика (гостевые
|
||
share-ссылки, личный кабинет, админка) внутри одного процесса + PostgreSQL.
|
||
|
||
## Состав репозитория
|
||
|
||
```
|
||
Go/
|
||
├── cmd/
|
||
│ ├── server/ — основной HTTP-сервер (слушает APP_PORT)
|
||
│ └── cleanup/ — разовая задача очистки просроченных share-ссылок
|
||
├── internal/
|
||
│ ├── config/ — чтение переменных окружения
|
||
│ ├── db/ — подключение к БД + миграции
|
||
│ ├── models/ — доменные структуры (ShareLink, Member, ServerInfo, ...)
|
||
│ ├── panel/ — клиент Amnezia Web Panel API
|
||
│ ├── settings/ — key-value настройки в БД (URL панели, токен, лейблы и т.д.)
|
||
│ ├── auth/ — вход администратора, Pocket ID (OIDC)
|
||
│ ├── member/ — личный кабинет (регистрация, подписка, конфиги)
|
||
│ ├── share/ — гостевые share-ссылки, коды продления, сборка бандлов
|
||
│ ├── i18n/ — переводы RU/EN
|
||
│ └── web/ — HTTP-слой: App, роуты, middleware, шаблоны
|
||
│ └── handlers/ — обработчики, сгруппированные по разделам
|
||
├── web/
|
||
│ ├── templates/ — HTML-шаблоны (layouts, share, cabinet, admin, auth)
|
||
│ └── static/ — CSS/иконки (Bootstrap 5 подключается через CDN)
|
||
├── migrations/ — SQL-схема (идемпотентные CREATE TABLE IF NOT EXISTS)
|
||
├── Dockerfile
|
||
├── docker-compose.yml
|
||
└── .env.example
|
||
```
|
||
|
||
## Запуск локально (без Docker)
|
||
|
||
Требуется Go 1.22+ и PostgreSQL 14+.
|
||
|
||
```bash
|
||
cd Go
|
||
cp .env.example .env # заполните пароли/секреты
|
||
go mod tidy
|
||
go build ./...
|
||
DATABASE_URL="postgres://vpn_admin:vpn_admin@127.0.0.1:5432/vpn_admin?sslmode=disable" \
|
||
APP_SESSION_SECRET="локальный-дев-секрет-минимум-32-символа" \
|
||
go run ./cmd/server
|
||
```
|
||
|
||
Сервер поднимется на `http://127.0.0.1:30000`. При первом запуске
|
||
(таблица администраторов пуста) корень `/` перенаправит на `/install` —
|
||
форму создания единственного администратора. Дальше вход через `/login`.
|
||
|
||
Миграции (`migrations/001_schema.sql`) применяются автоматически при
|
||
старте `cmd/server` и `cmd/cleanup` — отдельно накатывать их не нужно.
|
||
|
||
## Запуск через Docker Compose / Dokploy
|
||
|
||
```bash
|
||
cd Go
|
||
cp .env.example .env
|
||
# отредактируйте .env: POSTGRES_PASSWORD, APP_SESSION_SECRET (32+ символов)
|
||
docker compose up -d --build
|
||
```
|
||
|
||
Сервисы:
|
||
|
||
- **app** — веб-приложение, слушает `30000:30000` (в Dokploy пробросьте
|
||
этот порт через ваш прокси/домен).
|
||
- **db** — PostgreSQL 17, доступен только внутри docker-сети `amnezia`
|
||
(порт 5432 наружу не публикуется; не открывайте его в проде).
|
||
- **cleanup** — тот же образ, в цикле раз в 5 минут запускает
|
||
`/app/cleanup`, который удаляет истёкшие share-ссылки и их конфиги
|
||
на панели Amnezia.
|
||
|
||
Проверка живости: `GET /health` → `{"ok":true,"db":true,"time":"..."}`.
|
||
Этот же путь используют healthcheck-и в docker-compose.
|
||
|
||
### Переменные окружения
|
||
|
||
| Переменная | Назначение | По умолчанию |
|
||
|---|---|---|
|
||
| `APP_PORT` | порт HTTP-сервера | `30000` |
|
||
| `APP_BASE_URL` | префикс пути, если приложение висит не на корне домена (например `vpn`) | пусто |
|
||
| `APP_SESSION_SECRET` | секрет сессий (используется как соль для CSRF/токенов); задайте случайную строку 32+ символов | — |
|
||
| `APP_HTTP_BUDGET_SEC` | таймаут на HTTP-запросы к панели Amnezia в рамках одного запроса | `52` |
|
||
| `DATABASE_URL` | строка подключения к PostgreSQL | `postgres://vpn_admin:vpn_admin@127.0.0.1:5432/vpn_admin?sslmode=disable` |
|
||
| `AMNEZIA_PANEL_URL`, `AMNEZIA_API_TOKEN` | адрес и токен панели Amnezia (можно также задать в `/admin/settings`) | пусто |
|
||
| `AMNEZIA_SERVER_LABELS_JSON` | JSON `{"1":"Германия"}` — переопределение названий серверов через окружение | пусто |
|
||
| `MIGRATIONS_DIR` | путь к папке с SQL-миграциями | `migrations` |
|
||
| `WEB_DIR` | путь к папке `templates/` и `static/` | `web` |
|
||
|
||
Настройки панели, Pocket ID, режим техработ, лейблы/флаги/скорости
|
||
серверов и лимиты личного кабинета по умолчанию удобнее менять прямо в
|
||
админке (`/admin/settings`, `/admin/servers`) — они хранятся в таблице
|
||
`site_settings` и переживают перезапуск контейнера.
|
||
|
||
## Основные маршруты
|
||
|
||
Гостевые:
|
||
|
||
- `GET /` — редирект на `/admin`, `/install` или `/login` в зависимости от состояния.
|
||
- `GET/POST /install` — создание единственного администратора (доступно, пока админов нет).
|
||
- `GET/POST /login`, `GET /login?oidc=1`, `GET /oidc/callback`, `GET /logout` — вход администратора (пароль или Pocket ID SSO).
|
||
- `GET/POST /share?k=ТОКЕН` — гостевая страница share-ссылки: выбор сервера/протокола, создание/перенос/продление конфига, скачивание. POST с заголовком `X-Share-Async: 1` отвечает JSON.
|
||
- `GET /share/servers?k=`, `GET /share/download?k=&cre=&part=conf|vpn|zip`.
|
||
- `GET /faq`, `GET /rules`, `GET /status` — статические страницы + пинг серверов.
|
||
- `GET/POST /cabinet`, `/cabinet/login`, `/cabinet/register`, `/cabinet/logout`, `/cabinet/servers`, `/cabinet/download` — личный кабинет.
|
||
|
||
Администрирование (требует входа):
|
||
|
||
- `GET /admin` — дашборд.
|
||
- `GET/POST /admin/links` — управление share-ссылками (создание, продление, список серверов, удаление конфигов).
|
||
- `GET/POST /admin/renewal` — коды продления (для гостевых ссылок и/или личного кабинета).
|
||
- `GET/POST /admin/configs` — обзор всех выданных конфигов с фильтрами и удалением.
|
||
- `GET/POST /admin/servers` — метки, протоколы, флаги, скорость и отключение серверов панели.
|
||
- `GET/POST /admin/settings` — URL/токен панели, Pocket ID, техработы, лимиты кабинета, проверка соединения.
|
||
|
||
Статика: `/static/*` раздаётся из `WEB_DIR/static`.
|
||
|
||
## Миграция с PHP-версии
|
||
|
||
- Схема БД совместима: `migrations/001_schema.sql` использует
|
||
`CREATE TABLE IF NOT EXISTS` — можно указать Go-приложению ту же базу,
|
||
на которой уже работала PHP-панель, без потери данных.
|
||
- Ключи в таблице настроек (`site_settings`) переиспользованы 1:1
|
||
(`amnezia_panel_url`, `amnezia_api_token`, `amnezia_server_labels_json`,
|
||
`share_maintenance_mode`, `pocket_id_*` и т.д.) — значения, заданные в
|
||
PHP-админке, подхватятся автоматически.
|
||
- Cookie для языка (`share_lang`) и сессии называются иначе
|
||
(`amnezia_session`), поэтому после переключения все пользователи один
|
||
раз залогинятся заново — это нормально.
|
||
- Разовый крон-скрипт очистки истёкших ссылок (`cleanup_share.php`)
|
||
заменён на бинарник `cmd/cleanup`, который в docker-compose запускается
|
||
в цикле каждые 5 минут отдельным контейнером.
|
||
- Файлы конфигов больше не пишутся на диск — тело ответа панели
|
||
сохраняется в БД (`share_creations.response_json`) и конфиги
|
||
собираются "на лету" при скачивании, как и в PHP-версии.
|
||
|
||
## Тесты
|
||
|
||
```bash
|
||
go build ./...
|
||
go test ./...
|
||
```
|
||
|
||
`internal/web` и `internal/web/handlers` содержат smoke-тесты, которые
|
||
парсят все HTML-шаблоны и рендерят каждую страницу с реалистичными
|
||
данными без подключения к базе — это ловит опечатки в шаблонах ещё на
|
||
этапе CI, до реального деплоя.
|