Skip to content

Releases: sleep3r/mtproto.zig

v0.20.1

25 Apr 09:13
16abcba

Choose a tag to compare

🇷🇺 Что нового (RU)

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

Этот релиз содержит набор важных исправлений для дашборда и безопасности установки.

Что изменено

  • Защита порта (#211): Инсталлятор и сам прокси теперь проверяют, чтобы порт прокси не совпадал с портом маскировки Nginx (8443). Это предотвращает тихие падения сервиса при неверной конфигурации.
  • Установка UV: Скрипт установки менеджера пакетов uv (используется для дашборда) переведён с astral.sh на прямую загрузку из GitHub Releases. Это решает проблему недоступности astral.sh в некоторых регионах.
  • Парсинг конфига дашборда (#213): Исправлен баг, из-за которого секция [monitor] в config.toml могла игнорироваться, если она содержала незначительные отклонения от стандарта TOML (из-за молчаливого падения tomllib). Теперь используется надёжный построчный парсер, как и во всём остальном прокси.
  • Grafana Dashboard (#214): Добавлен недостающий файл mtproto-zig-grafana.json, на который ссылалась документация по Docker. Теперь можно сразу импортировать дашборд со всеми прокси-метриками.

Изменений в конфигурации не требуется.


🇬🇧 Release notes (EN)

What this release addresses

This release brings a set of important bugfixes for the monitoring dashboard and installation safety.

What changed

  • Port Conflict Guard (#211): The installer and proxy runtime now actively prevent binding the proxy to the same port as the Nginx zero-RTT masking server (8443), avoiding silent service failures on misconfiguration.
  • UV Installation: The uv package manager bootstrap script (used by the dashboard) now downloads directly from GitHub Releases instead of astral.sh, bypassing regional network blocks.
  • Dashboard Config Parsing (#213): Fixed a bug where the [monitor] section in config.toml could be completely ignored due to silent parsing failures in tomllib. It now uses a robust line-by-line parser consistent with the rest of the proxy codebase.
  • Grafana Dashboard (#214): Added the missing mtproto-zig-grafana.json file referenced in the Docker documentation, providing a ready-to-import Grafana dashboard with comprehensive metrics visualization.

No configuration changes required.

Changelog

  • fix: resolve dashboard config parsing, UV installation, port conflicts, and Grafana dashboard (#215)

v0.20.0

22 Apr 17:58
683d2fe

Choose a tag to compare

🇷🇺 Что нового (RU)

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

Релиз улучшает операционный UX dashboard и исправляет некорректный учёт активных сессий по пользователям.

  • Управление пользователями стало проще: можно быстро отключать/включать доступ прямо из UI.
  • Метрики подключений стали прозрачнее: видно не только общее active, но и распределение по пользователям.

[!NOTE]
Сумма сессий по пользователям может быть меньше active в моменте: часть соединений может находиться в handshake-стадии и ещё не быть атрибутированной конкретному пользователю.

Что изменено

Dashboard: toggle пользователя и UX формы (#207)

  • Добавлен enable/disable toggle в списке пользователей.
  • Отключённый пользователь переносится из [access.users] в [access.disabled_users] (и обратно при включении).
  • Исправлен баг, из-за которого поля SOCKS5/HTTP upstream сбрасывались во время ввода на каждом poll-цикле.

Метрики сессий: корректность и наблюдаемость

  • Исправлен декремент per-user connections_active при закрытии соединения.
  • В conn stats добавлены агрегаты users_total и unassigned.
  • В dashboard добавлены users_active_total и unassigned_active, а также более явное отображение sessions X/Y.

Изменений в конфигурации не требуется.


🇬🇧 Release notes (EN)

What this release addresses

This release improves dashboard operability and fixes per-user active session accounting.

  • User management is now faster: access can be disabled/enabled directly from the UI.
  • Connection metrics are clearer: you can see both total active and user-attributed session counts.

[!NOTE]
The sum of per-user sessions can be lower than active at a given moment: some connections may still be in handshake stage and not yet attributed to a specific user.

What changed

Dashboard: user toggle and form UX (#207)

  • Added per-user enable/disable toggle in the users list.
  • Disabled users are moved from [access.users] to [access.disabled_users] (and moved back when re-enabled).
  • Fixed SOCKS5/HTTP upstream inputs being reset while typing on each poll cycle.

Session metrics: correctness and observability

  • Fixed per-user connections_active decrement on connection teardown.
  • Added users_total and unassigned aggregates to conn stats logs.
  • Added users_active_total and unassigned_active to dashboard output, plus clearer sessions X/Y presentation.

No configuration changes required.

Changelog

  • feat(dashboard): user toggle, per-user session tooltip, input fix (#207) (b5eb3dc)

v0.19.3

21 Apr 17:53
15da747

Choose a tag to compare

🇷🇺 Что нового (RU)

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

Исправлена порча config.toml при добавлении пользователя через веб-панель мониторинга (/api/users/add). После чистой установки конфиг генерировался без завершающего перевода строки — новая запись склеивалась с предыдущей, и парсер переставал видеть обоих пользователей.

[!NOTE]
Баг проявлялся только при добавлении пользователя через dashboard. Ручное редактирование config.toml не затронуто.

Что изменено

Dashboard: корректная запись пользователей (#204)

  • server.py_add_user_to_config, _remove_user_from_config, _set_user_direct: перед вставкой/удалением строк файл нормализуется — если последняя строка не заканчивается \n, перевод строки добавляется автоматически.
  • toml.zigTomlDoc.save(): каждая строка теперь всегда завершается \n, что исключает генерацию конфигов без завершающего перевода строки при установке.

Изменений в конфигурации не требуется.


🇬🇧 Release notes (EN)

What this release addresses

Fixed config.toml corruption when adding a user via the monitoring dashboard (/api/users/add). After a clean install the config was generated without a trailing newline — the new entry was concatenated onto the previous line, causing the parser to lose both users.

[!NOTE]
This bug only affected user addition through the dashboard. Manual config.toml editing was not impacted.

What changed

Dashboard: correct user entry writing (#204)

  • server.py_add_user_to_config, _remove_user_from_config, _set_user_direct: the file is now normalised before insertion/removal — if the last line does not end with \n, a newline is appended automatically.
  • toml.zigTomlDoc.save(): every line is now unconditionally terminated with \n, preventing the installer from generating configs without a trailing newline.

No configuration changes required.

Changelog

  • fix(dashboard): fix config corruption on user add missing trailing newline (#204) (811b0f7)

v0.19.2

20 Apr 22:10
72db381

Choose a tag to compare

🇷🇺 Что нового (RU)

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

Исправлены неактуальные bundled-адреса MiddleProxy, которые используются как fallback при первом запуске — до того, как прокси загрузит актуальный getProxyConfig из Telegram.

Note

На работающем прокси эти адреса перезаписываются runtime-обновлением из core.telegram.org. Исправление затрагивает только сценарий, когда прокси стартует впервые и refresh ещё не отработал (или не может отработать, например, из-за блокировки без настроенного туннеля).

Что изменено

Bundled MiddleProxy адреса (#199)

Сверка с реальным выводом getProxyConfig выявила три расхождения:

DC Тип Было Стало (реальный)
5 media (proxy_for -5) 91.108.56.180:8888 91.108.56.170:8888
4 regular (proxy_for 4) 91.108.4.136:8888 91.108.4.169:8888
5 regular (proxy_for 5) 91.108.56.183:8888 91.108.56.170:8888

Адрес media DC5 содержал опечатку (.180 вместо .170), адреса regular DC4/DC5 устарели.

Изменений в конфигурации не требуется.


🇬🇧 Release notes (EN)

What this release addresses

Corrected stale bundled MiddleProxy fallback addresses used during first startup — before the proxy fetches the live getProxyConfig from Telegram.

Note

On a running proxy these addresses are overwritten by the runtime refresh from core.telegram.org. This fix only affects the scenario where the proxy starts for the first time and the refresh hasn't completed yet (or can't complete, e.g. blocked network without a configured tunnel).

What changed

Bundled MiddleProxy addresses (#199)

Cross-checked against live getProxyConfig output, three mismatches were found:

DC Type Was Now (actual)
5 media (proxy_for -5) 91.108.56.180:8888 91.108.56.170:8888
4 regular (proxy_for 4) 91.108.4.136:8888 91.108.4.169:8888
5 regular (proxy_for 5) 91.108.56.183:8888 91.108.56.170:8888

The media DC5 address had a typo (.180 instead of .170); the regular DC4/DC5 addresses were outdated.

No configuration changes required.

Changelog

  • fix(constants): correct bundled middle-proxy addresses to match getProxyConfig (#199) (20c5089)

v0.19.1

20 Apr 21:49
bd83a86

Choose a tag to compare

🇷🇺 Что нового (RU)

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

Комплексное укрепление надёжности, безопасности и производительности прокси по итогам code review. Главные пользовательские эффекты:

  • Медиа-трафик больше не тормозит. Прокси теперь различает обычные и медиа‑MiddleProxy и маршрутизирует фото/видео через выделенный media‑MP флот Telegram. Ранее все запросы шли на один MP, что вызывало стеллы и сбросы при загрузке медиа.
  • Прокси на цензурируемых хостах обновляет конфигурацию MP через туннель. Если core.telegram.org заблокирован, прокси автоматически фоллбэчит на curl --interface <tunnel> и прогревает кэш MP в первые минуты работы (а не через 24 часа).
  • Устранены уязвимости: коллизия IPv4-mapped IPv6 в rate limiter, потенциальная коррупция данных в SOCKS5/HTTP CONNECT, переполнение буфера MiddleProxy, паника @memcpy при формировании nonce.
  • Повышена производительность: O(1) поиск секрета вместо O(N), streaming HMAC без аллокации ~3 KB, корректный DRS при отключённом anti-DPI.

Что изменено

Безопасность и корректность

  • Rate-limit: IPv4-mapped IPv6 (#197)

    • На dual-stack [::] listener'ах все IPv4-клиенты приходят как ::ffff:a.b.c.d. Без патча они коллапсировали в один subnet key, и весь IPv4 интернет делил один token bucket.
    • subnetKey() теперь детектирует IPv4-mapped адреса и применяет IPv4-specific /24 логику.
  • SOCKS5/HTTP CONNECT pipelined data

    • Лишние байты после успешного SOCKS5/HTTP CONNECT handshake теперь приводят к закрытию соединения с предупреждением вместо потенциальной коррупции протокола.
  • MiddleProxy buffer overflow

    • Scratch-буфер mp_c2s_scratch теперь выделяется с запасом ×96 (реальный worst-case расширения обфускации) + 256 байт заголовков.
  • MiddleProxy nonce selector fix

    • Исправлена регрессия формирования nonce-фрейма: 4 байта ключевого селектора корректно копируются побайтово вместо потенциально паникующего @memcpy.
  • TOML escape tracking (src/ctl/toml.zig)

    • При удалении инлайн-комментариев теперь учитывается escaped-состояние (символ # внутри экранированной последовательности не считается началом комментария).

Производительность

  • O(1) secret resolution

    • В finishClientHandshake используется slot.validation_secret напрямую вместо перебора всего списка пользователей.
  • Streaming HMAC (src/protocol/tls.zig)

    • В buildServerHelloWithTemplate убрана heap-аллокация ~3 KB: данные теперь подаются в хэшер потоково.
  • DRS init при drs = false

    • Когда Dynamic Record Sizing отключён, инициализация теперь стартует с full_size (16384), а не с 1369 — нет смысла клэмпить записи при отключённом anti-DPI.

Медиа-aware MiddleProxy routing (ключевое изменение)

  • Bundled media MP addresses (src/protocol/constants.zig)

    • Добавлен массив tg_media_middle_proxies_v4 с отдельными адресами для media‑MP, чтобы proxy_for -N endpoints были доступны даже без подключения к core.telegram.org.
  • DcSignFilter в парсере getProxyConfig

    • parseMiddleProxyAddressesForDc() теперь принимает фильтр positive_only (обычный трафик) / negative_only (медиа) / any (legacy), корректно разделяя два пула MP.
  • MiddleProxySnapshot с media-полями

    • Добавлены addrs_media_primary[5] и addrs_media_dc4[16] для хранения media‑MP.
    • getForDc() принимает media: bool и возвращает соответствующий endpoint.
  • buildDcConnectPlan() с media fallback

    • Если is_media_path — используется media-MP; если media-пул пуст — fallback на обычный MP.

Работа из цензурируемой сети

  • fetchUrlBytesViaInterface() — curl-based fallback

    • Когда прямой HTTP к core.telegram.org недоступен и сконфигурирован tunnel upstream, прокси вызывает curl --interface <tunnel_iface>.
    • Исправлена передача аргументов: --interface и значение как два отдельных элемента argv (не --interface=val).
  • Early retry loop в middleProxyUpdaterMain()

    • Перед переходом к 24-часовому циклу обновления MP выполняются ретраи с нарастающими интервалами: 10 с → 30 с → 1 мин → 5 мин → 30 мин.
    • На цензурируемом хосте кэш MP с media-endpoints прогревается в первые минуты, а не на следующие сутки.

Edge-cases

  • ENOBUFS / TCP aborts — корректная обработка error.SystemResources и benign TCP-abort в acceptNewConnections.
  • @memcpy panic guard — в middleProxyBegin предварительный @memset и условное побайтовое копирование ключевого селектора.

Tip

Обновление не требует изменения конфигурации. Все bundled MP-адреса автоматически обновляются из getProxyConfig при наличии связности (напрямую или через туннель).


🇬🇧 Release notes (EN)

What this release addresses

Comprehensive hardening of proxy reliability, security, and performance based on code review findings. Key user-visible effects:

  • Media traffic no longer stalls. The proxy now distinguishes regular vs media MiddleProxy endpoints and routes photo/video downloads through Telegram's dedicated media MP fleet. Previously all traffic was routed to the same MP, causing stalls and connection resets on large media downloads.
  • Proxy on censored hosts refreshes MP config via tunnel. When core.telegram.org is blocked, the proxy automatically falls back to curl --interface <tunnel> and warms the MP cache within the first few minutes (instead of waiting 24 hours).
  • Security fixes: IPv4-mapped IPv6 rate-limiter collision, potential SOCKS5/HTTP CONNECT data corruption, MiddleProxy buffer overflow, @memcpy panic in nonce frame construction.
  • Performance improvements: O(1) secret lookup instead of O(N), streaming HMAC without ~3 KB allocation, correct DRS initialization when anti-DPI is disabled.

What changed

Security & correctness

  • Rate-limit: IPv4-mapped IPv6 (#197)

    • On dual-stack [::] listeners, all IPv4 clients arrive as ::ffff:a.b.c.d. Without this fix they collapsed to a single subnet key, sharing one token bucket across the entire IPv4 internet.
    • subnetKey() now detects mapped addresses and applies IPv4-specific /24 logic.
  • SOCKS5/HTTP CONNECT pipelined data

    • Extra bytes after a successful SOCKS5/HTTP CONNECT handshake now cause the connection to be closed with a warning, preventing potential protocol corruption.
  • MiddleProxy buffer overflow

    • The mp_c2s_scratch buffer now allocates ×96 headroom (real worst-case obfuscation expansion) + 256 bytes for headers.
  • MiddleProxy nonce selector fix

    • Fixed a regression in nonce frame construction: 4 bytes of the key selector are now safely copied byte-by-byte instead of using a potentially panicking @memcpy.
  • TOML escape tracking (src/ctl/toml.zig)

    • Inline comment removal now respects the escaped state — a # inside an escape sequence is no longer treated as a comment start.

Performance

  • O(1) secret resolutionfinishClientHandshake now uses slot.validation_secret directly instead of iterating all users.
  • Streaming HMAC (src/protocol/tls.zig) — removed ~3 KB heap allocation from buildServerHelloWithTemplate; data is now fed to the hasher in a streaming fashion.
  • DRS init when drs = false — when Dynamic Record Sizing is disabled, initialization starts at full_size (16384) instead of the probe-friendly 1369.

Media-aware MiddleProxy routing (key change)

  • Bundled tg_media_middle_proxies_v4 addresses in constants.zig for fallback when getProxyConfig is unavailable.
  • parseMiddleProxyAddressesForDc() now takes a DcSignFilter parameter (positive_only/negative_only/any) to correctly separate regular vs media MP pools.
  • MiddleProxySnapshot carries separate addrs_media_primary and addrs_media_dc4 fields.
  • buildDcConnectPlan() selects media MP when is_media_path, with automatic fallback to regular MP if the media pool is empty.

Censored-network operation

  • fetchUrlBytesViaInterface() — curl-based fallback through the configured tunnel interface when core.telegram.org is unreachable.
  • Early retry loop in middleProxyUpdaterMain() — retries at 10s, 30s, 1m, 5m, 30m before entering the 24-hour refresh cadence. Warms the MP cache within the first few minutes on censored hosts.

Edge-cases

  • ENOBUFS / TCP aborts — proper handling of error.SystemResources and benign TCP abort in acceptNewConnections.
  • @memcpy panic guard — safe byte-by-byte copy of the key selector in middleProxyBegin.

Tip

This update requires no configuration changes. Bundled MP addresses are automatically refreshed from getProxyConfig when connectivity is available (directly or via tunnel).

Changelog

  • fix(proxy): address critical review findings (data corruption, DoS, perf) (#197) (a6b6c80)
  • fix(proxy): restore middleproxy key selector bytes in nonce request (58dd39f)
  • feat(proxy): media-aware middle-proxy routing with tunnel fallback (82366ba)

v0.19.0

15 Apr 20:21
fda3a84

Choose a tag to compare

🇷🇺 Что нового (RU)

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

• В дашборде теперь отображается версия прокси — можно визуально убедиться, что обновление прошло.
• Исправлена ошибка, из-за которой release-please не обновлял версию в бинарнике.
• Повторный деплой дашборда больше не падает с ошибкой uv venv creation failed.

Что изменено

Версия в хедере дашборда (#190, #191)

  • В API-ответ /api/stats добавлено поле proxy_version.
  • Сервер определяет версию из mtproto-proxy --version или парсит version.zig (кэш 5 минут).
  • В хедере дашборда рядом с названием появился pill-бейдж v0.19.0 в стиле Zig-акцента.

Фикс version.zig / release-please

  • version.zig не обновлялся при релизах — release-please-config.json указывал на src/main.zig и src/ctl/main.zig, которые не содержат маркер x-release-please-version.
  • Теперь extra-files указывает на src/version.zig, где реально находится маркер. Следующие релизы будут обновлять версию автоматически.

Фикс повторного деплоя дашборда

  • make deploy выполняет chown mtproto:mtproto на /opt/mtproto-proxy/, включая .venv. При следующем деплое uv venv (от root) не мог перезаписать каталог с другим владельцем.
  • Теперь dashboard.zig делает rm -rf .venv перед uv venv, что решает проблему.

Tip

Версия прокси теперь видна сразу в хедере дашборда — не нужно лезть в логи или SSH, чтобы проверить обновление.


🇬🇧 Release notes (EN)

What this release addresses

• The dashboard now shows the proxy version — you can visually confirm that an update was applied.
• Fixed a bug where release-please was not updating the version in the binary.
• Repeated dashboard deploys no longer fail with uv venv creation failed.

What changed

Version badge in dashboard header (#190, #191)

  • Added proxy_version field to the /api/stats response.
  • The server detects the version from mtproto-proxy --version or by parsing version.zig (cached for 5 minutes).
  • A pill badge v0.19.0 now appears next to the title in the dashboard header, styled with the Zig accent color.

version.zig / release-please fix

  • version.zig was not being updated on releases — release-please-config.json pointed at src/main.zig and src/ctl/main.zig, which do not contain the x-release-please-version marker.
  • extra-files now points to src/version.zig where the marker actually lives. Future releases will bump the version automatically.

Fix repeated dashboard deploy failure

  • make deploy runs chown mtproto:mtproto on /opt/mtproto-proxy/, including .venv. On the next deploy, uv venv (running as root) could not overwrite the directory owned by a different user.
  • dashboard.zig now runs rm -rf .venv before uv venv, fixing the ownership mismatch.

Tip

The proxy version is now visible right in the dashboard header — no need to SSH in or check logs to verify an update.


Changelog

  • feat(dashboard): show proxy version in header (#191, closes #190) (99b5d7d)

v0.18.0

15 Apr 15:17
4574c2c

Choose a tag to compare

🇷🇺 Что нового (RU)

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

  • Встроенный Prometheus-эндпоинт — мониторинг прокси без парсинга логов и внешних экспортёров.
  • Установка дашборда больше не ломается на Debian 12+ / Ubuntu 23.04+ из-за PEP 668 (externally-managed-environment).

Что изменено

  • Prometheus /metrics endpoint (#179)

    • Новая секция [metrics] в config.toml (enabled, host, port).
    • Прокси поднимает отдельный HTTP-listener и отдаёт метрики в Prometheus text format.
    • Глобальные метрики: активные подключения, handshakes in flight, accepted/closed totals, drop-счётчики, трафик (C2S/S2C bytes).
    • Per-user метрики: mtproto_user_connections_active, mtproto_user_*_bytes_total — по настроенным пользователям.
    • Метрики процесса: RSS, VSZ, CPU, open FDs.
    • cgroup-метрики (опциональные): mtproto_cgroup_memory_usage_bytes, mtproto_cgroup_memory_limit_bytes — для Docker/контейнеров.
    • Готовый Grafana-дашборд (hack/docker/grafana-dashboard.json) + Docker Compose стек (Prometheus + Grafana).
    • Документация в hack/docker/README.md.
  • Dashboard: pip3 → uv (#185, #189)

    • pip3 install заменён на uv — быстрый менеджер Python-пакетов.
    • Зависимости ставятся в изолированный virtualenv (/opt/mtproto-proxy/monitor/.venv), а не в системный Python.
    • Если uv не установлен — скачивается автоматически через официальный astral.sh/uv/install.sh.
    • Systemd-сервис proxy-monitor теперь запускает server.py через .venv/bin/python.
    • Убрана зависимость от python3-pip.

Important

Для обновления дашборда на существующих серверах:

sudo mtbuddy update          # обновить бинарь
sudo mtbuddy setup dashboard # переустановить дашборд (создаст venv через uv)

🇬🇧 Release notes (EN)

What this release addresses

  • Built-in Prometheus metrics — monitor the proxy without log parsing or external exporters.
  • Dashboard installation no longer breaks on Debian 12+ / Ubuntu 23.04+ due to PEP 668 (externally-managed-environment).

What changed

  • Prometheus /metrics endpoint (#179)

    • New [metrics] config section (enabled, host, port).
    • The proxy starts a dedicated HTTP listener serving metrics in Prometheus text format.
    • Global metrics: active connections, handshakes in flight, accepted/closed totals, drop counters, C2S/S2C traffic bytes.
    • Per-user metrics: mtproto_user_connections_active, mtproto_user_*_bytes_total — keyed by configured users.
    • Process metrics: RSS, VSZ, CPU seconds, open/max FDs.
    • Optional cgroup metrics: mtproto_cgroup_memory_usage_bytes, mtproto_cgroup_memory_limit_bytes — appear automatically in containers.
    • Ready-to-import Grafana dashboard (hack/docker/grafana-dashboard.json) + Docker Compose stack (Prometheus + Grafana).
    • Docs at hack/docker/README.md.
  • Dashboard: pip3 → uv (#185, #189)

    • Replaced pip3 install with uv for Python dependency management.
    • Dependencies are installed into an isolated virtualenv (/opt/mtproto-proxy/monitor/.venv) instead of the system Python.
    • If uv is not present, it is bootstrapped automatically via the official astral.sh/uv/install.sh installer.
    • The proxy-monitor systemd service now runs server.py via .venv/bin/python.
    • Removed python3-pip prerequisite.

Important

To update the dashboard on existing servers:

sudo mtbuddy update          # update the binary
sudo mtbuddy setup dashboard # redeploy dashboard (creates venv via uv)

Changelog

  • feat: Metrics endpoint (#179) (6cc6674)
  • feat(dashboard): replace pip3 with uv for dependency management (#189, closes #185) (83614bc)

v0.17.1

13 Apr 17:37
5604113

Choose a tag to compare

🇷🇺 Что нового (RU)

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

• Дашборд показывал healthy: true при мёртвом VPN-туннеле — теперь корректно определяет нерабочие соединения.

Что изменено

Tunnel health check: добавлена проверка реального состояния WireGuard/AmneziaWG туннеля. Раньше дашборд считал туннель живым если endpoint был прописан в конфигурации (статическое значение). Теперь проверяется:

  • latest-handshake — был ли хотя бы один успешный хэндшейк
  • transfer rx — поступали ли данные через туннель
    Новое поле handshake_ok в API /api/statsrouting.primary_tunnel — показывает, прошёл ли хэндшейк с VPN-сервером.
    Понятная причина отказа: при недоступном VPN-сервере дашборд теперь возвращает reason: "endpoint configured, no handshake (VPN server unreachable)" вместо молчаливого healthy: true.
    Хелперы: _parse_transfer_bytes() для парсинга WG transfer (5.69 KiB → байты), _has_valid_handshake() для валидации хэндшейка.

Important

Если вы используете внешний мониторинг, проверяйте поле routing.healthy — теперь оно надёжно отражает реальное состояние upstream-туннеля.

До / После

Сценарий Было Стало
VPN мёртв, handshake=0, rx=0 healthy: true healthy: false
VPN работает, handshake OK healthy: true healthy: true
Интерфейс не поднят healthy: false healthy: false

🇬🇧 Release notes (EN)

What this release addresses

• The monitoring dashboard reported healthy tunnel status for dead VPN connections — the proxy appeared operational while unable to reach Telegram DCs.

What changed

Tunnel health check overhaul: the dashboard now verifies actual WireGuard tunnel liveness, not just static configuration. Previously, a configured endpoint was enough to report active: true even when the VPN server was completely unreachable.
Handshake validation: tunnels are only marked active when latest-handshake indicates a completed exchange (not 0 / none / idle).
Transfer verification: rx > 0 is checked to confirm data is actually flowing.
New handshake_ok field in tunnel status API — exposes handshake state to external monitors.
Clear failure reason: "endpoint configured, no handshake (VPN server unreachable)" instead of silent false-positive.

Important

If you poll the dashboard API for monitoring, the routing.healthy field now correctly reflects actual tunnel connectivity.

Before / After

Scenario Before After
Dead VPN, handshake=0, rx=0 healthy: true healthy: false
Working VPN, handshake OK healthy: true healthy: true
Interface down healthy: false healthy: false

Changelog

• fix(dashboard): detect dead tunnels as unhealthy (#180) (b6e6b8c)

v0.17.0

13 Apr 11:28
945715d

Choose a tag to compare

🇷🇺 Что нового (RU)

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

• Установка и ссылки стали предсказуемее в mixed IPv4/IPv6 окружениях.
• Появилась возможность привязать прокси к конкретному IP/интерфейсу.
• Обновление теперь корректно переустанавливает dashboard, если он уже был включен.

Что изменено

Новый bind address в установке и рантайме
mtbuddy install --bind <ip>
[server].bind_address в config.toml
• Прокси слушает ровно указанный IPv4/IPv6 адрес; при невалидном адресе старт останавливается с понятной ошибкой.
• Если параметр не задан, поведение прежнее: попытка [::] с fallback на 0.0.0.0.

Исправлены ссылки подключения для IPv6
tg:// и t.me ссылки теперь корректно URL-encoded для IPv6/скобок.
• Исправление применено в mtbuddy summary, startup banner прокси и dashboard.
• Убрана тихая обрезка адреса при формировании ссылки.

Авто-детект публичного IP теперь предпочитает IPv4
• Сначала проверяются IPv4-сервисы, затем fallback на IPv6.
• Это снижает число кейсов, когда Telegram-клиенты не принимают IPv6-only deep link.

Обновление dashboard при mtbuddy update
• Если сервис proxy-monitor уже активен, dashboard автоматически переdeployится после обновления.
• Во время update это делается в quiet-режиме, без лишнего summary-шума.

Документация
• Обновлены README.md и config.toml.example для --bind / bind_address.
• Добавлена явная подсказка про ручной IPv4 override через [server].public_ip.

Important

Если клиент не принимает ссылку с IPv6, задайте IPv4 вручную в /opt/mtproto-proxy/config.toml:

[server]
public_ip = "203.0.113.10"

Примеры

# Установка с привязкой к конкретному адресу
sudo mtbuddy install --port 443 --domain wb.ru --bind 127.0.0.1 --yes
[server]
bind_address = "10.0.0.5"
public_ip = "203.0.113.10"

🇬🇧 Release notes (EN)

What this release addresses

• Setup and generated links are now more predictable on mixed IPv4/IPv6 hosts.
• You can bind the proxy to a specific interface address.
mtbuddy update now keeps dashboard deployments in sync when monitoring is already enabled.

What changed

New bind address support in install + runtime
mtbuddy install --bind <ip>
[server].bind_address in config.toml
• Proxy now binds to the exact IPv4/IPv6 address you set; invalid values fail fast with a clear startup error.
• If not set, default behavior stays the same: try [::], then fall back to 0.0.0.0.

IPv6 deep-link fixes
tg:// and t.me links now URL-encode server addresses correctly (including IPv6/brackets).
• Applied in mtbuddy post-install summary, proxy startup banner, and dashboard.
• Removed silent truncation when building encoded server links.

Public IP detection now prefers IPv4
• Installer/runtime first query IPv4 endpoints, then fall back to IPv6.
• Helps in environments where Telegram clients/networks reject IPv6-only deep links.

Dashboard redeploy on update
mtbuddy update now redeploys dashboard automatically when proxy-monitor is already active.
• This path runs in quiet mode to avoid noisy extra summary output.

Docs updates
• Updated README.md and config.toml.example for --bind / bind_address.
• Added explicit guidance for forcing IPv4 via [server].public_ip.

Important

If a client rejects IPv6 links, force an IPv4 public endpoint in /opt/mtproto-proxy/config.toml:

[server]
public_ip = "203.0.113.10"

Examples

# Install and bind to a specific interface address
sudo mtbuddy install --port 443 --domain wb.ru --bind 127.0.0.1 --yes
[server]
bind_address = "10.0.0.5"
public_ip = "203.0.113.10"

Changelog

  • feat: mtbuddy enhancements and custom bind IP (#177) (8c6796f)

v0.16.0

11 Apr 19:26
5304b58

Choose a tag to compare

🇷🇺 Что нового (RU)

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

• При установке через mtbuddy теперь явно спрашивается про MiddleProxy (релей Telegram) — чтобы пользователь осознанно выбирал, нужен ли ему этот режим.

Что изменено

Интерактивная установка (TUI): после выбора DPI-модулей появляется отдельный блок с описанием MiddleProxy — что даёт, сколько потребляет RAM (~2 МБ на подключение), и для чего обязателен.
Предупреждение при отказе: если пользователь не включает MiddleProxy, показывается ⚠ с пояснением — промо-тег (ad_tag) не будет работать, а у аккаунтов без Premium могут не загружаться медиа (фото, видео, истории).
CLI-режим: добавлен флаг --middle-proxy для non-interactive установки.
Генерация конфига: [general].use_middle_proxy теперь явно записывается в config.toml при установке.
Post-install summary: статус MiddleProxy отображается в финальном summary box.
i18n: все новые строки на EN и RU.

Important

Дефолт — выключено. MiddleProxy потребляет значительно больше RAM, но без него не работает промо-тег и могут быть проблемы с медиа у пользователей без Premium.

Пример one-liner:

sudo mtbuddy install --port 443 --domain wb.ru --middle-proxy --yes

🇬🇧 Release notes (EN)

What this release addresses

• The mtbuddy installer now explicitly asks about MiddleProxy (Telegram relay) during setup, so users can make an informed choice about whether to enable it.

What changed

Interactive install (TUI): a dedicated MiddleProxy prompt appears after DPI module selection, with a detailed description of what it provides, its RAM cost (~2 MB per connection), and what depends on it.
Warning on decline: if the user skips MiddleProxy, a ⚠ warning explains that promo tags (ad_tag) will not work and non-Premium accounts may fail to load media (photos, video, stories).
CLI mode: new --middle-proxy flag for non-interactive installation.
Config generation: [general].use_middle_proxy is now explicitly written to config.toml during install.
Post-install summary: MiddleProxy status is shown in the final summary box.
i18n: all new strings available in English and Russian.

Important

Default is off. MiddleProxy uses significantly more RAM, but without it promo tags do not work and non-Premium users may have issues loading media.

Example one-liner:

sudo mtbuddy install --port 443 --domain wb.ru --middle-proxy --yes

Changelog

  • mtbuddy: ask about MiddleProxy during install (#174) (6985478)