github sleep3r/mtproto.zig v0.25.1

latest releases: v1.15.2, v1.15.1, v1.15.0...
3 months ago
🇷🇺 Что нового (RU)

Что решает этот релиз

v0.25.1 — patch-релиз для операторов, которые используют AmneziaWG / WireGuard tunnel mode через mtbuddy setup tunnel.

В v0.25.0 tunnel pool получил нормальный lifecycle management: TUI и dashboard научились видеть, заменять и удалять tunnel interfaces. Но в production-варианте обнаружился отдельный systemd edge case: mtproto-tunnel-pool.timer мог быть enabled, но больше не запускать periodic failover checks.

Выглядело это так:

mtproto-tunnel-pool.timer: active (elapsed)
Trigger: n/a
LastTriggerUSec: Sat 2026-05-23 ...

Из-за этого setup_tunnel.sh не перепроверял tunnel health и не переустанавливал fwmark 200 -> table 200 -> awg0. Если route/tunnel state деградировал, пользовательские соединения могли зависать на MTProto handshake, а ручной restart mtproto-proxy временно всё лечил, потому что mtproto-proxy.service снова запускал:

ExecStartPre=/usr/local/bin/setup_tunnel.sh

Корень проблемы был в systemd timer contract для oneshot service: timer использовал OnUnitActiveSec=30s, а mtproto-tunnel-pool.service — это короткий Type=oneshot. Для таких health-check jobs надёжнее планировать следующий запуск от момента завершения unit, то есть через OnUnitInactiveSec=30s.

v0.25.1 меняет timer template именно на это поведение и добавляет regression test, чтобы future mtbuddy setup tunnel больше не генерировал одноразовый elapsed timer.

[!NOTE]
Обновление бинарника само по себе не переписывает уже установленный /etc/systemd/system/mtproto-tunnel-pool.timer. После обновления заново выполните tunnel setup через sudo mtbuddy --interactiveSetup tunnel или повторите sudo mtbuddy setup tunnel ... с текущим tunnel config/link, чтобы regenerate systemd units.

[!TIP]
После regeneration проверьте:

systemctl list-timers mtproto-tunnel-pool.timer --all
systemctl status mtproto-tunnel-pool.timer

У здорового timer должен быть будущий NEXT trigger и состояние active (waiting), а не active (elapsed) / Trigger: n/a.

Что изменено

Tunnel pool timer снова повторяется после oneshot run (#291)

  • mtproto-tunnel-pool.timer теперь генерируется с OnUnitInactiveSec=30s.
  • Следующий запуск планируется после завершения mtproto-tunnel-pool.service, что подходит для Type=oneshot.
  • Periodic failover checks снова продолжают:
    • поднимать/проверять configured tunnel interfaces;
    • обновлять route table 200;
    • подтверждать ip route get ... mark 200;
    • писать свежий /run/mtproto-proxy/tunnel-pool.state.

Рестарт прокси больше не должен быть единственным способом «оживить» tunnel route (#291)

  • До фикса route refresh мог происходить только при systemctl restart mtproto-proxy, потому что proxy unit запускал setup_tunnel.sh в ExecStartPre.
  • После regeneration timer сам продолжает выполнять tunnel pool controller.
  • Это закрывает класс ситуаций, где MTProto connections застревают в hs_inflight, а ручной restart выглядит как единственное восстановление.

Тесты mtbuddy теперь реально подтягивают tunnel command tests (#291)

  • Добавлен test hook для src/ctl/tunnel.zig из mtbuddy test target.
  • Добавлен regression test на OnUnitInactiveSec=30s в timer template.
  • Обновлён один tunnel test под текущий Zig 0.16 file IO API.

Проверено

  • zig build test --summary all
  • GitHub Actions:
    • Test & Build
    • Bench (No Soak)
    • E2E Integration
    • installer e2e: debian:12
    • installer e2e: ubuntu:24.04
  • На affected host проверено, что обновлённый timer переходит в active (waiting) и повторно запускает mtproto-tunnel-pool.service.

🇬🇧 Release notes (EN)

What this release addresses

v0.25.1 is a patch release for operators using AmneziaWG / WireGuard tunnel mode through mtbuddy setup tunnel.

v0.25.0 added proper tunnel pool lifecycle management: the TUI and dashboard can now inspect, replace, and delete tunnel interfaces. A separate production systemd edge case showed up afterwards: mtproto-tunnel-pool.timer could remain enabled while no longer scheduling periodic failover checks.

It looked like this:

mtproto-tunnel-pool.timer: active (elapsed)
Trigger: n/a
LastTriggerUSec: Sat 2026-05-23 ...

As a result, setup_tunnel.sh stopped rechecking tunnel health and stopped refreshing fwmark 200 -> table 200 -> awg0. If route or tunnel state degraded, user connections could get stuck during MTProto handshake, while manually restarting mtproto-proxy appeared to fix it because the proxy unit ran:

ExecStartPre=/usr/local/bin/setup_tunnel.sh

The root cause was the timer contract for a oneshot service: the timer used OnUnitActiveSec=30s, while mtproto-tunnel-pool.service is a short Type=oneshot job. For this kind of health check, the next run should be scheduled after the unit exits, using OnUnitInactiveSec=30s.

v0.25.1 changes the generated timer template to that behavior and adds a regression test so future mtbuddy setup tunnel runs no longer create a one-shot elapsed timer.

[!NOTE]
Updating the binary alone does not rewrite an already installed /etc/systemd/system/mtproto-tunnel-pool.timer. After updating, rerun tunnel setup through sudo mtbuddy --interactiveSetup tunnel, or rerun sudo mtbuddy setup tunnel ... with the current tunnel config/link to regenerate the systemd units.

[!TIP]
After regeneration, check:

systemctl list-timers mtproto-tunnel-pool.timer --all
systemctl status mtproto-tunnel-pool.timer

A healthy timer should have a future NEXT trigger and show active (waiting), not active (elapsed) / Trigger: n/a.

What changed

Tunnel pool timer repeats after each oneshot run again (#291)

  • mtproto-tunnel-pool.timer is now generated with OnUnitInactiveSec=30s.
  • The next run is scheduled after mtproto-tunnel-pool.service finishes, matching its Type=oneshot behavior.
  • Periodic failover checks keep:
    • bringing up/checking configured tunnel interfaces;
    • refreshing route table 200;
    • validating ip route get ... mark 200;
    • writing fresh /run/mtproto-proxy/tunnel-pool.state.

Restarting the proxy should no longer be the only way to refresh tunnel routing (#291)

  • Before this fix, route refresh could happen only on systemctl restart mtproto-proxy, because the proxy unit ran setup_tunnel.sh in ExecStartPre.
  • After regenerating the units, the timer continues running the tunnel pool controller by itself.
  • This closes the class of incidents where MTProto connections accumulate in hs_inflight, while a manual proxy restart looks like the only recovery path.

mtbuddy tests now include tunnel command tests (#291)

  • Added a test hook so the mtbuddy test target references src/ctl/tunnel.zig.
  • Added a regression test for OnUnitInactiveSec=30s in the generated timer template.
  • Updated one tunnel test to the current Zig 0.16 file IO API.

Verified

  • zig build test --summary all
  • GitHub Actions:
    • Test & Build
    • Bench (No Soak)
    • E2E Integration
    • installer e2e: debian:12
    • installer e2e: ubuntu:24.04
  • Verified on the affected host that the updated timer enters active (waiting) and repeatedly triggers mtproto-tunnel-pool.service.

Changelog

Don't miss a new mtproto.zig release

NewReleases is sending notifications on new releases.