v1.9.0
sleep3r/mtproto.zigv1.9.0Jun 15, 2026by sleep3r
Upgrading?
AI Summary
Adds two security/robustness features derived from external analysis of MTProxy: an optional kernel-level SYN rate limiter and a per-endpoint DC connection timeout.
Key Highlights
- Adds optional kernel SYN rate limiting (mtbuddy setup syn-limit) to drop abusive connections before accept().
- Adds a per-endpoint DC connect timeout (dc_connect_timeout_sec) to fail fast on dead endpoints.
- Uses iptables (not nftables) to integrate with the existing stack.
- Off by default with warnings about carrier-NAT/CGNAT.
- Does not include other features from the analyzed library due to conflicts or redundancy.
New Features
- Kernel SYN rate limiter with presets (soft, medium, hard).
- Per-endpoint DC connect timeout.
- Drop counter in mtbuddy status.
- SYN limiter idempotent installation and full uninstall cleanup.
Full Release Notes
<details open> <summary>🇷🇺 Что нового (RU)</summary> ## Коротко `v1.9.0` добавляет два усиления, отобранных при разборе [MTproxy-reanimation](https://github.com/Liafanx/MTproxy-reanimation) (тюнинг-обвязка для Telemt/MTProxyMax). Из пяти её приёмов мы взяли только два — остальные мы уже делаем лучше или они конфликтуют с нашими инвариантами. Апгрейд безопасен: ограничение SYN — опциональное и по умолчанию **выключено**, а таймаут коннекта к DC — безопасный дефолт, на здоровые соединения не влияет. ## Ограничение SYN на уровне ядра (опционально) — `mtbuddy setup syn-limit` - Per-IP ограничение входящих **SYN** на порту прокси через `iptables -m hashlimit`. Дропает абьюзные SYN-всплески **в ядре, до `accept()`** — там, где наши внутрипроксийные стражи слабее всего (flood guard и per-/24 лимитер работают **после** `accept()` и сами по умолчанию выключены, так что каждый абьюзный SYN сейчас всё равно стоит сокета и `accept()`). - Ставится **отдельным** systemd-oneshot (`mtproto-syn-limit.service`), поэтому `CAP_NET_ADMIN` прокси **не выдаётся**. - **По умолчанию выключено** и с громким предупреждением про carrier-NAT/CGNAT (та же проблема общего egress-IP, из-за которой выключены внутрипроксийные стражи). Пресеты: **soft** `2/с·burst 5` (дефолт при включении, безопаснее для CGNAT), **medium** `1/с·3`, **hard** `1/с·1`. Предупреждает, если включён `accept_proxy_protocol` (ядро видит IP балансировщика, а не клиента). - Счётчик дропов в `mtbuddy status`; проверяет, что правило реально применилось (модуль `xt_hashlimit` на месте), а не молча превратилось в no-op. Идемпотентная установка + полная очистка при uninstall. - Взяли **iptables** (а не nftables), чтобы лечь в существующий стек (TCPMSS, nfqws) — без новой зависимости. ```bash sudo mtbuddy setup syn-limit --preset soft # soft 2/с·5 | medium 1/с·3 | hard 1/с·1 sudo mtbuddy setup syn-limit --status sudo mtbuddy setup syn-limit --remove ``` ## Per-endpoint таймаут коннекта к DC — `dc_connect_timeout_sec` (дефолт 10с) - Дедлайн на завершение TCP-`connect()` к **каждому** эндпоинту Telegram DC. Заблэкхоленный эндпоинт не шлёт RST, и ядро держит `SYN_SENT` ~2 минуты. `handshake_timeout_sec` (15с) уже ограничивает весь хендшейк — но **глобально**, поэтому медленный первый эндпоинт съедает бюджет failover для остальных. - Теперь один мёртвый эндпоинт отбрасывается быстро, и failover переходит к следующему **в пределах** общего потолка `handshake_timeout_sec`. - На здоровые коннекты не влияет (они завершаются за <1с); проверка привязана к фазе `.connecting_upstream`, поэтому **никогда не трогает установленный релей**. - Сознательно **не** поднимали `handshake_timeout_sec` до больших значений — это расширило бы окно для active-probe/slow-loris, против которого заточены DD-логика и flood guard. ## Что НЕ взяли (и почему) - **iOS keepalive sysctl (60/15/3):** для нас no-op — на established-сокетах мы уже ставим `SO_KEEPALIVE 60/10/3` + `TCP_USER_TIMEOUT=30s` (жёстче), а host-wide sysctl не достаёт pre-handshake сокеты без `SO_KEEPALIVE` (их и так жнут idle/handshake-таймауты). - **iOS MSS=92 + отдельный порт с DNAT:** отдельный порт = вторая `tg://`-ссылка (наши ссылки иммутабельны после раздачи — твёрдое «нет»); MSS-половина конфликтует с нашим `TCPMSS=88`; и это folk-remedy для iOS-зависания, которое мы уже докопали до клиентского бага MtProtoKit (`bad_server_salt`) и закрыли `client_silence_close_sec` (+ апстрим-PR Telegram-iOS#2197). - **Автодетект деплоя + персист правил в systemd:** у нас уже всё это есть для своего стека. ## Проверено `zig build test` зелёный + кросс-сборки + install-матрица (debian 11/12, ubuntu 20.04/22.04/24.04) + E2E + bench. Изменение в ядре прокси байт-прозрачно и вне happy-path; firewall-фича опциональна и изолирована в своём unit. Документация обновлена во всех README (en/ru/zh/fa/vi) и THREAT_MODEL. </details> --- <details> <summary>🇬🇧 Release notes (EN)</summary> ## TL;DR `v1.9.0` adds two hardening features picked from analysing [MTproxy-reanimation](https://github.com/Liafanx/MTproxy-reanimation) (a tuning wrapper for Telemt/MTProxyMax). Of its five techniques we kept only two — the rest we already do better or they conflict with our invariants. Upgrading is safe: the SYN limiter is optional and **off by default**, and the DC connect timeout is a safe default that never affects healthy connections. ## Optional kernel SYN rate-limiter — `mtbuddy setup syn-limit` - Per-source-IP inbound **SYN** rate-limit on the proxy port via `iptables -m hashlimit`. Drops abusive SYN bursts **in the kernel, before `accept()`** — exactly where our in-proxy guards are weakest (the flood guard and per-/24 limiter run **after** `accept()` and themselves default off, so every abusive SYN currently still costs a socket + an `accept()`). - Installed as a **separate** systemd oneshot (`mtproto-syn-limit.service`), so `CAP_NET_ADMIN` is **never granted to the proxy**. - **Off by default**, behind a loud carrier-NAT/CGNAT warning (the same shared-egress-IP problem that keeps the in-proxy guards off). Presets: **soft** `2/s·burst 5` (default when enabling, CGNAT-safer), **medium** `1/s·3`, **hard** `1/s·1`. Warns when `accept_proxy_protocol` is set (kernel sees the LB IP, not clients). - Drop counter in `mtbuddy status`; verifies the rule actually landed (`xt_hashlimit` present) instead of a silent no-op. Idempotent apply + full uninstall cleanup. - Uses **iptables** (not nftables) to match our existing stack (TCPMSS, nfqws) — no new dependency. ```bash sudo mtbuddy setup syn-limit --preset soft # soft 2/s·5 | medium 1/s·3 | hard 1/s·1 sudo mtbuddy setup syn-limit --status sudo mtbuddy setup syn-limit --remove ``` ## Per-endpoint DC connect timeout — `dc_connect_timeout_sec` (default 10s) - A deadline for completing the TCP `connect()` to **each** Telegram DC endpoint. A filtered/black-holed endpoint sends no RST, so the kernel sits in `SYN_SENT` for ~2 min. `handshake_timeout_sec` (15s) already caps the whole handshake — but **globally**, so a slow first endpoint starves the failover budget for the rest. - Now one dead endpoint is abandoned fast and failover advances to the next, **within** the overall `handshake_timeout_sec` ceiling. - Never affects healthy connects (they finish in <1s); the check is gated on the `.connecting_upstream` phase, so it **can never touch an established relay**. - Deliberately does **not** raise `handshake_timeout_sec` — that would widen the active-probe / slow-loris window our DD-decision and flood guards exist to shrink. ## Not ported (and why) - **iOS keepalive sysctl (60/15/3):** a no-op for us — relay sockets already set `SO_KEEPALIVE 60/10/3` + `TCP_USER_TIMEOUT=30s` (stricter), and a host-wide sysctl can't touch pre-handshake sockets that lack `SO_KEEPALIVE` (already reaped by our idle/handshake timeouts). - **iOS MSS=92 + separate port DNAT:** a second port = a second `tg://` link (our links are immutable once distributed — hard no); the MSS half conflicts with our `TCPMSS=88`; and it's a mechanism-free folk remedy for the iOS resume hang we already root-caused to the client MtProtoKit `bad_server_salt` bug and addressed with `client_silence_close_sec` (+ upstream PR Telegram-iOS#2197). - **Deployment autodetection + systemd rule persistence:** already implemented for our own stack. ## Verified `zig build test` green + cross-builds + install matrix (debian 11/12, ubuntu 20.04/22.04/24.04) + E2E + bench. The proxy-core change is byte-transparent and off the happy path; the firewall feature is opt-in and isolated in its own unit. Docs updated across all READMEs (en/ru/zh/fa/vi) and THREAT_MODEL. </details> --- **Full Changelog**: https://github.com/sleep3r/mtproto.zig/compare/v1.8.1...v1.9.0
Related Repositories
lightpanda-io/browser★ 36,848
Lightpanda: the headless browser designed for AI and automation
nullclaw/nullclaw★ 8,131
Fastest, smallest, and fully autonomous AI assistant infrastructure written in Zig
zml/zml★ 4,194
Any model. Any hardware. Zero compromise. Built with @ziglang / @openxla / MLIR / @bazelbuild
dmtrKovalenko/odiff★ 3,280
A very fast SIMD-first image comparison library (with nodejs API)
tigerbeetle/tigerbeetle★ 132
The financial transactions database designed for mission critical safety and performance.