# wswg Простой менеджер WireGuard + wstunnel. Один статический Go-бинарник, встроенный GUI без JS-фреймворков и терминальное меню. GUI открывается в локальном браузере, не требует GTK, Qt, WebView или интернета. Закрытие вкладки не останавливает VPN; для отключения нажмите Disconnect или завершите процесс Ctrl+C. ## Запуск Распакуйте **весь** ZIP, сохраняя папки `bin/` и `redist/` рядом с программой. ```sh ./wswg # DISPLAY/WAYLAND_DISPLAY: GUI, иначе TUI; Windows: GUI ./wswg -t # принудительно TUI ./wswg -g # принудительно GUI ./wswg -c 1 # подключить первый конфиг, обновлять строку статуса ./wswg -c 'Home' # подключить по имени ./wswg -a # подключить последний успешно использованный конфиг ./wswg -a -d # то же в фоне ./wswg -c 1 -d # конкретный конфиг в фоне ./wswg -a --no-wstunnel # последний конфиг напрямую, не меняя сохранённые настройки ./wswg -c Home -d --no-wstunnel # тот же временный override для демона ./wswg --data-dir /path # отдельное хранилище ``` Короткие флаги имеют длинные варианты: `--tui`, `--gui`, `--config`, `--auto`, `--daemon`. `-d` без `-a` или `-c` считается ошибкой. `--no-wstunnel` требует `-a` или `-c`, действует на один запуск и не сохраняет изменение в профиль. `-t` и `-g` несовместимы. `-a` и `-c` запускают подключение со строкой статуса вместо меню. Нужны root на Linux/Android и Administrator на Windows. Запускайте приложение сразу с этими правами. Хранилище по умолчанию: `os.UserConfigDir()/wswg`, обычно `~/.config/wswg` на Linux, `%AppData%\wswg` на Windows. При запуске через sudo укажите `--data-dir`, чтобы использовать ту же папку. Конфиги содержат приватные ключи и сохраняются с правами 0600, каталог 0700. На Windows доступ регулирует ACL пользовательского профиля, не кладите data-dir в общедоступную папку. ## Конфиги и интерфейс New → вставить WireGuard-конфиг → Save → Connect. Редактирование и удаление подключённого профиля запрещено. WireGuard-конфиги с PreUp, PostUp, PreDown, PostDown и SaveConfig не поддерживаются: приложение не исполняет конфиги как код. Сохранённый оригинал не меняется при подключении. Галочка DNS определяет, попадёт ли DNS в рабочую копию. В TUI выберите номер профиля, затем номер операции. WireGuard открывается через `$EDITOR`, иначе `nano`. Допускаются аргументы и путь в кавычках, например `EDITOR='"/path with spaces/editor" --wait'`. После подключения статус обновляется в одной строке. Enter возвращает в меню, соединение остаётся активным. Статус: адрес сервера, возраст последнего WireGuard-handshake в секундах, ICMP ping, `Packet loss: N%`. Один ICMP-запрос в секунду с таймаутом 950 мс; процент округляется до ближайшего целого по последним 100 попыткам. До 100 попыток используются имеющиеся результаты. Окно сбрасывается при подключении. Если сервер блокирует ICMP, потеря будет 100%, даже если VPN работает. `Connected` означает поднятый интерфейс; успешный handshake показывается отдельно. ## wstunnel Поле IP/host задаёт адрес **wstunnel-сервера**. Пустое поле берёт host из WG Endpoint. Порт по умолчанию 443. HTTPS включает `wss://`, выключенный переключатель использует `ws://`. Как в стандартном wstunnel, допускаются self-signed TLS сертификаты; аутентификацию VPN обеспечивает ключ WireGuard. На сервере должен быть запущен wstunnel, например: ```sh wstunnel server --restrict-to 127.0.0.1:51820 wss://0.0.0.0:443 ``` UDP на серверной стороне направляется на `127.0.0.1:<порт исходного WG Endpoint>`. То есть wstunnel и WireGuard должны находиться на одной машине или в одном сетевом namespace. Режим wstunnel поддерживает один Peer на профиль. На клиенте Endpoint временно заменяется на локальный UDP-порт. До подъёма WG добавляется отдельный маршрут до wstunnel, после отключения удаляются только маршруты, созданные приложением. Для доменного имени сохраняются TLS SNI и HTTP Host. При проблемах с MTU попробуйте `MTU = 1280` в секции Interface. ## Системные требования * Linux: ядро с WireGuard, `bash`, `iproute2`, `ping`, `nft` либо `iptables` для полного туннеля. Для включённого DNS нужен `resolvconf`. `wg` и `wg-quick` включены в архив. Пример для Debian: `apt install iproute2 iputils-ping nftables openresolv bash`. Root без сетевых capabilities в контейнере не хватит. * Windows: Administrator. Официальные `wireguard.exe` и `wg.exe` включены в архив; WireGuard устанавливает подписанный драйвер через tunnel service. В `redist/` лежит VC++ Redistributable своей архитектуры. При коде отсутствующей runtime 0xC0000135/0xC000007B он устанавливается автоматически и запуск повторяется один раз. Другие ошибки не запускают установку. Сам Go-бинарник не требует VC++. * Termux: root и Android-ядро с WireGuard. `pkg install bash iproute2 nano iputils`. Статические Linux ELF для ARMv7 и ARM64 не требуют Bionic/NDK. Запускайте из Termux через root-окружение с сохранением PATH, например `su -c 'PATH=/data/data/com.termux/files/usr/bin:/system/bin /полный/путь/wswg -t --data-dir /полный/путь/data'`. В Android нет обычного resolvconf: отключите DNS из конфига и настройте DNS средствами системы. Доступность маршрутов и root зависит от прошивки. Для надёжности в Termux используйте числовые IP, Linux resolver не использует Android DNS API. Процесс должен работать всё время подключения. Ctrl+C/SIGTERM отключает туннель, останавливает wstunnel и удаляет временный конфиг. SIGKILL/отключение питания не дают выполнить очистку; при необходимости удалите интерфейс командой `bin/wg-quick down /wswg0.conf` или удалите Windows tunnel service. Параллельные подключения не поддерживаются, интерфейс называется `wswg0`. Фоновый процесс пишет в `daemon.log`; его PID выводится при запуске. Для остановки используйте `kill ` на Linux или завершите процесс Windows. ## Автозапуск * Autorun в GUI автоматически подключает последний профиль при следующем обычном запуске GUI. Флаг `-a` действует независимо от этой галочки. * On boot на Linux создаёт `/etc/systemd/system/wswg.service`, включает его через `systemctl enable` и запускает приложение с `-a`. Нужен работающий systemd. Файлы программы и data-dir должны оставаться на постоянном месте. * В Windows On boot создаёт задачу `wswg` в Task Scheduler от SYSTEM с ONSTART. * В TUI Settings содержит только On boot. На системах без systemd настройка возвращает ошибку и не записывает фиктивное состояние. * Сначала подключите профиль вручную, чтобы сохранить последний выбор. On boot вступает в силу при следующей загрузке. Выключение галочки отменяет будущий автозапуск, текущую сессию можно отключить кнопкой Disconnect. ## Сборка Go 1.24+, Python 3.11+, make, gcc, cross GCC для arm-linux-gnueabi, arm-linux-gnueabihf и aarch64-linux-gnu, 32-битные заголовки gcc, `msiextract`. На Debian: `apt install --no-install-recommends build-essential gcc-arm-linux-gnueabi gcc-arm-linux-gnueabihf gcc-aarch64-linux-gnu libc6-dev-i386 lib32gcc-12-dev msitools`. ```sh ./scripts/build.sh # Только приложение, без загрузки и сборки сторонних инструментов: SKIP_BUNDLE=1 ./scripts/build.sh # После осознанного обновления зависимостей, записать новые SHA-256: UPDATE_LOCK=1 ./scripts/build.sh # На сервере с уже настроенным html_plans.t.snw.su: python3 scripts/publish.py 0.1.0 ``` `dist/` содержит папки и ZIP для Linux amd64, 386, ARMv6, ARMv7, ARM64; Windows amd64, x86, ARM64; Termux ARMv7, ARM64. ARMv8 здесь ARM64. Windows ARM32 не поддерживается Go. `wswg-all.zip` содержит все платформенные ZIP, `SHA256SUMS` позволяет проверить целостность. Бинарники Go и Linux wg статические, wstunnel берётся из официальных Linux-сборок и проверяется по upstream checksums. Библиотеки системных утилит и браузер принадлежат ОС, они не встраиваются. ```sh go test -race ./... go vet ./... # Необязательный локальный тест настоящего handshake, нужны root/CAP_NET_ADMIN: sudo python3 scripts/integration.py ```