- Rust 86.7%
- Shell 10.6%
- Dockerfile 2.7%
|
|
||
|---|---|---|
| .forgejo/workflows | ||
| acme | ||
| cover-nginx | ||
| gateway | ||
| tt-image | ||
| .gitignore | ||
| docker-compose.yml | ||
| README.md | ||
CaviCodeVPN Plugin: TrustTunnel
Traffic-плагин для CaviCodeVPN, обеспечивающий маскировку VPN-трафика под легитимный HTTPS через протокол TrustTunnel.
Компоненты
| Директория | Назначение |
|---|---|
gateway/ |
Rust L4-классификатор на :443. Парсит TLS ClientHello, маршрутизирует по стего-маркеру в Random[0..32]. Без совпадения — splice на сайт прикрытия |
tt-image/ |
Docker-образ TT endpoint + socat sidecar. No-auth режим на loopback, TCP и DNS/UDP идут через SOCKS5 Egress Core |
cover-nginx/ |
Реверс-прокси на настраиваемый внешний HTTPS-сервис (по умолчанию www.wikipedia.org). Pass-through для CDN. ACME HTTP-01 на :80 |
acme/ |
Certbot sidecar. Получает и обновляет Let's Encrypt сертификат, рестартит потребителей TLS |
Как это работает
Интернет :443
│
▼
Gateway ── маркер совпал ──► tt-shared (TT endpoint)
│ │
└── нет совпадения ──► cover-nginx (маскируемый внешний сервис)
│
SOCKS5 Egress (Core)
│
Интернет
- Клиент подключается к
vpn.example.com:443с deeplink'ом - Gateway читает первый пакет (TLS ClientHello), извлекает
Random[0..32] - Проверяет стего-маркер
(prefix & mask)— при совпадении splice в TT endpoint - TT endpoint работает без авторизации, прокидывает credentials клиента в SOCKS5 Egress через
extended_auth - SOCKS5 Egress валидирует login/password и выпускает TCP CONNECT и UDP ASSOCIATE в интернет
Установка
Плагин устанавливается через панель управления CaviCodeVPN Core:
- Откройте Плагины → Установка
- Git URL: URL этого репозитория
- Имя:
tt, Тип:Traffic - Нажмите «Установить» — Core клонирует, соберёт и запустит все 4 контейнера
Настройка
После установки настройте плагин через Плагины → карточка tt → шестерёнка:
Плагин предоставляет собственный интерфейс настроек (iframe) со следующими параметрами:
| Параметр | Описание | Обязателен |
|---|---|---|
cover_hostname |
Публичный домен VPN: DNS должен указывать на IP сервера; используется для TLS, SNI, deeplink и TOML профилей | Да |
cover_target_hostname |
Маскируемый внешний HTTPS-сервис для обычных запросов без TT-маркера, например www.wikipedia.org |
Нет, по умолчанию www.wikipedia.org |
acme_email |
Email для уведомлений Let's Encrypt | Для боевого ACME |
acme_staging |
Тестовый режим LE (без rate limit, сертификат не доверен) | Нет |
marker_length |
Длина стего-маркера в байтах (по умолчанию 6) | Нет |
marker_percent |
Плотность значимых бит маски в % (по умолчанию 70) | Нет |
rotation_interval_days |
Период ротации маркеров (по умолчанию 30) | Нет |
grace_period_days |
Overlap при ротации (по умолчанию 7) | Нет |
project_name |
Название проекта в имени профиля подключения (по умолчанию CaviCodeVPN) |
Нет |
node_name |
Название ноды в имени профиля подключения (по умолчанию Germany) |
Нет |
tt_icmp_enabled |
Прокидывание ICMP/ping через TrustTunnel endpoint (по умолчанию включено) | Нет |
tt_icmp_interface |
Сетевой интерфейс контейнера shared для raw ICMP socket (по умолчанию eth0) |
Нет |
После сохранения настроек нажмите Перезапустить — контейнеры пересоздаются с новыми переменными окружения. ACME контейнер автоматически запросит сертификат для указанного домена.
Протокол Config UI (postMessage)
Iframe плагина взаимодействует с Core через window.postMessage:
- Core → iframe:
{ type: 'cavicodevpn-plugin-load-settings', settings: {...} }— загрузка текущих настроек при открытии - iframe → Core:
{ type: 'cavicodevpn-plugin-save-settings', settings: {...} }— сохранение - iframe → Core:
{ type: 'cavicodevpn-plugin-request-settings' }— повторный запрос настроек
Передача настроек в контейнеры
Настройки из JSON передаются как env-переменные с префиксом CaviCodeVPN_:
cover_hostname→CaviCodeVPN_COVER_HOSTNAMEcover_target_hostname→CaviCodeVPN_COVER_TARGET_HOSTNAMEacme_email→CaviCodeVPN_ACME_EMAILacme_staging→CaviCodeVPN_ACME_STAGING(bool:true→1,false→0)project_name→CaviCodeVPN_PROJECT_NAMEnode_name→CaviCodeVPN_NODE_NAMEtt_icmp_enabled→CaviCodeVPN_TT_ICMP_ENABLEDtt_icmp_interface→CaviCodeVPN_TT_ICMP_INTERFACE
Gateway загружает настройки из Core API при старте: GET /api/plugin-api/traffic/settings.
Генерация клиентского профиля дополнительно перечитывает актуальные настройки из Core, поэтому сохранённый cover_hostname сразу попадает в deeplink/TOML и не заменяется старым localhost. Для применения cover_target_hostname к nginx-прикрытию перезапустите плагин из Core UI.
Некоторые крупные сайты могут отдавать пустой ответ или антибот-страницу при проксировании из серверной сети. Например, vk.com в части окружений отвечает HTTP 418 с пустым телом. В таком случае смените cover_target_hostname на сервис, который стабильно отдаёт обычную HTML-страницу с IP вашего сервера.
ICMP не проходит через SOCKS5 Egress: SOCKS5 не поддерживает ICMP, поэтому TrustTunnel endpoint отправляет ping через raw socket из контейнера shared. Для этого контейнер получает CAP_NET_RAW, а бинарник trusttunnel_endpoint собран с cap_net_raw.
Генерация клиентских конфигураций
Gateway предоставляет callback для Core:
POST /client-config
Запрос:
{
"subscriptionId": "guid",
"login": "subscription-login",
"plainPassword": "одноразово известный пароль",
"transport": "http2",
"filterProfile": {
"vpnMode": "general",
"exclusions": ["example.com", "*.example.org", "203.0.113.10"],
"excludedRoutes": ["203.0.113.0/24"],
"includedRoutes": null
}
}
Ответ:
{
"deeplink": "tt://?...",
"toml": "vpn_mode = \"general\"...",
"markerHex": "aabb/ff00",
"warnings": []
}
TOML содержит client_random, dns_upstreams, vpn_mode, exclusions, [listener.tun].included_routes и [listener.tun].excluded_routes. По умолчанию DNS upstreams — https://1.1.1.1/dns-query и https://8.8.8.8/dns-query, чтобы DNS не зависел от UDP ASSOCIATE; локальные/private маршруты остаются вне TUN. Маркер берётся из локального registry Gateway.
Deeplink исправлен под спецификацию TrustTunnel: upstream_protocol кодируется одним байтом (0x01 = http2, 0x02 = http3), dns_upstreams — TLV-массивом строк, а display name пишется в тег name как {project_name} @{login} ({node_name}). Текущая upstream-спецификация deeplink не содержит тегов для vpn_mode, exclusions и routes, поэтому при непустых фильтрах deeplink/QR возвращаются с предупреждением: фильтры сохраняются только в TOML.
Клиентский bypass остаётся основным механизмом защиты локальных ресурсов пользователя: Desktop применяет exclusions и routes из TOML. Core дополнительно привязывает выбранный filter profile к подписке, а SOCKS5 Egress блокирует совпадающие домены/IP/CIDR как серверную страховку для TCP/UDP. Этот блок только предотвращает выход с IP VPN-сервера; TT-плагин не заставляет клиента повторять запрос в обход VPN.
Требования
- CaviCodeVPN Core запущен и доступен
- Доменное имя направлено на IP сервера (для ACME сертификата)
- Порт 443 (TCP) открыт (входящие TLS-соединения)
- Порт 80 (TCP) открыт и не занят другим сервисом:
cover-nginxпубликует его для ACME HTTP-01 challenge - Для ping/ICMP у
sharedдолжен работатьCAP_NET_RAW; стандартный compose уже добавляет эту capability.
Docker Compose — сервисы
| Сервис | Контейнер | Описание |
|---|---|---|
| gateway | cavicodevpn-plugin-tt-gateway | Rust L4-классификатор, слушает :443 |
| shared | cavicodevpn-plugin-tt-shared | TT endpoint + socat, принимает от gateway |
| cover | cavicodevpn-plugin-tt-cover | nginx реверс-прокси на выбранный внешний сервис |
| acme | cavicodevpn-plugin-tt-acme | Certbot, управляет TLS-сертификатами |
Compose использует готовые Docker images из registry, а не локальный build:. Для Forgejo Packages задайте в Core окружение:
CaviCodeVPN_PLUGIN_IMAGE_PREFIX=git.dsvinka.ru/cavicode/
CaviCodeVPN_PLUGIN_IMAGE_TAG=latest
Core прокидывает эти значения в .env плагина при установке, поэтому тяжёлый tt-image собирается в CI и скачивается сервером как cavicodevpn-plugin-tt-shared.
Общие тома: cavicodevpn-acme-certs (TLS сертификаты), cavicodevpn-acme-webroot (ACME challenge), cavicodevpn-acme-work (Let's Encrypt). ACME sidecar использует Docker socket, чтобы перезапустить TLS consumers после выдачи или обновления сертификата.
Связанные репозитории
- CaviCodeVPN-Core — ядро платформы
- CaviCodeVPN-Plugin-UserSync — синхронизация пользователей