v1.5.0

sleep3r/mtproto.zigv1.5.0Jun 11, 2026by sleep3r

Upgrading?

AI Summary

A major upgrade focusing on FakeTLS fidelity and anti-DPI capabilities, including post-quantum key support and refined masking techniques.

Key Highlights

  • Support for post-quantum `X25519MLKEM768` key_share
  • Profile-matched cert-record size (`fake_cert_size`)
  • Jittered desync split to avoid timing fingerprints
  • Dynamic SNI mask target (`mask_sni_safelist`)
  • Added PROXY-protocol v1/v2 support

New Features

  • Post-quantum cryptography support
  • Jittered desync splitting
  • Dynamic SNI masking
  • PROXY-protocol integration
  • Clock synchronization via HTTP-Date

Full Release Notes

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

## Что добавляет этот релиз

`v1.5.0` — большой апгрейд **FakeTLS-фиделити и анти-DPI**. Поведение по умолчанию не меняется; все новые опции — opt-in/безопасные. Апгрейд рекомендуется.

## Анти-DPI фиделити

- **Пост-квантовый key_share `X25519MLKEM768` (0x11ec).** Большинство реальных browser→CDN ClientHello к 2026 несут гибридную PQ-группу; ответ классическим `x25519` — пассивный group-downgrade tell. Теперь при offer'е 0x11ec отдаём корректный 0x11ec key_share (1120 байт).
- **Профиль-матч размера cert-записи (`fake_cert_size`).** Фейковая cert-запись (AppData) в ServerHello была фиксированной 2878 — а реальный mask-бэкенд отдаёт свой размер: активный пробер видел разные размеры на accept-пути и mask-пути. Задайте `fake_cert_size` = реальному размеру первого flight'а вашего бэкенда — оба пути совпадут. (+ парсер `firstAppDataRecordLen` как seam для будущего zero-config авто-зонда.)
- **Джиттер desync-сплита.** Фиксированный зазор 3 мс сам был timing-фингерпринтом → теперь `desync_split_delay_ms` + `desync_split_jitter_ms` (3 + 0..3).
- **RST-teardown на reject (`reject_rst`).** Слать TCP RST вместо alert+FIN, под fronted-CDN, которые ресетят плохой хендшейк.

## Активное probing

- **Dynamic SNI mask-таргет (`mask_sni_safelist`).** Пробу с SNI из сейфлиста фронтим на сервер этого домена (резолв на старте) — разговор совпадает с заявленным SNI. Никогда не open-relay.
- **Метрики** `mtproto_replay_hits_total` + `mtproto_unknown_sni_total` на `/metrics`.
- **Кэп длительности mask-relay (`mask_relay_max_secs`).**

## Операторский UX

- **Само-коррекция часов по HTTP-Date (`clock_sync_url`).** Кривые часы VPS иначе тихо рубят все хендшейки на проверке time-skew. RFC 7231 парсер, offset зажат ±1 день.
- **PROXY-protocol v1/v2 (`accept_proxy_protocol`).** За TLS-терминирующим LB восстанавливаем реальный IP клиента (MSG_PEEK + точный drain).

## Проверено

`zig build test` — **258/258** (новые KAT: PQ-билдер/детектор, IMF-date, template-alloc, record-parser, PROXY v1/v2) + кросс-сборки `x86_64-linux`/`aarch64-linux` + `zig fmt`. THREAT_MODEL.md дополнен PQ-вектором.

</details>

---

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

## What this release adds

`v1.5.0` is a large **FakeTLS-fidelity / anti-DPI** upgrade from a competitor (telemt) survey + real DPI cases. Defaults are unchanged; every new option is opt-in / fallback-safe. Upgrading is recommended.

## Anti-DPI fidelity

- **Post-quantum `X25519MLKEM768` (0x11ec) key_share.** Most real browser→CDN ClientHellos now carry the hybrid PQ group; answering with classical `x25519` is a passive group-downgrade tell. When the client offers 0x11ec we now echo a correct 0x11ec key_share (1120 bytes).
- **Profile-matched cert-record size (`fake_cert_size`).** The fake cert (AppData) record in the ServerHello was a fixed 2878 while a real mask backend serves its own size — an active prober saw different sizes on the accept vs mask path. Set `fake_cert_size` to your backend's real first-flight size so both match. (+ a `firstAppDataRecordLen` parser as the seam for a future zero-config auto-probe.)
- **Jittered desync split.** The fixed 3ms gap was itself a timing fingerprint → `desync_split_delay_ms` + `desync_split_jitter_ms` (3 + 0..3).
- **RST teardown on reject (`reject_rst`).** Emit a TCP RST instead of alert+FIN for fronted CDNs that reset a bad handshake.

## Active probing

- **Dynamic SNI mask target (`mask_sni_safelist`).** Front a safelisted-SNI probe to that domain's own server (resolved at startup) so the conversation matches the claimed SNI. Never an open relay.
- **Metrics** `mtproto_replay_hits_total` + `mtproto_unknown_sni_total` on `/metrics`.
- **mask-relay duration cap (`mask_relay_max_secs`).**

## Operator UX

- **HTTP-Date clock self-correction (`clock_sync_url`).** A skewed VPS clock otherwise silently rejects every handshake on the time-skew check. RFC 7231 parser; offset clamped to ±1 day.
- **PROXY-protocol v1/v2 (`accept_proxy_protocol`).** Recover the real client IP behind a TLS-terminating LB (MSG_PEEK + exact drain).

## Verified

`zig build test` — **258/258** (new KATs: PQ builder/detector, IMF-date, template-alloc, record-parser, PROXY v1/v2) + `x86_64-linux`/`aarch64-linux` cross-builds + `zig fmt`. THREAT_MODEL.md gains a post-quantum key_share section.

</details>

## Changelog

* feat(faketls): PQ key_share, RST teardown, jittered desync split, probe metrics ([#347](https://github.com/sleep3r/mtproto.zig/pull/347))
* feat(faketls): opt-in SNI-following mask target ([#349](https://github.com/sleep3r/mtproto.zig/pull/349))
* feat(faketls): clock-sync, mask-relay cap, fake_cert_size, PROXY-protocol ([#350](https://github.com/sleep3r/mtproto.zig/pull/350))

**Full diff:** https://github.com/sleep3r/mtproto.zig/compare/v1.4.4...v1.5.0

Related Repositories