Skip to content

v0.25.0

Choose a tag to compare

@sleep3r sleep3r released this 24 May 10:42
f37e418
🇷🇺 Что нового (RU)

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

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

После нескольких итераций tunnel mode стал надёжнее на старте и failover, но оставался неприятный UX/ops gap: туннель можно было «удалить» руками или заменить частично, а система всё ещё показывала его как настроенный. На практике это проявлялось так:

  • в config.toml оставался interfaces = ["awg0"] или legacy interface = "awg0";
  • на диске лежали старые /etc/amnezia/amneziawg/awg0.conf, awg1.conf или /etc/wireguard/<iface>.conf;
  • /run/mtproto-proxy/tunnel-pool.state продолжал говорить active=awg0;
  • mtproto-tunnel-pool.timer и table 200 могли жить дальше;
  • интерактивный mtbuddy setup tunnel предлагал создать следующий awgN, хотя оператор ожидал пустой пул.

v0.25.0 добавляет нормальное управление жизненным циклом tunnel pool: теперь в TUI и dashboard можно увидеть реальные tunnel interfaces, понять их состояние и удалить stale tunnel полностью, а не только поправить одну строку конфига.

[!NOTE]
Это не автоматическая миграция и не удаляет туннели само по себе. После обновления откройте sudo mtbuddy --interactiveSetup tunnel или dashboard, проверьте список и удалите ненужные интерфейсы явно.

[!TIP]
Если после ручной чистки dashboard всё ещё показывает awg0 / awg1, обновитесь до v0.25.0 и удалите stale entry через новый delete action. Он чистит config, .conf, runtime state и policy routing в одном потоке.

Что изменено

TUI теперь управляет tunnel pool, а не только создаёт его (#272)

  • mtbuddy --interactiveSetup tunnel теперь показывает текущие tunnel interfaces перед выбором действия.
  • Список включает не только [upstream.tunnel].interfaces из config.toml, но и stale .conf файлы из:
    • /etc/amnezia/amneziawg/*.conf;
    • /etc/wireguard/*.conf.
  • Для каждого интерфейса показывается runtime status:
    • active — interface поднят и handshake был;
    • up, no handshake — interface есть, endpoint есть, но handshake ещё не состоялся;
    • up, no endpoint / up, show failed — interface поднят, но состояние неполное;
    • down — interface/config найден, но link сейчас отсутствует.
  • В меню появились действия:
    • create new tunnel;
    • replace existing tunnel;
    • delete tunnel.

Delete tunnel делает hard cleanup (#272)

При удалении интерфейса mtbuddy теперь:

  • удаляет interface из [upstream.tunnel].interfaces;
  • обновляет legacy [upstream.tunnel].interface на первый оставшийся member;
  • очищает pinned_interface, если pinned interface удалён;
  • останавливает tunnel через awg-quick down / wg-quick down where available;
  • удаляет link через ip link delete dev <iface> как fallback cleanup;
  • удаляет known config files:
    • /etc/amnezia/amneziawg/<iface>.conf;
    • /etc/wireguard/<iface>.conf;
    • legacy /etc/amnezia/awg0.conf для awg0.

Если в пуле остаются другие туннели, controller запускается ещё раз, чтобы table 200 переехала на следующий доступный interface.

Last tunnel removal возвращает proxy в обычный режим (#272)

Если удалён последний tunnel member, mtbuddy теперь дополнительно:

  • переключает [upstream].type обратно в auto;
  • записывает interfaces = [], interface = "", pinned_interface = "";
  • отключает mtproto-tunnel-pool.timer и останавливает pool service;
  • удаляет /usr/local/bin/setup_tunnel.sh и /run/mtproto-proxy/tunnel-pool.state;
  • чистит fwmark 200 -> table 200 rules и route table 200;
  • восстанавливает обычный mtproto-proxy.service без tunnel ExecStartPre;
  • рестартит mtproto-proxy уже без tunnel policy routing.

Это закрывает класс ситуаций, где «туннелей уже нет», но systemd / route table / runtime state продолжают вести себя так, будто tunnel mode всё ещё активен.

Dashboard получил тот же delete flow (#272)

  • Routing card теперь видит stale tunnel config files, даже если они не входят в TOML pool.
  • У tunnel row появилась кнопка Delete с confirmation modal.
  • Новый API endpoint: POST /api/routing/tunnel-delete с body { "interface": "awg0" }.
  • API делает тот же cleanup contract, что и TUI:
    • config pool update;
    • interface shutdown;
    • config file deletion;
    • last-tunnel cleanup;
    • proxy restart;
    • routing cache invalidation.
  • Dashboard различает pool и config sources, чтобы stale files были видны оператору, а не прятались за fallback awg0.

Empty tunnel pool больше не превращается обратно в awg0 (#272)

  • Dashboard parser теперь отличает отсутствие interfaces от явно заданного interfaces = [].
  • Если pool явно пустой, UI/API не подставляют fallback awg0 как «настроенный туннель».
  • Это важно после удаления последнего tunnel: пустой pool остаётся пустым, а не выглядит как новый awg0.

Проверено

  • zig build test
  • python3 -m py_compile src/ctl/dashboard_assets/server.py
  • node --check src/ctl/dashboard_assets/static/app.js
  • GitHub Actions:
    • Test & Build
    • E2E Integration
    • Bench (No Soak)
    • installer e2e: debian:12
    • installer e2e: ubuntu:24.04

🇬🇧 Release notes (EN)

What this release addresses

v0.25.0 is a feature release for operators using the AmneziaWG / WireGuard tunnel pool through mtbuddy setup tunnel and the dashboard.

Tunnel mode had become more reliable around startup and failover, but it still had a painful UX/ops gap: an operator could partially remove or replace a tunnel, while the system continued to show it as configured. In practice this looked like:

  • config.toml still containing interfaces = ["awg0"] or legacy interface = "awg0";
  • stale /etc/amnezia/amneziawg/awg0.conf, awg1.conf, or /etc/wireguard/<iface>.conf files remaining on disk;
  • /run/mtproto-proxy/tunnel-pool.state still reporting active=awg0;
  • mtproto-tunnel-pool.timer and table 200 still being present;
  • interactive mtbuddy setup tunnel offering the next awgN even when the operator expected an empty pool.

v0.25.0 adds proper tunnel pool lifecycle management: both the TUI and dashboard can now show real tunnel interfaces, explain their state, and delete stale tunnels fully instead of only editing one config key.

[!NOTE]
This is not an automatic migration and does not delete tunnels by itself. After updating, open sudo mtbuddy --interactiveSetup tunnel or the dashboard, review the list, and explicitly delete any stale interfaces.

[!TIP]
If a server still shows awg0 / awg1 after manual cleanup, update to v0.25.0 and remove the stale entry through the new delete action. It cleans config, .conf files, runtime state, and policy routing in one flow.

What changed

TUI now manages the tunnel pool instead of only creating it (#272)

  • mtbuddy --interactiveSetup tunnel now shows current tunnel interfaces before asking for an action.
  • The list includes both [upstream.tunnel].interfaces from config.toml and stale .conf files from:
    • /etc/amnezia/amneziawg/*.conf;
    • /etc/wireguard/*.conf.
  • Each interface gets a runtime status:
    • active — the interface is up and has completed a handshake;
    • up, no handshake — the interface and endpoint exist, but no handshake has happened yet;
    • up, no endpoint / up, show failed — the link is present, but state is incomplete;
    • down — a config or pool entry exists, but the link is currently absent.
  • The menu now supports:
    • create new tunnel;
    • replace existing tunnel;
    • delete tunnel.

Delete tunnel performs hard cleanup (#272)

When deleting an interface, mtbuddy now:

  • removes the interface from [upstream.tunnel].interfaces;
  • updates legacy [upstream.tunnel].interface to the first remaining member;
  • clears pinned_interface if the pinned interface was removed;
  • brings the tunnel down through awg-quick down / wg-quick down when available;
  • deletes the link through ip link delete dev <iface> as fallback cleanup;
  • removes known config files:
    • /etc/amnezia/amneziawg/<iface>.conf;
    • /etc/wireguard/<iface>.conf;
    • legacy /etc/amnezia/awg0.conf for awg0.

If other pool members remain, the pool controller is run once so table 200 moves to the next available interface.

Last tunnel removal returns the proxy to normal mode (#272)

When the removed tunnel was the last pool member, mtbuddy also:

  • switches [upstream].type back to auto;
  • writes interfaces = [], interface = "", and pinned_interface = "";
  • disables mtproto-tunnel-pool.timer and stops the pool service;
  • removes /usr/local/bin/setup_tunnel.sh and /run/mtproto-proxy/tunnel-pool.state;
  • clears fwmark 200 -> table 200 rules and route table 200;
  • restores the regular mtproto-proxy.service without the tunnel ExecStartPre;
  • restarts mtproto-proxy without tunnel policy routing.

This closes the class of issues where “all tunnels are gone” but systemd, route table, or runtime state still behaves as if tunnel mode is active.

Dashboard now has the same delete flow (#272)

  • The Routing card now detects stale tunnel config files even when they are not in the TOML pool.
  • Tunnel rows have a Delete button with a confirmation modal.
  • New API endpoint: POST /api/routing/tunnel-delete with body { "interface": "awg0" }.
  • The API follows the same cleanup contract as the TUI:
    • config pool update;
    • interface shutdown;
    • config file deletion;
    • last-tunnel cleanup;
    • proxy restart;
    • routing cache invalidation.
  • The dashboard distinguishes pool and config sources so stale files are visible to operators instead of being hidden behind the awg0 fallback.

Empty tunnel pools no longer become awg0 again (#272)

  • The dashboard parser now distinguishes a missing interfaces key from an explicit interfaces = [].
  • When the pool is explicitly empty, the UI/API do not inject fallback awg0 as a configured tunnel.
  • This matters after deleting the last tunnel: an empty pool stays empty instead of looking like a fresh awg0 setup.

Verified

  • zig build test
  • python3 -m py_compile src/ctl/dashboard_assets/server.py
  • node --check src/ctl/dashboard_assets/static/app.js
  • GitHub Actions:
    • Test & Build
    • E2E Integration
    • Bench (No Soak)
    • installer e2e: debian:12
    • installer e2e: ubuntu:24.04

Changelog