Help us shape the future of Go! Take the 2026 Go Developer Survey

qwdtt-cli

module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 14, 2026 License: GPL-3.0

README

qwdtt-cli

Консольный клиент к протоколу qWDTT: VPN поверх TURN-инфраструктуры звонков VK. Трафик уходит на ваш VPS через TURN-relay ВКонтакте и для сети выглядит как медиапоток звонка WebRTC, а не как подключение к VPN-серверу.

Это только клиент. Установка и настройка серверной части, панель управления, импорт подписок и сканирование QR остаются в Android-приложении qWDTT — здесь их нет и не будет. Чтобы подключиться, у вас уже должны быть адрес сервера, пароль подключения и хотя бы одна ссылка на звонок VK (хеш звонка) — те же, что вводятся в приложении. Либо ссылка qwdtt://config?… из приложения или от бота сервера: в ней всё это сразу.

Клиент работает на переднем плане: пока запущен tt connect, туннель поднят. Службы и автозапуска нет. Первый Ctrl+C останавливает туннель и убирает за собой, второй убивает процесс.

Быстрый старт без командной строки

Набирать команды не обязательно: tt, запущенный без аргументов, ведёт вопросами.

  1. Скачайте архив для своей системы (раздел «Установка») и распакуйте его.
  2. Запустите tt:
    • Windows — дважды щёлкните по tt.exe в распакованной папке. Откроется окно консоли с меню. Если Windows предупредит о программе из интернета — «Подробнее» → «Выполнить в любом случае».
    • Linux — откройте терминал в распакованном каталоге и наберите ./tt.
  3. Профиля ещё нет — меню предложит его создать (Enter). Дальше:
    • если у вас есть ссылка qwdtt://config?… (Android-приложение qWDTT → экспорт профиля, или бот сервера), вставьте её: адрес, пароль и ссылки на звонки tt возьмёт из неё. Ссылку при вставке не видно — так и задумано: в ней ваш пароль;
    • если ссылки нет, нажмите Enter и ответьте на вопросы: имя профиля (Enter — home), адрес сервера, пароль подключения (дважды) и ссылки на звонки VK. Адрес и пароль даёт тот, кто настроил сервер.
  4. Выберите, что пускать через туннель: весь трафик компьютера (Enter) или только программы, где указан прокси SOCKS5 127.0.0.1:1080. Первому режиму нужны права администратора — tt попросит их сам: на Windows появится окно «Разрешить этому приложению вносить изменения?», и подключение откроется в новом окне; на Linux sudo спросит пароль вашей учётной записи. Если ваша учётная запись Windows без прав администратора, tt скажет об этом и предложит второй режим.
  5. В меню нажмите Enter — «Подключиться». Когда в строке состояния появится «туннель работает», можно пользоваться интернетом.

Остановить — Ctrl+C (снова откроется меню) или закрыть окно. Выйти из меню — 0.

Ссылка на звонок VK выглядит как https://vk.com/call/join/…: такую ссылку даёт звонок VK, к которому присоединяются по ссылке. Обычно ссылки выдаёт тот же, кто дал пароль. Звонки со временем закрываются — тогда tt скажет, что ссылки больше не работают, и предложит ввести новые. Проверить ссылки и убрать закрытые можно и сами — пункт «Обновить ссылки на звонки VK». Там же, в меню, — другой профиль, новый пароль или адрес сервера, удаление профиля.

Если что-то пошло не так, окно, открытое двойным щелчком, само не закроется: ошибку можно прочитать, Enter закрывает окно. Запуск без человека — планировщик заданий, служба, вывод в файл — Enter не ждёт: tt завершается сразу.

Меню — это те же команды, что ниже; tt menu открывает его явно (для ярлыка). В скриптах и конвейерах tt без аргументов, как и раньше, печатает список команд.

Установка

Готовая сборка — архив tt_<версия>_windows_amd64.zip: распакуйте его целиком («Извлечь всё»). В нём каталог с тем же именем: tt.exe, wintun.dll с её лицензией wintun-LICENSE.txt, пример настроек tt.example.toml, лицензия, лицензии сторонних компонентов THIRD_PARTY_NOTICES.txt и этот файл. Установка не нужна. Режиму по умолчанию tun, который пускает через туннель весь трафик системы, нужны права администратора — из меню tt попросит их сам — и wintun.dll: она уже лежит в архиве и должна оставаться рядом с tt.exe.

Для Linux готовая сборка — архив tt_<версия>_linux_amd64.tar.gz. В нём каталог с тем же именем: tt, пример настроек, лицензия, THIRD_PARTY_NOTICES.txt и этот файл.

tar xzf tt_<версия>_linux_amd64.tar.gz

tt — один исполняемый файл, рядом с ним ничего не нужно; его можно переложить, например, в /usr/local/bin. Как собрать его самому — в разделе «Сборка и отладка под Linux». Права root (через sudo) нужны только режиму tun.

Сборка под Windows

Нужен Go 1.26 или новее, cgo не требуется. Из корня репозитория:

go build -o build\out\tt.exe ./cmd/tt

Этого достаточно для режимов socks и external. Режиму tun (свой сетевой адаптер, нужны права администратора) нужна ещё wintun.dll — библиотека драйвера Wintun от авторов WireGuard. В репозитории её нет: это чужой бинарь под своей лицензией. Скачать и проверить её можно скриптом, он кладёт DLL в build\out рядом с tt.exe:

pwsh scripts/fetch-wintun.ps1

Скрипт берёт фиксированную версию Wintun (сейчас 0.14.1) с wintun.net, сверяет SHA256 архива с зашитым в скрипт, проверяет подпись DLL (WireGuard LLC) и копирует wintun.dll вместе с её лицензией. Хеш не совпал или подпись не та — скрипт останавливается и ничего не копирует. Другая архитектура — -Arch arm64, другой каталог — -Dest <путь>, без сети — -Archive <путь к wintun-0.14.1.zip>.

Можно и вручную: скачайте wintun-0.14.1.zip с https://www.wintun.net, сверьте хеш

(Get-FileHash wintun-0.14.1.zip).Hash
07C256185D6EE3652E09FA55C0B673E2624B565E02C4B9091C79CA7D2F24EF51

и положите wintun\bin\amd64\wintun.dll рядом с tt.exe. DLL ищется только в каталоге tt.exe и в System32 — текущий каталог консоли и PATH не подходят. Без неё tt connect -datapath tun откажет сразу, до подключения: «рядом с tt нет файла wintun.dll».

Сборка и отладка под Linux

Сборка та же, Go 1.26 или новее, cgo не нужен:

go build -o build/out/tt ./cmd/tt

На Linux работают режимы socks и tun; external здесь не поддерживается. Режиму socks ничего, кроме самого tt, не нужно: ни прав root, ни системных пакетов. Режиму tun нужны sudo и ядро 5.12 или новее (подробности — в разделе «tun на Linux»). Утилиты ip и nft ему не нужны: адаптер, маршруты и правила tt ставит сам через netlink. Из системных программ он зовёт только resolvconf — если /etc/resolv.conf ведёт он.

Для отладки пригодятся пакеты (имена — для Debian и Ubuntu):

sudo apt install wireguard wireguard-tools iproute2 nftables tcpdump resolvconf
  • wireguard, wireguard-tools — модуль ядра и wg, wg-quick: сверить конфиг от сервера и поднять туннель вручную. Сам tt wireguard-go встраивает библиотекой, отдельный wireguard-go не нужен.
  • iproute2, nftables — ip route, ip rule, ss, nft: маршруты и правила при поднятом туннеле.
  • tcpdump — убедиться, что трафик и DNS идут через туннель, а не мимо.
  • resolvconf — без него wg-quick up падает на конфиге со строкой DNS =.

Если сетью управляет NetworkManager, после установки resolvconf файл /etc/resolv.conf становится ссылкой на /run/resolvconf/resolv.conf и до перезапуска NetworkManager остаётся без серверов — DNS на машине не работает. Чинится sudo systemctl restart NetworkManager.

Релиз

Релиз для трёх платформ собирает pwsh scripts/build-release.ps1 (из корня репозитория, нужен pwsh 7.3 или новее): zip для Windows и tar.gz для Linux и macOS. wintun.dll в zip для Windows он кладёт тем же fetch-wintun.ps1 (без сети — с -WintunArchive <путь>), а THIRD_PARTY_NOTICES.txt в каждый архив собирает go run ./scripts/notices — лицензии всех модулей, слинкованных в tt, и самого Go. Время файлов в tar.gz фиксированное, так что одинаковые файлы дают одинаковый архив. Модуль без файла лицензии или с нераспознанной лицензией останавливает сборку: новую зависимость надо разобрать вручную. Бинари для Linux и macOS собираются и запускаются. На Linux вживую проверены режимы socks и tun; на macOS работает только socks, и вживую он там ещё не проверялся.

Тот же скрипт запускает GitHub Actions (.github/workflows/release.yml) на Windows: на тег v* после тестов собирается релиз, проверяется, что в каждом архиве есть всё нужное для запуска и что tt.exe из zip запускается, и архивы вместе с SHA256SUMS.txt выкладываются черновиком в Releases — опубликовать его надо вручную. Ручной запуск workflow только собирает: архивы остаются артефактом прогона.

Быстрый старт в командной строке

  1. Заведите профиль. Пароль и хеши спрашиваются скрытым вводом; в файл настроек попадают только ссылки на хранилище секретов (на Windows — DPAPI, привязка к вашей учётной записи):

    tt profile set home -peer example.org:56000
    

    Или из ссылки qwdtt://config?…: команда спросит её скрытым вводом (в ссылке пароль, поэтому аргументом её не передать) или прочитает из stdin:

    tt profile import home
    tt profile import home < ссылка.txt
    

    Без имени профиль называется именем из ссылки латиницей. Профиль с таким именем уже есть — отказ, -replace заменяет в нём адрес, воркеры и секреты. -datapath socks сразу записывает режим. Чего в ссылке нет (пароля, хешей), спрашивается.

  2. Проверьте хеши и задержку до сервера. Обе команды не поднимают туннель:

    tt hashes
    tt ping
    

    hashes печатает по строке на хеш со статусом ok, captcha, dead, limited, network или error и возвращает код 1, если годных нет.

  3. Поднимите туннель. По умолчанию через него идёт весь трафик системы (режим tun), поэтому нужны права: на Windows — консоль от имени администратора, на Linux — sudo:

    tt connect
    sudo tt connect
    

    Через секунду-две в выводе появится == туннель работает. Проверить можно так: curl https://ifconfig.me покажет адрес сервера, а не ваш.

    Имя профиля можно опускать, если профиль один или назван в default_profile. Флаг перекрывает то же поле профиля на один запуск: tt connect home -workers 27. -v печатает весь лог ядра. На терминале внизу держится статусная строка с состоянием, аптаймом и счётчиками; при перенаправлении в файл её нет.

  4. Без прав администратора работает режим только для программ с прокси:

    tt connect -datapath socks
    

    В выводе появится [SOCKS] слушает 127.0.0.1:1080. Направьте на этот адрес браузер или приложение, которое умеет ходить через прокси SOCKS5, и проверьте:

    curl -x socks5h://127.0.0.1:1080 https://example.org/
    

    Можно и записать datapath = "socks" в профиль. На macOS режим socks — единственный и потому умолчание. Подробности — в разделе «Режимы доставки трафика».

Если VK попросит капчу, которую ядро не осилило само, на Windows откроется окно со страницей капчи: решите её, и окно закроется само, а tt продолжит. Срок написан в заголовке окна. Если окна не видно, оно может оказаться за консолью — поищите его на панели задач. Окну нужен WebView2 Runtime: он есть в Windows 11 и в актуальных Windows 10. Если Runtime нет, если tt запущен по SSH или система не Windows, в stderr вместо окна появится ссылка и инструкция: открыть её в браузере, решить, вставить токен. На это даётся три минуты. На Linux tt сам открывает ссылку в браузере (xdg-open), а под sudo — в браузере того пользователя, который вызвал sudo, а не root.

Файл настроек

profiles.toml лежит в каталоге настроек пользователя: на Windows это %APPDATA%\qwdtt-cli\, рядом — secrets.json с зашифрованными секретами. На Linux и macOS — $XDG_CONFIG_HOME/qwdtt-cli/ (обычно ~/.config), секреты там не шифруются и защищены правами 0600 на файл. Под sudo tt берёт каталог того, кто вызвал sudo (~/.config/qwdtt-cli/ его домашнего каталога, а не root), и созданные файлы оставляет ему во владение. Другой путь — флаг -config. Файл правится командами tt profile set и tt profile import, меню или руками, пример со всеми полями и пояснениями — tt.example.toml.

Поле Что задаёт По умолчанию
peer адрес сервера host:port обязательно
password_ref, vk_hashes_ref ссылки на секреты, пишет tt profile set обязательно
workers число воркеров, кратно девяти, потолок 108 9
obfs RTP-маскировка: audio или video audio
turn_transport udp или tcp; TCP помогает там, где душат UDP udp
dtls DTLS поверх TURN; false требует сервера с -listen-direct true
dns резолвер для доменов VK: yandex, cloudflare, google, doh-*, custom:IP, doh:URL yandex
datapath как отдавать трафик: socks, tun или external tun (на macOS — socks)
kill_switch в tun и external блокировать трафик системы, пока туннель не поднят (раздел «Kill-switch») true
[profile.<имя>.socks] listen адрес локального SOCKS5 127.0.0.1:1080

Секреты просматриваются только замаскированными (tt profile show), удаляются вместе с профилем (tt profile rm) и перезаписываются по tt profile set <имя> -password или -hashes. Аргументом командной строки их передать нельзя намеренно.

Режимы доставки трафика

Режим задаёт поле datapath профиля или флаг -datapath. Прежнее имя режима tun — wintun — тоже принимается: старые профили и команды работают как раньше.

Режим Что идёт через туннель Права Что нужно Системы
socks программы, настроенные на прокси SOCKS5 не нужны ничего Windows, Linux, macOS
tun весь трафик системы администратор, на Linux — root (sudo) Windows — wintun.dll рядом с tt.exe, Linux — ядро 5.12+ Windows, Linux
external весь трафик системы администратор установленный WireGuard для Windows Windows
socks

Режим без прав администратора (на macOS — единственный и умолчание): WireGuard целиком внутри процесса и локальный SOCKS5 над ним. Прав администратора не нужно, устанавливать ничего не нужно. Ограничения: только TCP, только IPv4, только приложения, которые умеют ходить через прокси; DNS-запросы приложения уйдут мимо туннеля, если оно не проксирует их само (в curl для этого socks5h, в браузерах — настройка «DNS через прокси»).

tun — весь трафик системы

Режим по умолчанию на Windows и Linux. tt создаёт свой сетевой адаптер tt — на Windows на драйвере Wintun от авторов WireGuard, на Linux через /dev/net/tun, — а сам WireGuard работает внутри процесса tt: ставить ничего не нужно. Нужны права: на Windows — консоль от имени администратора, на Linux — sudo; адаптер, маршруты и фильтры без них не создать. Без прав tt откажет сразу, до подключения, и предложит -datapath socks. На Windows без wintun.dll рядом с tt.exe он откажет с сообщением «рядом с tt нет файла wintun.dll» (как её получить при сборке из исходников — в разделе «Сборка под Windows»). Что на Linux устроено иначе — в разделе «tun на Linux».

Пока туннель поднят:

  • адаптер tt получает адрес и DNS-серверы, которые выдал сервер; если DNS сервер не прислал — 1.1.1.1;
  • весь трафик забирают маршруты 0.0.0.0/1 и 128.0.0.0/1 через tt (для IPv6 — ::/1 и 8000::/1). Маршрут по умолчанию остаётся на месте: половины выигрывают у него длиной префикса;
  • собственные соединения tt — с VK, с DNS для доменов VK и с TURN-relay — привязаны к физическому адаптеру и идут мимо туннеля, иначе туннель зависел бы от самого себя. Какой адаптер выбран, tt пишет строкой netguard: …; с -v видно каждое такое соединение строкой [NETGUARD] … → интерфейс N;
  • DNS-запросы системы идут только к DNS-серверам туннеля (раздел «Защита DNS»).

Пока туннель не поднят — до первого подъёма и между попытками, — трафик системы заблокирован, кроме локальной сети (раздел «Kill-switch»).

Маршруты всегда забирают всё адресное пространство, что бы сервер ни выдал в AllowedIPs. Если сервер разрешил не всё, трафик к остальным адресам уходит в туннель и там отбрасывается, а не идёт тихо мимо него; об этом предупреждает строка [TUN] Внимание: сервер разрешил в туннеле не весь IPv4 (AllowedIPs: …).

Адаптер живёт, пока работает tt connect: переподключения его не пересоздают, и Windows не заводит «Сеть 2», «Сеть 3». Второй tt connect -datapath tun на той же машине откажет сразу: «адаптер уже занят: на этой машине работает другой tt с datapath tun».

tun на Linux
sudo tt connect -datapath tun

Профили и секреты под sudo берутся из каталога того, кто вызвал sudo (раздел «Файл настроек»), так что заводить их заново для root не нужно.

Ядро. Нужно ядро 5.12 или новее: защита DNS держится на таблице nftables с флагом owner, который появился в 5.12. Ядро само удаляет такую таблицу вместе с процессом tt, даже если его убили. Модуль tun нужен тоже, но он есть почти везде.

Обратный фильтр (rp_filter). Собственные соединения tt привязаны к физическому интерфейсу, а маршруты /1 ведут в tt. Строгий обратный фильтр (rp_filter = 1) считает ответы VK и TURN на физический интерфейс подделкой и отбрасывает их, так что туннель не поднялся бы. Поэтому при строгом фильтре tt откажет до подключения и подскажет команду:

sudo sysctl -w net.ipv4.conf.<интерфейс>.rp_filter=2

Нестрогий режим (2) проверяет только, что обратный маршрут вообще есть. Сам tt sysctl не меняет: такая правка пережила бы его падение. Чтобы она сохранилась после перезагрузки, запишите её файлом в /etc/sysctl.d/. Действует большее из значений all и самого интерфейса.

firewalld. У firewalld по умолчанию строгая проверка обратного пути для IPv6 (IPv6_rpfilter). Она отбрасывала бы ответы IPv6 соединениям tt, поэтому при работающем firewalld tt ходит к VK и TURN только по IPv4 и пишет об этом строкой netguard: сокеты ядра — только IPv4: …. Трафика системы в туннеле это не касается.

DNS туннеля. Как задать системе DNS туннеля, tt решает по тому, кто ведёт /etc/resolv.conf, и печатает выбор строкой DNS системы: …:

Кто ведёт resolv.conf Что делает tt После Ctrl+C
systemd-resolved DNS и домен ~. на линке tt по D-Bus уходят вместе с адаптером
Debian resolvconf запись tun.tt запись удаляется
openresolv запись tun.tt в монопольном режиме запись удаляется
никто (обычный файл) перезаписывает файл, прежний — в /etc/resolv.conf.tt-backup файл возвращается из копии

Если resolv.conf — ссылка на незнакомый генератор, tt откажет до подключения: перезаписать такой файл значило бы сломать его владельцу. Debian resolvconf монопольного режима не умеет, поэтому в resolv.conf вслед за DNS туннеля остаются и прежние серверы. Утечки через них нет: запросы к ним отклоняет защита DNS (если tt не запущен с -allow-leak и она не отказала). Если обычный файл написала другая программа (заголовок # Generated by …), tt предупредит: когда она перепишет файл, например при смене сети, DNS туннеля пропадёт до следующего переподключения.

Корпоративный VPN. Если рядом поднят другой VPN с маршрутами к конкретным сетям, его маршруты конкретнее половин /1 и остаются за ним. А вот DNS системы при поднятом tt — только туннельный: внутренние имена такого VPN не разрешаются, пока работает tt, и снова разрешаются после его остановки.

Контейнеры. Защита DNS действует и на пересылаемый трафик: контейнеры docker и виртуальные машины за NAT хоста тоже не дойдут до чужого DNS мимо туннеля.

external

Конфиг от сервера передаётся штатному WireGuard для Windows: wireguard.exe /installtunnelservice ставит службу туннеля, при остановке она снимается. Нужны установленный WireGuard и консоль от имени администратора. Пока туннель поднят, служба видна в services.msc как «WireGuard Tunnel: tt», а её конфиг с приватным ключом лежит в %APPDATA%\qwdtt-cli\tt.conf: служба читает его при запуске. При остановке tt снимает службу и удаляет файл.

Собственные соединения tt идут мимо туннеля, как и в tun. Маршрут по умолчанию из конфига сервера (AllowedIPs = 0.0.0.0/0, ::/0) tt записывает в tt.conf двумя половинами (0.0.0.0/1, 128.0.0.0/1): охват тот же, но с /0 штатный WireGuard включил бы свой kill-switch и отрезал бы соединения tt. Вместо него работает kill-switch самого tt (раздел «Kill-switch»), а DNS защищает сам tt, как в tun. Если сервер выдал маршрут только для IPv4, tt дописывает и половины IPv6 — раздел «IPv6».

Если нет причин держаться за штатный WireGuard, берите tun: он не ставит службу и не пишет на диск файл с приватным ключом.

IPv6

Если сервер выдал адрес только IPv4, IPv6 машины не идёт мимо туннеля с вашим настоящим адресом, а блокируется: маршруты ::/1 и 8000::/1 ведут в туннель, и там такие пакеты отбрасываются. Так в обоих режимах полного туннеля; в external tt дописывает эти половины в tt.conf и пишет об этом строкой [WG-EXT] сервер не выдал маршрута IPv6: ….

На Linux есть особый случай. Ядро не держит IPv6 на интерфейсе с MTU меньше 1280, поэтому если сервер выдал такой MTU, маршрутов IPv6 на tt нет. Тогда IPv6 системы закрывает таблица nftables защиты DNS (строка [TUN] IPv6 системы, кроме loopback и сокетов tt, закрыт защитой DNS). Если защита не включилась и tt запущен с -allow-leak, закрыть его нечем: tt предупредит, и IPv6 пойдёт мимо туннеля.

Если IPv6 у вашего провайдера нет, ничего не меняется. Если есть, у блокировки есть цена. Браузеры и большинство современных программ пробуют IPv6 и IPv4 параллельно и за доли секунды переходят на IPv4 — разницы не видно. Программа, которая перебирает адреса по очереди и начинает с IPv6, будет ждать таймаута соединения, иногда десятки секунд, и только потом попробует IPv4. Если это мешает, отключите IPv6 у физического адаптера на время работы туннеля.

Защита DNS

Windows рассылает DNS-запросы и резолверам других адаптеров, не только туннеля, — без защиты имена посещаемых сайтов уходили бы провайдеру. Поэтому в tun и external, пока туннель поднят, tt ставит фильтры брандмауэра Windows (WFP): обращения на порт 53, UDP и TCP, разрешены только к DNS-серверам туннеля, к loopback и самому tt — ему нужен DNS для доменов VK мимо туннеля. В выводе это строка «защита DNS: пока туннель поднят, DNS системы — только к резолверам туннеля».

  • Программа со своим резолвером, которая обращается на порт 53 к другому серверу, пока туннель поднят, получит отказ. Это и есть защита.
  • DNS поверх HTTPS у браузеров идёт на порт 443, фильтр его не трогает, но идёт он по маршрутам через туннель — мимо туннеля не уходит.
  • dns = "doh:URL" с именем хоста в адресе: имя самого DoH-сервера tt разрешает системным резолвером. С kill-switch это не работает: пока туннель не поднят, системный DNS закрыт, и tt не найдёт свой DoH-сервер. Пишите в адресе IP (doh:https://1.1.1.1/dns-query) или берите пресеты doh-*: они начинаются с адресов, и их это не касается.

Фильтры живут в динамической сессии WFP: система снимает их вместе с процессом, даже если tt убит. Если поставить их не удалось (например, остановлена служба базовой фильтрации, BFE), tt откажет до подключения.

На Linux то же делает таблица nftables inet tt: порт 53 открыт только к DNS-серверам туннеля и loopback, для исходящего и для пересылаемого трафика (контейнеры, ВМ). Собственные запросы tt к DNS для доменов VK таблица узнаёт по метке сокета (SO_MARK), а не по пользователю. Под sudo правило «root может всё» пропустило бы любую программу root. UDP мимо туннеля отклоняется сразу (Operation not permitted), TCP ждёт таймаута. Таблица создана с флагом owner: ядро удаляет её вместе с процессом, даже убитым.

Флаг -allow-leak разрешает подключиться без защиты — только на этот запуск, в профиль он не записывается. Прежнее имя флага, -allow-dns-leak, тоже принимается.

Kill-switch

В tun и external, пока туннель не поднят, трафик системы заблокирован — до первого подъёма и всё время, пока туннель переподключается. Иначе он уходил бы мимо туннеля с вашим настоящим адресом, а DNS — к резолверам провайдера. Kill-switch включён по умолчанию.

Пока туннель не поднят, разрешены:

  • сам tt — ему нужно добраться до VK и TURN;
  • loopback;
  • DHCP (IPv4 и IPv6) и обнаружение соседей IPv6 — без них сеть машины разваливается;
  • локальная сеть: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16, fe80::/10, fc00::/7, мультикаст и широковещание. Роутер, принтер и NAS остаются доступны.

Порт 53 закрыт и в локальной сети: резолвер роутера отправил бы запросы провайдеру. Остальное отклоняется: UDP — сразу (на Linux — Operation not permitted), TCP ждёт таймаута. На Linux закрыт и пересылаемый трафик — контейнеры docker и виртуальные машины за NAT хоста. Корпоративный VPN отдельно не пропускается: его соединение с сервером оборвётся и восстановится, когда туннель поднимется.

Когда туннель поднят, kill-switch ничего не блокирует — работает только защита DNS. Программы, которые сами привязываются к физическому адаптеру, и маршруты конкретнее половин /1 (например, к серверу корпоративного VPN) работают как без tt.

В выводе это видно так:

kill-switch: пока туннель не поднят, трафик системы заблокирован
…
туннель переподключается — трафик системы заблокирован (kill-switch)
…
туннель снова поднят — трафик системы идёт через него

Капча. При переподключении VK может попросить капчу. На Windows с WebView2 окно капчи ходит в сеть через локальный прокси tt — только к доменам VK и только на порт 443, — и kill-switch при этом не снимается. В ручном режиме (Linux, Windows без WebView2 или по SSH) страница капчи открывается в вашем браузере, а пропустить мимо блокировки один браузер нельзя. Поэтому на время ручной капчи — от ссылки до ответа — kill-switch снимается, и трафик системы идёт мимо туннеля:

kill-switch снят на время капчи — трафик системы идёт мимо туннеля
…
kill-switch возвращён: пока туннель не поднят, трафик системы заблокирован

Если прокси для окна не поднялся, tt пишет «окно капчи пойдёт в сеть само» и тоже снимает kill-switch на время капчи.

Если tt упал или убит, правила kill-switch уходят вместе с процессом, как фильтры защиты DNS: машина не остаётся без сети, но и не защищена — трафик идёт напрямую. Постоянной блокировки, которая пережила бы tt, нет намеренно.

Как выключить. На один запуск — флаг -no-kill-switch, насовсем — kill_switch = false в профиле или tt profile set <имя> -kill-switch=false. Без kill-switch, пока туннель переподключается, трафик и DNS системы идут мимо туннеля: tt снимает маршруты и защиту DNS, иначе страница капчи не загрузилась бы. Это видно строками

маршруты сняты на время переподключения — трафик и DNS системы идут мимо туннеля
…
маршруты возвращены — трафик системы снова идёт через туннель

Обычно это секунды — одна попытка и задержка перед следующей, от 1 до 64 с. Дольше — когда пропала сеть или VK несколько минут не выдаёт новых каналов TURN (с -v видно Allocation Quota Reached).

Если kill-switch не включился (например, на Windows остановлена служба базовой фильтрации, BFE), tt откажет до подключения. Подключиться без него — -no-kill-switch или -allow-leak (на один запуск). Если правила откажут посреди сеанса, tt пишет «Внимание: kill-switch не встал: …», и до подъёма туннеля трафик идёт мимо него.

Если tt упал или был убит

Первый Ctrl+C останавливает туннель и убирает за собой всё. Второй Ctrl+C, taskkill /F, kill -9 или падение убрать не дают, и тогда:

  • tun — адаптер tt, маршруты через него, фильтры DNS и kill-switch исчезают вместе с процессом: адаптер снимает драйвер Wintun, фильтры — система. Убирать вручную нечего, новый tt connect можно запускать сразу. Остаётся только запись реестра с DNS бывшего адаптера (HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{GUID}): адаптера нет, поэтому ни на что она не влияет, а следующий запуск её перезапишет.
  • tun на Linux — адаптер tt с маршрутами и таблица inet tt (защита DNS и kill-switch) исчезают вместе с процессом. Остаётся DNS туннеля в системе: запись tun.tt у resolvconf или перезаписанный /etc/resolv.conf с копией .tt-backup (у systemd-resolved настройки уходят вместе с адаптером). DNS при этом работает — запросы идут к тем же серверам, но уже напрямую, мимо туннеля. Следующий tt connect -datapath tun убирает остаток сам и пишет об этом: «DNS системы: запись tun.tt прошлого запуска tt снята» или «прежний resolv.conf возвращён из /etc/resolv.conf.tt-backup». Вручную — sudo resolvconf -d tun.tt или sudo mv /etc/resolv.conf.tt-backup /etc/resolv.conf.
  • external — служба и файл конфига могли остаться, и тогда весь трафик по-прежнему идёт в туннель, которого уже нет. Снимите службу командой wireguard.exe /uninstalltunnelservice tt и удалите %APPDATA%\qwdtt-cli\tt.conf. Фильтры DNS и kill-switch система сняла сама.

Что осталось в системе, показывает снимок go run ./scripts/checktunnel (раздел «Отладка»).

Восстановление

При обрыве клиент переподключается сам с нарастающей задержкой: 1, 2, 4 … 64 с. В режимах tun и external tt ещё и следит за сетью. Смена сети — другой Wi-Fi, кабель вместо Wi-Fi — перезапускает подключение сразу, без задержки, строкой «сеть сменилась: …». Если сеть пропала, tt пишет «сеть пропала — туннель переподключится, когда она вернётся» и перезапускает подключение, как только она вернётся.

Хеш, по которому VK отвечает «звонок закрыт», исключается из перебора; когда годных не остаётся, клиент останавливается с ошибкой — заведите новые через tt profile set <имя> -hashes.

Отладка

  • -v — весь лог ядра и строка [NETGUARD] на каждое соединение tt мимо туннеля. Строки [TUN] и [WG-EXT] печатаются и без него.
  • TT_WG_DEBUG=1 — подробный лог самого WireGuard: рукопожатия, ошибки приёма. В PowerShell: $env:TT_WG_DEBUG = 1; tt connect -v. На Linux под sudo переменную надо передать явно: sudo env TT_WG_DEBUG=1 tt connect -datapath tun -v.
  • go run ./scripts/checktunnel — снимок системы, запускается из исходников. Windows и Linux. Показывает процессы tt, адаптеры, маршруты /0 и /1, внешний адрес без прокси, кто отвечает на DNS; на Windows ещё фильтры WFP (без прав администратора их нет), записи реестра, службу и tt.conf режима external, на Linux — правила маршрутизации, таблицы nftables (только под sudo), resolv.conf и записи resolvconf, rp_filter. Ничего не меняет; снимки до запуска, во время и после остановки удобно сравнивать.

Предупреждения

Релизные бинари не подписаны. Windows SmartScreen и антивирусы могут возражать против программы, которая держит сетевой туннель, — это ожидаемо до появления подписи. Исходники открыты, сборка воспроизводима скриптом из репозитория.

Лицензия

GNU General Public License v3.0 — см. LICENSE.

Проект включает исходный код qWDTT и распространяется на тех же условиях.

Directories

Path Synopsis
cmd
tt command
Command tt — консольный клиент qWDTT для настольных систем.
Command tt — консольный клиент qWDTT для настольных систем.
internal
captcha
manual.go — консольный решатель (задача E2): тот, который работает всегда.
manual.go — консольный решатель (задача E2): тот, который работает всегда.
cli
connect.go — команда tt connect.
connect.go — команда tt connect.
config
Package config читает profiles.toml — файл с настройками подключения.
Package config читает profiles.toml — файл с настройками подключения.
datapath
Package datapath отвечает за то, каким способом трафик приложений попадает в туннель.
Package datapath отвечает за то, каким способом трафик приложений попадает в туннель.
linuxsys
Package linuxsys — системная часть Linux для Э4: выбор физического интерфейса и подписка на смену сети (plan-e4.md, блок N), дальше — адаптер, маршруты и DNS.
Package linuxsys — системная часть Linux для Э4: выбор физического интерфейса и подписка на смену сети (plan-e4.md, блок N), дальше — адаптер, маршруты и DNS.
netguard
Package netguard уводит собственные сокеты ядра мимо туннеля (architecture.md §05, дорожка 2).
Package netguard уводит собственные сокеты ядра мимо туннеля (architecture.md §05, дорожка 2).
sudo
Package sudo узнаёт, от чьего имени tt запущен через sudo.
Package sudo узнаёт, от чьего имени tt запущен через sudo.
supervisor
lifecycle.go — цикл подключения (задача F3): то единственное место в супервизоре, где есть время, горутины и внешний мир.
lifecycle.go — цикл подключения (задача F3): то единственное место в супервизоре, где есть время, горутины и внешний мир.
winsys
Package winsys — системная часть Windows для Э2: выбор физического интерфейса, маршруты, DNS и подписка на смену сети (architecture.md §09).
Package winsys — системная часть Windows для Э2: выбор физического интерфейса, маршруты, DNS и подписка на смену сети (architecture.md §09).
scripts
checktunnel command
Общее для снимков Windows и Linux: разделы, маршруты /0 и /1, внешний адрес и резолвер.
Общее для снимков Windows и Linux: разделы, маршруты /0 и /1, внешний адрес и резолвер.
notices command
Команда notices собирает THIRD_PARTY_NOTICES.txt — лицензии всего, что слинковано в tt.
Команда notices собирает THIRD_PARTY_NOTICES.txt — лицензии всего, что слинковано в tt.
outage command
Команда outage устраивает обрыв связи на время — для живых проверок переподключения tt (plan-e4.md, R1 и R2; на Windows — plan-e2.md, S1).
Команда outage устраивает обрыв связи на время — для живых проверок переподключения tt (plan-e4.md, R1 и R2; на Windows — plan-e2.md, S1).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL