qWDTT — это улучшенный форк оригинального проекта WDTT (WireGuard over TURN Tunnel). Приложение разработано для создания защищённого WireGuard-туннеля поверх TURN/DTLS. Клиент поднимает локальный VPN-интерфейс на устройстве, получает WireGuard-конфигурацию от вашего VPS и передаёт транспорт через TURN-серверы VK, маскируя трафик под обычный зашифрованный медиапоток звонка (WebRTC).
Проект получил обновленный современный интерфейс, поддержку виджетов на главном экране, плитки быстрого доступа (Quick Settings Tile) и исправления критических багов оригинального клиента.
- Добавлена возможность создавать и сохранять профили.
- Быстрое переключение между конфигурациями.
- Проверка пинга до серверов (ICMP с автоматическим TCP-fallback).
- График скорости сети в реальном времени.
- Добавлен виджет для быстрого запуска туннеля.
- Добавлен пункт быстрых действий в шторке Android для подключения/отключения туннеля.
- Создана отдельная вкладка настроек.
- Улучшена стр��ктура параметров приложения.
- Исправлены баги.
- Общие улучшения стабильности и UX.
Добавлена поддержка импорта через:
- ссылку;
- QR-код;
- конфигурационный файл.
Приложение поддерживает автоматическое распознавание и импорт конфигураций из QR-кодов, файлов и специальных ссылок.
Вы можете импортировать профиль, открыв ссылку или отсканировав QR-код со следующей схемой:
qwdtt://config?name=ИмяПрофиля&peer=IP_Сервера:Порт&hashes=ХешиЗвонка&workers=18&port=9000&pass=ПарольТуннеля
Параметры ссылки:
name— название профиля в приложении.peer— IP-адрес или домен вашего VPS с портом DTLS (например,192.168.1.1:56000).hashes— один или несколько VK-хешей звонка (через запятую).workers— количество потоков на один хеш (по умолчанию18).port— локальный порт проксирования (по умолчанию9000).pass— пароль подключения к вашему туннелю.
Файлы конфигурации должны иметь расширение .qwdtt и содержать внутри себя:
- Либо вышеуказанную URI-ссылку (
qwdtt://config?...). - Либо текстовый объект JSON (в обычном текстовом виде или закодированный в Base64).
Приложение считывает JSON-конфигурации из файлов или QR-кодов. Поддерживается гибкая структура ключей:
{
"name": "Имя профиля",
"peer": "192.168.1.1:56000",
"hashes": "хеш1,хеш2",
"workers": 18,
"port": 9000,
"password": "ваш_пароль_подключения"
}Допустимые альтернативные ключи:
- Вместо
"hashes"можно использовать"vkHashes". - Вместо
"workers"можно использовать"workersPerHash". - Вместо
"port"можно использовать"listenPort". - Вместо
"password"можно использовать"pass".
- Полноценный VPN-режим: приложение использует
VpnServiceи WireGuard GoBackend, поэтому трафик выбранных приложений проходит через системный VPN-интерфейс без ручного импорта конфигов. - TURN/DTLS-транспорт: нативный Go-клиент получает временные TURN-учётные данные VK-звонка и поднимает DTLS-соединения к relay-серверу, через который передаётся трафик до вашего VPS.
- WRAP без захардкоженного ключа: внешний RTP AEAD/ChaCha20-Poly1305 слой выводится из пароля подключения через HKDF. Один пароль — один WRAP-ключ, ключ не хранится в APK.
- RTP AEAD обфускация: транспорт маскируется под RTP/WebRTC аудиотрафик с OPUS payload type, а полезная нагрузка шифруется AEAD-слоем поверх DTLS/WireGuard.
- Деплой с телефона: вкладка «Деплой» подключается к серверу по SSH, загружает
wdtt-server, создаётsystemd-сервис, включает NAT/firewall и открывает рабочие UDP-порты. - Парольная модель доступа: сервер поддерживает главный пароль, до 10 активных пользовательских паролей, 16-символьную генерацию, привязку пароля к устройству, истечение срока и управление через Telegram-бота.
- Горячее обновление WRAP-ключей: создание, удаление и истечение паролей обновляют набор WRAP-ключей на сервере без перезапуска ядра.
- Исключения приложений: можно выбрать, какие приложения идут через туннель, а какие работают напрямую. Поддерживаются режимы ЧС (Черный список) и БС (Белый список).
- Капча VK Smart Captcha: по умолчанию включён режим «Авто капча»: Go v2-решатель, Auto WebView и ручной WebView используются по цепочке без выбора режима пользователем. При отключении авто-режима доступны ручные настройки метода.
- Живой лог-вьюер: события Go-клиента, DTLS, WireGuard, WRAP, капчи, деплоя и статистики отображаются в приложении с группировкой одинаковых сообщений и счётчиками повторов.
- Фоновая устойчивость:
Foreground Service,WakeLock,WifiLock, мониторинг смены сети и watchdog помогают переживать Doze, смену Wi-Fi/LTE и падение нативного процесса. - DNS fallback: сначала используются Yandex DNS
77.88.8.8/77.88.8.1, а при отказе или таймаутах выполняется fallback на системный провайдерский DNS устройства. - Автообновления: приложение проверяет GitHub releases, показывает диалог обновления и периодически повторяет проверку в фоне.
Android-приложение (qWDTT) → VpnService / WireGuard GoBackend → локальный UDP 127.0.0.1:9000
→ Go-клиент qWDTT → WRAP RTP AEAD → VK TURN / DTLS → wdtt-server на VPS → интернет
- Приложение запускает нативный Go-клиент
libclient.soи передаёт ему адрес VPS, VK-хеши звонка, пароль туннеля и количество потоков. - Go-клиент выводит WRAP-ключ из пароля подключения, получает TURN-учётные данные через VK-звонок, при необходимости решает VK Smart Captcha и устанавливает DTLS-соединения через TURN relay.
- Внешний WRAP-слой упаковывает DTLS-пакеты в RTP AEAD/ChaCha20-Poly1305, чтобы ключ не был захардкожен в APK.
- Первый рабочий канал запрашивает у VPS WireGuard-конфигурацию через
GETCONF, передавая локальный порт,device-idи пароль подключения. - Android-часть парсит полученный WireGuard-конфиг, поднимает системный VPN-туннель и применяет исключения приложений.
- Скачайте актуальный
APKсо страницы релизов. - Установите приложение на Android-смартфон.
- Подготовьте IP, логин, пароль от имеющегося VPS.
- В VK создайте или откройте групповой звонок и скопируйте ссылку вида
vk.com/call/join/xxxxxxxxxxx(где xxxxxxxxxxx — ваш хеш), либо вставьте ссылку целиком. - Откройте qWDTT и перейдите во вкладку «Деплой».
- Введите IP/домен VPS, SSH-логин, пароль и SSH-порт.
- В «Секретах» задайте главный пароль туннеля. При необходимости добавьте Telegram
admin_id/bot_tokenдля управления доступом. - Нажмите «Установить» и дождитесь завершения деплоя.
- Во вкладке «Туннель» укажите IP/домен сервера, VK-хеши, пароль подключения и количество потоков.
- Нажмите «Подключить», предварительно выдав необходимые разрешения приложению.
APK ожидает нативный бинарь в app/src/main/jniLibs/<abi>/libclient.so. Перед сборкой приложения запустите:
export ANDROID_NDK_HOME=/path/to/android-ndk
./scripts/build-native-libs.sh
./gradlew :app:assembleDebugЕсли нужно собрать только одну библиотеку вручную и потом подменить её в проекте:
./scripts/build-go-lib.sh arm64-v8aVK → группа → звонок → ссылка приглашения → код после /join/
- Откройте VK и создайте пустую группу или используйте существующую.
- Начните групповой звонок.
- Скопируйте ссылку приглашения.
- Вставьте в qWDTT всю ссылку или только хеш после
/join/. - Можно использовать до 4 хешей одновременно для распределения нагрузки.
Important
При выходе из звонка нажимайте «Просто завершить», а не «Завершить для всех». Если закрыть комнату для всех участников, хеш перестанет работать.
Серверная часть ставится автоматически из приложения:
Android → SSH → /tmp/deploy.sh + /tmp/wdtt-server → /usr/local/bin/wdtt-server
→ systemd wdtt.service → wdtt0 + NAT + firewall
По умолчанию используются:
56000/udp— DTLS-сервер WDTT.56001/udp— внутренний WireGuard-порт сервера.9000/udp— локальный порт Android-клиента.10.66.66.0/24— подсеть WireGuard-устройств.
Если включить ручное управление портами, эти значения можно изменить в «Секретах».
В форке qWDTT реализована продвинутая технология бесшовного обновления базы паролей и активных пользователей на сервере без необходимости перезапускать системную службу wdtt.service и разрывать соединение у работающих клиентов.
-
Изоляция памяти (Memory Isolation): При подключении клиента сервер делает независимую копию (клон) его ключа шифрования. Благодаря этому, при перезагрузке базы паролей старые ключи активных сессий не обнуляются, и работающие пользователи продолжают скачивать трафик без единого разрыва связи.
-
Динамический перевыбор ключа (Session Rollover): Поскольку UDP не имеет состояния соединения, переподключение клиента с новым паролем с того же IP и порта могло «залипать» в старой сессии на стороне сервера. В qWDTT сервер при ошибке расшифровки пакета в рамках существующей сессии автоматически пробует расшифровать его другими ключами из обновленной базы. При совпадении ключ сессии обновляется на лету!
-
Управление внешними скриптами (SIGHUP): Сервер слушает стандартный системный сигнал
SIGHUP(сигнал перезапуска конфигурации). Чтобы мгновенно обновить ключи из любого стороннего скрипта (например, вашего бота на Python), достаточно записать изменения в файл/etc/wdtt/passwords.jsonи послать серверу сигнал:kill -HUP $(pidof wdtt-server)
Все изменения вступят в силу моментально и абсолютно бесшовно для всех участников сети!
Этот проект распространяется под лицензией GNU General Public License v3.0.