Files
awg-profiler-golang/README.md
T
2026-07-18 10:02:43 +03:00

20 KiB
Raw Blame History

awg_profiler

Инструмент на Go для развёртывания и управления сервером AmneziaWG (форк WireGuard с обфускацией трафика): установка зависимостей, инициализация сервера, управление клиентами (CLI и веб-UI) и сбор статистики трафика, переживающей перезапуски.

Проект самодостаточен: единственный бинарник awg_profiler, встроенный веб-интерфейс (без внешних зависимостей в браузере) и Docker-образы для запуска без установки чего-либо на хост.


Quick Start

Ниже — два независимых пути развёртывания «с нуля» (Green Field): в контейнере (рекомендуется, не требует ничего кроме Docker) или напрямую на хосте.

Вариант A — в контейнере (рекомендуется)

Требования: Docker + Docker Compose, ядро Linux с включённым модулем tun (есть на любом современном дистрибутиве).

Контейнер запускает встроенный веб-интерфейс на :8080 (WEB UI) и слушает VPN-трафик на UDP :51820. AmneziaWG-стек (awg, awg-quick, amneziawg-go) собирается внутри образа — на хосте ничего ставить не нужно.

git clone <repo-url> awg_profiler && cd awg_profiler

# Сборка и запуск (образ на базе Alpine)
docker compose up -d --build

# Логи / статус
docker compose logs -f

По умолчанию порт 8080 публикуется только на 127.0.0.1 хоста (см. docker-compose.yml) — веб-UI недоступен по сети, пока вы явно не расширите доступ. На самой машине откройте http://127.0.0.1:8080, либо для доступа с другого компьютера прокиньте порт по SSH: ssh -L 8080:127.0.0.1:8080 user@server и откройте http://127.0.0.1:8080 локально.

Веб-UI покажет мастер настройки:

  1. install-deps — пропускается автоматически (зависимости уже в образе).
  2. init-server — заполните форму (сеть, порт, DNS, MTU — можно оставить значения по умолчанию) и отправьте. Сервер сгенерирует ключи, параметры обфускации и запустится.
  3. Создавайте клиентов на вкладке Clients, скачивайте .conf / QR-код.

Чтобы открыть UI на всех интерфейсах (LAN/интернет), сначала включите Basic-аутентификацию, иначе панель управления сервером останется без пароля:

# в docker-compose.yml:
# 1. раскомментировать блок environment: и задать
AWG_WEB_USER=admin
AWG_WEB_PASS=длинный-пароль
# 2. заменить порт "127.0.0.1:8080:8080" на "8080:8080"
docker compose up -d --build

Все изменяемые данные (конфиг, реестр клиентов, профили, статистика) живут в именованных томах awg-data и awg-etc — переживают docker compose down без -v.

Альтернативный образ (Linux Mint база, вендорские пакеты AmneziaWG вместо собранных из исходников):

docker compose -f docker-compose.mint.yml up -d --build

Вариант B — на хосте (без контейнера)

Требования: Linux (Ubuntu, Debian, Linux Mint или Alpine), Go ≥ 1.26, root/sudo. install-deps сам ставит AmneziaWG: на apt-based дистрибутивах — пакеты amneziawg/amneziawg-tools из ppa:amnezia/ppa; на Alpine, где готового пакета amneziawg-tools нет, — собирает awg/awg-quick из исходников (нужен интернет для git clone на этапе install-deps). На Alpine kernel-модуль amneziawg при этом не ставится — его нужно предоставить отдельно (DKMS/akmods или готовый модуль под ваше ядро), install-deps только предупредит об этом.

git clone <repo-url> awg_profiler && cd awg_profiler

# 1. Сборка бинарника
export PATH=$PATH:/usr/local/go/bin
go build -o awg_profiler .

# 2. Установка зависимостей (AmneziaWG, qrencode, nftables, jq) — один раз
sudo ./awg_profiler install-deps

# 3. Интерактивная инициализация сервера (ключи, обфускация, конфиг, служба)
sudo ./awg_profiler init-server

# 4. Первый клиент
sudo ./awg_profiler create phone

# 5. (опционально) веб-UI поверх той же установки
sudo ./awg_profiler web --addr 0.0.0.0:8080

install-deps и init-server — обязательно раздельные шаги и в этом порядке: init-server проверяет флаг, оставленный install-deps, и отказывается работать, если пакеты ещё не установлены.

На вопрос «VPN network CIDR» принимается только /24 (например 10.0.0.0/24 или 192.168.5.0/24) — весь остальной код (адрес сервера, адреса клиентов, запись в конфиг) жёстко расчитан на /24, другой префикс init-server отклонит с ошибкой.

Дальше — управление через CLI (server-status, create, list, …) или запущенный web; см. полный список команд в CLI-командах.


Detailed Info

Расположение файлов

Пути привязаны к каталогу исполняемого файла (<dir>, переопределяется переменной AWG_PROFILER_DIR — так собран Docker-образ, где <dir>=/data):

Назначение Путь
Конфиг профилировщика <dir>/awg_config (формат shell KEY="value")
Реестр клиентов <dir>/data/awg_clients.json
Накопленная статистика трафика <dir>/data/awg_stats.json
Профили клиентов <dir>/awg_clients/<name>.conf + .png (QR)
Флаг «зависимости установлены» <dir>/awg_state.json
Interface conf / nft-правила /etc/amnezia/amneziawg/<iface>.conf, <iface>-rules.nft

CLI-команды

SERVER SETUP
  install-deps             Установить AmneziaWG, jq, qrencode для текущей ОС
                            и записать флаг deps_installed (выполнить ПЕРВЫМ)
  init-server               Интерактивная настройка сервера: проверяет флаг
                            зависимостей, затем генерирует ключи + параметры
                            обфускации, пишет конфиги, включает IP-forwarding
                            и запускает службу (пакеты НЕ ставит)

SERVER MANAGEMENT
  server-status             Статус интерфейса и список пиров
  server-start               Запустить службу AmneziaWG
  server-stop                Остановить службу AmneziaWG
  server-restart             Перезапустить службу AmneziaWG
  show-config                Показать текущий конфиг (приватные ключи скрыты)
  sync-config                Пересобрать <conf-dir>/<iface>.conf из реестра
                            клиентов и (по подтверждению) перезапустить службу

CLIENT MANAGEMENT
  create  <name>             Создать клиента: ключи, .conf, QR-код
  delete  <id>                Удалить клиента (файлы + запись в реестре)
  disable <id>                Перевести клиента в статус DISABLED
  enable  <id>                Перевести клиента в статус ACTIVE
  list                        Список всех зарегистрированных клиентов

WEB UI
  web [--addr host:port]     Запустить веб-UI (по умолчанию 127.0.0.1:8080)
      [--theme classic|glass]
      [--ui-mode dark|light|auto]

Поддерживаемые ОС: Ubuntu, Debian, Linux Mint, Alpine Linux (автоопределение по /etc/os-release; на apt-based используется systemd, на Alpine — OpenRC; если систем systemd не является PID 1 — например, в контейнере — используется прямое управление через awg-quick).

Разделение install-deps и init-server

Установка пакетов полностью отделена от настройки сервера:

  1. install-deps ставит AmneziaWG и тулинг под текущую ОС и пишет флаг deps_installed=true в awg_state.json (с временем и версией ОС).
  2. init-server пакеты не ставит. Сначала проверяет флаг: если install-deps не запускался, завершается ошибкой Dependencies not installed — run 'install-deps' first. При установленном флаге переходит к генерации ключей, параметров обфускации, конфигов, включению IP-forwarding и запуску службы.

В контейнерных образах этот флаг сеется автоматически при старте (entrypoint.sh / entrypoint.mint.sh), так как AmneziaWG-стек уже запечён в образ на этапе сборки — шаг install-deps в UI/CLI внутри контейнера не требуется.

Web-UI

Команда web поднимает встроенный веб-интерфейс управления. Он использует ту же логику, что и CLI (общий Go-пакет), поэтому реестр/конфиг/служба остаются совместимыми. Статические ассеты (webui/, webui_glass/) вшиты в бинарник через go:embed — дополнительных файлов при развёртывании не нужно.

sudo ./awg_profiler web                          # 127.0.0.1:8080 (по умолчанию)
sudo ./awg_profiler web --addr 0.0.0.0:8080      # на всех интерфейсах
sudo ./awg_profiler web --theme glass            # альтернативный дизайн (glassmorphism)
sudo ./awg_profiler web --ui-mode auto           # следовать светлой/тёмной теме ОС

Дизайн выбирается флагом --theme classic|glass (env AWG_WEB_THEME, по умолчанию classic), цвет-режим — --ui-mode dark|light|auto (env AWG_WEB_MODE, по умолчанию dark — тёмная форсируется). glass — dark-only, --ui-mode для неё игнорируется.

Возможности UI:

  • Дашборд — статус интерфейса (UP/DOWN), эндпоинт, сеть, публичный ключ, счётчики «всего / активных / онлайн», кнопки start/stop/restart и sync.
  • Клиенты — список с индикатором онлайна и накопленным трафиком; создание, включение/выключение, удаление, скачивание .conf и просмотр QR-кода.
  • Статистика по пользователю — по каждому клиенту показываются накопленные байты (↓ rx / ↑ tx), отметка «Stats since», последний handshake, эндпоинт и признак «онлайн» (handshake ≤ 150 c), а также кнопка Reset stats для быстрой очистки. Живые данные берутся из awg show <iface> dump и сопоставляются с реестром по публичному ключу.
  • Мастер настройки — если сервер ещё не инициализирован, UI показывает форму install-depsinit-server (неинтерактивные аналоги CLI-команд).

UI построен как одностраничное приложение на «ванильном» JS/CSS (без внешних зависимостей — работает офлайн), mobile-first, с обновлением статистики каждые 10 c. По умолчанию всегда тёмная тема (см. --ui-mode выше).

Накопление статистики (переживает перезапуск)

awg show <iface> dump отдаёт счётчики rx/tx, которые обнуляются при каждом перезапуске интерфейса — а в контейнере userspace-data-plane amneziawg-go рестартует вместе с приложением, поэтому «сырое» чтение после рестарта показывает ноль. Чтобы этого не происходило, трафик накапливается инкрементально и отдельно по каждому клиенту в data/awg_stats.json:

  • Значения складываются как дельты между замерами. Если счётчик «ушёл назад» (rx стал меньше предыдущего) — это трактуется как сброс, и всё текущее значение засчитывается как новый трафик. Дельты всегда неотрицательны, поэтому итог может только расти.
  • В каждой записи хранится базовая точка (last_rx/last_tx) — она тоже пишется на диск. После рестарта итог берётся с диска, а маленькое пост-рестарт чтение корректно распознаётся как сброс. Перезапуск программы не может уменьшить или обнулить уже накопленную статистику.
  • У каждого клиента есть отметка since — момент, с которого идёт накопление (при первом появлении пира или после очистки). Трафик, накопленный интерфейсом до начала отслеживания, задним числом не засчитывается.
  • Замер выполняется фоном (раз в 20 c) и попутно при опросе API, под отдельным мьютексом; запись — атомарно (temp + rename). Битый файл сохраняется как awg_stats.json.bad, чтобы ошибка парсинга не затёрла данные.
  • POST /api/clients/{id}/stats/reset (кнопка Reset stats) обнуляет накопленное для клиента и заново выставляет since. Удаление клиента удаляет и его запись статистики.

Безопасность

  • Приватные и preshared-ключи не передаются в браузер в JSON-списках — секреты покидают сервер только в файле .conf при явном скачивании.
  • По умолчанию сервер слушает 127.0.0.1. Для доступа извне включите HTTP Basic-аутентификацию, задав переменные окружения:
export AWG_WEB_USER=admin
export AWG_WEB_PASS='длинный-пароль'
sudo -E ./awg_profiler web --addr 0.0.0.0:8080

(за TLS/публичный доступ отвечает обратный прокси, например nginx/caddy).

  • Каждая операция сериализуется мьютексом; в веб-режиме внутренние ошибки перехватываются и возвращаются как HTTP-ответ, а не роняют сервер.

Docker-образы

Проект поставляет два независимых образа — оба запускают тот же бинарник и веб-UI, различается только то, откуда берётся сам AmneziaWG-стек:

Dockerfile (по умолчанию) Dockerfile.mint (альтернатива)
Базовый образ alpine:3.20 (рантайм) Linux Mint 22 (linuxmintd/mint22-amd64)
awg / awg-quick собираются из исходников (amneziawg-tools) пакет из официального ppa:amnezia/ppa
amneziawg-go (userspace data-plane) собирается из исходников собирается из исходников
compose-файл docker-compose.yml docker-compose.mint.yml

Оба варианта:

  • используют userspace data-plane amneziawg-go вместо kernel-модуля — контейнер не может загрузить модуль ядра, awg-quick автоматически переключается на userspace через /dev/net/tun, когда /sys/module/amneziawg отсутствует;
  • требуют cap_add: NET_ADMIN и проброс /dev/net/tun (уже прописано в compose-файлах);
  • сохраняют состояние в volume'ах: /data (конфиг, реестр, профили, статистика) и /etc/amnezia/amneziawg (interface .conf + nft-правила);
  • внутри контейнера слушают 51820/udp (VPN) и 8080/tcp (веб-UI), команда по умолчанию — web --addr 0.0.0.0:8080 (переопределяется через command: в compose или аргументом docker run); наружу же порт 8080 по умолчанию публикуется только на 127.0.0.1 хоста (см. compose-файлы) — расширяйте его на все интерфейсы только вместе с AWG_WEB_USER/AWG_WEB_PASS.

Технические особенности реализации

  • Работа с JSON-реестром клиентов и статистикой — нативно (encoding/json), без внешнего jq. jq всё ещё ставится install-deps (используется в ручной отладке конфигов), но в рантайме профилировщика не требуется.
  • awg (genkey/pubkey/genpsk/set/show) и qrencode вызываются как внешние бинарники.
  • Случайные значения (ключи, параметры обфускации) берутся из crypto/rand.
  • Определение публичного IP — нативный HTTP-клиент (IPv4-only), аналог curl -sf4.

Тесты

go test ./...