v0.24.1
sleep3r/mtproto.zigv0.24.1May 19, 2026by sleep3r
Upgrading?
AI Summary
Fixes tunnel pre-start failures caused by strict Telegram HTTPS probe requirements or missing route tables.
Key Highlights
- Tunnel pre-start no longer fails if the Telegram HTTPS probe is down.
- Policy rule setup is now idempotent and handles existing rules gracefully.
- First run no longer fails on an empty route table 200.
Full Release Notes
<details open> <summary>🇷🇺 Что нового (RU)</summary> ## Что решает этот релиз `v0.24.1` - patch-релиз для операторов, которые настраивают AmneziaWG / WireGuard tunnel mode через `mtbuddy setup tunnel`. В `v0.23.0` tunnel mode перешёл на явный contract `SO_MARK=200 -> table 200`: прокси помечает upstream sockets, а host policy routing отправляет только этот трафик через выбранный tunnel interface. Но в реальном install path нашёлся неприятный edge case: после успешной установки конфига туннеля `mtproto-proxy.service` мог не стартовать, потому что падал `ExecStartPre=/usr/local/bin/setup_tunnel.sh`. Выглядело это так: ```text Restarting proxy...... Job for mtproto-proxy.service failed because the control process exited with error code. Proxy failed to start. Check: journalctl -u mtproto-proxy -n 30 ``` Причин было две: - Telegram HTTPS probe через `curl --interface awg0 https://core.telegram.org/getProxyConfig` считался обязательным условием старта. Если `core.telegram.org`, DNS или HTTPS probe недоступны, pre-start валил весь proxy service, даже когда policy route уже можно было поставить. - На первом запуске table 200 ещё могла не существовать. Команда чтения предыдущего route возвращала non-zero, а `set -euo pipefail` завершал скрипт до выбора tunnel. `v0.24.1` делает pre-start поведение более прагматичным: сервис стартует, если tunnel interface поднят, `awg/wg show` отвечает, policy rule установлен, а `ip route get ... mark 200` реально указывает на выбранный interface. Telegram probe остаётся полезной диагностикой, но больше не блокирует запуск прокси. > [!NOTE] > Конфиг менять не нужно. После обновления достаточно повторить `mtbuddy setup tunnel ...`, чтобы пересоздать `/usr/local/bin/setup_tunnel.sh` и systemd unit с исправленным поведением. > [!TIP] > Если сервер уже застрял на старом `ExecStartPre`, обновите `mtbuddy` до `v0.24.1` и заново выполните tunnel setup с тем же `.conf` или `vpn://` link. ## Что изменено ### Tunnel pre-start больше не зависит от Telegram HTTPS probe ([#269](https://github.com/sleep3r/mtproto.zig/pull/269)) - `curl --interface <iface> https://core.telegram.org/getProxyConfig` больше не является fatal check. - Tunnel считается пригодным, когда: - interface можно поднять через `awg-quick` / `wg-quick`; - `awg show <iface>` / `wg show <iface>` возвращает состояние; - route table 200 указывает default route на выбранный interface; - `ip -4 route get <telegram-dc-ip> mark 200` подтверждает `dev <iface>`. - Если Telegram probe падает, controller пишет reason `policy route ready; Telegram probe failed` и логирует это как диагностику, не ломая `mtproto-proxy.service`. ### Policy rule setup стал идемпотентным ([#269](https://github.com/sleep3r/mtproto.zig/pull/269)) - `fwmark 200 -> table 200` теперь ставится через explicit ensure-step. - Старые rules с тем же `fwmark/table/priority` удаляются перед добавлением нового rule. - После добавления rule скрипт отдельно проверяет, что `ip -4 rule show` действительно содержит нужный `fwmark` mapping. - Это делает повторные запуски `setup_tunnel.sh`, timer failover и `systemctl restart mtproto-proxy` устойчивее к уже существующим rules. ### Первый запуск больше не падает на пустой table 200 ([#269](https://github.com/sleep3r/mtproto.zig/pull/269)) - Чтение предыдущего default route из table 200 теперь допускает отсутствие самой FIB table. - Пустая table 200 больше не завершает script из-за `set -euo pipefail`. - Route всё равно создаётся через `ip -4 route replace default dev <iface> table 200` после выбора tunnel. ### Installer e2e теперь покрывает этот сценарий ([#269](https://github.com/sleep3r/mtproto.zig/pull/269)) - В installer e2e добавлен tunnel regression test. - Тест подставляет fake `awg` / `awg-quick`, создаёт dummy/veth `awg0` и специально ломает только `curl --interface awg0`. - Проверяется, что `mtbuddy setup tunnel`: - успешно рестартит `mtproto-proxy`; - оставляет `mtproto-tunnel-pool.timer` active/enabled; - пишет `active=awg0` и `status=healthy` в pool state; - создаёт `fwmark 200 -> table 200 -> dev awg0`; - не считает падение Telegram probe фатальным. - Debug dump installer e2e теперь сохраняет tunnel rules/routes/state для будущих разборов. ## Проверено - `bash -n test/installer-e2e/run.sh` - `zig build test` - `MTPROTO_INSTALLER_E2E_IMAGES='debian:12' test/installer-e2e/run.sh` </details> --- <details> <summary>🇬🇧 Release notes (EN)</summary> ## What this release addresses `v0.24.1` is a patch release for operators configuring AmneziaWG / WireGuard tunnel mode through `mtbuddy setup tunnel`. `v0.23.0` moved tunnel mode to an explicit `SO_MARK=200 -> table 200` contract: the proxy marks upstream sockets, and host policy routing sends only that traffic through the selected tunnel interface. A real install-path edge case showed up afterwards: tunnel config installation could succeed, but `mtproto-proxy.service` failed to start because `ExecStartPre=/usr/local/bin/setup_tunnel.sh` exited non-zero. It looked like this: ```text Restarting proxy...... Job for mtproto-proxy.service failed because the control process exited with error code. Proxy failed to start. Check: journalctl -u mtproto-proxy -n 30 ``` There were two root causes: - The Telegram HTTPS probe through `curl --interface awg0 https://core.telegram.org/getProxyConfig` was treated as a startup requirement. If `core.telegram.org`, DNS, or that HTTPS probe was unavailable, pre-start failed the whole proxy service even when the policy route could be installed. - On first run, table 200 may not exist yet. Reading the previous route returned non-zero, and `set -euo pipefail` terminated the script before tunnel selection. `v0.24.1` makes pre-start behavior more pragmatic: the service starts when the tunnel interface is up, `awg/wg show` works, the policy rule is installed, and `ip route get ... mark 200` actually resolves through the selected interface. The Telegram probe remains useful diagnostics, but it no longer blocks proxy startup. > [!NOTE] > No config changes are required. After updating, rerun `mtbuddy setup tunnel ...` to regenerate `/usr/local/bin/setup_tunnel.sh` and the systemd unit with the fixed behavior. > [!TIP] > If a server is already stuck on the old `ExecStartPre` failure, update `mtbuddy` to `v0.24.1` and rerun tunnel setup with the same `.conf` or `vpn://` link. ## What changed ### Tunnel pre-start no longer depends on the Telegram HTTPS probe ([#269](https://github.com/sleep3r/mtproto.zig/pull/269)) - `curl --interface <iface> https://core.telegram.org/getProxyConfig` is no longer a fatal check. - A tunnel is considered usable when: - the interface can be brought up with `awg-quick` / `wg-quick`; - `awg show <iface>` / `wg show <iface>` returns state; - route table 200 points its default route at the selected interface; - `ip -4 route get <telegram-dc-ip> mark 200` confirms `dev <iface>`. - If the Telegram probe fails, the controller writes reason `policy route ready; Telegram probe failed` and logs it as diagnostics without breaking `mtproto-proxy.service`. ### Policy rule setup is idempotent ([#269](https://github.com/sleep3r/mtproto.zig/pull/269)) - `fwmark 200 -> table 200` is now installed through an explicit ensure step. - Stale rules with the same `fwmark/table/priority` are removed before adding the new rule. - After adding the rule, the script verifies that `ip -4 rule show` contains the expected `fwmark` mapping. - This makes repeated `setup_tunnel.sh` runs, timer failover, and `systemctl restart mtproto-proxy` more robust when rules already exist. ### First run no longer fails on an empty table 200 ([#269](https://github.com/sleep3r/mtproto.zig/pull/269)) - Reading the previous default route from table 200 now tolerates the FIB table not existing yet. - An empty table 200 no longer exits the script via `set -euo pipefail`. - The route is still created with `ip -4 route replace default dev <iface> table 200` after tunnel selection. ### Installer e2e now covers this scenario ([#269](https://github.com/sleep3r/mtproto.zig/pull/269)) - Added a tunnel regression test to installer e2e. - The test injects fake `awg` / `awg-quick`, creates a dummy/veth `awg0`, and deliberately fails only `curl --interface awg0`. - It verifies that `mtbuddy setup tunnel`: - restarts `mtproto-proxy` successfully; - leaves `mtproto-tunnel-pool.timer` active/enabled; - writes `active=awg0` and `status=healthy` to pool state; - creates `fwmark 200 -> table 200 -> dev awg0`; - does not treat the Telegram probe failure as fatal. - Installer e2e debug dumps now include tunnel rules/routes/state for future investigations. ## Verified - `bash -n test/installer-e2e/run.sh` - `zig build test` - `MTPROTO_INSTALLER_E2E_IMAGES='debian:12' test/installer-e2e/run.sh` </details> ## Changelog * fix: tunnel prestart policy routing ([#269](https://github.com/sleep3r/mtproto.zig/pull/269)) ([7c62b30](https://github.com/sleep3r/mtproto.zig/commit/7c62b30b744c620dab916e92a89ab07fd3e70062)) * chore(main): release 0.24.1 ([#270](https://github.com/sleep3r/mtproto.zig/pull/270)) ([48df22f](https://github.com/sleep3r/mtproto.zig/commit/48df22f))
Related Repositories
lightpanda-io/browser★ 36,854
Lightpanda: the headless browser designed for AI and automation
tigerbeetle/tigerbeetle★ 17,229
The financial transactions database designed for mission critical safety and performance.
nullclaw/nullclaw★ 8,131
Fastest, smallest, and fully autonomous AI assistant infrastructure written in Zig
zml/zml★ 4,194
Any model. Any hardware. Zero compromise. Built with @ziglang / @openxla / MLIR / @bazelbuild
dmtrKovalenko/odiff★ 3,280
A very fast SIMD-first image comparison library (with nodejs API)