v0.25.1
🇷🇺 Что нового (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 --interactive→Setup 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 должен быть будущий
NEXTtrigger и состояние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изmtbuddytest target. - Добавлен regression test на
OnUnitInactiveSec=30sв timer template. - Обновлён один tunnel test под текущий Zig 0.16 file IO API.
Проверено
zig build test --summary all- GitHub Actions:
Test & BuildBench (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 throughsudo mtbuddy --interactive→Setup tunnel, or rerunsudo 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.timerA healthy timer should have a future
NEXTtrigger and showactive (waiting), notactive (elapsed)/Trigger: n/a.
What changed
Tunnel pool timer repeats after each oneshot run again (#291)
mtproto-tunnel-pool.timeris now generated withOnUnitInactiveSec=30s.- The next run is scheduled after
mtproto-tunnel-pool.servicefinishes, matching itsType=oneshotbehavior. - 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 ransetup_tunnel.shinExecStartPre. - 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
mtbuddytest target referencessrc/ctl/tunnel.zig. - Added a regression test for
OnUnitInactiveSec=30sin 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 & BuildBench (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 triggersmtproto-tunnel-pool.service.