🇷🇺 Что нового (RU)
Что решает этот релиз
v0.23.0 - большой feature-релиз про tunnel pool failover, более честную документацию по ограничениям и нормальную русскую версию README.
До этого mtbuddy setup tunnel фактически был рассчитан на один tunnel interface: прокси ставил SO_MARK=200, а host routing table 200 указывала на один настроенный awg0. Это работало, пока один туннель жив. Но если Telegram route через него умирал, оператору приходилось вручную менять интерфейс, перезапускать routing setup и держать в голове текущее состояние.
В v0.23.0 tunnel mode стал pool-based: mtproto-proxy по-прежнему использует один data-plane контракт (SO_MARK=200 -> table 200), а mtbuddy управляет ordered pool туннелей и выбирает первый живой интерфейс. Если основной туннель отваливается, новые upstream-соединения уходят через следующий здоровый tunnel. Когда приоритетный туннель возвращается, контроллер автоматически переключает table 200 обратно, если не задан manual pin.
[!NOTE]
Уже открытые TCP-соединения не мигрируют между туннелями. Failover влияет на новые upstream connections и клиентские reconnects.
[!IMPORTANT]
Telegram calls по-прежнему не поддерживаются. В Telegram они завязаны на SOCKS-поведение, которое нельзя нормально замаскировать в этой модели. Также медиа на аккаунтах без Premium требует MiddleProxy: без него такие загрузки не станут надёжно работать только за счёт tunnel pool.
Что изменено
Tunnel pool failover (#250)
[upstream.tunnel]теперь поддерживает ordered pool:interfaces = ["awg0", "awg1", ...];pinned_interface = "awg1"для ручного предпочтения;- старый
interface = "awg0"остаётся совместимым fallback.
mtbuddyставитmtproto-tunnel-pool.serviceиmtproto-tunnel-pool.timer./usr/local/bin/setup_tunnel.shтеперь:- поднимает все интерфейсы из пула;
- проверяет
fwmark 200 -> table 200; - пробует Telegram через каждый интерфейс;
- переключает route через
ip -4 route replace default dev <iface> table 200.
- Selection policy - priority auto-failback: первый живой интерфейс в списке снова становится активным, когда восстанавливается.
- Automatic failover не перезапускает
mtproto-proxy.
Настройка tunnel pool через mtbuddy (#250)
- Повторный
mtbuddy setup tunnel <conf|vpn://>добавляет следующий свободныйawgN. - Добавлен
--iface <name>, чтобы установить или заменить конкретный участник пула. - Интерактивный wizard теперь показывает:
- выбор VPN-типа (пока AmneziaWG);
- текущий tunnel pool;
- действие: создать новый tunnel или заменить существующий.
- Конфиги сохраняются в
/etc/amnezia/amneziawg/<iface>.conf. - Input sanitizing стал явным: удаляются
DNS, пустые AWG assignments, добавляетсяTable = off.
Runtime и dashboard знают про активный tunnel (#250)
Configпарситinterfacesиpinned_interfaceвместе с legacyinterface.- MiddleProxy metadata refresh больше не предполагает один legacy interface: активный tunnel определяется из table 200 / pool state.
- Dashboard routing card показывает ordered pool, active route, pinned interface, last switch, health reason и per-interface probe status.
- Dashboard action
Set ifaceпереосмыслен какPin: он пишетpinned_interface, запускает pool controller один раз и не рестартит прокси. /api/stats.routingполучил поля для pool/active/pinned/health state.
Документация и UX (#250, #252)
- Добавлен
README.ru.md. - В верхней части README появился более заметный переключатель языков EN/RU.
- Docker описан честнее: контейнер полезен для тестов, упаковки и простых запусков, но основной production path проекта - native Linux host под управлением
mtbuddy. - README теперь явно описывает tunnel pool,
pinned_interface, dashboard monitoring/pinning и ограничения Telegram calls / non-Premium media без MiddleProxy. config.toml.exampleобновлён под ordered tunnel pool.THREAT_MODEL.mdдополнен ограничениями по calls/media.
Проверено
python3 -m py_compile src/ctl/dashboard_assets/server.pynode --check src/ctl/dashboard_assets/static/app.js- generated tunnel controller script checked with
bash -n zig build testzig build -Dtarget=x86_64-linuxgit diff --check
🇬🇧 Release notes (EN)
What this release addresses
v0.23.0 is a larger feature release for tunnel pool failover, clearer compatibility documentation, and first-class Russian README coverage.
Before this release, mtbuddy setup tunnel was effectively designed around a single tunnel interface: the proxy marked upstream sockets with SO_MARK=200, and host routing table 200 pointed at one configured awg0. That was fine while the tunnel stayed healthy. Once that route failed, operators had to manually change the interface, rerun routing setup, and keep the current state in their head.
v0.23.0 makes tunnel mode pool-based. mtproto-proxy still keeps one data-plane contract (SO_MARK=200 -> table 200), while mtbuddy manages an ordered pool of tunnels and selects the first healthy interface. If the primary tunnel fails, new upstream connections use the next healthy tunnel. When the higher-priority tunnel recovers, the controller automatically points table 200 back to it unless a manual pin is set.
[!NOTE]
Existing TCP connections are not migrated between tunnels. Failover affects new upstream connections and client reconnects.
[!IMPORTANT]
Telegram calls are still unsupported. Telegram calls depend on SOCKS behavior that cannot be masked properly in this model. Media loading on non-Premium accounts also still requires MiddleProxy; the tunnel pool alone does not make that path reliable.
What changed
Tunnel pool failover (#250)
[upstream.tunnel]now supports an ordered pool:interfaces = ["awg0", "awg1", ...];pinned_interface = "awg1"for manual preference;- legacy
interface = "awg0"remains a compatible fallback.
mtbuddyinstallsmtproto-tunnel-pool.serviceandmtproto-tunnel-pool.timer./usr/local/bin/setup_tunnel.shnow:- brings up all configured pool interfaces;
- ensures
fwmark 200 -> table 200; - probes Telegram through each interface;
- switches the route with
ip -4 route replace default dev <iface> table 200.
- The selection policy is priority auto-failback: the first healthy interface in the list becomes active again when it recovers.
- Automatic failover does not restart
mtproto-proxy.
Tunnel pool setup through mtbuddy (#250)
- Re-running
mtbuddy setup tunnel <conf|vpn://>appends the next freeawgN. - Added
--iface <name>to install or replace a specific pool member. - The interactive wizard now shows:
- VPN type selection (AmneziaWG for now);
- the current tunnel pool;
- an action choice: create a new tunnel or replace an existing one.
- Configs are stored as
/etc/amnezia/amneziawg/<iface>.conf. - Input sanitizing is explicit:
DNSis removed, empty AWG assignments are removed, andTable = offis added.
Runtime and dashboard know the active tunnel (#250)
Configparsesinterfacesandpinned_interfacealongside the legacyinterface.- MiddleProxy metadata refresh no longer assumes one legacy interface; it resolves the active tunnel from table 200 / pool state.
- The dashboard routing card shows the ordered pool, active route, pinned interface, last switch, health reason, and per-interface probe status.
- Dashboard
Set ifaceis now aPinaction: it writespinned_interface, invokes the pool controller once, and does not restart the proxy. /api/stats.routingnow exposes pool/active/pinned/health state.
Documentation and UX (#250, #252)
- Added
README.ru.md. - The README language switcher near the top is now easier to spot.
- Docker documentation is more explicit: containers are useful for testing, packaging, and simple runs, but the main production path is a native Linux host managed by
mtbuddy. - README now documents the tunnel pool,
pinned_interface, dashboard monitoring/pinning, and the Telegram calls / non-Premium media limitations without MiddleProxy. config.toml.examplenow includes the ordered tunnel pool fields.THREAT_MODEL.mddocuments the calls/media limitations.
Verified
python3 -m py_compile src/ctl/dashboard_assets/server.pynode --check src/ctl/dashboard_assets/static/app.js- generated tunnel controller script checked with
bash -n zig build testzig build -Dtarget=x86_64-linuxgit diff --check