9.8 KiB
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+.
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
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-версии.
Тесты
go build ./...
go test ./...
internal/web и internal/web/handlers содержат smoke-тесты, которые
парсят все HTML-шаблоны и рендерят каждую страницу с реалистичными
данными без подключения к базе — это ловит опечатки в шаблонах ещё на
этапе CI, до реального деплоя.