Skip to content

v1.2.0

Choose a tag to compare

@sleep3r sleep3r released this 09 Jun 12:45
4b00113
🇷🇺 Что нового (RU)

Что добавляет этот релиз

v1.2.0 — релиз про расширение апстрима: новый провайдер egress превращает обычную VPN-ссылку в чистый, трудноблокируемый выход для хопа прокси→Telegram. Плюс — фикс автопереключения в туннель-пуле (по репорту #323) и рефактор проверки fronting-домена.

[!NOTE]
Новая фича включается только явной командой — обновление безопасно, существующие деплои ничего не меняют. Egress ложится в ту же абстракцию type = tunnel, что и AmneziaWG.

Egress из VPN-ссылки — mtbuddy setup egress <ссылка>

Одна команда превращает share-ссылку в туннельный egress (прозрачный L3 + policy-routing — ровно как AmneziaWG), на двух бэкендах:

  • vless:// vmess:// trojan:// ss:// → локальный sing-box в TUN-режиме (интерфейс sbx0). DC-трафик прокси (SO_MARK=200) направляется через него (fwmark 200 → table 200 → sbx0) — тот же механизм, что у WG-туннеля. VLESS-Reality маскирует хоп выхода под настоящий TLS к реальному сайту — заметно труднее блокировать, чем фингерпринт WireGuard.
  • wireguard:// → нативный kernel-WG/AmneziaWG-туннель (переиспользует существующий флоу; AmneziaWG-ручки jc/s1/h1.. и presharedkey проносятся).

Несколько ссылок → sing-box urltest-пул с failover. Ядро прокси не меняется — оно просто метит сокеты, как для любого туннеля; вся работа в mtbuddy.

Автопереключение в туннель-пуле теперь работает (#323)

Проблема: при двух WG-туннелях в пуле (priority auto) выключение активного туннеля не приводило к переключению на второй рабочий.

Причина: контроллер пула (setup_tunnel.sh, раз в 30с) считал «здоровым» любой поднятый интерфейс — результат проверки достижимости Telegram логировался, но игнорировался (всегда return 0). Поэтому всегда выбирался первый поднятый интерфейс, а мёртвый-но-поднятый активный туннель никогда не пропускался.

Фикс: двухфазный выбор — сперва туннель, который реально достаёт до Telegram (настоящий failover), иначе fallback на первый просто-рабочий (чтобы single-tunnel-деплой не ушёл в чёрную дыру — помечается degraded). Выбор стал «липким»: предпочитает текущий активный туннель, если он ещё здоров, чтобы не флапать каждые 30с. Покрыто новым installer-e2e-тестом.

Проверка fronting-домена — общий хелпер

x25519-проверка пригодности tls_domain вынесена из инсталлера в fronting_domain.zig и теперь шарится тремя точками: mtbuddy install, mtbuddy setup masking --domain … и mtbuddy config doctor --network (где рассинхрон теперь ещё и плюсует к счётчику предупреждений в summary). Плюс тесты на классификацию вывода openssl (single-round x25519 / доступен-без-x25519 / недоступен).

Закалка (из самоаудита)

Перед мержем — два независимых код-ревью + ручной проход; найденное закрыто:

  • Эксклюзивность table 200: sing-box-egress и WG-пул владеют одной таблицей маршрутизации/fwmark 200 — теперь взаимоисключающие (поднятие одного снимает другой), иначе таймер пула каждые 30с молча уводил бы маршрут с sbx0.
  • Валидация ссылок: транспорты кроме tcp/ws/grpc и неизвестные sing-box'у SS-шифры отклоняются с понятной ошибкой на этапе разбора, а не молча вырождаются в plain-TCP / роняют весь конфиг sing-box.
  • Порядок старта: mtproto-proxy упорядочен After=/Wants= egress-юнита (drop-in) — на ребуте sbx0 и его маршрут поднимаются раньше, чем прокси метит DC-сокеты.
  • Тихий и проверенный uninstall: удаление больше не сыпет ожидаемыми ошибками (stop/flush/netns del отсутствующих компонентов) поверх спиннера; в installer-e2e добавлена проверка удаления — и она сразу поймала реальный баг: юнит mtproto-mask-health.service никогда не удалялся (путь с двойным .service).

Проверено

  • Сквозная проверка egress (systemd-контейнер ubuntu:20.04, arm64): setup egress с реальной VLESS-Reality-ссылкой → sbx0 поднят, table 200 default dev sbx0, и запрос с fwmark 200 (тот самый SO_MARK прокси) выходит с IP сервера сквозь Reality-туннель.
  • Failover-e2e (verify_tunnel_pool_failover): awg0 (Telegram-проба заблокирована) + awg1 (проба ок) → контроллер выбирает awg1.
  • zig build test, кросс-сборка x86_64-linux + aarch64-linux, zig fmt — зелёные; installer-e2e на 5 ОС (debian 11/12, ubuntu 20.04/22.04/24.04), включая новую проверку удаления.

🇬🇧 Release notes (EN)

What this release adds

v1.2.0 is an upstream-egress release: a new egress provider turns an ordinary VPN share-link into a clean, hard-to-block exit for the proxy→Telegram hop. Plus a tunnel-pool failover fix (reported in #323) and a fronting-domain-check refactor.

[!NOTE]
The new feature is opt-in via an explicit command — upgrading is safe and existing deployments change nothing. The egress slots into the same type = tunnel abstraction as AmneziaWG.

VPN-link egress — mtbuddy setup egress <link>

One command turns a share-link into a tunnel egress (transparent L3 + policy routing — exactly like AmneziaWG), on two backends:

  • vless:// vmess:// trojan:// ss:// → a local sing-box in TUN mode (interface sbx0). The proxy's SO_MARK=200 DC traffic is policy-routed through it (fwmark 200 → table 200 → sbx0) — the same mechanism the WG tunnel uses. VLESS-Reality camouflages the egress hop as real TLS to a real site — much harder to block than WireGuard's fingerprint.
  • wireguard:// → the native kernel WG/AmneziaWG tunnel (reuses the existing flow; AmneziaWG knobs jc/s1/h1.. and presharedkey are carried through).

More than one link → a sing-box urltest failover pool. The proxy relay is unchanged — it just SO_MARKs, as for any tunnel; all the work lives in mtbuddy.

Tunnel-pool failover actually switches now (#323)

The problem: with two WG tunnels in the pool (priority auto), disabling the active tunnel did not fail over to the second working one.

Root cause: the pool controller (setup_tunnel.sh, every 30s) treated any up interface as healthy — the Telegram-reachability probe result was logged but ignored (always return 0). So the first up interface always won, and a dead-but-up active tunnel was never skipped.

The fix: two-pass selection — first a tunnel that actually reaches Telegram (real failover), else fall back to the first merely-usable one (so a single-tunnel deploy doesn't go dark — marked degraded). Selection is now sticky: it prefers the currently-active tunnel while it's still healthy, to avoid flapping every 30s. Covered by a new installer-e2e test.

Fronting-domain check — a shared helper

The x25519 tls_domain suitability check moves out of the installer into fronting_domain.zig, now shared by mtbuddy install, mtbuddy setup masking --domain …, and mtbuddy config doctor --network (where a mismatch now also bumps the summary warning count). Plus tests for the openssl-output classification (single-round x25519 / reachable-without-x25519 / unreachable).

Hardening (from a self-audit)

Before merge: two independent code reviews + a manual pass; findings closed:

  • table 200 exclusivity: the sing-box egress and the WG pool both own the same routing table / fwmark 200 — they're now mutually exclusive (setting one up retires the other), otherwise the pool timer would silently steal the route from sbx0 every 30s.
  • Link validation: transports other than tcp/ws/grpc and shadowsocks ciphers sing-box doesn't accept are rejected with a clear error at parse time, instead of silently degrading to plain TCP / making sing-box refuse the whole config.
  • Startup ordering: mtproto-proxy is ordered After=/Wants= the egress unit (drop-in) so sbx0 and its route exist before the proxy marks DC sockets on reboot.
  • Quiet, verified uninstall: uninstall no longer spews expected-failure noise (stop/flush/netns del of absent components) over the spinner; installer-e2e gained an uninstall check — which immediately caught a real bug: the mtproto-mask-health.service unit was never deleted (a double-.service path).

Verified

  • End-to-end egress (ubuntu:20.04 systemd container, arm64): setup egress with a real VLESS-Reality link → sbx0 up, table 200 default dev sbx0, and a fwmark 200 request (the proxy's SO_MARK) egresses with the server's IP through the Reality tunnel.
  • Failover e2e (verify_tunnel_pool_failover): awg0 (Telegram probe blocked) + awg1 (probe ok) → the controller selects awg1.
  • zig build test, cross-builds for x86_64-linux + aarch64-linux, zig fmt — green; installer-e2e across 5 OSes (debian 11/12, ubuntu 20.04/22.04/24.04), including the new uninstall check.

Changelog

  • feat(egress): VPN-link tunnel egress + tunnel-pool failover fix + fronting x25519 helper (#324) (f8bca07)