github sleep3r/mtproto.zig v0.26.0

latest releases: v1.13.0, v1.12.0, v1.11.0...
2 months ago
🇷🇺 Что нового (RU)

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

v0.26.0 — feature-релиз для операторов, у которых прокси выглядит «залипшим» из-за входящего handshake flood, хотя tunnel/upstream остаются живыми.

Последний production-инцидент оказался не повтором проблемы с tunnel pool: маршрут через awg0 был здоров, core.telegram.org отвечал, а прокси продолжал принимать TCP. Реальная нагрузка шла снаружи: шумные источники набивали hs_inflight, упирали процесс в hs_budget и генерировали handshake timeouts. Ручной restart помогал только потому, что очищал накопленное runtime-состояние, но следующий наплыв мог снова привести к той же картине.

v0.26.0 добавляет in-process handshake flood guard: прокси теперь запоминает плохие handshake-related события по точному source IP и временно отклоняет слишком шумные адреса ещё до выделения connection slot. Это дополняет subnet rate limiter: один агрессивный IP можно притормозить без наказания всего /24 или /48 провайдера.

[!NOTE]
Для существующих config.toml новые настройки не обязательны: если ключей нет, используются безопасные defaults. При желании их можно добавить вручную в [server] и применить через reload/restart.

[!TIP]
Если снова видите рост hs_inflight, hs_budget или hs_timeout, смотрите periodic stats: новый лог flood_guard: ... top{...} покажет top source IP и смесь событий.

Что изменено

Exact-IP handshake flood guard перед slot allocation (#295)

  • Добавлен новый guard, который считает плохие события по точному client IP.
  • В guard попадают:
    • subnet rate-limit drops;
    • handshake-budget drops;
    • handshake timeouts.
  • Если IP набирает threshold в заданном окне, он временно блокируется.
  • Уже заблокированные IP закрываются сразу после accept, до TCP_NODELAY, handshake accounting и выделения slot.
  • Guard не управляет iptables/firewall и не пишет ban state на диск: состояние хранится в памяти процесса и сбрасывается при restart.

Новые hot-reloadable настройки в [server] (#295)

handshake_flood_guard_enabled = true
handshake_flood_guard_threshold = 20
handshake_flood_guard_window_sec = 30
handshake_flood_guard_block_sec = 120
  • enabled включает/выключает guard.
  • threshold задаёт число плохих событий с одного IP до временного deny.
  • window_sec задаёт rolling window для подсчёта.
  • block_sec задаёт длительность временного deny.
  • Все значения применяются через текущий config reload path.

Логи и метрики теперь показывают источник проблемы (#295)

  • Periodic stats получили новый counter flood_guard+=... в строке drops.
  • При активности guard логируется top offenders, например:
flood_guard: blocked+=7 top{203.0.113.10=total:42/rate:3/budget:9/timeout:30/blocked:91s}
  • Prometheus endpoint получил новый counter:
mtproto_drops_flood_guard_total

Это помогает быстро отличить upstream/tunnel деградацию от входящего handshake flood.

Документация и mtbuddy знают новые параметры (#295)

  • Обновлены README.md и README.ru.md.
  • mtbuddy install теперь генерирует config с новыми defaults.
  • mtbuddy config print-effective показывает текущие значения flood guard.

Проверено

  • zig build test --summary all — 161/161 tests passed.
  • zig build -Dtarget=x86_64-linux-gnu --summary all — 8/8 steps succeeded.
  • GitHub Actions:
    • Test & Build
    • Bench (No Soak)
    • E2E Integration
    • installer e2e: debian:12
    • installer e2e: ubuntu:24.04

🇬🇧 Release notes (EN)

What this release addresses

v0.26.0 is a feature release for operators whose proxy can appear “stuck” under inbound handshake flood even while tunnel/upstream connectivity is healthy.

The latest production incident was not another tunnel pool failure: routing through awg0 was healthy, core.telegram.org responded, and the proxy was still accepting TCP. The pressure came from inbound noisy sources piling up hs_inflight, exhausting the handshake budget, and producing handshake timeouts. A manual restart helped only because it cleared runtime state; it did not protect the proxy from the next wave.

v0.26.0 adds an in-process handshake flood guard: the proxy now tracks bad handshake-related events by exact source IP and temporarily denies noisy addresses before allocating a connection slot. This complements the subnet rate limiter: one aggressive IP can be slowed down without penalizing the entire provider /24 or /48.

[!NOTE]
Existing config.toml files do not need to be edited immediately: missing keys use safe defaults. Add the new [server] keys only if you want to tune the behavior, then reload or restart the service.

[!TIP]
If hs_inflight, hs_budget, or hs_timeout rises again, check periodic stats: the new flood_guard: ... top{...} line shows the top source IPs and event mix.

What changed

Exact-IP handshake flood guard before slot allocation (#295)

  • Added a new guard that counts bad events per exact client IP.
  • The guard records:
    • subnet rate-limit drops;
    • handshake-budget drops;
    • handshake timeouts.
  • When an IP crosses the threshold inside the configured window, it is temporarily denied.
  • Already denied IPs are closed immediately after accept, before TCP_NODELAY, handshake accounting, or slot allocation.
  • The guard does not manage iptables/firewall rules and does not persist ban state to disk: state is in memory and resets on process restart.

New hot-reloadable [server] settings (#295)

handshake_flood_guard_enabled = true
handshake_flood_guard_threshold = 20
handshake_flood_guard_window_sec = 30
handshake_flood_guard_block_sec = 120
  • enabled turns the guard on or off.
  • threshold controls how many bad events from one IP trigger a temporary deny.
  • window_sec controls the rolling counting window.
  • block_sec controls the temporary deny duration.
  • All values are applied through the existing config reload path.

Logs and metrics now expose the noisy source (#295)

  • Periodic stats now include flood_guard+=... in the drops line.
  • When the guard is active, top offenders are logged, for example:
flood_guard: blocked+=7 top{203.0.113.10=total:42/rate:3/budget:9/timeout:30/blocked:91s}
  • The Prometheus endpoint now exports:
mtproto_drops_flood_guard_total

This makes it easier to distinguish upstream/tunnel degradation from inbound handshake flood.

Docs and mtbuddy know the new knobs (#295)

  • Updated README.md and README.ru.md.
  • mtbuddy install now generates configs with the new defaults.
  • mtbuddy config print-effective now prints the current flood guard values.

Verified

  • zig build test --summary all — 161/161 tests passed.
  • zig build -Dtarget=x86_64-linux-gnu --summary all — 8/8 steps succeeded.
  • GitHub Actions:
    • Test & Build
    • Bench (No Soak)
    • E2E Integration
    • installer e2e: debian:12
    • installer e2e: ubuntu:24.04

Changelog

Don't miss a new mtproto.zig release

NewReleases is sending notifications on new releases.