v0.21.0

sleep3r/mtproto.zigv0.21.0May 5, 2026by sleep3r

Upgrading?

AI Summary

v0.21.0 is a major release migrating the codebase to Zig 0.16.0 and introducing strict signature verification for installation artifacts. It refactors the proxy core into smaller modules and adds comprehensive E2E and fuzz testing.

Key Highlights

  • Migrated codebase to Zig 0.16.0 APIs.
  • Split `src/proxy/proxy.zig` into focused modules (connection pool, relay, MiddleProxy, etc.).
  • Enforced signed release verification by default (requires `--insecure` to disable).
  • Added comprehensive Linux e2e harness and fuzz/property tests.

New Features

  • Migrated proxy core to Zig 0.16 and split focused proxy modules
  • Enforced signed release verification by default
  • Added Linux e2e harness and fuzz tests
  • Added security documentation (SECURITY.md, etc.)
  • Added `mtbuddy config validate/doctor/print-effective` commands
  • Implemented graceful operations (SIGTERM/SIGHUP/SIGUSR1)

Full Release Notes

<details open>
<summary>🇷🇺 Что нового (RU)</summary>

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

`v0.21.0` — большой инженерный релиз про доверие к установке, поддержку Zig 0.16.0 и дальнейшее взросление proxy core.

После аудита проекта основной риск оказался не в MTProto data-plane, а вокруг эксплуатации: release artifacts, bootstrap/update, silent error handling, конфиг-валидация, lifecycle фоновых задач и отсутствие настоящего e2e harness. Этот релиз закрывает именно эти зоны: официальные сборки теперь проверяются по SHA-256 и minisign, `mtbuddy` несёт embedded public key, unsigned mode требует явного opt-in, а proxy получил более строгий startup/shutdown/reload path.

Параллельно мы продолжили разбирать огромный `src/proxy/proxy.zig` на небольшие модули. Это не косметика: теперь проще ревьюить relay, MiddleProxy, upstream failover, очереди, fd limits и сетевые helpers отдельно, не держа в голове весь event loop целиком.

> [!NOTE]
> Пользовательский `config.toml` менять не нужно. Если вы используете официальные release artifacts, `mtbuddy install/update` и `deploy/bootstrap.sh` будут проверять подписи автоматически.

> [!IMPORTANT]
> Для Docker/GHCR лучше использовать `v0.21.1` или `latest`: patch-релиз исправляет Dockerfile default Zig version. Бинарные release assets `v0.21.0` валидны и подписаны.

## Что изменено

### Release trust: подписи включены по умолчанию ([#228](https://github.com/sleep3r/mtproto.zig/pull/228), [#229](https://github.com/sleep3r/mtproto.zig/pull/229))

- Официальные `mtbuddy` builds теперь содержат pinned minisign public key.
- `mtbuddy install`, `mtbuddy update` и `deploy/bootstrap.sh` проверяют `*.sha256` и `*.sha256.minisig` перед распаковкой или запуском бинарника.
- Release workflow публикует tarball, checksum и minisign signature для каждого artifact.
- Unsigned mode больше не включается “случайно”: нужен явный `--insecure` или `MTPROTO_INSECURE=1`.
- Bootstrap тоже содержит pinned public key, так что checksum из того же GitHub Release больше не является единственной линией защиты.

### Zig 0.16.0 и proxy refactor ([#228](https://github.com/sleep3r/mtproto.zig/pull/228))

- Кодовая база мигрирована на Zig 0.16.0 APIs.
- `src/proxy/proxy.zig` заметно разгружен: выделены модули для connection pool, connection phases, queue I/O, relay steps, MiddleProxy routing/frames/handshake/fallback, upstream handshake/failover, fd limits, network detection и socket helpers.
- `ProxyState.init` стал fallible и больше не может молча стартовать с пустым или частично собранным списком пользователей.
- Detached MiddleProxy updater заменён на управляемый lifecycle с shutdown flag и `join()`.
- Runtime banner больше не печатает MTProto secrets и готовые proxy links в journald/stdout.

### Control-plane hardening и config UX ([#228](https://github.com/sleep3r/mtproto.zig/pull/228), [#229](https://github.com/sleep3r/mtproto.zig/pull/229))

- Cloudflare DNS update path в `ipv6hop` больше не собирает shell-команды через `bash -c`; curl вызывается через argv, ответы парсятся как JSON.
- Добавлены `mtbuddy config validate`, `mtbuddy config doctor` и `mtbuddy config print-effective`.
- Исправлен false-positive warning про конфликт masking port для дефолтного `tls_domain:443`.
- Memory/capacity warnings учитывают фактическое использование MiddleProxy и `unsafe_override_limits`.
- `Lang.fromEnv()` теперь читает `LANG`/`LC_ALL`, а `--lang` появился в help.
- Dashboard uv installer больше не hard-code’ит x86_64 archive и выбирает artifact под текущую архитектуру.

### Graceful operations ([#229](https://github.com/sleep3r/mtproto.zig/pull/229))

- `SIGTERM` останавливает accept, даёт активным соединениям drain window и затем принудительно закрывает хвост.
- `SIGHUP` перезагружает поддерживаемые runtime settings без полного restart.
- `SIGUSR1` печатает runtime stats.
- Добавлен `mtbuddy reload` для systemd reload path.

### E2E, fuzz/property tests и CI ([#229](https://github.com/sleep3r/mtproto.zig/pull/229))

- Добавлен Linux e2e harness: fake Telegram DC, SOCKS5/HTTP CONNECT success/failure, MiddleProxy fallback, mask fallback, invalid handshakes, replay rejection, slowloris, 10k connection churn и SIGTERM во время active relay.
- `zig build e2e` подключён к CI.
- Добавлены fuzz/property-style тесты для TLS parser, MTProto obfuscation handshake, MiddleProxy frames, SOCKS5, HTTP CONNECT, config parser, replay cache и subnet limiter.
- Старый long-running soak больше не является единственной “интеграционной” проверкой.

### Документация и trust docs ([#229](https://github.com/sleep3r/mtproto.zig/pull/229))

- Добавлены `SECURITY.md`, `THREAT_MODEL.md`, `CONTRIBUTING.md`, CODEOWNERS и security issue template.
- README синхронизирован с Zig 0.16.0, текущими Make targets, signed release flow, e2e/fuzz командами и known limitations.
- Документированы OS/kernel compatibility, Telegram client caveats и что может сломаться при изменениях Telegram/DC.

</details>

---

<details>
<summary>🇬🇧 Release notes (EN)</summary>

## What this release addresses

`v0.21.0` is a large engineering release focused on install/update trust, Zig 0.16.0 support, and continued proxy-core cleanup.

The latest audit showed that the biggest risks were not in the MTProto data-plane itself, but around operations: release artifacts, bootstrap/update, silent error handling, config validation, background task lifecycle, and the lack of a real e2e harness. This release addresses those areas directly: official builds now verify SHA-256 and minisign signatures, `mtbuddy` embeds the release public key, unsigned mode requires explicit opt-in, and the proxy has stricter startup/shutdown/reload behavior.

At the same time, the huge `src/proxy/proxy.zig` file has been split further into focused modules. This is not just tidying: relay, MiddleProxy, upstream failover, queues, fd limits, and socket helpers can now be reviewed and tested in smaller pieces.

> [!NOTE]
> No user `config.toml` changes are required. If you use official release artifacts, `mtbuddy install/update` and `deploy/bootstrap.sh` verify signatures automatically.

> [!IMPORTANT]
> Docker/GHCR users should prefer `v0.21.1` or `latest`: the patch release fixes the Dockerfile default Zig version. The binary `v0.21.0` release assets are valid and signed.

## What changed

### Release trust: signatures enforced by default ([#228](https://github.com/sleep3r/mtproto.zig/pull/228), [#229](https://github.com/sleep3r/mtproto.zig/pull/229))

- Official `mtbuddy` builds now embed the pinned minisign public key.
- `mtbuddy install`, `mtbuddy update`, and `deploy/bootstrap.sh` verify `*.sha256` and `*.sha256.minisig` before extracting or executing binaries.
- The release workflow publishes a tarball, checksum, and minisign signature for every artifact.
- Unsigned mode is no longer accidental: it requires explicit `--insecure` or `MTPROTO_INSECURE=1`.
- Bootstrap also carries the pinned public key, so a checksum downloaded from the same GitHub Release is no longer the only protection layer.

### Zig 0.16.0 and proxy refactor ([#228](https://github.com/sleep3r/mtproto.zig/pull/228))

- The codebase has been migrated to Zig 0.16.0 APIs.
- `src/proxy/proxy.zig` has been reduced by extracting modules for connection pool, connection phases, queue I/O, relay steps, MiddleProxy routing/frames/handshake/fallback, upstream handshake/failover, fd limits, network detection, and socket helpers.
- `ProxyState.init` is now fallible and can no longer silently start with an empty or partially constructed user list.
- The detached MiddleProxy updater has been replaced with an owned lifecycle using a shutdown flag and `join()`.
- The runtime banner no longer prints MTProto secrets or ready-to-use proxy links to journald/stdout.

### Control-plane hardening and config UX ([#228](https://github.com/sleep3r/mtproto.zig/pull/228), [#229](https://github.com/sleep3r/mtproto.zig/pull/229))

- The Cloudflare DNS update path in `ipv6hop` no longer builds shell commands through `bash -c`; curl is called via argv and responses are parsed as JSON.
- Added `mtbuddy config validate`, `mtbuddy config doctor`, and `mtbuddy config print-effective`.
- Fixed a false-positive masking port warning for the default `tls_domain:443` path.
- Memory/capacity warnings now account for effective MiddleProxy usage and `unsafe_override_limits`.
- `Lang.fromEnv()` now reads `LANG`/`LC_ALL`, and `--lang` is shown in help.
- The dashboard uv installer no longer hard-codes the x86_64 archive and chooses the correct artifact for the current architecture.

### Graceful operations ([#229](https://github.com/sleep3r/mtproto.zig/pull/229))

- `SIGTERM` stops accepting new clients, drains active connections for the configured window, then force-closes the remaining tail.
- `SIGHUP` reloads supported runtime settings without a full restart.
- `SIGUSR1` dumps runtime stats.
- Added `mtbuddy reload` for the systemd reload path.

### E2E, fuzz/property tests, and CI ([#229](https://github.com/sleep3r/mtproto.zig/pull/229))

- Added a Linux e2e harness covering fake Telegram DC, SOCKS5/HTTP CONNECT success/failure, MiddleProxy fallback, mask fallback, invalid handshakes, replay rejection, slowloris, 10k connection churn, and SIGTERM during active relay.
- `zig build e2e` is now part of CI.
- Added fuzz/property-style coverage for the TLS parser, MTProto obfuscation handshake, MiddleProxy frames, SOCKS5, HTTP CONNECT, config parser, replay cache, and subnet limiter.
- The old long-running soak is no longer the only integration-like safety net.

### Documentation and trust docs ([#229](https://github.com/sleep3r/mtproto.zig/pull/229))

- Added `SECURITY.md`, `THREAT_MODEL.md`, `CONTRIBUTING.md`, CODEOWNERS, and a security issue template.
- README now matches Zig 0.16.0, current Make targets, the signed release flow, e2e/fuzz commands, and known limitations.
- Documented OS/kernel compatibility, Telegram client caveats, and what may break after Telegram/DC changes.

</details>

## Changelog

* refactor: migrate proxy core to Zig 0.16 and split focused proxy modules ([#228](https://github.com/sleep3r/mtproto.zig/pull/228)) ([ea0c927](https://github.com/sleep3r/mtproto.zig/commit/ea0c9279ea9d99e1b86d5b5ae7af6d0ce60fbec6))
* security: enforce signed release verification by default ([#229](https://github.com/sleep3r/mtproto.zig/pull/229)) ([0fea3fc](https://github.com/sleep3r/mtproto.zig/commit/0fea3fc45ed5bd32853a1877dbd96b7c0c229fbb))

Related Repositories