amnezia_web
Веб‑панель AmneziaWG на своём VPS (Docker): таблица клиентов, статусы «в туннеле», AllowedIPs, несколько инстансов через AWG_PROFILES, часы сервера и браузера, смена пароля панели.
Редакция по умолчанию — FREE (community): просмотр клиентов, удаление peer с сервера, раздел установки Telegram MTProto‑прокси (Docker). Полное управление (вкл/выкл, даты, переименование, экспорт .conf, каскад, Cloudflare WARP, синхронизация времени и т.д.) — в amnezia_web-PRO; из FREE можно запустить переход на PRO по GitHub‑токену (см. жёлтый баннер после входа).
Amnezia Web — зачем этот проект
Безопасный доступ к интернету без сложной настройки панели
Amnezia Web (amnezia_web) — это веб‑панель для администрирования уже развёрнутого сервера AmneziaWG: клиенты, статусы, несколько инстансов WireGuard на одном VPS (AWG_PROFILES), пароль доступа и дополнительные блоки в браузере — вместо ручной возни только через SSH и конфиги.
Проект ориентирован на тех, кому важны:
- приватность и контроль над своим узлом;
- стабильная работа привычного VPN‑стека Amnezia;
- понятный интерфейс без лишней боли в повседневном администрировании.
Установка панели и лендинга — скриптом одной командой в Docker; сам VPN‑контейнер AmneziaWG вы обычно поднимаете своим способом (как уже делаете с экосистемой Amnezia).
Что умеет Amnezia Web
- Управление через браузер — таблица клиентов AmneziaWG, время сервера и браузера, быстрые действия там, где редакция это позволяет (FREE vs PRO).
- Быстрое развёртывание панели — образ админки и опционально страницы для пользователей через
scripts/install.sh. - Приватность — всё крутится на вашем VPS; доступ к панели ограничиваете паролем (и при желании сетью/TLS).
- Удобство — одно место для обзора клиентов и (в FREE) установки MTProto‑прокси из интерфейса.
- Несколько инстансов AWG на одном хосте — переключатель профилей через
AWG_PROFILES. - Современный стек — Docker, Node.js, веб‑интерфейс.
Полный список возможностей FREE и PRO см. в тексте выше и в репозитории amnezia_web-PRO.
Для кого этот проект
- администраторам своего VPS с AmneziaWG;
- тем, кому нужна простая панель поверх уже знакомого стека Amnezia;
- небольшим группам пользователей одного сервера.
Почему проект развивается
Независимое open‑source решение для тех, кому нужен удобный инструмент администрирования без перегруженных коммерческих панелей. Идея — упростить сопровождение своего узла и при этом не навязывать чужую инфраструктуру.
Поддержка проекта
Ссылки на GitHub, Boosty, Ozon СБП и Telegram — в конце этого README. Также можно поставить ⭐ репозиторию и рассказать тем, кому будет полезно.
Спасибо всем, кто поддерживает развитие проекта.
Скриншоты
В редакции FREE сверху панели отображается жёлтый блок «базовая версия» и меньше кнопок, чем в PRO (см. список ограничений выше); общая разметка и таблица клиентов сохраняются.
Установка для клиента (маркер в томе + явный ALLOW в контейнере)
Раньше многие полагались на этот режим ради поля PAT — сейчас оно включено по умолчанию. INSTALL_FREE_COMMUNITY_ACTIVATION=1 по-прежнему полезен: создаёт /opt/amnezia-admin-data/.install-free-github-pro-opt-in и при следующих curl … | sudo bash снова прокидывает ALLOW_COMMUNITY_GITHUB_ACTIVATION=1 в контейнер (если когда-то задали отключение вручную).
export INSTALL_FREE_COMMUNITY_ACTIVATION=1
curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web/main/scripts/install.sh | sudo -E bash
если нужно сменить порт например на 8884
curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web/main/scripts/install.sh \
| sudo -E env HOST_PORT=8884 LANDING_PORT=8081 bash
Переменная INSTALL_FREE_COMMUNITY_ACTIVATION сохранится в томе как файл .install-free-github-pro-opt-in: следующие апдейты через sudo bash подхватят маркер без повторного export (или с sudo -E, если передаёте другие переменные в той же сессии).
Отключить поле GitHub и установку из панели (жёсткий FREE)
Чтобы под баннером не было ввода токена и запретить POST …/run-private-install, задайте в контейнере ALLOW_COMMUNITY_GITHUB_ACTIVATION=0 (или false / no / off) и перезапустите панель. Обычная установка curl … | sudo bash без этой переменной оставляет поле включённым в FREE.
Стандартная установка того же образа без отключения:
curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web/main/scripts/install.sh | sudo bash
Форк или ветка (с тем же режимом маркера по желанию):
export GITHUB_REPO="вы/репо"
export BRANCH="main"
export INSTALL_FREE_COMMUNITY_ACTIVATION=1
curl -fsSL "https://raw.githubusercontent.com/${GITHUB_REPO}/${BRANCH}/scripts/install.sh" | sudo -E bash
Уже скачали проект:
cd /opt/amnezia-admin && chmod +x scripts/install.sh && sudo SKIP_DOWNLOAD=1 bash scripts/install.sh
Переменные окружения и sudo
Если передаёте AWG_PROFILES или ADMIN_PASSWORD в одной строке с curl, используйте sudo -E bash, иначе sudo не увидит переменные. Альтернатива — записать JSON профилей в /root/amnezia-admin.awg-profiles.json и запустить обычный curl … | sudo bash. Подробнее см. историю коммитов и зеркальный README в репозитории PRO.
Важные переменные
| Переменная | По умолчанию | Назначение |
|---|---|---|
INSTALL_FREE_COMMUNITY_ACTIVATION |
(не задано) | 1: маркер .install-free-github-pro-opt-in в томе + явно ALLOW_COMMUNITY_GITHUB_ACTIVATION=1 при сборке RUN_ENV (удобно после ручного ALLOW=0 или если нужно навсегда фиксировать в томе). |
GITHUB_REPO |
andrey271192/amnezia_web |
Архив для установки |
HOST_PORT |
8080 |
Порт панели |
AWG_CONTAINER |
amnezia-awg2 |
Контейнер WG по умолчанию |
AWG_PROFILES |
(нет) | Несколько инстансов; см. примеры в репозитории PRO |
COMMUNITY_UPGRADE_URL |
Страница подписки PRO на Boosty (зашита в код по умолчанию) | Переопределите, если смените уровень подписки |
COMMUNITY_UPGRADE_PITCH |
(текст по умолчанию в коде) | Текст под заголовком базовой версии |
PANEL_FOOTER_DONATE_URL |
Как COMMUNITY_UPGRADE_URL |
Ссылка «донат» в шапке и подвале веб‑панели (не добавляется на nginx‑лендинг пользователей). |
PANEL_FOOTER_TELEGRAM_URL |
https://t.me/lot_andrey |
Ссылка Telegram‑спонсора / канала (там же: только панель). |
PANEL_FOOTER_OZON_URL |
Ссылка на Ozon СБП автора (дефолт в server.js) |
Донат через Ozon — шапка и подвал панели с остальными ссылками. |
PANEL_FOOTER_DONATE_LABEL |
Поддержать проект |
Текст якоря доната |
PANEL_FOOTER_OZON_LABEL |
Донат · Ozon СБП |
Текст якоря Ozon |
PANEL_FOOTER_TELEGRAM_LABEL |
Telegram‑канал спонсора |
Текст якоря Telegram |
PANEL_FOOTER_PROMO_SUBTITLE |
(строка по умолчанию в коде) | Поясняющий текст в верхней полосе панели |
SKIP_LANDING |
0 |
1 — без лендинга на порту 80 |
ALLOW_COMMUNITY_GITHUB_ACTIVATION |
в редакции **community поле вкл по умолчанию |
Явное 0 / false / no / off — скрыть ввод PAT и заблокировать POST /api/community/run-private-install (после перезапуска контейнера). 1 / true не обязательны. |
COMMUNITY_PRIVATE_INSTALL_SCRIPT_URL |
https://raw.githubusercontent.com/andrey271192/amnezia_web-pro/main/scripts/install.sh |
Сырой URL scripts/install.sh в вашем приватном репозитории PRO |
COMMUNITY_INSTALL_FETCH_MS |
60000 |
Таймаут HTTP при скачивании установщика из GitHub |
PRIVATE_INSTALL_SCRIPT_MAX_BYTES |
2097152 |
Максимальный размер скачанного скрипта (байты) |
COMMUNITY_INSTALL_LOG_TAIL_BYTES |
98304 |
Первый ответ GET /api/community/install-log без since отдаёт хвост последних N байт (для живого блока в UI при установке PRO). Диапазон 1 KiB … 512 KiB через env. |
COMMUNITY_INSTALL_LOG_API_CHUNK_MAX |
524288 |
Максимум байт за один запрос «догонять» журнал (~512 KiB; верхний предел через env ограничен). |
COMMUNITY_DISABLE_DOCKER_CLI_HELPER |
(не задано) | Если 1, установка из UI снова только «bash внутри панели» (часто конфликт :8080 с PRO). По умолчанию используется одноразовый контейнер docker:cli, который снимает FREE и зависший PRO перед install.sh. |
COMMUNITY_SKIP_REMOVE_FREE_BEFORE_PRIVATE_PRO |
0 |
1 — не выполнять docker rm FREE/лендинга перед install (если знаете, что делаете). |
COMMUNITY_PRO_INSTALL_HELPER_IMAGE |
docker:26-cli |
Образ с бинарём docker для фонового контейнера (нужен доступ к демону по сокету). |
COMMUNITY_HELPER_SKIP_PREPARE_TOOLS |
(не задано) | 1 — helper не ставит bash и curl в образе Alpine (обычно не нужно; без них #!/usr/bin/env bash или curl в PRO install.sh падают). |
MTPRO_PROXY_CONTAINER |
mtproto-proxy |
Имя контейнера MTProto‑прокси Telegram (официальный образ telegrammessenger/proxy, см. Dockerfile на Docker Hub). |
MTPRO_PROXY_IMAGE |
telegrammessenger/proxy:latest |
Образ docker pull + docker run при установке из панели (FREE/community). |
MTPRO_INTERNAL_PORT |
443 |
Порт процесса внутри контейнера (официальный прокси слушает 443/tcp). Мапится на MTPRO_PUBLISH_*. |
MTPRO_PUBLISH_PORT |
8443 |
Порт хоста VPS (внешний), проброшенный в контейнер. |
MTPRO_PUBLISH_BIND |
0.0.0.0 |
Адрес биндинга на хосте (-p в Docker); при нескольких сетевых интерфейсах при необходимости уточняют. |
MTPRO_PUBLIC_HOST |
(нет) | Публичный IP или DNS для ссылки tg://proxy в UI; можно вместо него задать CLIENT_CONFIG_ENDPOINT. |
UI_HIDE_MTPROTO |
(не задано) | 1 или UI_HIDE_SECTIONS=...,mtproto — скрыть раздел установки MTProto в веб‑интерфейсе (по умолчанию виден даже FREE). |
FREE_PANEL_CONTAINER_FOR_PRO_INSTALL и др. |
см. server.js |
Имена контейнеров для docker rm перед install (по умолчанию amnezia-admin, amnezia-web-landing, amnezia-admin-pro). |
MTProto‑прокси и API панели: GET /api/mtproto/status отдаёт состояние контейнера и ссылку tg:// без тяжёлых операций при открытии блока. Опционально GET /api/mtproto/status?withLogs=1 добавляет в ответ хвост docker logs (поле logsFetched). Отдельные эндпоинты: GET /api/mtproto/logs и GET /api/mtproto/tail (тот же смысл, если обратный прокси режет URI с logs). За nginx/Caddy перед панелью нужно пробрасывать весь префикс /api/ одним правилом — см. блок «Not found» в «Частые проблемы» ниже.
Поле токена по умолчанию уже есть. Чтобы убрать его — см. раздел «Отключить поле GitHub…» выше. URL приватного install.sh задаёт COMMUNITY_PRIVATE_INSTALL_SCRIPT_URL.
Важно: при одноразовом запуске с переменными в одной строке с curl … | sudo bash они пропадают — нужен export перед curl и sudo -E bash, см. блок «Установка для клиента» выше.
Остальные переменные совместимы с образом панели (см. Dockerfile / server.js в этом репозитории).
Обновление
Обычно достаточно:
curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web/main/scripts/install.sh | sudo bash
Если нужен маркер .install-free-github-pro-opt-in в томе (см. раздел выше) или переменные хоста при sudo, используйте export INSTALL_FREE_COMMUNITY_ACTIVATION=1 и sudo -E bash.
После сообщения → Клонирование релиза … несколько минут может ничего не печататься: идёт curl … | tar с GitHub. Для полосы прогресса: sudo INSTALL_SCRIPT_VERBOSE=1 bash (или передайте переменную в окружение до |). Если обрывает по времени или «тишина» часами задайте таймауты: CURL_CONNECT_TIMEOUT (по умолчанию 30 с к подключению), CURL_MAX_TIME (по умолчанию до 900 с на загрузку), CURL_RETRY. Полный URL tar.gz можно подменить: GITHUB_REPO_URL_OVERRIDE (должен указывать на архив того же вида ${REPO}-${BRANCH}.tar.gz, после распаковки каталог будет ИмяРепозитория-${BRANCH}).
Принудительная пересборка образа: NO_CACHE=1.
Удаление
curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web/main/scripts/uninstall.sh | sudo bash
Частые проблемы
Пропало поле «токен GitHub» под плашкой FREE
Редакция должна быть community. Чаще всего в docker inspect amnezia-admin → Env осталось ALLOW_COMMUNITY_GITHUB_ACTIVATION=0 (или false / no / off) — удалите переменную или поставьте 1 и снова выполните install.sh. Установщик при апдейте переносит ALLOW_* из предыдущего контейнера. Маркер ${DATA_DIR}/.install-free-github-pro-opt-in при INSTALL_FREE_COMMUNITY_ACTIVATION=1 снова прокинет ALLOW=1, если установщику на хосте не задали ALLOW_COMMUNITY_GITHUB_ACTIVATION=0.
Журнал установки и docker-helper
После успешной кнопки «Установить PRO» в той же панели открывается живой блок «Журнал установки» (поллинг каждые 2 с к GET /api/community/install-log; для запросов нужна сессия в браузере). Пока старый контейнер FREE снят и новый образ ещё не поднял ту же вкладку, поток журнала в браузере прерывается — откройте адрес панели снова после старта PRO; файл community-install-last.log на томе данных тот же. Кнопка «Пауза» останавливает опрос журнала.
В режиме docker-helper панель пишет в community-install-last.log финальную строку --- helper завершён code=… внутри одноразового контейнера: её видно даже если процесс FREE-панели убрал docker rm и Node не успевает добавить строку --- завершено …. Если в логе после преамбулы одноразового установщика нет ни одной финальной строки — обновите образ панели с актуального amnezia_web и повторите установку.
Bind for 0.0.0.0:8080 failed: port is already allocated у amnezia-admin-pro
На 8080 уже слушает FREE‑панель (amnezia-admin). Пока она работает, второй контейнер панели (PRO) на тот же порт не поднимется. Кнопка «Установить PRO» из UI по умолчанию использует одноразовый контейнер docker:cli (пауза → docker rm FREE / лендинг / amnezia-admin-pro и любые имена вида _…_…-amnezia-admin-pro из docker compose → затем ваш install.sh). Иначе вручную: docker rm -f amnezia-admin, затем установщик PRO. Отключить авто-снос: COMMUNITY_DISABLE_DOCKER_CLI_HELPER=1.
В community-install-last.log: curl: command not found, tar: invalid magic, **code=2 сразу после helper
Образ docker:26-cli на Alpine обычно без bash и без curl. PRO install.sh с #!/usr/bin/env bash и загрузкой архива через curl | tar без них не стартуют (curl: command not found, tar: invalid magic). Если после строки «одноразовый установщик» почти сразу --- завершено … code=2 — возможны ошибка сборки prelude в sh, ошибка docker run … -e TOKEN=… из‑за спецсимволов в PAT, или apk не смог добавить bash (сеть из контейнера). Обновите панель с main: helper целиком шлёт stdout/stderr в лог, токены передаются средой процесса (без интерполяции в аргументе -e), prelude разделён ;; перед install.sh скрипт сообщает если нет bash/curl (выход по коду ~126). Если apk недоступен — свой COMMUNITY_PRO_INSTALL_HELPER_IMAGE с bash и curl, либо в приватном install.sh перейти на #!/bin/sh и wget. Отключить подготовку: COMMUNITY_HELPER_SKIP_PREPARE_TOOLS=1.
Установка «зависла» на сообщении → Клонирование релиза … и долго без вывода
Это этап скачивания и распаковки архива с GitHub. Запустите установщик с INSTALL_SCRIPT_VERBOSE=1 (полоска загрузки curl). Задайте CURL_MAX_TIME если нужно усечь ожидание. При блокировках GitHub с хоста — зеркальный полный URL в GITHUB_REPO_URL_OVERRIDE (см. раздел «Обновление»).
SKIP_DOWNLOAD=1 bash scripts/install.sh завершается сразу без вывода («нифига» не происходит)
В старых версиях под set -o pipefail подсчёт контейнеров через grep падал, если нет ни одного запущенного имени amnezia-awg…; отдельно тот же эффект давал пайплайн docker port … | head | awk при остановленном amnezia-admin: docker inspect ещё «видит» контейнер, а docker port возвращает ошибку. Скрипт обрывался до «Сборка образа». Обновите scripts/install.sh до актуального из main или временно выполните docker rm -f amnezia-admin перед установкой.
Лендинг: порт 80 занят
Если на хосте уже что-то слушает TCP 80, установщик сообщит об этом и, при дефолтном LANDING_PORT=80, сам попробует другой свободный порт (обычно начиная с 8081). Либо явно: LANDING_PORT=8083, либо SKIP_LANDING=1.
Раздел MTProto или вся панель: ошибка «Not found», API не отвечает
Чаще всего браузер бьётся не в Node‑процесс панели, а в прокси (nginx и т.п.) с неполным маппингом: /api/mtproto/*, /api/clients и остальное должны уходить на тот же upstream, что и / панели. Должен проксироваться любой путь под /api/, а не только отдельные location. На самой VPS curl -fsS http://127.0.0.1:ПОРТ_ПАНЕЛИ/health должен вернуть JSON с version. Если с localhost работает, а через домен — 404, смотрите конфигурацию обратного прокси и TLS.
AmneziaWG Legacy: удаление клиента не срабатывает (wg0.conf is world accessible / No such device)
Панель синхронизирует живой интерфейс через wg-quick strip + syncconf. У Legacy конфиг часто /opt/amnezia/awg/wg0.conf, интерфейс — wg0, не awg0. В актуальном коде интерфейс выводится из имени файла (wg0.conf → wg0). Если путь другой — задайте в профиле AWG_IFACE / в AWG_PROFILES поле iface. Предупреждение про world-accessible: перед применением конфига файл на стороне контейнера выставляется в chmod 600.
Лицензия
MIT — см. LICENSE.
Поддержка проекта
- ⭐ GitHub: andrey271192/amnezia_web
- 💖 Boosty: boosty.to/andrey27/donate
- 💳 Ozon Bank (СБП): ссылка
- ✉️ Telegram: @lot_andrey


