v0.25.0
🇷🇺 Что нового (RU)
Что решает этот релиз
v0.25.0 — feature-релиз для операторов, которые используют AmneziaWG / WireGuard tunnel pool через mtbuddy setup tunnel и dashboard.
После нескольких итераций tunnel mode стал надёжнее на старте и failover, но оставался неприятный UX/ops gap: туннель можно было «удалить» руками или заменить частично, а система всё ещё показывала его как настроенный. На практике это проявлялось так:
- в
config.tomlоставалсяinterfaces = ["awg0"]или legacyinterface = "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 --interactive→Setup tunnelили dashboard, проверьте список и удалите ненужные интерфейсы явно.
[!TIP]
Если после ручной чистки dashboard всё ещё показываетawg0/awg1, обновитесь доv0.25.0и удалите stale entry через новый delete action. Он чистит config,.conf, runtime state и policy routing в одном потоке.
Что изменено
TUI теперь управляет tunnel pool, а не только создаёт его (#272)
mtbuddy --interactive→Setup 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 downwhere 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 200rules и route table 200; - восстанавливает обычный
mtproto-proxy.serviceбез tunnelExecStartPre; - рестартит
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иconfigsources, чтобы stale files были видны оператору, а не прятались за fallbackawg0.
Empty tunnel pool больше не превращается обратно в awg0 (#272)
- Dashboard parser теперь отличает отсутствие
interfacesот явно заданногоinterfaces = []. - Если pool явно пустой, UI/API не подставляют fallback
awg0как «настроенный туннель». - Это важно после удаления последнего tunnel: пустой pool остаётся пустым, а не выглядит как новый
awg0.
Проверено
zig build testpython3 -m py_compile src/ctl/dashboard_assets/server.pynode --check src/ctl/dashboard_assets/static/app.js- GitHub Actions:
Test & BuildE2E IntegrationBench (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.tomlstill containinginterfaces = ["awg0"]or legacyinterface = "awg0";- stale
/etc/amnezia/amneziawg/awg0.conf,awg1.conf, or/etc/wireguard/<iface>.conffiles remaining on disk; /run/mtproto-proxy/tunnel-pool.statestill reportingactive=awg0;mtproto-tunnel-pool.timerand table 200 still being present;- interactive
mtbuddy setup tunneloffering the nextawgNeven 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, opensudo mtbuddy --interactive→Setup tunnelor the dashboard, review the list, and explicitly delete any stale interfaces.
[!TIP]
If a server still showsawg0/awg1after manual cleanup, update tov0.25.0and remove the stale entry through the new delete action. It cleans config,.conffiles, runtime state, and policy routing in one flow.
What changed
TUI now manages the tunnel pool instead of only creating it (#272)
mtbuddy --interactive→Setup tunnelnow shows current tunnel interfaces before asking for an action.- The list includes both
[upstream.tunnel].interfacesfromconfig.tomland stale.conffiles 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].interfaceto the first remaining member; - clears
pinned_interfaceif the pinned interface was removed; - brings the tunnel down through
awg-quick down/wg-quick downwhen 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.confforawg0.
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].typeback toauto; - writes
interfaces = [],interface = "", andpinned_interface = ""; - disables
mtproto-tunnel-pool.timerand stops the pool service; - removes
/usr/local/bin/setup_tunnel.shand/run/mtproto-proxy/tunnel-pool.state; - clears
fwmark 200 -> table 200rules and route table 200; - restores the regular
mtproto-proxy.servicewithout the tunnelExecStartPre; - restarts
mtproto-proxywithout 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
Deletebutton with a confirmation modal. - New API endpoint:
POST /api/routing/tunnel-deletewith 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
poolandconfigsources so stale files are visible to operators instead of being hidden behind theawg0fallback.
Empty tunnel pools no longer become awg0 again (#272)
- The dashboard parser now distinguishes a missing
interfaceskey from an explicitinterfaces = []. - When the pool is explicitly empty, the UI/API do not inject fallback
awg0as a configured tunnel. - This matters after deleting the last tunnel: an empty pool stays empty instead of looking like a fresh
awg0setup.
Verified
zig build testpython3 -m py_compile src/ctl/dashboard_assets/server.pynode --check src/ctl/dashboard_assets/static/app.js- GitHub Actions:
Test & BuildE2E IntegrationBench (No Soak)- installer e2e:
debian:12 - installer e2e:
ubuntu:24.04