README
¶
qwdtt-cli
Консольный клиент к протоколу qWDTT: VPN поверх TURN-инфраструктуры звонков VK. Трафик уходит на ваш VPS через TURN-relay ВКонтакте и для сети выглядит как медиапоток звонка WebRTC, а не как подключение к VPN-серверу.
Это только клиент. Установка и настройка серверной части, панель управления, импорт
подписок и сканирование QR остаются в Android-приложении
qWDTT — здесь их нет и не будет.
Чтобы подключиться, у вас уже должны быть адрес сервера, пароль подключения и хотя бы
одна ссылка на звонок VK (хеш звонка) — те же, что вводятся в приложении. Либо ссылка
qwdtt://config?… из приложения или от бота сервера: в ней всё это сразу.
Клиент работает на переднем плане: пока запущен tt connect, туннель поднят.
Службы и автозапуска нет. Первый Ctrl+C останавливает туннель и убирает за собой,
второй убивает процесс.
Быстрый старт без командной строки
Набирать команды не обязательно: tt, запущенный без аргументов, ведёт вопросами.
- Скачайте архив для своей системы (раздел «Установка») и распакуйте его.
- Запустите
tt:- Windows — дважды щёлкните по
tt.exeв распакованной папке. Откроется окно консоли с меню. Если Windows предупредит о программе из интернета — «Подробнее» → «Выполнить в любом случае». - Linux — откройте терминал в распакованном каталоге и наберите
./tt.
- Windows — дважды щёлкните по
- Профиля ещё нет — меню предложит его создать (Enter). Дальше:
- если у вас есть ссылка
qwdtt://config?…(Android-приложение qWDTT → экспорт профиля, или бот сервера), вставьте её: адрес, пароль и ссылки на звонки tt возьмёт из неё. Ссылку при вставке не видно — так и задумано: в ней ваш пароль; - если ссылки нет, нажмите Enter и ответьте на вопросы: имя профиля (Enter —
home), адрес сервера, пароль подключения (дважды) и ссылки на звонки VK. Адрес и пароль даёт тот, кто настроил сервер.
- если у вас есть ссылка
- Выберите, что пускать через туннель: весь трафик компьютера (Enter) или только
программы, где указан прокси SOCKS5
127.0.0.1:1080. Первому режиму нужны права администратора — tt попросит их сам: на Windows появится окно «Разрешить этому приложению вносить изменения?», и подключение откроется в новом окне; на Linuxsudoспросит пароль вашей учётной записи. Если ваша учётная запись Windows без прав администратора, tt скажет об этом и предложит второй режим. - В меню нажмите 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: сверить конфиг от сервера и поднять туннель вручную. Самttwireguard-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 только собирает: архивы остаются артефактом
прогона.
Быстрый старт в командной строке
-
Заведите профиль. Пароль и хеши спрашиваются скрытым вводом; в файл настроек попадают только ссылки на хранилище секретов (на 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сразу записывает режим. Чего в ссылке нет (пароля, хешей), спрашивается. -
Проверьте хеши и задержку до сервера. Обе команды не поднимают туннель:
tt hashes tt pinghashesпечатает по строке на хеш со статусомok,captcha,dead,limited,networkилиerrorи возвращает код 1, если годных нет. -
Поднимите туннель. По умолчанию через него идёт весь трафик системы (режим
tun), поэтому нужны права: на Windows — консоль от имени администратора, на Linux —sudo:tt connect sudo tt connectЧерез секунду-две в выводе появится
== туннель работает. Проверить можно так:curl https://ifconfig.meпокажет адрес сервера, а не ваш.Имя профиля можно опускать, если профиль один или назван в
default_profile. Флаг перекрывает то же поле профиля на один запуск:tt connect home -workers 27.-vпечатает весь лог ядра. На терминале внизу держится статусная строка с состоянием, аптаймом и счётчиками; при перенаправлении в файл её нет. -
Без прав администратора работает режим только для программ с прокси:
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). |