v0.23.4

sleep3r/mtproto.zigv0.23.4May 14, 2026by sleep3r

Upgrading?

AI Summary

Patch release improving installer reliability on fresh Debian 12 and Ubuntu 24.04 hosts by enforcing dependencies and using robust command resolution paths.

Key Highlights

  • Mandatory base dependencies including `passwd` for group/user creation
  • Robust command lookup with fallback paths for system binaries
  • NFQUEUE rule verification before reporting success
  • Installer now honestly fails on errors instead of masking them

Full Release Notes

## [0.23.4](https://github.com/sleep3r/mtproto.zig/compare/v0.23.3...v0.23.4) (2026-05-14)

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

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

`v0.23.4` - patch-релиз для надежной установки `mtbuddy` на чистые Debian 12 и Ubuntu 24.04 хосты.

`v0.23.3` закрыл первый острый сценарий с `groupadd` / `/usr/sbin`, но дальнейшие e2e-прогоны на свежих VPS показали ещё несколько мест, где clean install мог ломаться не по вине proxy runtime:

```text
Failed to create system group 'mtproto'
Failed to spawn command: FileNotFound
```

```text
cc: fatal error: cannot execute 'cc1': execvp: No such file or directory
```

```text
Failed to apply IPv4 NFQUEUE rule
Failed to spawn command: FileNotFound
```

Плюс после bootstrap на некоторых минимальных окружениях бинарь уже лежал в `/usr/local/bin/mtbuddy`, но shell всё ещё отвечал `mtbuddy: command not found`. И самый неприятный UX-момент: если `nfqws` падал, итоговый install summary мог всё равно показать `nfqws TCP Desync (Zapret)` как активный.

Этот релиз доводит installer path до честного fail-closed поведения: зависимости ставятся обязательно, команды ищутся через устойчивые fallback paths, `nfqws` собирается предсказуемо, повторный `mtbuddy setup nfqws` идемпотентен, а финальный экран показывает только то, что реально поднялось.

> [!NOTE]
> Конфиг менять не нужно. Релиз чинит installer/bootstrap/control-plane поведение, а не MTProto protocol или формат `config.toml`.

> [!TIP]
> Если сервер уже застрял после старой ошибки, обновите `mtbuddy` до `v0.23.4` и повторите установку или выполните `mtbuddy setup nfqws`. Существующий `/opt/mtproto-proxy/config.toml` сохраняется.

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

### Fresh install dependencies теперь обязательные и lock-aware ([#261](https://github.com/sleep3r/mtproto.zig/pull/261))

- `install` больше не игнорирует ошибки `apt-get update` / `apt-get install` на базовых системных зависимостях.
- Все важные apt paths получили `DPkg::Lock::Timeout=600`, чтобы переживать стандартные `unattended-upgrades` / dpkg locks на свежих Ubuntu/Debian образах.
- В базовые зависимости добавлен пакет `passwd`, который предоставляет `groupadd` и `useradd`.
- После установки зависимостей installer явно проверяет, что `groupadd` и `useradd` доступны, и останавливается с понятной ошибкой, если базовый образ сломан.
- Такой же lock timeout добавлен в masking, nfqws, tunnel, update и bootstrap flows.

### Команды устойчивее ищутся в минимальных root окружениях ([#261](https://github.com/sleep3r/mtproto.zig/pull/261))

- `sys.exec()` и `sys.execForward()` теперь используют `expand_arg0`, чтобы Zig runtime мог корректно резолвить команды через окружение.
- `sys.commandExists()` проверяет команды через `/bin/sh -c 'command -v ...'` с безопасной передачей аргумента.
- `sys.commandOrPath()` сначала пробует известные absolute paths, затем `PATH`.
- `groupadd`, `useradd`, `iptables`, `ip6tables`, `iptables-save` и `ip6tables-save` теперь не зависят от того, есть ли `/usr/sbin` в текущем `PATH`.

### nfqws / Zapret setup стал воспроизводимым на чистых Debian/Ubuntu ([#261](https://github.com/sleep3r/mtproto.zig/pull/261))

- Build dependencies для `nfqws` теперь включают полный GCC toolchain: `build-essential`, `gcc`, `g++`, `cpp`, `make`, `binutils`, `libc6-dev` и нужные netfilter libraries.
- Сборка zapret запускается со стабильным `PATH` и явным `CC=/usr/bin/gcc`, когда системный GCC найден.
- Если GCC всё же отсутствует после dependency install, installer пробует восстановить toolchain через reinstall базовых и versioned `gcc-N` / `cpp-N` packages.
- IPv4/IPv6 NFQUEUE rules ставятся через resolved absolute iptables paths.
- systemd unit `nfqws-mtproto` теперь сам удаляет старые NFQUEUE rules и добавляет нужные rules на start/restart через `ExecStartPre`.
- Повторный `mtbuddy setup nfqws` больше не плодит duplicate rules: после проверки остаётся одно правило для `--sport 443 --queue-num 200`.
- Setup явно проверяет, что IPv4 `NFQUEUE` rule действительно появился, прежде чем показывать success.

### Bootstrap-installed `mtbuddy` сразу доступен как команда ([#261](https://github.com/sleep3r/mtproto.zig/pull/261))

- После установки в `/usr/local/bin/mtbuddy` bootstrap создаёт `/usr/bin/mtbuddy` symlink, если `command -v mtbuddy` всё ещё не видит бинарь.
- Forwarded arguments теперь запускаются через точный install path, а не через повторный `PATH` lookup.
- Uninstall удаляет `/usr/bin/mtbuddy`, если это symlink на `/usr/local/bin/mtbuddy`.

### Итоговый summary больше не показывает ложный успех ([#261](https://github.com/sleep3r/mtproto.zig/pull/261))

- После masking setup installer проверяет реальное наличие nginx site и активный `nginx` service.
- После nfqws setup installer проверяет `/opt/zapret/nfq/nfqws` и активный `nfqws-mtproto` service.
- Если модуль не поднялся, финальный summary показывает его disabled и отдельно предупреждает оператора.

## Проверено

- `zig fmt src/ctl/install.zig src/ctl/sys.zig src/ctl/nfqws.zig src/ctl/masking.zig src/ctl/tunnel.zig src/ctl/uninstall.zig src/ctl/update.zig`
- `git diff --check`
- `zig build test`
- `zig build -Dtarget=x86_64-linux-musl -Doptimize=ReleaseFast`
- `bash -n deploy/bootstrap.sh`
- Fresh Debian 12 VPS e2e:
  - полный `mtbuddy install --port 443 --domain wb.ru --yes`;
  - повторный `mtbuddy setup nfqws`;
  - `mtproto-proxy`, `nginx`, `nfqws-mtproto`, `mtproto-mask-health.timer` active/enabled;
  - NFQUEUE rule count = 1;
  - listeners on `*:443` and `127.0.0.1:8443`.
- Fresh Ubuntu 24.04 VPS e2e:
  - полный `mtbuddy install --port 443 --domain wb.ru --yes`;
  - повторный `mtbuddy setup nfqws`;
  - `mtproto-proxy`, `nginx`, `nfqws-mtproto`, `mtproto-mask-health.timer` active/enabled;
  - NFQUEUE rule count = 1;
  - listeners on `*:443` and `127.0.0.1:8443`.

</details>

---

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

## What this release addresses

`v0.23.4` is a patch release for reliable `mtbuddy` installation on clean Debian 12 and Ubuntu 24.04 hosts.

`v0.23.3` fixed the first sharp `groupadd` / `/usr/sbin` failure, but deeper e2e runs on fresh VPS images exposed a few more places where clean installs could fail before the proxy runtime itself was involved:

```text
Failed to create system group 'mtproto'
Failed to spawn command: FileNotFound
```

```text
cc: fatal error: cannot execute 'cc1': execvp: No such file or directory
```

```text
Failed to apply IPv4 NFQUEUE rule
Failed to spawn command: FileNotFound
```

In addition, bootstrap could install the binary to `/usr/local/bin/mtbuddy` while the shell still reported `mtbuddy: command not found` in minimal environments. The final install summary could also claim `nfqws TCP Desync (Zapret)` was active even after the setup step had failed.

This release makes the installer path honestly fail-closed: dependencies are required, system commands use robust fallback paths, `nfqws` builds predictably, repeated `mtbuddy setup nfqws` runs are idempotent, and the final screen only marks modules as enabled when they are actually running.

> [!NOTE]
> No config changes are required. This release fixes installer/bootstrap/control-plane behavior, not the MTProto protocol or `config.toml` format.

> [!TIP]
> If a host is already stuck after the older installer failure, update `mtbuddy` to `v0.23.4` and rerun the install or run `mtbuddy setup nfqws`. The existing `/opt/mtproto-proxy/config.toml` is preserved.

## What changed

### Fresh install dependencies are now required and lock-aware ([#261](https://github.com/sleep3r/mtproto.zig/pull/261))

- `install` no longer ignores `apt-get update` / `apt-get install` failures for base system dependencies.
- Important apt paths now use `DPkg::Lock::Timeout=600`, so fresh Ubuntu/Debian images can wait out normal `unattended-upgrades` / dpkg locks.
- The base dependency set now includes `passwd`, which provides `groupadd` and `useradd`.
- After dependency installation, the installer explicitly verifies that `groupadd` and `useradd` are available and stops with a clear error if the base image is broken.
- The same lock timeout was added to masking, nfqws, tunnel, update, and bootstrap flows.

### Command lookup is more robust in minimal root environments ([#261](https://github.com/sleep3r/mtproto.zig/pull/261))

- `sys.exec()` and `sys.execForward()` now use `expand_arg0`, allowing the Zig runtime to resolve commands through the environment correctly.
- `sys.commandExists()` checks commands through `/bin/sh -c 'command -v ...'` with safe argument passing.
- `sys.commandOrPath()` tries known absolute paths first, then falls back to `PATH`.
- `groupadd`, `useradd`, `iptables`, `ip6tables`, `iptables-save`, and `ip6tables-save` no longer depend on `/usr/sbin` being present in the current `PATH`.

### nfqws / Zapret setup is reproducible on clean Debian/Ubuntu ([#261](https://github.com/sleep3r/mtproto.zig/pull/261))

- `nfqws` build dependencies now include the full GCC toolchain: `build-essential`, `gcc`, `g++`, `cpp`, `make`, `binutils`, `libc6-dev`, and the required netfilter libraries.
- zapret builds with a stable `PATH` and explicit `CC=/usr/bin/gcc` when the system GCC is available.
- If GCC is still missing after dependency installation, the installer attempts to repair the toolchain by reinstalling base packages and versioned `gcc-N` / `cpp-N` packages.
- IPv4/IPv6 NFQUEUE rules are installed through resolved absolute iptables paths.
- The `nfqws-mtproto` systemd unit now removes stale NFQUEUE rules and adds the required rules on start/restart via `ExecStartPre`.
- Re-running `mtbuddy setup nfqws` no longer creates duplicate rules: verification leaves one `--sport 443 --queue-num 200` rule.
- Setup verifies that the IPv4 `NFQUEUE` rule is present before reporting success.

### Bootstrap-installed `mtbuddy` is immediately usable as a command ([#261](https://github.com/sleep3r/mtproto.zig/pull/261))

- After installing `/usr/local/bin/mtbuddy`, bootstrap creates a `/usr/bin/mtbuddy` symlink when `command -v mtbuddy` still cannot see the binary.
- Forwarded arguments are now executed through the exact install path instead of a second `PATH` lookup.
- Uninstall removes `/usr/bin/mtbuddy` when it is a symlink to `/usr/local/bin/mtbuddy`.

### The final summary no longer reports false success ([#261](https://github.com/sleep3r/mtproto.zig/pull/261))

- After masking setup, the installer checks the actual nginx site and active `nginx` service.
- After nfqws setup, the installer checks `/opt/zapret/nfq/nfqws` and the active `nfqws-mtproto` service.
- If a module did not come up, the final summary shows it as disabled and warns the operator.

## Verified

- `zig fmt src/ctl/install.zig src/ctl/sys.zig src/ctl/nfqws.zig src/ctl/masking.zig src/ctl/tunnel.zig src/ctl/uninstall.zig src/ctl/update.zig`
- `git diff --check`
- `zig build test`
- `zig build -Dtarget=x86_64-linux-musl -Doptimize=ReleaseFast`
- `bash -n deploy/bootstrap.sh`
- Fresh Debian 12 VPS e2e:
  - full `mtbuddy install --port 443 --domain wb.ru --yes`;
  - repeated `mtbuddy setup nfqws`;
  - `mtproto-proxy`, `nginx`, `nfqws-mtproto`, `mtproto-mask-health.timer` active/enabled;
  - NFQUEUE rule count = 1;
  - listeners on `*:443` and `127.0.0.1:8443`.
- Fresh Ubuntu 24.04 VPS e2e:
  - full `mtbuddy install --port 443 --domain wb.ru --yes`;
  - repeated `mtbuddy setup nfqws`;
  - `mtproto-proxy`, `nginx`, `nfqws-mtproto`, `mtproto-mask-health.timer` active/enabled;
  - NFQUEUE rule count = 1;
  - listeners on `*:443` and `127.0.0.1:8443`.

</details>

## Changelog

* fix: harden installer e2e dependencies ([#261](https://github.com/sleep3r/mtproto.zig/pull/261)) ([69931cb](https://github.com/sleep3r/mtproto.zig/commit/69931cbe462546854a8df03a890f2a665c1345b9))
* chore(main): release 0.23.4 ([#262](https://github.com/sleep3r/mtproto.zig/pull/262)) ([c6f685b](https://github.com/sleep3r/mtproto.zig/commit/c6f685b390c8a29daa267a462410df1e8de7e32a))

Related Repositories