Files

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, до реального деплоя.