Skip to content
FreedomCatsPublic

Repository files navigation

csqtt-cli

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

Это только клиент. Установка сервера, его панель, автообновление, исключения приложений и прочее остаются в проекте CSQTT и его Android-приложении — здесь их нет. Чтобы подключиться, у вас уже должны быть адрес сервера CSQTT, пароль подключения и хотя бы одна ссылка на звонок VK. Либо ссылка csqtt://… из панели сервера: в ней всё это сразу (панель 2.5.0 выдаёт её зашифрованной, csqtt-cli такую понимает; пароля в ней может не быть — тогда его спросят). Без ссылок на звонки можно подключаться в режиме auto_js: звонок создаёт само ядро от имени вашего аккаунта VK (раздел «Вход в VK») — или от аккаунта владельца сервера, если он положил в ссылку свой токен VK (раздел «Токен VK от сервера»).

Исходный репозиторий CSQTT переведён автором в архив; есть продолжение от другого автора — CSQTT-Rebirth. csqtt-cli пока собран на ядре 2.5.0 из исходного репозитория (раздел «Совместимый сервер»).

Капчу VK csqtt-cli проходит сам: ставит галочку «Я не робот» в скрытом окне и показывает окно, только если не вышло. С настоящей капчей VK это проверено на Windows и на Linux (X11; раздел «Капча»).

Чем csqtt-cli отличается от других настольных клиентов CSQTT — раздел «Сравнение с другими настольными клиентами CSQTT».

Клиент работает на переднем плане: пока запущен csqtt-cli connect (или подключение из меню), туннель поднят. Службы и автозапуска нет. Первый Ctrl+C останавливает туннель и убирает за собой; второй, пока ядро ещё останавливается, убивает ядро, не дожидаясь его, а следующий — сам процесс.

Проект молодой. Готовые архивы для Windows и Linux — на странице Releases (раздел «Установка»). Что работает на какой системе — в таблице ниже.

Что работает сейчас

Linux Windows
Режим socks — программы, настроенные на прокси SOCKS5 работает, прав не нужно работает, прав не нужно
Режим tun — весь трафик системы, защита DNS, kill-switch работает, нужен sudo работает, нужны права администратора
Меню и мастер профиля работают; права для tun меню запрашивает само через sudo работают, в том числе запуск двойным щелчком (проверено на чистой Windows из архива выпуска); права для tun меню запрашивает окном контроля учётных записей — этот запрос ещё не проверялся
Окно капчи браузер на Chromium; сначала csqtt-cli сам ставит галочку в скрытом окне, не вышло — окно у вас; проверено с настоящей капчей VK (X11, и под sudo с tun); в Wayland галочку ставит на виду, в открытом окне (не проверялось) WebView2; сначала csqtt-cli сам ставит галочку в скрытом окне, не вышло — окно у вас; проверено с настоящей капчей VK
Вход в VK (vk login) и подключение без ссылок на звонки (auto_js) вход — окно на Chromium, с настоящим VK проверен; подключение в auto_js с настоящим VK проверено в режимах socks и tun (звонок создаётся и по Ctrl+C завершается) WebView2; на Windows ещё не проверялись
Пароль, ссылки на звонки, токен VK связка ключей сеанса (Secret Service), без неё — файл с правами 0600 DPAPI
Ссылки csqtt://: открытые и зашифрованные панели 2.5.0, с токеном VK сервера разбор проверен на ссылках, собранных кодом сервера 2.5.0; с настоящей панелью и токеном сервера подключение не проверялось то же

macOS не поддерживается.

Совместимый сервер

Ядро клиента — CSQTT 2.5.0. Сервер нужен той же версии, 2.5.0: между версиями CSQTT протокол меняется. Со старым сервером 2.1.9 клиент не договорится — у ядра 2.5.0 другой формат запроса настроек (GETCONF). Если сервер прямо ответит, что версия протокола другая, csqtt-cli останавливается со строкой «сервер CSQTT другой версии, чем ядро клиента» и не переподключается без конца. Обычно же сервер другой версии просто молчит: тогда, если в этом запуске сервер ещё ни разу не ответил, через 30 с после того, как VK выдал креды, connect останавливается со строкой «сервер CSQTT не отвечает» и называет версию ядра клиента (её же печатает csqtt-cli version). Если сервер замолчал после того, как уже отвечал, connect не останавливается — см. «Восстановление». Сервер ставится средствами самого CSQTT.

Исходный репозиторий CSQTT (amurcanov/csqtt) переведён автором в архив; есть продолжение от другого автора — CSQTT-Rebirth. csqtt-cli пока собран на ядре 2.5.0 из исходного репозитория; с серверами из нового репозитория он не проверялся.

Протокол и формат пакетов клиент не меняет: сервер не отличает csqtt-cli от Android-приложения.

Один пароль — одно подключение за раз. Сервер CSQTT 2.1.9 закреплял пароль подключения за первым устройством и отказывал второму. В 2.5.0 такого отказа нет: ядро не сообщает серверу, с какого устройства оно подключается, и пароль можно перенести на другое устройство без отвязки в панели. Но одновременно с одним паролем работает одно подключение: новое вытесняет сессии прежнего. Поэтому для одновременной работы — телефон и компьютер, два профиля csqtt-cli разом — заведите на каждое свой пароль. Поле device_id в профиле осталось ради формата файла: ядро 2.5.0 его не использует.

Установка

Готовые сборки лежат на странице Releases: архив под каждую систему и файл контрольных сумм SHA256SUMS.txt. Установщика нет — архив распаковывается в любой каталог, и программа запускается оттуда. Собрать самому — подраздел «Сборка из исходников» ниже.

Система Архив
Windows, x86-64 csqtt-cli_<версия>_windows_amd64.zip
Linux, x86-64 (обычные ПК и серверы) csqtt-cli_<версия>_linux_amd64.tar.gz
Linux, ARM64 (64-битные ARM-машины) csqtt-cli_<версия>_linux_arm64.tar.gz

<версия> — тег выпуска, например v0.1.0: csqtt-cli_v0.1.0_linux_amd64.tar.gz. Архив ARM64 собран кросс-сборкой и запускался только под эмуляцией: подключение на настоящей ARM-машине ещё не проверялось.

В архиве — каталог с тем же именем, а в нём:

  • csqtt-cli (csqtt-cli.exe) — сама программа;
  • csqtt-core (csqtt-core.exe) — ядро CSQTT, его запускает csqtt-cli;
  • только для Windows — wintun.dll и её лицензия wintun-LICENSE.txt: библиотека адаптера для режима tun;
  • README.md — этот файл, csqtt-cli.example.toml — пример настроек;
  • LICENSE.txt — лицензия csqtt-cli, LICENSE-core.txt — лицензия ядра, THIRD_PARTY_NOTICES.txt — лицензии сторонних компонентов (раздел «Лицензия»).

csqtt-cli ищет ядро только в своём каталоге: ни текущий каталог, ни PATH не подходят. Переносите csqtt-cli и csqtt-core только вместе, и ядро должно быть из того же архива.

Проверка архива

Скачайте рядом с архивом SHA256SUMS.txt с той же страницы. Совпавшая сумма значит, что архив скачался целиком и это тот же файл, что выложен в выпуске.

Linux, в каталоге с обоими файлами:

sha256sum -c --ignore-missing SHA256SUMS.txt

Нужна строка csqtt-cli_<версия>_linux_amd64.tar.gz: OK (или …_linux_arm64…; в русской локали вместо OK — ЦЕЛ). --ignore-missing пропускает архивы других систем, которых у вас нет.

Windows, в PowerShell в папке загрузок:

Get-FileHash .\csqtt-cli_<версия>_windows_amd64.zip

Сравните значение Hash со строкой этого архива в SHA256SUMS.txt (файл открывается Блокнотом). PowerShell печатает сумму заглавными буквами, а в файле она строчными — это не расхождение.

Linux

tar -xzf csqtt-cli_<версия>_linux_amd64.tar.gz
cd csqtt-cli_<версия>_linux_amd64
./csqtt-cli

./csqtt-cli в терминале открывает меню — дальше ведут вопросы (раздел «Быстрый старт: меню»). Права root нужны только режиму tun: меню запросит их само через sudo, а командой это sudo ./csqtt-cli connect. Чтобы запускать csqtt-cli из любого каталога, положите оба файла вместе, например в /usr/local/bin:

sudo install -m 755 csqtt-cli csqtt-core /usr/local/bin/

Что нужно в системе:

  • glibc 2.35 или новее — например, Ubuntu 22.04, Debian 12 и новее. Ядро связано с glibc, на системах с musl (Alpine) оно не запустится. Сам csqtt-cli собран статически;
  • режиму tun — sudo и ядро Linux 5.12 или новее (раздел «tun на Linux — весь трафик системы»). Утилиты ip и nft не нужны;
  • окну капчи — браузер на Chromium: Chrome, Chromium, Яндекс Браузер, Edge или Brave. Без него капчу решают в обычном браузере (раздел «Капча»);
  • связка ключей сеанса (Secret Service) — желательно, но не обязательно: без неё пароль и ссылки на звонки хранятся в файле с правами 0600 (раздел «Файл настроек»).

Других пакетов ставить не нужно.

Windows

Распакуйте zip целиком: правой кнопкой → «Извлечь все…». Запуск прямо из открытого архива не подойдёт: ядро должно лежать на диске рядом с csqtt-cli.exe.

Запустите csqtt-cli.exe двойным щелчком или из консоли — откроется меню (раздел «Быстрый старт: меню»). Режиму tun (весь трафик) нужны права администратора: меню попросит их само окном контроля учётных записей, а connect из консоли запускайте от имени администратора. wintun.dll для него уже лежит в архиве рядом с csqtt-cli.exe. Режиму socks прав не нужно. Окну капчи нужен WebView2 Runtime — он есть в Windows 11 и в обновлённых Windows 10.

csqtt-cli.exe и csqtt-core.exe не подписаны. SmartScreen может предупредить о программе из интернета — «Подробнее» → «Выполнить в любом случае»; может насторожиться и антивирус. Что архив тот самый, подтверждает сумма из SHA256SUMS.txt.

Напомним: на Windows проверены режимы socks и tun и запуск двойным щелчком с меню; окно капчи — тоже, а запрос прав окном UAC там ещё не проверялся (таблица «Что работает сейчас»).

Сборка из исходников

Сборка — два исполняемых файла, те же, что в архиве:

  • csqtt-cli (csqtt-cli.exe) — сама программа, на Go;
  • csqtt-core (csqtt-core.exe) — ядро CSQTT на Rust, отдельным процессом.

Обе команды ниже кладут файлы в build/out, рядом друг с другом.

Linux

Нужны:

  • Go 1.26.2 или новее; cgo не нужен;
  • Rust 1.97.1 или новее (rustup) и компилятор C (gcc) — для ядра. CMake не нужен.

Из корня репозитория:

go run ./scripts/buildcore
go build -o build/out/csqtt-cli ./cmd/csqtt-cli

buildcore собирает ядро под эту же машину (x86_64 или aarch64, цель gnu) и кладёт его в build/out/csqtt-core. Если rustc старше, чем нужно ядру, он скажет об этом до сборки. Ядро связано с glibc машины сборки и на системе со старой glibc может не запуститься — тогда собирайте на ней же.

Под aarch64 ядро собирается и на x86_64 — кросс-сборкой. Нужны цель Rust (rustup target add aarch64-unknown-linux-gnu) и кросс-компилятор C: в Debian и Ubuntu — пакет gcc-aarch64-linux-gnu. Чего не хватает, buildcore скажет до сборки.

go run ./scripts/buildcore -target aarch64-unknown-linux-gnu -out build/out/linux-arm64
GOARCH=arm64 go build -o build/out/linux-arm64/csqtt-cli ./cmd/csqtt-cli

Запуск — build/out/csqtt-cli; оба файла можно переложить вместе, например в /usr/local/bin. Права root (через sudo) нужны только режиму tun. Что ещё нужно в системе — подраздел «Linux» выше.

Windows

Нужны:

  • Go 1.26.2 или новее;
  • Rust 1.97.1 или новее с тулчейном MSVC (stable-x86_64-pc-windows-msvc) и Visual Studio Build Tools с компонентом C++. NASM, CMake и консоль разработчика не нужны.

Из корня репозитория:

go run ./scripts/buildcore
go build -o build\out\csqtt-cli.exe .\cmd\csqtt-cli

Если по умолчанию у rustup стоит тулчейн windows-gnu, укажите MSVC явно: go run ./scripts/buildcore -toolchain stable-x86_64-pc-windows-msvc.

Рантайм C buildcore вшивает в само ядро: csqtt-core.exe не зависит от VC++ Redistributable, ставить его не нужно.

Что нужно для запуска и что работает на Windows — подраздел «Windows» выше.

Быстрый старт: меню

Набирать команды не обязательно: csqtt-cli, запущенный в терминале без аргументов, открывает меню и ведёт вопросами. Так же открывает его команда csqtt-cli menu.

  1. Скачайте и распакуйте архив для своей системы (раздел «Установка») и запустите csqtt-cli: на Linux — ./csqtt-cli в терминале, в распакованном каталоге; на Windows — csqtt-cli.exe в консоли или двойным щелчком.
  2. Профиля ещё нет — меню предложит его создать (Enter). Профиль — это адрес сервера CSQTT, пароль подключения и ссылки на звонки VK. Дальше:
    • если у вас есть ссылка csqtt://… из панели сервера (открытая или зашифрованная, как у панели 2.5.0), вставьте её: адрес, пароль и ссылки на звонки csqtt-cli возьмёт из неё. Ссылку при вставке не видно — так и задумано: в ней ваш пароль. Если ссылок на звонки в ней нет, мастер спросит их; если нет пароля — спросит и его. Если вместо ссылок на звонки в ней токен VK сервера, звонки не спрашиваются: их создаёт ядро от аккаунта владельца сервера (раздел «Токен VK от сервера»);
    • если ссылки нет, нажмите Enter и ответьте на вопросы: имя профиля (Enter — home), адрес сервера (без порта — 46000), пароль подключения (дважды) и ссылки на звонки VK через пробел. Пароль и ссылки при вводе тоже не видны.
  3. Выберите, что пускать через туннель:
    • весь трафик компьютера (режим tun, Enter). Нужны права root, на Windows — администратора: меню запросит их само при подключении. На Linux sudo спросит пароль вашей учётной записи, на Windows появится окно контроля учётных записей;
    • только программы, где указан прокси SOCKS5 127.0.0.1:1080 (режим socks) — прав не нужно.
  4. В меню нажмите Enter — «Подключиться». Когда появится строка «туннель работает», можно пользоваться интернетом (в режиме socks — программами с прокси).

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

Первый профиль становится профилем по умолчанию. В меню есть и остальное: выбрать другой профиль, создать ещё один, обновить ссылки на звонки, заменить пароль или адрес сервера, удалить профиль. Меню делает всё теми же командами, что описаны ниже, и пишет в тот же файл настроек.

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

Режим tun из меню на Linux. Меню, запущенное от вашего пользователя, для подключения в tun запускает себя ещё раз через sudo в том же терминале — одно подключение. Профили и пароль при этом берутся ваши, заводить их для root не нужно. После Ctrl+C снова открывается ваше меню. Путь к файлу настроек меню передаёт само (-config), так что подключение с правами читает тот же файл, что и меню. Можно и сразу sudo csqtt-cli: меню под sudo тоже видит ваши профили, если они лежат в ~/.config/csqtt-cli (раздел «Файл настроек»). Если sudo в системе нет, меню скажет об этом и предложит подключиться в socks — только на этот раз, профиль не меняется.

В скриптах и конвейерах csqtt-cli без аргументов меню не открывает, а печатает список команд. csqtt-cli menu -connect <профиль> подключается сразу, без меню, но с теми же вопросами (новые ссылки на звонки, если старые закрылись), и после остановки выходит.

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

Команды ниже написаны так, будто csqtt-cli лежит в PATH (например, в /usr/local/bin, раздел «Установка»). Из распакованного каталога на Linux набирайте ./csqtt-cli, в PowerShell — .\csqtt-cli.

  1. Заведите профиль. Пароль и ссылки на звонки спрашиваются скрытым вводом, в файл настроек попадают только ссылки на хранилище секретов:

    csqtt-cli profile add home -peer 203.0.113.10
    

    Или из ссылки csqtt://… — открытой или зашифрованной, как её выдаёт панель 2.5.0. Команда спросит ссылку скрытым вводом или прочитает из stdin:

    csqtt-cli profile add home -link
    csqtt-cli profile add home -link < ссылка.txt
    

    Чего в ссылке нет — пароля или ссылок на звонки, — команда спросит отдельно (из stdin — следующими строками). Ссылка с токеном VK сервера заводит профиль в режиме auto_js (раздел «Токен VK от сервера»).

    Режим по умолчанию — tun. Если нужен только прокси, добавьте -datapath socks. -default делает профиль профилем по умолчанию; первый профиль выбирается и без этого, пока он единственный.

    Аргументами пароль, ссылки на звонки и ссылку csqtt:// передать нельзя намеренно: они попали бы в историю оболочки и в список процессов.

    Выдали новую ссылку — новый пароль, другой сервер или токен VK сервера, — удалять профиль не нужно:

    csqtt-cli profile set home -link
    

    Из ссылки берутся адрес сервера, пароль и ссылки на звонки; пароля в ней нет — команда его спросит, ссылок на звонки нет — остаются прежние. Режим tun или socks, маршрутизация, kill-switch и остальные поля профиля не меняются. Ссылка с токеном VK сервера переводит профиль в auto_js, а ссылка без токена стирает прежний токен и возвращает профиль к ссылкам на звонки (раздел «Токен VK от сервера»).

  2. Проверьте звонки. Команда спрашивает VK о каждом звонке профиля, к серверу CSQTT не подключаясь:

    csqtt-cli hashes check home
    

    По строке на звонок, номером в профиле: живой, мёртвый (звонок закрыт, с кодом ошибки VK) или недоступен (VK не ответил: сеть, лимит). Сами ссылки не печатаются. Код возврата 0 — только если живы все. Профиль проверка не меняет.

  3. Поднимите туннель. На Linux в режиме tun — через sudo:

    sudo csqtt-cli connect home
    

    На Windows — та же команда без sudo, в консоли, открытой от имени администратора.

    Через несколько секунд появится строка

    == туннель работает · весь трафик системы — через адаптер csqtt-cli
    

    Проверить можно так: сервис определения внешнего адреса (например, curl https://ifconfig.me) покажет адрес вашего сервера CSQTT, а не ваш (если в профиле не включён routing.template: ifconfig.me — в его списке). Без прав root connect в режиме tun откажет сразу, до подключения, и подскажет команду с sudo и режим socks.

  4. Без прав root (на Windows — администратора) — режим для программ с прокси:

    csqtt-cli connect -datapath socks home
    

    Строка «туннель работает» кончается словами SOCKS5 на 127.0.0.1:1080. Направьте на этот адрес браузер или другую программу, которая умеет SOCKS5, и проверьте:

    curl -x socks5h://127.0.0.1:1080 https://ifconfig.me
    

    Чтобы не набирать флаг каждый раз — csqtt-cli profile set home -datapath socks.

Имя профиля можно не называть, если он в файле один или назван в default_profile. На терминале под строками хода подключения держится строка состояния: состояние, аптайм, воркеры, трафик, скорость; при выводе в файл её нет. -v печатает подробно: журнал ядра, SOCKS5 и капчи.

Остальные команды:

Команда Что делает
connect [флаги] [профиль] подключиться; флаги -datapath tun|socks, -no-kill-switch, -allow-leak, -v, -config
menu [-config] [-connect <профиль>] меню; с -connect — сразу подключение к профилю
profile add <имя> завести профиль: -link (адрес, пароль, ссылки на звонки или токен VK сервера) или -peer, остальные поля — флагами
profile set <имя> изменить поля профиля; -password и -hashes спрашивают секреты заново; -link берёт новую ссылку csqtt:// взамен прежней; -vk-hash-mode auto_js|manual — откуда звонок VK
profile show <имя> показать профиль с умолчаниями; секреты не печатаются
profile rm <имя> удалить профиль вместе с секретами, в том числе с токеном VK сервера (с подтверждением; -y — без)
profile list перечислить профили
hashes check [профиль] проверить звонки профиля (в auto_js проверять нечего)
vk login войти в VK в окне браузера и сохранить токен (раздел «Вход в VK»); -v — подробно
vk status вошли ли в VK: id аккаунта и где лежит токен; сам токен не печатается
vk logout стереть токен вашего входа VK с этой машины; токен VK сервера в профилях не трогает
version версия и коммит сборки, версия ядра CSQTT — сервер нужен той же
help <команда> подробная справка; то же — csqtt-cli <команда> -h

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

profiles.toml лежит в каталоге настроек пользователя: на Linux — $XDG_CONFIG_HOME/csqtt-cli/ (обычно ~/.config/csqtt-cli/), на Windows — %APPDATA%\csqtt-cli\. Другой файл — флаг -config у любой команды. Пример со всеми полями и пояснениями — csqtt-cli.example.toml.

Секретов в profiles.toml нет: пароль подключения и ссылки на звонки лежат в хранилище секретов, а в профиле — только ссылки на них (password_ref, vk_hashes_ref). Так же и токен VK после vk login: в файле — секция [vk] со ссылкой на него (token_ref) и id аккаунта (user_id), одна на все профили. Токен VK сервера из ссылки csqtt:// — свой у профиля: в профиле — ссылка на него vk_token_ref.

  • Windows — secrets.json рядом с profiles.toml, значения зашифрованы DPAPI и привязаны к вашей учётной записи.
  • Linux — связка ключей сеанса (Secret Service: gnome-keyring, KWallet, KeePassXC и другие). Если связка заблокирована, она покажет своё окно разблокировки. Где связки нет (вход по SSH, сервер без графики), секреты лежат в secrets.json рядом с profiles.toml открытым текстом под защитой прав 0600. Куда записаны секреты, пишут profile add и profile set, а показывает profile show.
  • Под sudo csqtt-cli берёт каталог настроек и связку ключей того, кто вызвал sudo, а не root, и созданные файлы оставляет ему во владение. Каталог — всегда ~/.config/csqtt-cli его домашнего каталога: свой XDG_CONFIG_HOME вызвавшего sudo не передаёт, и узнать его неоткуда. Если у вас XDG_CONFIG_HOME свой, под sudo указывайте файл явно: sudo csqtt-cli connect -config <путь к profiles.toml>. Меню, запрашивая права, передаёт -config само.
Поле Что задаёт По умолчанию
peer адрес сервера host:port; IPv6 — в скобках обязательно; без порта — 46000
password_ref, vk_hashes_ref ссылки на секреты; пишут profile add, profile set и меню обязательно; vk_hashes_ref в auto_js не нужен
vk_hash_mode откуда звонок VK: manual — ссылки на звонки профиля, auto_js — звонок создаёт ядро по входу VK или по токену VK сервера (раздел «Вход в VK») manual
vk_token_ref ссылка на токен VK сервера из ссылки csqtt://; пишут profile add -link и мастер меню; в auto_js главнее входа [vk] (раздел «Токен VK от сервера») нет — токена сервера нет
device_id устройство для сервера до ядра 2.5.0; ядро 2.5.0 его не использует (раздел «Совместимый сервер») заводится при первой записи
datapath tun — весь трафик системы, socks — локальный SOCKS5 tun
workers воркеров: 5 или кратно 10, от 10 до 100; в auto_js — не больше 70 10
obfs маскировка RTP: audio, video или unified unified (умолчание ядра)
turn_transport до TURN по udp или tcp_tls; TCP помогает там, где душат UDP udp
kill_switch в tun — блокировать трафик системы, пока туннель не поднят true
[profile.<имя>.socks] listen адрес SOCKS5, только loopback 127.0.0.1:1080
[profile.<имя>.routing] template сайты встроенного списка ядра (российские сервисы) — мимо туннеля, с вашего адреса (раздел «Мимо туннеля») false — всё через туннель
[profile.<имя>.routing] server применять правило маршрутизации, которое сервер назначил паролю; заменяет template (раздел «Мимо туннеля») false — правило только показывается
[vk] token_ref, user_id вход в VK: ссылка на токен и id аккаунта; пишут vk login и vk logout нет — входа нет

Файл можно править руками, но profile add, profile set и меню переписывают его целиком, и комментарии не сохраняются. Неизвестное поле — ошибка, как и пароль, вписанный прямо в файл. Профиль, написанный руками без device_id, при первом подключении дописывается: connect заводит device_id и тоже переписывает файл целиком — комментарии при этом теряются.

Режимы

Режим задаёт поле datapath профиля или флаг -datapath на один запуск.

Режим Что идёт через туннель Права Системы
socks программы, настроенные на прокси SOCKS5 не нужны Linux, Windows
tun весь трафик системы root (sudo), на Windows — администратор Linux, Windows

socks

Внутри csqtt-cli работает свой сетевой стек, а сверху — локальный SOCKS5 на 127.0.0.1:1080 (другой адрес — socks.listen в профиле, только loopback: пароля у прокси нет). Прав и установки не нужно. Ограничения:

  • только TCP (CONNECT): UDP через прокси не идёт;
  • только IPv4;
  • только программы, которые умеют SOCKS5. Имена сайтов прокси разрешает сам, через DNS туннеля, — если программа отдаёт ему имя, а не адрес. В curl для этого socks5h://, в браузерах — настройка «DNS через прокси». Иначе DNS программы идёт мимо туннеля.

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

sudo csqtt-cli connect -datapath tun

csqtt-cli создаёт свой сетевой адаптер csqtt-cli (/dev/net/tun) и отдаёт его ядру. Нужны права root и ядро Linux 5.12 или новее: защита DNS и kill-switch держатся на таблице nftables с флагом owner, который появился в 5.12. Утилиты ip и nft не нужны: адаптер, маршруты и правила csqtt-cli ставит сам. Из системных программ он зовёт только resolvconf — если /etc/resolv.conf ведёт он.

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

  • адаптер получает адрес и DNS-серверы, которые выдал сервер CSQTT;
  • весь IPv4 забирают маршруты 0.0.0.0/1 и 128.0.0.0/1 через адаптер. Маршрут по умолчанию остаётся на месте: половины выигрывают у него длиной префикса;
  • собственные соединения ядра — с VK, с DNS для имён VK, с TURN — привязаны к физическому интерфейсу и идут мимо туннеля, иначе туннель зависел бы от самого себя. Какой интерфейс выбран, видно строкой «сокеты ядра идут мимо туннеля через физический интерфейс: …»;
  • DNS системы — только к DNS-серверам туннеля (раздел «Защита DNS»);
  • IPv6 туннель не везёт: сервер выдаёт только IPv4. IPv6 наружу закрыт, чтобы не уходить мимо туннеля с вашим настоящим адресом; локальная сеть IPv6 работает. Программы, которые пробуют IPv6 и IPv4 параллельно (браузеры), этого не замечают; программа, начинающая с IPv6, подождёт таймаута и перейдёт на IPv4.

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

Адаптер живёт весь сеанс connect. Второй csqtt-cli в режиме tun на той же машине откажет сразу: «адаптер уже занят: на этой машине работает другой csqtt-cli…».

Если csqtt-cli просит сменить rp_filter. В Linux есть защита от поддельных пакетов — «обратный фильтр» (rp_filter). Получив пакет, система прикидывает: если бы она отвечала на этот адрес, ушёл бы ответ через то же сетевое подключение, через которое пакет пришёл? Если нет, в строгом режиме пакет выбрасывается как подозрительный.

С csqtt-cli такое «нет» случается постоянно, и подделки здесь нет. Весь трафик системы идёт в туннель, но само ядро CSQTT связывается с VK и его TURN-серверами напрямую, через обычное подключение, — иначе туннелю не на чем было бы держаться. Ответы VK приходят через обычное подключение, а «обратная дорога» к адресам VK по таблице маршрутов ведёт в туннель. Строгий фильтр видит несовпадение и выбрасывает ответы, и туннель не поднимается.

Другие VPN решают это по-своему. OpenVPN прокладывает мимо туннеля отдельный маршрут к своему единственному серверу. У csqtt-cli адрес не один: VK раздаёт много TURN-серверов и меняет их на ходу, так что заранее маршрут к каждому не проложишь. WireGuard (wg-quick) заводит свою маршрутизацию по меткам и при этом сам, не спрашивая, меняет системную настройку (src_valid_mark).

csqtt-cli системные настройки сам не меняет. Обычно менять и не нужно: в большинстве дистрибутивов по умолчанию стоит нестрогий режим (2), который проверяет только, что обратная дорога к адресу вообще существует, — ему наш туннель не мешает. Строгий режим (1) включают руками или настройками «усиленной безопасности». Тогда csqtt-cli до подключения откажет и подскажет команду, которая переводит в нестрогий режим только ваше сетевое подключение:

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

<интерфейс> — имя подключения из подсказки (например, eth0 или wlan0). Команда действует до перезагрузки; чтобы насовсем — запишите строку net.ipv4.conf.<интерфейс>.rp_filter = 2 в файл в /etc/sysctl.d/, например /etc/sysctl.d/90-csqtt-cli.conf. Нестрогий режим подключения перекрывает строгий общий (all): система берёт большее из двух значений. Если ничего менять не хотите, работает режим socks — ему обратный фильтр не мешает.

DNS системы. Как задать системе DNS туннеля, csqtt-cli решает по тому, кто ведёт /etc/resolv.conf, и пишет выбор строкой «[TUN] DNS системы задаётся так: …»:

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

Если resolv.conf — ссылка на незнакомый генератор, csqtt-cli откажет до подключения: перезаписать такой файл значило бы сломать его владельцу. С Debian resolvconf в resolv.conf вслед за DNS туннеля остаются и прежние серверы. Утечки через них нет: запросы к ним отклоняет защита DNS. Между попытками DNS системы возвращается прежним.

Другой VPN рядом. Маршруты другого VPN к конкретным сетям конкретнее половин /1 и остаются за ним. А DNS системы при поднятом туннеле — только туннельный: внутренние имена такого VPN не разрешаются, пока работает csqtt-cli. Kill-switch отдельно его не пропускает: пока туннель не поднят, соединение такого VPN со своим сервером может оборваться.

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

В консоли, открытой от имени администратора:

csqtt-cli connect -datapath tun

csqtt-cli создаёт адаптер Wintun csqtt-cli; wintun.dll должна лежать рядом с csqtt-cli.exe. Пока туннель поднят, весь IPv4 забирают маршруты 0.0.0.0/1 и 128.0.0.0/1, а IPv6 — ::/1 и 8000::/1: пакеты IPv6 csqtt-cli отбрасывает, и программы переходят на IPv4. Соединения ядра идут мимо туннеля через физический интерфейс, DNS-серверы адаптера — те, что выдал сервер CSQTT.

Защита DNS и kill-switch на Windows — фильтры WFP (Windows Filtering Platform), они описаны ниже. Им разрешено всё двум программам: csqtt-cli.exe и csqtt-core.exe рядом с ним. WFP узнаёт программу по пути к файлу, поэтому оба файла должны лежать там, откуда их запускают.

Защита DNS

Пока туннель поднят, запросы на порт 53 (UDP и TCP) пропускаются только к DNS-серверам туннеля и к loopback. На Linux это таблица nftables inet csqtt-cli — для исходящего трафика и для пересылаемого (контейнеры, виртуальные машины). Собственные запросы ядра к DNS для имён VK таблица узнаёт по метке сокета, а не по пользователю: под sudo правило «root может всё» пропустило бы любую программу root. На Windows это фильтры WFP, а запросы ядра и csqtt-cli они узнают по их программам. В выводе это строка «защита DNS: пока туннель поднят, DNS системы — только к резолверам туннеля, IPv6 наружу закрыт».

DNS поверх HTTPS у браузеров идёт на порт 443 и уходит в туннель обычным трафиком.

Таблица создана с флагом owner: ядро Linux удаляет её вместе с процессом csqtt-cli, даже убитым. Фильтры WFP живут в динамической сессии, и Windows тоже снимает их вместе с процессом. Если защиту поставить не удалось, csqtt-cli откажет до подключения. -allow-leak разрешает подключиться без защиты — только на этот запуск, в профиль он не записывается.

Kill-switch

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

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

  • собственные соединения ядра и csqtt-cli — им нужно добраться до 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 закрыт и в локальной сети: резолвер роутера отправил бы запросы провайдеру. Остальное отклоняется: на Linux UDP — сразу (Operation not permitted), TCP ждёт таймаута. Закрыт и пересылаемый трафик — контейнеры и виртуальные машины за NAT хоста.

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

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

Когда туннель поднят, kill-switch ничего не блокирует — работает защита DNS.

Капча при kill-switch. Окно капчи ходит в сеть через локальный прокси csqtt-cli: только к доменам VK и только на порт 443, мимо туннеля. Kill-switch при этом не снимается («окно капчи — через прокси … kill-switch на время капчи не снимается»). Если капчу приходится решать в обычном браузере (ручной режим) или прокси не поднялся, пропустить мимо блокировки один браузер нельзя. Тогда на время капчи kill-switch снимается, и трафик системы идёт мимо туннеля:

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

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

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

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

Если kill-switch не включился, csqtt-cli откажет до подключения. Подключиться без него — -no-kill-switch или -allow-leak (на один запуск).

Мимо туннеля

По умолчанию мимо туннеля не идёт ничего: весь трафик — через сервер CSQTT. У ядра есть встроенный список доменов — около 500 российских сервисов: Яндекс, VK, Mail.ru и «Одноклассники», банки, Госуслуги, маркетплейсы, операторы связи, а также несколько сервисов определения адреса (2ip.ru, ifconfig.me, ipify.org). Опция профиля пускает этот список напрямую:

csqtt-cli profile set home -routing-template

(в файле — template = true в секции [profile.home.routing]; выключить — -routing-template=false). Одна настройка на оба режима, tun и socks. При подключении это видно строкой «мимо туннеля: сайты встроенного списка ядра …».

Что меняется:

  • сайты из списка открываются с вашего адреса, а не с адреса сервера: им виден ваш настоящий адрес, провайдеру — эти соединения и имена сайтов (SNI в TLS открыт). Для российских сервисов, которые не пускают зарубежные адреса, в этом и смысл. Проверка адреса через ifconfig.me с опцией покажет ваш адрес, а не адрес сервера;
  • решает ядро, по адресу назначения: адреса сайтов списка оно узнаёт из ответов DNS (они идут через туннель) и из имени сайта в начале соединения TLS. Поэтому первое соединение с сайтом может пройти через туннель, следующие — напрямую. Если по тому же адресу живёт другой сайт (общие адреса CDN), напрямую пойдёт и он;
  • прямые соединения ядро открывает само, своими сокетами: в tun они привязаны к физическому интерфейсу, как остальные соединения ядра. Прямое соединение не удалось — в туннель оно не переводится;
  • работает это, только пока туннель поднят: прямые соединения идут через ядро. Пока туннель переподключается, kill-switch закрывает и их;
  • при каждом запуске ядра — при подключении и при каждом переподключении, ещё до туннеля — ядро открыто разрешает около 70 имён списка, как в CSQTT: сначала системным резолвером (в socks и без kill-switch это резолвер сети, то есть провайдера; при закрытом kill-switch он недоступен), а если тот ничего не дал — своим запросом к DNS Яндекса через физический интерфейс. Провайдер видит эти имена;
  • в socks напрямую идёт только то, что программа отдаёт прокси (TCP), — как и всё остальное в этом режиме.

Строка состояния считает трафик вместе с прямыми соединениями.

Список обновляется только вместе с ядром — новой версией csqtt-cli. Свои домены и адреса и все зоны .ru csqtt-cli не включает.

Правило сервера

Владелец сервера может назначить паролю в панели правило маршрутизации: домены и адреса, которые идут мимо туннеля (чёрный список) или только которые идут через туннель (белый список), и встроенный список ядра. Сервер присылает правило при каждом подключении, и connect показывает его строкой «сервер прислал правило маршрутизации …» — с именем правила и числом доменов и адресов. По умолчанию правило не применяется: строка кончается словами «— не применяется», и весь трафик, кроме встроенного списка с опцией выше, идёт через туннель. Применять его — согласие в профиле:

csqtt-cli profile set home -routing-server

(в файле — server = true в секции [profile.home.routing]; выключить — -routing-server=false). При подключении это видно строкой «правило маршрутизации сервера, если сервер его пришлёт, будет применено …». Тогда:

  • правило заменяет настройки маршрутизации ядра, вместе с routing.template профиля: нет в правиле встроенного списка — он не идёт напрямую и с опцией. Строка connect кончается словами «— применяется вместо настройки профиля». Заменяет не до конца: адреса, которые ядро уже выучило как прямые (по встроенному списку — с самого запуска, по прежнему правилу), остаются прямыми до переподключения, пока маршрутизация включена (белый список доменов их сбрасывает);
  • белый список в правиле переворачивает смысл: через туннель идут только домены и адреса из списка, а всё остальное — напрямую, с вашего адреса, и провайдер видит эти соединения и имена сайтов. Напрямую уходит и всё, чьё имя ядро не узнало: программа обратилась по адресу без DNS, адрес остался в кэше системы с прошлого раза. connect предупреждает об этом строкой «ВНИМАНИЕ: правило сервера — белый список …». Белый список, пустой после проверки, не включается: с пустым напрямую пошло бы всё. Белый список больше чем из 1024 доменов не применяется вовсе: ядро берёт не больше 1024, и остальные ушли бы мимо туннеля;
  • чёрный список адресов с огромным диапазоном — сеть /8 и шире или такой же диапазон a-b — пускает мимо туннеля большую часть трафика; об этом тоже строка «ВНИМАНИЕ: …». Локальные и частные сети (10.0.0.0/8, 192.168.0.0/16 и подобные) ядро напрямую не пускает никогда, и предупреждения о них нет;
  • домены правила ядро разрешает заранее, как встроенный список: системным резолвером (в socks это резолвер сети, то есть провайдера), а если тот ничего не дал, — запросом к DNS Яндекса мимо туннеля. С белым списком провайдер так может увидеть имена именно тех сайтов, которые идут через туннель;
  • домены csqtt-cli чистит, как ядро (без схемы, пути, порта и www.); домены с национальными знаками (пример.рф) переводит в punycode — ядро само этого не делает и иначе не узнало бы такой сайт, — а непереводимые отбрасывает. Адреса принимаются в тех же формах, что у ядра: адрес IPv4, сеть адрес/длина или диапазон a-b. Отбрасываются (строка «из правила отброшено элементов: N»): то, что ядро не примет (не домен, IPv6), и элементы с пробелами, управляющими знаками или знаками ; , = | — ядро считает их разделителями команды. Правило, которое не умещается в команду ядру (64 КиБ), не применяется вовсе — трафик идёт по настройкам профиля;
  • то же правило работающему ядру второй раз не посылается. После переподключения новое ядро начинает с настроек профиля и получает правило снова, когда сервер его пришлёт. Что правило снято, сервер не сообщает: снятое в панели перестаёт действовать с переподключением;
  • в tun ядро с согласием запускается только с привязкой своих сокетов к физическому интерфейсу, как и с routing.template; приложения Android из правила на компьютере не применяются; остальное — как со встроенным списком выше.

Капча

VK иногда просит капчу. Встроенный решатель ядра выключен — его попытки портили сессию капчи, и потом её уже нельзя было решить в окне. Окно открывается сразу, как только VK попросил капчу, и на неё даётся три минуты. Сначала окно скрыто за краем экрана: csqtt-cli пробует пройти капчу сам — ставит галочку «Я не робот». Если VK поверил, окно так и не появится, а в выводе будет строка «Капча пройдена автоматически». Если нет (VK попросил собрать слайдер, галочки нет, страница не загрузилась), окно выйдет на экран со строкой о причине — решите капчу в нём; три минуты считаются с самого начала.

  • Linux — окно капчи — отдельное окно браузера на Chromium: Chrome, Chromium, Яндекс Браузер, Edge или Brave — какой найдётся. Если капчу решаете вы, окно закроется само, как только она решена. Это отдельный экземпляр браузера с пустым временным профилем: ваших вкладок, закладок и паролей он не видит. Под sudo окно открывается от имени того, кто вызвал sudo, а не root. Скрытое окно открывается в фоне, за нижним краем экрана, и фокус не забирает, но кнопка браузера на панели задач на эти секунды может появиться. Если оконный менеджер не пустит окно за край экрана, а в сеансе Wayland — всегда (там окно за край не спрятать), окно сразу откроется на экране и csqtt-cli попробует поставить галочку в нём у вас на глазах: строка в выводе попросит несколько секунд не трогать окно. Не вышло — окно выйдет на передний план, решите капчу в нём. С настоящей капчей VK автоматический проход проверен (X11) и без sudo, и под sudo: капча прошла за несколько секунд, окно не появлялось. Окно для человека с настоящей капчей проверено без sudo. В Wayland окно ещё не проверялось.
  • Windows — окно на WebView2. С настоящей капчей VK автоматический проход проверен: капча прошла за несколько секунд, окно не появлялось. Окну нужен WebView2 Runtime.

Если окна не будет — нет браузера на Chromium, нет WebView2, csqtt-cli запущен по SSH, — капча решается в обычном браузере, а csqtt-cli печатает инструкцию:

  1. Откройте ссылку на капчу (csqtt-cli попробует открыть её сам; не вышло — откройте вручную где угодно, лучше в окне инкогнито).
  2. Ещё до галочки нажмите F12 и откройте вкладку Network (Сеть).
  3. Решите капчу.
  4. Найдите запрос captchaNotRobot.check, откройте его ответ (Response) и скопируйте значение success_token — или ответ целиком.
  5. Вставьте в терминал csqtt-cli и нажмите Enter.

Токен приходится переносить руками: VK отдаёт его только в ответе страницы, в адресной строке его нет. Негодную вставку csqtt-cli объяснит и подождёт ещё; пустая строка — отказ от капчи.

Вход в VK

В режиме auto_js ядро CSQTT само создаёт звонок VK от имени вашего аккаунта, и ссылки на звонки не нужны. Для этого нужен вход в VK — команда csqtt-cli vk login. Что из этого проверено с настоящим VK — таблица «Что работает сейчас». Если владелец сервера выдал ссылку csqtt:// со своим токеном VK, вход не нужен: звонки создаются от его аккаунта (подраздел «Токен VK от сервера» ниже).

Риск для аккаунта VK. Режим пользуется неофициальными браузерными методами VK и маскирует запросы под браузер. Блокировку аккаунта исключить нельзя, и насколько она вероятна, неизвестно: если основной аккаунт вам дорог, входите второстепенным. Токен, который выдаёт VK, бессрочный и даёт широкий доступ к аккаунту — все права, кроме сообщений; храните его как пароль. Каждое подключение в этом режиме создаёт от имени аккаунта звонок и открывает под аккаунтом сессии звонков VK, и при переподключениях их число не ограничено.

csqtt-cli vk login

Запускайте в терминале; прав root вход не требует, sudo не нужен. Сначала csqtt-cli печатает это предупреждение и спрашивает согласие (y; Enter — отказ) — при каждом входе. Потом открывается окно со страницей входа VK: на Linux — браузер на Chromium, как у капчи, на Windows — WebView2; без такого окна войти нельзя. Войдите в нём сами. Экрана с правами приложения VK может не показать вовсе: при входе через VK ID (QR-код и код из приложения VK) окно просто закрывается после входа. Поэтому о доступе, который получает токен, говорит предупреждение выше, и согласие на нём — это и согласие на этот доступ. Если VK экран доступа покажет, подтвердите его сами: csqtt-cli в окне ничего не нажимает. На вход — 5 минут; закрыть окно или Ctrl+C — отмена, ничего не записывается. Окно — с пустым временным профилем: после входа он удаляется вместе с cookie VK, и следующий вход — снова с паролем.

Токен ложится в хранилище секретов, как пароль подключения (раздел «Файл настроек»). Вход один на все профили; новый вход заменяет прежний.

  • csqtt-cli vk status — есть ли вход, id аккаунта и где лежит токен; сам токен не печатается.
  • csqtt-cli vk logout — стирает токен с этой машины. К VK команда не ходит: у VK токен остаётся действительным, пока вы не отзовёте доступ приложения в настройках аккаунта VK.

Подключение в режиме auto_js

csqtt-cli vk login
csqtt-cli profile set home -vk-hash-mode auto_js
sudo csqtt-cli connect home

vk login — без sudo, connect — как обычно (без sudo — -datapath socks). Ссылки на звонки профилю не нужны; если они в нём есть, они не используются и остаются на месте. Вернуться к ссылкам — csqtt-cli profile set home -vk-hash-mode manual.

  • До подключения ядро открывает под аккаунтом сессию звонков VK и создаёт звонок; строка профиля говорит «звонок VK создаёт ядро (auto_js)». Воркеров — не больше 70.
  • При остановке звонок завершается — и по Ctrl+C, и перед каждым переподключением (следующая попытка создаёт новый звонок). Это занимает до 45 секунд, пока идёт строка «завершаем звонок VK…». Второй Ctrl+C в это время убивает ядро сразу, но звонок тогда может остаться в аккаунте, пока VK не закроет его сам, — csqtt-cli скажет об этом строкой. То же, если ядро не подтвердило, что звонок закрыт.
  • Нет входа или токен не читается — connect откажет до подключения и подскажет csqtt-cli vk login (с токеном VK сервера — подраздел ниже). VK не принял токен (отозван, просрочен) — подключение останавливается без повторов с той же подсказкой. Если VK ответил временной ошибкой (unknown error, too many requests per second, internal server error), csqtt-cli пробует ещё раз через 2, 4, 8, 16 и 32 секунды, строкой переподключения показывая ответ VK и номер повтора; когда туннель заработал, счёт повторов начинается заново. Если и шестая попытка подряд кончилась так же, подключение останавливается: «VK отказал 6 раз подряд, повторы исчерпаны: …». Другой отказ VK до старта ядра (например, flood control) останавливает подключение сразу: попробуйте позже, а если повторяется — csqtt-cli vk login. Если VK или сеть до него не ответили, csqtt-cli переподключается, как при любом обрыве.
  • hashes check для такого профиля откажет: проверять нечего. Меню не предлагает ссылок на звонки и подключает так же; включается режим только командой profile set.
  • Риски — выше, в начале раздела: каждое подключение и переподключение создаёт звонок и сессии под аккаунтом.

Токен VK от сервера

Панель сервера 2.5.0 может положить в ссылку csqtt:// вместо ссылок на звонки токен VK владельца сервера. Профиль из такой ссылки (profile add -link, profile set -link или мастер меню) сразу переводится в режим auto_js, а токен ложится в хранилище секретов как секрет этого профиля. Что это значит:

  • Звонки создаются от аккаунта владельца сервера, а не от вашего. Ваш vk login не нужен; если вход есть, профиль с токеном сервера им всё равно не пользуется. Строка профиля в connect так и говорит: «звонок VK создаёт ядро (auto_js) от аккаунта VK, выданного сервером», то же — profile show и список профилей в меню.
  • Риски — его аккаунта. Всё, что сказано выше о блокировке аккаунта, о звонках и сессиях при каждом подключении, относится к аккаунту владельца сервера: для VK ваши подключения — его звонки и его сессии.
  • Токен — чужой секрет у вас. Он даёт широкий доступ к аккаунту владельца сервера. csqtt-cli его не печатает и в журнале скрывает; храните ссылку так же бережно.
  • Сменить токен (владелец отозвал его или выдал новую ссылку) можно только новой ссылкой: csqtt-cli profile set <имя> -link. Если VK не принял токен, connect подскажет то же самое. Новая ссылка без токена стирает прежний токен, и профиль, который работал по нему, возвращается к ссылкам на звонки (manual).
  • profile rm стирает токен вместе с профилем, vk logout его не трогает: это не ваш вход. С -vk-hash-mode manual профиль работает по ссылкам на звонки, а токен остаётся на случай возврата к auto_js.

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

При обрыве клиент переподключается сам с нарастающей задержкой: 1, 2, 4 … 64 с. В режиме tun csqtt-cli ещё и следит за сетью: смена сети — другой Wi-Fi, кабель вместо Wi-Fi — перезапускает подключение сразу, строкой «сеть сменилась: …». Если сеть пропала, csqtt-cli пишет «сеть пропала — туннель переподключится, когда она вернётся». Если VK выдал креды, а сервер CSQTT молчит 30 с, csqtt-cli пишет об этом одну строку (сервер выключен, недоступен или другой версии) и продолжает попытки.

Если на Windows адаптер csqtt-cli отключили или удалили в системе, переподключаться некуда. csqtt-cli останавливается, убирает маршруты и защиту и пишет, что подключиться нужно заново: новый запуск создаст адаптер снова.

Звонок, который VK называет закрытым, исключается из подключения, но профиль не меняется. Когда живых звонков не остаётся, клиент останавливается и называет номера звонков в профиле. Новые ссылки — csqtt-cli profile set <имя> -hashes или меню: оно спросит их само.

Если сервер отказал (неверный пароль, пароль истёк, аккаунт отключён, другая версия сервера), csqtt-cli не переподключается без конца, а останавливается и подсказывает, что делать: обычно — csqtt-cli profile set <имя> -password или панель сервера.

В режиме auto_js звонков профиля нет, и исключать нечего: звонок, переставший работать, лечится переподключением — новое ядро создаёт новый звонок. Отказ VK в токене останавливает подключение с подсказкой csqtt-cli vk login, а с токеном VK сервера — с подсказкой взять новую ссылку (profile set <имя> -link).

Если csqtt-cli упал или был убит

Первый Ctrl+C останавливает туннель и убирает за собой всё. Второй Ctrl+C, пока ядро ещё останавливается, убивает ядро, не дожидаясь его уборки (в auto_js звонок тогда может остаться в аккаунте), а свою уборку csqtt-cli доводит до конца. Третий Ctrl+C, kill -9 или падение убрать не дают. Ядро в любом случае умирает вместе с csqtt-cli. В режиме tun на Linux адаптер с маршрутами и таблица inet csqtt-cli (защита DNS и kill-switch) тоже исчезают сами, на Windows — адаптер с маршрутами и фильтры WFP. Остаётся DNS туннеля в системе: запись tun.csqtt-cli у resolvconf или перезаписанный /etc/resolv.conf с копией /etc/resolv.conf.csqtt-cli-backup (у systemd-resolved настройки уходят вместе с адаптером). DNS при этом работает, но запросы идут напрямую, мимо туннеля. Следующий csqtt-cli connect -datapath tun убирает остаток сам и пишет об этом строкой «DNS системы: …». Вручную — sudo resolvconf -d tun.csqtt-cli или sudo mv /etc/resolv.conf.csqtt-cli-backup /etc/resolv.conf.

Отладка

  • -v у connect и hashes check — журнал ядра, SOCKS5 и капчи. Хеши звонков и токены капчи в нём скрыты: звонки называются номерами в профиле, а звонок, созданный ядром в auto_js, — <хеш>. Токена VK в журнале нет. С routing.template в нём есть строки ядра [DNS-РОУТИНГ]/[SNI-РОУТИНГ] Прямой домен: <домен> -> <адрес> — история посещений прямых сайтов, а с routing.server — ещё и строка [STDIN] UPDATE_DOMAINS|… со списками правила сервера целиком; учитывайте это, прежде чем делиться выводом.
  • -v у vk login — что видит окно входа: дошло ли оно до адреса с токеном и где его увидело. Ни адресов, ни токена там нет.
  • go run ./scripts/checktunnel (из исходников, Linux и Windows) — снимок системы: процессы, адаптеры, маршруты, внешний адрес, кто отвечает на DNS; на Linux ещё правила маршрутизации, таблицы nftables (под sudo), resolv.conf и записи resolvconf, rp_filter. Ничего не меняет; снимки до запуска, во время и после остановки удобно сравнивать. Внешний адрес снимок берёт у ifconfig.me, а он во встроенном списке ядра: с routing.template снимок покажет ваш домашний адрес, и это не утечка.
  • csqtt-cli profile show <имя> — профиль с подставленными умолчаниями и то, читаются ли секреты на этой машине.

Ограничения

  • csqtt-cli.exe и csqtt-core.exe не подписаны: SmartScreen и антивирусы могут о них предупреждать.
  • На Windows ещё не проверялся запрос прав окном UAC из меню.
  • Туннель везёт только IPv4.
  • socks — только TCP, без UDP.
  • Ссылки на звонки VK заводит человек — или звонок создаёт ядро в режиме auto_js (раздел «Вход в VK»); включается он командой profile set или ссылкой csqtt:// с токеном VK сервера, а сам мастер меню о нём не спрашивает.
  • Капчу csqtt-cli сначала пробует пройти сам — ставит галочку; в Wayland окно не прячется — галочка ставится на виду. Если VK попросит не галочку, а слайдер, решать придётся вам.
  • Окно капчи в Wayland ещё не проверялось.
  • Службы и автозапуска нет; macOS не поддерживается.

Устройство

csqtt-cli — оболочка на Go, ядро CSQTT на Rust работает рядом отдельным процессом (csqtt-core), как в Android-приложении. Ядро взято из CSQTT версии 2.5.0 (этот репозиторий теперь в архиве, см. «Совместимый сервер») целиком и лежит в core/, версия апстрима — в core/CORE_VERSION. Поверх него — небольшие правки, которые нужны настольному клиенту (раздел «Исправления в ядре CSQTT»). Из маршрутизации мимо туннеля, появившейся в ядре 2.5.0, csqtt-cli включает только встроенный список доменов ядра и правило сервера, и только опциями профиля (раздел «Мимо туннеля»); без них весь трафик идёт через туннель.

Протокол с сервером правки не трогают. Как всё устроено, — в doc/architecture.md, план работ — в doc/plan.md. Меню, профили, защита DNS, kill-switch и окна капчи перенесены из qwdtt-cli — консольного клиента к qWDTT того же автора.

Исправления в ядре CSQTT

Ядро взято из CSQTT 2.5.0 целиком, но для настольного клиента в нём кое-что поправлено. Протокол с сервером правки не трогают: сервер не отличает csqtt-cli от Android-приложения.

  • Пароль и ссылки на звонки не видны в списке процессов. Ядро апстрима получает хеши звонков аргументами командной строки, а её видят и другие пользователи машины; по хешу звонка кто угодно получит креды TURN. Здесь ядро получает пароль и хеши строкой через stdin.
  • Чужая программа не уведёт туннель. Когда пакеты идут между csqtt-cli и ядром по loopback (режим socks, режим tun на Windows), ядро апстрима отвечает тому, кто прислал ему последний пакет: одного пакета от любого процесса машины хватило бы, чтобы трафик туннеля уходил к нему. Здесь ядро принимает пакеты и отвечает только своему csqtt-cli.
  • Чужой процесс не подменит адаптер. В режиме tun на Linux ядро получает адаптер через сокет, к которому может подключиться любой процесс машины, причём в любой момент сеанса. Здесь ядро принимает адаптер только от процесса того же пользователя.
  • Соединения ядра идут мимо туннеля и без петли. Подключения ядра к VK, DNS и TURN, а с ядра 2.5.0 и прямые соединения маршрутизации мимо туннеля привязаны к физическому интерфейсу. Они не попадают в сам туннель, kill-switch и защита DNS их пропускают, и маршруты к адресам VK для этого не нужны.
  • Три минуты на капчу вместо одной-двух. Минуты человеку часто не хватает: окно нужно заметить, дождаться страницы VK и пройти проверку. Свой решатель капчи ядро не запускает — csqtt-cli сначала пробует пройти её сам, а не вышло — капчу решает человек (раздел «Капча»).

Описание каждой правки с тестами, а ещё ошибки ядра 2.5.0, которые мы нашли, но не правили, — в doc/upstream-proposals.md.

Сравнение с другими настольными клиентами CSQTT

Кроме csqtt-cli, к серверу CSQTT с компьютера подключаются графические клиенты FOCSQ (Windows и Linux), LaLune (Windows, Linux, а также Android, iOS и OpenWrt) и CSQTT for Windows (только Windows). Ниже — различия по FOCSQ v1.0.0, LaLune 0.9.1 и CSQTT for Windows 3.13.1.

csqtt-cli FOCSQ LaLune CSQTT for Windows
Интерфейс консольный: меню вопросами и команды для скриптов графический; трей и автозапуск графический, поверх локальной службы графический: экраны подключения, установки сервера и журнала; трея нет
Платформы Windows x64, Linux x64 и ARM64 (ARM64 — кросс-сборка, на настоящей ARM-машине не проверялась) Windows x64, Linux x64 Windows, Linux; ещё Android, iOS, OpenWrt Windows 10/11 x64
Сервер CSQTT 2.5.0 2.1.9: ядро 2.1.9, с сервером 2.5.0 не договорится 2.1.9 или 2.5 — выбирается в настройках 2.1.9: ядро 2.1.9, с сервером 2.5.0 не договорится
Ядро CSQTT 2.5.0 из апстрима, отдельным процессом в архиве; свои правки — правилами переноса форк ядра 2.1.9 внутри приложения, свои правки вручную скачивается при подключении из стороннего репозитория сборок CSQTT 2.1.9 из апстрима без правок, отдельным процессом в архиве
Режимы весь трафик системы (tun) и SOCKS5 без прав администратора (socks) весь трафик системы весь трафик системы весь трафик системы (адаптер Wintun)
Kill-switch есть: пока туннель не поднят, трафик системы закрыт, кроме локальной сети нет: туннель остановлен — трафик идёт напрямую нет нет: туннель остановлен — трафик идёт напрямую
Что идёт мимо туннеля у всех программ по умолчанию ничего: мимо туннеля ходят только соединения ядра, они привязаны к физическому интерфейсу 13 сетей VK и Яндекса и DNS-серверы сети — маршрутами для всей системы адреса TURN — маршрутами для всей системы (Windows) адрес сервера, адреса VK и OK на момент подключения и адреса TURN из журнала ядра — маршрутами /32 для всей системы
Защита DNS DNS системы — только к DNS туннеля; IPv6 наружу закрыт Windows: правило NRPT направляет системный резолвер в DNS туннеля, но DNS-серверы сети для программ остаются мимо туннеля. Linux: DNS туннеля добавляется адаптеру без домена ~., и systemd-resolved спрашивает и прежние серверы. IPv6 не закрывается DNS туннеля назначается адаптеру, запросы к прежним серверам ничем не закрыты; на Linux дописывается в конец /etc/resolv.conf и после отключения остаётся DNS туннеля назначается адаптеру через netsh, DNS-серверы сети остаются и ничем не закрыты; IPv6 не закрывается
Обрыв и смена сети подключение перезапускается целиком с нарастающей задержкой (1–64 с); в tun смена сети замечается сразу воркеры ядра переподключаются сами; первое подключение — до 60 с, потом остановка; смена сети не отслеживается не выяснено воркеры ядра переподключаются сами; первое подключение — до 90 с, потом остановка; падение ядра и смена сети не отслеживаются
Мимо туннеля по выбору встроенный список доменов ядра — опцией профиля; правило сервера — только с согласием в профиле нет (в ядре 2.1.9 этого нет) не выяснено нет (в ядре 2.1.9 этого нет)
Звонок от аккаунта VK без ссылок (auto_js) есть; вход — в окне Chromium (Linux) или WebView2 (Windows); или токен VK сервера из ссылки есть, включён по умолчанию; вход — в окне WebView; ещё режим, где звонки создаёт сама программа через API VK есть; токен добывает отдельная программа на Playwright с Chromium есть; вход — в окне WebView2 на странице OAuth VK; токен ядру — через stdin
Капча автоматически: csqtt-cli сам ставит галочку в скрытом окне — WebView2 на Windows (проверено с настоящей капчей VK) или Chromium на Linux (проверено с настоящей капчей VK в X11; в Wayland — в видимом окне), не вышло — решает человек в том же окне; без окна — в любом браузере; решатель ядра выключен сначала решатель ядра, затем окно WebView только решатель ядра, окна нет только решатель ядра, окна нет
Пароль, ссылки на звонки, токен VK хранилище секретов: DPAPI на Windows, связка ключей на Linux (без неё — файл 0600); ядру — через stdin пароль и хеши открытым текстом в базе приложения; токен VK — в хранилище секретов системы открытым текстом в файлах приложения; ядру — аргументами командной строки пароль, ссылка и токен VK — DPAPI в файле настроек, хеши — там же открытым текстом; пароль и хеши ядру — аргументами командной строки
Ссылки csqtt:// открытые и зашифрованные ссылки панели 2.5.0, в том числе без пароля и с токеном VK сервера, — в меню и командой открытый формат открытый и зашифрованный формат сервера 2.5 открытый формат (v=2 и старый пароль@хост:порт)
Что нужно поставить ничего: два файла из архива (на Linux ядру нужна glibc 2.35+); wintun.dll — в архиве; окнам — браузер на Chromium или WebView2 Windows — установщик или архив и WebView2; Linux — webkit2gtk-4.1, libsecret, ayatana-appindicator (лаунчер ставит их сам) установщик (irm … | iex, curl … | bash) скачивает программу, службу и ядро .NET Desktop Runtime 10 x64; WebView2 — для входа VK; wintun.dll — в архиве
Права sudo или администратор — только для tun Windows — администратор; Linux — право cap_net_admin на вспомогательной программе Windows — администратор; Linux — сетевые команды через sudo администратор — всегда (программа запускается только с правами)
Обновления не проверяет, в сеть сам не ходит проверяет GitHub при запуске проверяет GitHub; ядро скачивает сам не проверяет
Лицензия MIT, ядро — PolyForm Noncommercial PolyForm Noncommercial; дизайн и название — все права защищены PolyForm Noncommercial PolyForm Noncommercial

Ещё клиенты: csqtt-desktop — графическая переработка FOCSQ на ядре 2.5.0 со своими списками прямых доменов и адресов; готовая сборка — только для Windows. CSQTT VPN Desktop — графический клиент для Windows и Linux на своей ветке ядра; работает только с сервером той же сборки. csq-socks — скрипты для Linux: SOCKS5 или весь трафик, ядра 2.1.9 и 2.5, ставится под root.

Коротко: FOCSQ удобнее, если нужен графический интерфейс с треем и автозапуском, а сервер — 2.1.9. LaLune — если нужен графический клиент под сервер 2.5 или одна программа на компьютер, телефон и роутер. CSQTT for Windows — если нужен простой графический клиент только для Windows под сервер 2.1.9 и хочется ставить сервер на VPS прямо из программы. csqtt-cli — если важно, чтобы при обрыве туннеля и в DNS ничего не уходило мимо, чтобы пароль и токен не лежали открытым текстом, чтобы не ставить лишних пакетов и не давать программе прав сверх нужного, чтобы капчу-галочку клиент проходил сам — на Windows и Linux, в своём окне, а не решателем ядра, — и чтобы клиент работал на сервере, на ARM (сборка есть, на настоящей машине пока не проверялась) или по SSH. Зато у csqtt-cli нет окна и трея, а на Windows проверено пока не всё (таблица «Что работает сейчас»).

Лицензия

Собственный код csqtt-cli распространяется по лицензии MIT — текст в LICENSE; в архиве релиза — LICENSE.txt. Это всё в репозитории, кроме ядра, правок к нему и чужих файлов (см. ниже).

Ядро CSQTT (core/, бинарь csqtt-core) распространяется по лицензии PolyForm Noncommercial 1.0.0 — текст и обязательные уведомления автора CSQTT в core/LICENSE. Ядро взято из исходного репозитория CSQTT, который автор перевёл в архив (есть продолжение от другого автора — CSQTT-Rebirth). Правки к ядру — под той же лицензией: и в core/, и их исходники в scripts/vendorcore (модули files/ и фрагменты кода ядра в правилах). Эта лицензия разрешает только некоммерческое использование.

Поэтому сборка csqtt-cli целиком — некоммерческая. csqtt-cli без ядра не работает, и использовать сборку в коммерческих целях нельзя. Коммерческое использование CSQTT требует отдельной письменной лицензии от его автора.

MIT оболочки этого не меняет: она относится только к коду csqtt-cli, не к ядру и не к сборке вместе с ним. Крейты primp и primp-hyper-util, вендоренные в core/rust-client/vendor/, сохраняют свою лицензию (MIT); это же относится к архиву primp-hyper-util в scripts/vendorcore/crates/ и к копиям файлов лицензий в scripts/notices/licenses/ (primp — из архива crates.io; etherparse и yasna — из репозиториев проектов, в их архивах файлов нет; все MIT или Apache-2.0). Исключение — добавленный в primp-hyper-util файл csqtt_bind.rs: это правка ядра (PolyForm NC). Лицензии остальных зависимостей Go и Rust — в THIRD_PARTY_NOTICES.txt в архиве релиза.