🇷🇺 Что нового (RU)
Коротко
v1.10.0 — ответ на блокировку MTProto-прокси, которую РКН/ТСПУ выкатил в ночь с 4 на 5 июня 2026. Релиз добавляет детект и предупреждения для нового доменного маркера + режим быстрого реконнекта в SYN-лимитере. Ядро прокси не тронуто и байт-прозрачно; SYN---reject опционален (дефолт DROP без изменений); проверка домена работает только на этапе установки (варнинги) и на живой релей не влияет. Апгрейд безопасен.
Важная оговорка: для доменного маркера (ниже) настоящего лечения «на месте» нет — оно упирается в иммутабельность tls_domain. Этот релиз про то, чтобы выбрать правильный домен до раздачи ссылок.
Доменный маркер X25519MLKEM768 (главное)
Даже пройдя SYN-лимит, iOS-клиенты — и все, кто за тем же NAT-IP — блокируются, если tls_domain негоциирует только классический x25519 и не поддерживает пост-квантовый гибрид X25519MLKEM768. Судя по всему, ТСПУ пробит SNI out-of-band: маркер — свойство домена, а не нашего ServerHello. Поэтому эхо 0x11ec (оно чинит connection-level downgrade tell и уже есть с #347) этот маркер не снимает — снимает только выбор PQ-домена, который наш FakeTLS дальше корректно мимикрит тем же эхо.
Это переворачивает прежнюю доктрину проекта («бери single-round-x25519 домены, напр. rutube.ru») — теперь именно этот класс и метит iOS.
fronting_domain.zigтеперь пробит домен как современный клиент (-groups X25519MLKEM768:X25519), добавлен вердиктpq_capableи предупреждение, когда домен делает только классический x25519 (маркер) или HRR. Есть fallback-проба на голом x25519 — чтобы не орать ложно, если у оператора локальный OpenSSL старше 3.5.mtbuddy install/setup maskingпредупреждают до того, как ссылка зафиксирована.- Гайд по выбору
tls_domainперевёрнут вconfig.zig,config.toml.example,THREAT_MODEL.md,ARCHITECTURE.md: бери домен, который негоциирует single-round X25519MLKEM768; голый x25519 — теперь опасный класс. Задокументировано столкновение с иммутабельностью: деплой на уже помеченном домене нельзя мигрировать, не сломав все выданные ссылки.
# проверить домен (и конкретный IP) на PQ ДО выбора:
openssl s_client -groups X25519MLKEM768 -connect <домен>:443 # нужен OpenSSL 3.5+
# либо ботом @Sni_checker_botSYN-лимитер: режим REJECT --reject-with tcp-reset
SYN-лимитер из v1.9.0 дропал сверх-лимитные SYN молча — это правильно для анти-флуда, но throttled-клиент ждёт полный TCP-ретрансмит (~20с до коннекта). Когда лимитер используют, чтобы пережить июньский параллельно-коннектный блок ТСПУ, а не флуд, RST даёт клиенту переподключиться сразу (~5с) — как и нашло комьюнити.
- Новые флаги
--reject/--drop:--rejectпереключает сверх-лимитное действие наREJECT --reject-with tcp-reset;DROPостаётся дефолтом. Действие вшивается в генерируемый скрипт через переменнуюACTION, проверка «правило встало» и счётчик обобщены на оба действия, в summary добавлена строка Action. - Для «сладкой точки» из статьи (~1.1с на IP) —
--rate 54/minute --burst 1 --reject.
sudo mtbuddy setup syn-limit --preset hard --reject # RST вместо тихого DROP
sudo mtbuddy setup syn-limit --rate 54/minute --burst 1 --reject # ~1.1с на IP (приём статьи)Что НЕ взяли (и почему)
- u32-исключение для iOS в SYN-лимитере (комьюнити-V3): не стали вшивать непроверенный магический байт-паттерн iOS-SYN в генерируемый root-скрипт iptables — для верификации нужен реальный дамп iOS-SYN. Без него подход статьи уже воспроизводится связкой
--rate 54/minute --burst 1 --reject. - Настоящая ML-KEM-768 инкапсуляция для 0x11ec-share: в std лежит X-Wing combiner, а не TLS-0x11ec — нужен свой. Пассивный фингерпринт по group+size проходит и так; актуально, только если ТСПУ начнёт валидировать структуру ML-KEM.
- Хардкод «выверенного» списка PQ-доменов: проверять надо каждый домен и конкретный IP — у одного домена разные IP метятся по-разному (классика — rutube с двумя серверами, 50/50), поэтому тулинг и доки шлют к
openssl/@Sni_checker_bot, а не к статическому списку.
Проверено
zig build test зелёный (58/58 ctl + 206/206 proxy) + кросс-сборки + install-матрица (debian 11/12, ubuntu 20.04/22.04/24.04) + E2E + bench. Изменений в ядре прокси нет; проверка домена — install-time варнинг; SYN---reject опционален и изолирован в своём unit. Документация обновлена (config, config.toml.example, THREAT_MODEL, ARCHITECTURE).
🇬🇧 Release notes (EN)
TL;DR
v1.10.0 responds to the RKN/TSPU block of MTProto proxies that started the night of 4→5 June 2026. It adds detection and warnings for the new domain-level marker plus a fast-reconnect mode for the SYN limiter. The proxy core is untouched and byte-transparent; the SYN --reject mode is opt-in (DROP stays the default); the domain check runs at install time only (warnings) and never affects a live relay. Upgrading is safe.
Important caveat: for the domain marker (below) there is no in-place fix — it collides with tls_domain immutability. This release is about choosing the right domain before links are distributed.
The X25519MLKEM768 domain marker (the important one)
Even past a SYN limit, iOS clients — and everyone sharing their NAT egress IP — get blocked when the tls_domain negotiates only classical x25519 and not the post-quantum hybrid X25519MLKEM768. The censor appears to probe the SNI out-of-band: the marker is a property of the domain, not of our ServerHello. So the 0x11ec echo (which fixes the connection-level downgrade tell and has shipped since #347) does not clear this marker — only picking a PQ-capable domain does, which our FakeTLS then mimics correctly via that same echo.
This inverts the project's prior doctrine ("prefer single-round-x25519 domains, e.g. rutube.ru") — that class is now exactly what flags iOS.
fronting_domain.zignow probes as a modern client (-groups X25519MLKEM768:X25519), adds apq_capableverdict, and warns when a domain does only classical x25519 (the marker) or an HRR. A legacy x25519-only fallback probe avoids false alarms when the operator's local OpenSSL predates 3.5.mtbuddy install/setup maskingwarn before the link is frozen.- The
tls_domainguidance is flipped inconfig.zig,config.toml.example,THREAT_MODEL.md,ARCHITECTURE.md: prefer a domain that negotiates single-round X25519MLKEM768; classical-x25519-only is now the dangerous class. The collision with immutability is documented: a deploy on a now-marked domain cannot migrate without invalidating every distributed link.
# check a domain (and the exact IP) for PQ BEFORE committing:
openssl s_client -groups X25519MLKEM768 -connect <domain>:443 # needs OpenSSL 3.5+
# or the @Sni_checker_botSYN limiter: REJECT --reject-with tcp-reset mode
The SYN limiter from v1.9.0 dropped over-limit SYNs silently — correct for flood defense, but a throttled client waits a full TCP retransmit (~20s to connect). When the limiter is used to survive the June-2026 TSPU parallel-connect block rather than a flood, an RST lets the client retry immediately (~5s) — as the community found.
- New
--reject/--dropflags:--rejectswitches the over-limit target toREJECT --reject-with tcp-reset;DROPstays the default. The target is baked into the generated script via anACTIONvariable, the rule-landed check and the counter are generalized to match either target, and the summary shows the action. - For the article's per-IP sweet spot (~1.1s):
--rate 54/minute --burst 1 --reject.
sudo mtbuddy setup syn-limit --preset hard --reject # RST instead of a silent DROP
sudo mtbuddy setup syn-limit --rate 54/minute --burst 1 --reject # ~1.1s per IP (the article's tuning)Not ported (and why)
- u32 iOS exemption in the SYN limiter (community V3): we won't bake an unverified magic iOS-SYN byte pattern into a generated root iptables script — verifying it needs a real iOS SYN capture. Until then the article's approach is reproducible with
--rate 54/minute --burst 1 --reject. - Real ML-KEM-768 encapsulation for the 0x11ec share: std ships an X-Wing combiner, not the TLS
0x11econe — that needs a bespoke implementation. Passive group+size fingerprinting passes as-is; it only matters if the TSPU starts validating ML-KEM structure. - A hardcoded "vetted" PQ-domain list: each domain and each IP must be checked — one domain's IPs can score differently (the canonical case is rutube's two servers, 50/50) — so the tooling and docs point at
openssl/@Sni_checker_botrather than a static list.
Verified
zig build test green (58/58 ctl + 206/206 proxy) + cross-builds + install matrix (debian 11/12, ubuntu 20.04/22.04/24.04) + E2E + bench. There is no proxy-core change; the domain check is an install-time warning; the SYN --reject mode is opt-in and isolated in its own unit. Docs updated (config, config.toml.example, THREAT_MODEL, ARCHITECTURE).
Full Changelog: v1.9.0...v1.10.0