From 60a2edd6fec2e5cfa17611b3131f509446830b4f Mon Sep 17 00:00:00 2001 From: TWRoman Date: Sun, 5 Apr 2026 21:17:25 +0300 Subject: [PATCH 1/3] Docs and README edits --- README.md | 191 +++--------------- README.ru.md | 123 +++++++++++ docs/{ => Advanced_settings}/TUNING.de.md | 0 docs/{ => Advanced_settings}/TUNING.en.md | 0 docs/{ => Advanced_settings}/TUNING.ru.md | 0 docs/{ => Architecture/API}/API.md | 0 .../Fronting-splitting}/TLS-F-TCP-S.ru.md | 2 +- .../KDF-internals/MIDDLE-END-KDF.de.md | 0 .../KDF-internals/MIDDLE-END-KDF.en.md | 0 .../KDF-internals/MIDDLE-END-KDF.ru.md | 0 .../{model => Architecture/Model}/FakeTLS.png | Bin .../{model => Architecture/Model}/MODEL.en.md | 0 .../{model => Architecture/Model}/MODEL.ru.md | 0 .../Model}/architecture.png | Bin docs/{ => Config_params}/CONFIG_PARAMS.en.md | 0 docs/FAQ.en.md | 152 +++++++++++++- docs/FAQ.ru.md | 134 +++++++++++- .../OPENBSD_QUICK_START_GUIDE.en.md} | 0 .../{ => Quick_start}/QUICK_START_GUIDE.en.md | 0 .../{ => Quick_start}/QUICK_START_GUIDE.ru.md | 0 .../{ => Setup_examples}/VPS_DOUBLE_HOP.en.md | 0 .../{ => Setup_examples}/VPS_DOUBLE_HOP.ru.md | 0 .../XRAY-SINGBOX-ROUTING.ru.md | 0 docs/assets/telegram_button.png | Bin 0 -> 4352 bytes docs/assets/telemt.png | Bin 0 -> 164632 bytes 25 files changed, 423 insertions(+), 179 deletions(-) create mode 100644 README.ru.md rename docs/{ => Advanced_settings}/TUNING.de.md (100%) rename docs/{ => Advanced_settings}/TUNING.en.md (100%) rename docs/{ => Advanced_settings}/TUNING.ru.md (100%) rename docs/{ => Architecture/API}/API.md (100%) rename docs/{fronting-splitting => Architecture/Fronting-splitting}/TLS-F-TCP-S.ru.md (99%) rename docs/{middle-end => Architecture/Middle-end}/KDF-internals/MIDDLE-END-KDF.de.md (100%) rename docs/{middle-end => Architecture/Middle-end}/KDF-internals/MIDDLE-END-KDF.en.md (100%) rename docs/{middle-end => Architecture/Middle-end}/KDF-internals/MIDDLE-END-KDF.ru.md (100%) rename docs/{model => Architecture/Model}/FakeTLS.png (100%) rename docs/{model => Architecture/Model}/MODEL.en.md (100%) rename docs/{model => Architecture/Model}/MODEL.ru.md (100%) rename docs/{model => Architecture/Model}/architecture.png (100%) rename docs/{ => Config_params}/CONFIG_PARAMS.en.md (100%) rename docs/{OPENBSD.en.md => Quick_start/OPENBSD_QUICK_START_GUIDE.en.md} (100%) rename docs/{ => Quick_start}/QUICK_START_GUIDE.en.md (100%) rename docs/{ => Quick_start}/QUICK_START_GUIDE.ru.md (100%) rename docs/{ => Setup_examples}/VPS_DOUBLE_HOP.en.md (100%) rename docs/{ => Setup_examples}/VPS_DOUBLE_HOP.ru.md (100%) rename docs/{ => Setup_examples}/XRAY-SINGBOX-ROUTING.ru.md (100%) create mode 100644 docs/assets/telegram_button.png create mode 100644 docs/assets/telemt.png diff --git a/README.md b/README.md index 5cfc277..6327233 100644 --- a/README.md +++ b/README.md @@ -2,189 +2,60 @@ ***Löst Probleme, bevor andere überhaupt wissen, dass sie existieren*** / ***It solves problems before others even realize they exist*** -### [**Telemt Chat in Telegram**](https://t.me/telemtrs) -#### Fixed TLS ClientHello is now available in Telegram Desktop starting from version 6.7.2: to work with EE-MTProxy, please update your client; -#### Fixed TLS ClientHello for Telegram Android Client is available in [our chat](https://t.me/telemtrs/30234/36441); official releases for Android and iOS are "work in progress"; +> [!NOTE] +> +> Fixed TLS ClientHello is now available in **Telegram Desktop** starting from version **6.7.2**: to work with EE-MTProxy, please update your client; +> +> Fixed TLS ClientHello for Telegram Android Client is available in [our chat](https://t.me/telemtrs/30234/36441); **official releases for Android and iOS are "work in progress"**; +

+ + Join us in Telegram + +

**Telemt** is a fast, secure, and feature-rich server written in Rust: it fully implements the official Telegram proxy algo and adds many production-ready improvements such as: -- [ME Pool + Reader/Writer + Registry + Refill + Adaptive Floor + Trio-State + Generation Lifecycle](https://github.com/telemt/telemt/blob/main/docs/model/MODEL.en.md) -- [Full-covered API w/ management](https://github.com/telemt/telemt/blob/main/docs/API.md) -- Anti-Replay on Sliding Window -- Prometheus-format Metrics -- TLS-Fronting and TCP-Splicing for masking from "prying" eyes +- [ME Pool + Reader/Writer + Registry + Refill + Adaptive Floor + Trio-State + Generation Lifecycle](https://github.com/telemt/telemt/blob/main/docs/model/MODEL.en.md); +- [Full-covered API w/ management](https://github.com/telemt/telemt/blob/main/docs/API.md); +- Anti-Replay on Sliding Window; +- Prometheus-format Metrics; +- TLS-Fronting and TCP-Splicing for masking from "prying" eyes. + +![telemt_scheme](docs/assets/telemt.png) ⚓ Our implementation of **TLS-fronting** is one of the most deeply debugged, focused, advanced and *almost* **"behaviorally consistent to real"**: we are confident we have it right - [see evidence on our validation and traces](#recognizability-for-dpi-and-crawler) ⚓ Our ***Middle-End Pool*** is fastest by design in standard scenarios, compared to other implementations of connecting to the Middle-End Proxy: non dramatically, but usual - Full support for all official MTProto proxy modes: - - Classic - - Secure - with `dd` prefix - - Fake TLS - with `ee` prefix + SNI fronting -- Replay attack protection -- Optional traffic masking: forward unrecognized connections to a real web server, e.g. GitHub 🤪 -- Configurable keepalives + timeouts + IPv6 and "Fast Mode" -- Graceful shutdown on Ctrl+C -- Extensive logging via `trace` and `debug` with `RUST_LOG` method + - Classic; + - Secure - with `dd` prefix; + - Fake TLS - with `ee` prefix + SNI fronting; +- Replay attack protection; +- Optional traffic masking: forward unrecognized connections to a real web server, e.g. GitHub 🤪; +- Configurable keepalives + timeouts + IPv6 and "Fast Mode"; +- Graceful shutdown on Ctrl+C; +- Extensive logging via `trace` and `debug` with `RUST_LOG` method. # GOTO -- [Quick Start Guide](#quick-start-guide) - [FAQ](#faq) - - [Recognizability for DPI and crawler](#recognizability-for-dpi-and-crawler) - - [Client WITH secret-key accesses the MTProxy resource:](#client-with-secret-key-accesses-the-mtproxy-resource) - - [Client WITHOUT secret-key gets transparent access to the specified resource:](#client-without-secret-key-gets-transparent-access-to-the-specified-resource) - - [Telegram Calls via MTProxy](#telegram-calls-via-mtproxy) - - [How does DPI see MTProxy TLS?](#how-does-dpi-see-mtproxy-tls) - - [Whitelist on IP](#whitelist-on-ip) - - [Too many open files](#too-many-open-files) +- [Architecture](docs/Architecture) +- [Quick Start Guide](#quick-start-guide) +- [Config parameters](docs/Config_params) - [Build](#build) - [Why Rust?](#why-rust) - [Issues](#issues) - [Roadmap](#roadmap) - ## Quick Start Guide -- [Quick Start Guide RU](docs/QUICK_START_GUIDE.ru.md) -- [Quick Start Guide EN](docs/QUICK_START_GUIDE.en.md) +- [Quick Start Guide RU](docs/Quick_start/QUICK_START_GUIDE.ru.md) +- [Quick Start Guide EN](docs/Quick_start/QUICK_START_GUIDE.en.md) ## FAQ - [FAQ RU](docs/FAQ.ru.md) - [FAQ EN](docs/FAQ.en.md) -### Recognizability for DPI and crawler - -On April 1, 2026, we became aware of a method for detecting MTProxy Fake-TLS, -based on the ECH extension and the ordering of cipher suites, -as well as an overall unique JA3/JA4 fingerprint -that does not occur in modern browsers: -we have already submitted initial changes to the Telegram Desktop developers and are working on updates for other clients. - -- We consider this a breakthrough aspect, which has no stable analogues today -- Based on this: if `telemt` configured correctly, **TLS mode is completely identical to real-life handshake + communication** with a specified host -- Here is our evidence: - - 212.220.88.77 - "dummy" host, running `telemt` - - `petrovich.ru` - `tls` + `masking` host, in HEX: `706574726f766963682e7275` - - **No MITM + No Fake Certificates/Crypto** = pure transparent *TCP Splice* to "best" upstream: MTProxy or tls/mask-host: - - DPI see legitimate HTTPS to `tls_host`, including *valid chain-of-trust* and entropy - - Crawlers completely satisfied receiving responses from `mask_host` - #### Client WITH secret-key accesses the MTProxy resource: - - telemt - - #### Client WITHOUT secret-key gets transparent access to the specified resource: - - with trusted certificate - - with original handshake - - with full request-response way - - with low-latency overhead -```bash -root@debian:~/telemt# curl -v -I --resolve petrovich.ru:443:212.220.88.77 https://petrovich.ru/ -* Added petrovich.ru:443:212.220.88.77 to DNS cache -* Hostname petrovich.ru was found in DNS cache -* Trying 212.220.88.77:443... -* Connected to petrovich.ru (212.220.88.77) port 443 (#0) -* ALPN: offers h2,http/1.1 -* TLSv1.3 (OUT), TLS handshake, Client hello (1): -* CAfile: /etc/ssl/certs/ca-certificates.crt -* CApath: /etc/ssl/certs -* TLSv1.3 (IN), TLS handshake, Server hello (2): -* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8): -* TLSv1.3 (IN), TLS handshake, Certificate (11): -* TLSv1.3 (IN), TLS handshake, CERT verify (15): -* TLSv1.3 (IN), TLS handshake, Finished (20): -* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1): -* TLSv1.3 (OUT), TLS handshake, Finished (20): -* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 -* ALPN: server did not agree on a protocol. Uses default. -* Server certificate: -* subject: C=RU; ST=Saint Petersburg; L=Saint Petersburg; O=STD Petrovich; CN=*.petrovich.ru -* start date: Jan 28 11:21:01 2025 GMT -* expire date: Mar 1 11:21:00 2026 GMT -* subjectAltName: host "petrovich.ru" matched cert's "petrovich.ru" -* issuer: C=BE; O=GlobalSign nv-sa; CN=GlobalSign RSA OV SSL CA 2018 -* SSL certificate verify ok. -* using HTTP/1.x -> HEAD / HTTP/1.1 -> Host: petrovich.ru -> User-Agent: curl/7.88.1 -> Accept: */* -> -* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): -* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): -* old SSL session ID is stale, removing -< HTTP/1.1 200 OK -HTTP/1.1 200 OK -< Server: Variti/0.9.3a -Server: Variti/0.9.3a -< Date: Thu, 01 Jan 2026 00:0000 GMT -Date: Thu, 01 Jan 2026 00:0000 GMT -< Access-Control-Allow-Origin: * -Access-Control-Allow-Origin: * -< Content-Type: text/html -Content-Type: text/html -< Cache-Control: no-store -Cache-Control: no-store -< Expires: Thu, 01 Jan 2026 00:0000 GMT -Expires: Thu, 01 Jan 2026 00:0000 GMT -< Pragma: no-cache -Pragma: no-cache -< Set-Cookie: ipp_uid=XXXXX/XXXXX/XXXXX==; Expires=Tue, 31 Dec 2040 23:59:59 GMT; Domain=.petrovich.ru; Path=/ -Set-Cookie: ipp_uid=XXXXX/XXXXX/XXXXX==; Expires=Tue, 31 Dec 2040 23:59:59 GMT; Domain=.petrovich.ru; Path=/ -< Content-Type: text/html -Content-Type: text/html -< Content-Length: 31253 -Content-Length: 31253 -< Connection: keep-alive -Connection: keep-alive -< Keep-Alive: timeout=60 -Keep-Alive: timeout=60 - -< -* Connection #0 to host petrovich.ru left intact - -``` -- We challenged ourselves, we kept trying and we didn't only *beat the air*: now, we have something to show you - - Do not just take our word for it? - This is great and we respect that: you can build your own `telemt` or download a build and check it right now -### Telegram Calls via MTProxy -- Telegram architecture **does NOT allow calls via MTProxy**, but only via SOCKS5, which cannot be obfuscated -### How does DPI see MTProxy TLS? -- DPI sees MTProxy in Fake TLS (ee) mode as TLS 1.3 -- the SNI you specify sends both the client and the server; -- ALPN is similar to HTTP 1.1/2; -- high entropy, which is normal for AES-encrypted traffic; -### Whitelist on IP -- MTProxy cannot work when there is: - - no IP connectivity to the target host: Russian Whitelist on Mobile Networks - "Белый список" - - OR all TCP traffic is blocked - - OR high entropy/encrypted traffic is blocked: content filters at universities and critical infrastructure - - OR all TLS traffic is blocked - - OR specified port is blocked: use 443 to make it "like real" - - OR provided SNI is blocked: use "officially approved"/innocuous name -- like most protocols on the Internet; -- these situations are observed: - - in China behind the Great Firewall - - in Russia on mobile networks, less in wired networks - - in Iran during "activity" -### Too many open files -- On a fresh Linux install the default open file limit is low; under load `telemt` may fail with `Accept error: Too many open files` -- **Systemd**: add `LimitNOFILE=65536` to the `[Service]` section (already included in the example above) -- **Docker**: add `--ulimit nofile=65536:65536` to your `docker run` command, or in `docker-compose.yml`: -```yaml -ulimits: - nofile: - soft: 65536 - hard: 65536 -``` -- **System-wide** (optional): add to `/etc/security/limits.conf`: -``` -* soft nofile 1048576 -* hard nofile 1048576 -root soft nofile 1048576 -root hard nofile 1048576 -``` - - ## Build ```bash # Cloning repo @@ -207,7 +78,7 @@ telemt config.toml ``` ### OpenBSD -- Build and service setup guide: [OpenBSD Guide (EN)](docs/OPENBSD.en.md) +- Build and service setup guide: [OpenBSD Guide (EN)](docs/Quick_start/OPENBSD_QUICK_START_GUIDE.en.md) - Example rc.d script: [contrib/openbsd/telemt.rcd](contrib/openbsd/telemt.rcd) - Status: OpenBSD sandbox hardening with `pledge(2)` and `unveil(2)` is not implemented yet. diff --git a/README.ru.md b/README.ru.md new file mode 100644 index 0000000..f5b0f9a --- /dev/null +++ b/README.ru.md @@ -0,0 +1,123 @@ +# Telemt — MTProxy на Rust + Tokio + +***Решает проблемы раньше, чем другие узнают об их существовании*** + +> [!Примечание] +> +> Исправленный TLS ClientHello доступен в **Telegram Desktop** начиная с версии **6.7.2**: для работы с EE-MTProxy обновите клиент. +> +> Исправленный TLS ClientHello для Telegram Android доступен в нашем чате; **официальные релизы для Android и iOS находятся в процессе разработки**. + +

+ + Мы в Telegram + +

+ +**Telemt** — это быстрый, безопасный и функциональный сервер, написанный на Rust. Он полностью реализует официальный алгоритм прокси Telegram и добавляет множество улучшений для продакшена: + +- [ME Pool + Reader/Writer + Registry + Refill + Adaptive Floor + Trio-State + жизненный цикл генераций](https://github.com/telemt/telemt/blob/main/docs/model/MODEL.en.md); +- [Полноценный API с управлением](https://github.com/telemt/telemt/blob/main/docs/API.md); +- Защита от повторных атак (Anti-Replay on Sliding Window); +- Метрики в формате Prometheus; +- TLS-fronting и TCP-splicing для маскировки от DPI. + +![telemt_scheme](docs/assets/telemt.png) + +## Особенности + +⚓ Реализация **TLS-fronting** максимально приближена к поведению реального HTTPS-трафика. + +⚓ ***Middle-End Pool*** оптимизирован для высокой производительности. + +- Поддержка всех режимов MTProto proxy: + - Classic; + - Secure (префикс `dd`); + - Fake TLS (префикс `ee` + SNI fronting); +- Защита от replay-атак; +- Маскировка трафика (перенаправление неизвестных подключений на реальные сайты); +- Настраиваемые keepalive, таймауты, IPv6 и «быстрый режим»; +- Корректное завершение работы (Ctrl+C); +- Подробное логирование через `trace` и `debug`. + +# Навигация +- [FAQ](#faq) +- [Архитектура](docs/Architecture) +- [Быстрый старт](#quick-start-guide) +- [Параметры конфигурационного файла](docs/Config_params) +- [Сборка](#build) +- [Почему Rust?](#why-rust) +- [Известные проблемы](#issues) +- [Планы](#roadmap) + +## Быстрый старт +- [Quick Start Guide RU](docs/Quick_start/QUICK_START_GUIDE.ru.md) +- [Quick Start Guide EN](docs/Quick_start/QUICK_START_GUIDE.en.md) + +## FAQ + +- [FAQ RU](docs/FAQ.ru.md) +- [FAQ EN](docs/FAQ.en.md) + +## Сборка + +```bash +# Клонируйте репозиторий +git clone https://github.com/telemt/telemt +# Смените каталог на telemt +cd telemt +# Начните процесс сборки +cargo build --release + +# Устройства с небольшим объёмом оперативной памяти (1 ГБ, например NanoPi Neo3 / Raspberry Pi Zero 2): +# используется параметр lto = «thin» для уменьшения пикового потребления памяти. +# Если ваш пользовательский набор инструментов переопределяет профили, не используйте Fat LTO. + +# Перейдите в каталог /bin +mv ./target/release/telemt /bin +# Сделайте файл исполняемым +chmod +x /bin/telemt +# Запустите! +telemt config.toml +``` + +### Устройства с малым объемом RAM +Для устройств с ~1 ГБ RAM (например Raspberry Pi): +- используется облегчённая оптимизация линковщика (thin LTO); +- не рекомендуется включать fat LTO. + +## OpenBSD + +- Руководство по сборке и настройке на английском языке [OpenBSD Guide (EN)](docs/Quick_start/OPENBSD_QUICK_START_GUIDE.en.md); +- Пример rc.d скрипта: [contrib/openbsd/telemt.rcd](contrib/openbsd/telemt.rcd); +- Поддержка sandbox с `pledge(2)` и `unveil(2)` пока не реализована. + +## Почему Rust? + +- Надёжность для долгоживущих процессов; +- Детерминированное управление ресурсами (RAII); +- Отсутствие сборщика мусора; +- Безопасность памяти; +- Асинхронная архитектура Tokio. + +## Известные проблемы + +- ✅ [Поддержка SOCKS5 как upstream](https://github.com/telemt/telemt/issues/1) -> added Upstream Management; +- ✅ [Проблема зависания загрузки медиа на iOS](https://github.com/telemt/telemt/issues/2). + +## Планы + +- Публичный IP в ссылках; +- Перезагрузка конфигурации на лету; +- Привязка к устройству или IP для входящих и исходящих соединений; +- Поддержка рекламных тегов по SNI / секретному ключу; +- Улучшенная обработка ошибок; +- Zero-copy оптимизации; +- Проверка состояния дата-центров; +- Отсутствие глобального изменяемого состояния; +- Изоляция клиентов и справедливое распределение трафика; +- «Политика секретов» — маршрутизация по SNI / секрету; +- Балансировщик с несколькими источниками и отработка отказов; +- Строгие FSM для handshake; +- Улучшенная защита от replay-атак; +- Веб-интерфейс: статистика, состояние работоспособности, задержка, пользовательский опыт... diff --git a/docs/TUNING.de.md b/docs/Advanced_settings/TUNING.de.md similarity index 100% rename from docs/TUNING.de.md rename to docs/Advanced_settings/TUNING.de.md diff --git a/docs/TUNING.en.md b/docs/Advanced_settings/TUNING.en.md similarity index 100% rename from docs/TUNING.en.md rename to docs/Advanced_settings/TUNING.en.md diff --git a/docs/TUNING.ru.md b/docs/Advanced_settings/TUNING.ru.md similarity index 100% rename from docs/TUNING.ru.md rename to docs/Advanced_settings/TUNING.ru.md diff --git a/docs/API.md b/docs/Architecture/API/API.md similarity index 100% rename from docs/API.md rename to docs/Architecture/API/API.md diff --git a/docs/fronting-splitting/TLS-F-TCP-S.ru.md b/docs/Architecture/Fronting-splitting/TLS-F-TCP-S.ru.md similarity index 99% rename from docs/fronting-splitting/TLS-F-TCP-S.ru.md rename to docs/Architecture/Fronting-splitting/TLS-F-TCP-S.ru.md index 1f9f872..750fb48 100644 --- a/docs/fronting-splitting/TLS-F-TCP-S.ru.md +++ b/docs/Architecture/Fronting-splitting/TLS-F-TCP-S.ru.md @@ -130,7 +130,7 @@ mask_host:mask_port **Telemt работает как TCP-переключатель:** 1) принимает соединение -2️) определяет тип клиента +2) определяет тип клиента 3) либо: - обрабатывает MTProxy внутри diff --git a/docs/middle-end/KDF-internals/MIDDLE-END-KDF.de.md b/docs/Architecture/Middle-end/KDF-internals/MIDDLE-END-KDF.de.md similarity index 100% rename from docs/middle-end/KDF-internals/MIDDLE-END-KDF.de.md rename to docs/Architecture/Middle-end/KDF-internals/MIDDLE-END-KDF.de.md diff --git a/docs/middle-end/KDF-internals/MIDDLE-END-KDF.en.md b/docs/Architecture/Middle-end/KDF-internals/MIDDLE-END-KDF.en.md similarity index 100% rename from docs/middle-end/KDF-internals/MIDDLE-END-KDF.en.md rename to docs/Architecture/Middle-end/KDF-internals/MIDDLE-END-KDF.en.md diff --git a/docs/middle-end/KDF-internals/MIDDLE-END-KDF.ru.md b/docs/Architecture/Middle-end/KDF-internals/MIDDLE-END-KDF.ru.md similarity index 100% rename from docs/middle-end/KDF-internals/MIDDLE-END-KDF.ru.md rename to docs/Architecture/Middle-end/KDF-internals/MIDDLE-END-KDF.ru.md diff --git a/docs/model/FakeTLS.png b/docs/Architecture/Model/FakeTLS.png similarity index 100% rename from docs/model/FakeTLS.png rename to docs/Architecture/Model/FakeTLS.png diff --git a/docs/model/MODEL.en.md b/docs/Architecture/Model/MODEL.en.md similarity index 100% rename from docs/model/MODEL.en.md rename to docs/Architecture/Model/MODEL.en.md diff --git a/docs/model/MODEL.ru.md b/docs/Architecture/Model/MODEL.ru.md similarity index 100% rename from docs/model/MODEL.ru.md rename to docs/Architecture/Model/MODEL.ru.md diff --git a/docs/model/architecture.png b/docs/Architecture/Model/architecture.png similarity index 100% rename from docs/model/architecture.png rename to docs/Architecture/Model/architecture.png diff --git a/docs/CONFIG_PARAMS.en.md b/docs/Config_params/CONFIG_PARAMS.en.md similarity index 100% rename from docs/CONFIG_PARAMS.en.md rename to docs/Config_params/CONFIG_PARAMS.en.md diff --git a/docs/FAQ.en.md b/docs/FAQ.en.md index 5e5a78a..7d477b2 100644 --- a/docs/FAQ.en.md +++ b/docs/FAQ.en.md @@ -1,5 +1,4 @@ ## How to set up a "proxy sponsor" channel and statistics via the @MTProxybot - 1. Go to the @MTProxybot. 2. Enter the `/newproxy` command. 3. Send your server's IP address and port. For example: `1.2.3.4:443`. @@ -32,13 +31,130 @@ use_middle_proxy = true hello = "ad_tag" hello2 = "ad_tag2" ``` +## Recognizability for DPI and crawler -## Why do you need a middle proxy (ME) +On April 1, 2026, we became aware of a method for detecting MTProxy Fake-TLS, +based on the ECH extension and the ordering of cipher suites, +as well as an overall unique JA3/JA4 fingerprint +that does not occur in modern browsers: +we have already submitted initial changes to the Telegram Desktop developers and are working on updates for other clients. + +- We consider this a breakthrough aspect, which has no stable analogues today +- Based on this: if `telemt` configured correctly, **TLS mode is completely identical to real-life handshake + communication** with a specified host +- Here is our evidence: + - 212.220.88.77 - "dummy" host, running `telemt` + - `petrovich.ru` - `tls` + `masking` host, in HEX: `706574726f766963682e7275` + - **No MITM + No Fake Certificates/Crypto** = pure transparent *TCP Splice* to "best" upstream: MTProxy or tls/mask-host: + - DPI see legitimate HTTPS to `tls_host`, including *valid chain-of-trust* and entropy + - Crawlers completely satisfied receiving responses from `mask_host` + ### Client WITH secret-key accesses the MTProxy resource: + + telemt + + ### Client WITHOUT secret-key gets transparent access to the specified resource: + - with trusted certificate + - with original handshake + - with full request-response way + - with low-latency overhead +```bash +root@debian:~/telemt# curl -v -I --resolve petrovich.ru:443:212.220.88.77 https://petrovich.ru/ +* Added petrovich.ru:443:212.220.88.77 to DNS cache +* Hostname petrovich.ru was found in DNS cache +* Trying 212.220.88.77:443... +* Connected to petrovich.ru (212.220.88.77) port 443 (#0) +* ALPN: offers h2,http/1.1 +* TLSv1.3 (OUT), TLS handshake, Client hello (1): +* CAfile: /etc/ssl/certs/ca-certificates.crt +* CApath: /etc/ssl/certs +* TLSv1.3 (IN), TLS handshake, Server hello (2): +* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8): +* TLSv1.3 (IN), TLS handshake, Certificate (11): +* TLSv1.3 (IN), TLS handshake, CERT verify (15): +* TLSv1.3 (IN), TLS handshake, Finished (20): +* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1): +* TLSv1.3 (OUT), TLS handshake, Finished (20): +* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 +* ALPN: server did not agree on a protocol. Uses default. +* Server certificate: +* subject: C=RU; ST=Saint Petersburg; L=Saint Petersburg; O=STD Petrovich; CN=*.petrovich.ru +* start date: Jan 28 11:21:01 2025 GMT +* expire date: Mar 1 11:21:00 2026 GMT +* subjectAltName: host "petrovich.ru" matched cert's "petrovich.ru" +* issuer: C=BE; O=GlobalSign nv-sa; CN=GlobalSign RSA OV SSL CA 2018 +* SSL certificate verify ok. +* using HTTP/1.x +> HEAD / HTTP/1.1 +> Host: petrovich.ru +> User-Agent: curl/7.88.1 +> Accept: */* +> +* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): +* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): +* old SSL session ID is stale, removing +< HTTP/1.1 200 OK +HTTP/1.1 200 OK +< Server: Variti/0.9.3a +Server: Variti/0.9.3a +< Date: Thu, 01 Jan 2026 00:0000 GMT +Date: Thu, 01 Jan 2026 00:0000 GMT +< Access-Control-Allow-Origin: * +Access-Control-Allow-Origin: * +< Content-Type: text/html +Content-Type: text/html +< Cache-Control: no-store +Cache-Control: no-store +< Expires: Thu, 01 Jan 2026 00:0000 GMT +Expires: Thu, 01 Jan 2026 00:0000 GMT +< Pragma: no-cache +Pragma: no-cache +< Set-Cookie: ipp_uid=XXXXX/XXXXX/XXXXX==; Expires=Tue, 31 Dec 2040 23:59:59 GMT; Domain=.petrovich.ru; Path=/ +Set-Cookie: ipp_uid=XXXXX/XXXXX/XXXXX==; Expires=Tue, 31 Dec 2040 23:59:59 GMT; Domain=.petrovich.ru; Path=/ +< Content-Type: text/html +Content-Type: text/html +< Content-Length: 31253 +Content-Length: 31253 +< Connection: keep-alive +Connection: keep-alive +< Keep-Alive: timeout=60 +Keep-Alive: timeout=60 + +< +* Connection #0 to host petrovich.ru left intact + +``` +- We challenged ourselves, we kept trying and we didn't only *beat the air*: now, we have something to show you + - Do not just take our word for it? - This is great and we respect that: you can build your own `telemt` or download a build and check it right now + + +## F.A.Q. + +### Telegram Calls via MTProxy +- Telegram architecture **does NOT allow calls via MTProxy**, but only via SOCKS5, which cannot be obfuscated + +### How does DPI see MTProxy TLS? +- DPI sees MTProxy in Fake TLS (ee) mode as TLS 1.3 +- the SNI you specify sends both the client and the server; +- ALPN is similar to HTTP 1.1/2; +- high entropy, which is normal for AES-encrypted traffic; + +### Whitelist on IP +- MTProxy cannot work when there is: + - no IP connectivity to the target host: Russian Whitelist on Mobile Networks - "Белый список" + - OR all TCP traffic is blocked + - OR high entropy/encrypted traffic is blocked: content filters at universities and critical infrastructure + - OR all TLS traffic is blocked + - OR specified port is blocked: use 443 to make it "like real" + - OR provided SNI is blocked: use "officially approved"/innocuous name +- like most protocols on the Internet; +- these situations are observed: + - in China behind the Great Firewall + - in Russia on mobile networks, less in wired networks + - in Iran during "activity" + +### Why do you need a middle proxy (ME) https://github.com/telemt/telemt/discussions/167 - -## How many people can use one link - +### How many people can use one link By default, an unlimited number of people can use a single link. However, you can limit the number of unique IP addresses for each user: ```toml @@ -47,8 +163,7 @@ hello = 1 ``` This parameter sets the maximum number of unique IP addresses from which a single link can be used simultaneously. If the first user disconnects, a second one can connect. At the same time, multiple users can connect from a single IP address simultaneously (for example, devices on the same Wi-Fi network). -## How to create multiple different links - +### How to create multiple different links 1. Generate the required number of secrets using the command: `openssl rand -hex 16`. 2. Open the configuration file: `nano /etc/telemt/telemt.toml`. 3. Add new users to the `[access.users]` section: @@ -64,7 +179,7 @@ user3 = "00000000000000000000000000000003" curl -s http://127.0.0.1:9091/v1/users | jq ``` -## "Unknown TLS SNI" error +### "Unknown TLS SNI" error Usually, this error occurs if you have changed the `tls_domain` parameter, but users continue to connect using old links with the previous domain. If you need to allow connections with any domains (ignoring SNI mismatches), add the following parameters: @@ -73,7 +188,7 @@ If you need to allow connections with any domains (ignoring SNI mismatches), add unknown_sni_action = "mask" ``` -## How to view metrics +### How to view metrics 1. Open the configuration file: `nano /etc/telemt/telemt.toml`. 2. Add the following parameters: @@ -87,6 +202,25 @@ metrics_whitelist = ["127.0.0.1/32", "::1/128", "0.0.0.0/0"] > [!WARNING] > The value `"0.0.0.0/0"` in `metrics_whitelist` opens access to metrics from any IP address. It is recommended to replace it with your personal IP, for example: `"1.2.3.4/32"`. +### Too many open files +- On a fresh Linux install the default open file limit is low; under load `telemt` may fail with `Accept error: Too many open files` +- **Systemd**: add `LimitNOFILE=65536` to the `[Service]` section (already included in the example above) +- **Docker**: add `--ulimit nofile=65536:65536` to your `docker run` command, or in `docker-compose.yml`: +```yaml +ulimits: + nofile: + soft: 65536 + hard: 65536 +``` +- **System-wide** (optional): add to `/etc/security/limits.conf`: +``` +* soft nofile 1048576 +* hard nofile 1048576 +root soft nofile 1048576 +root hard nofile 1048576 +``` + + ## Additional parameters ### Domain in the link instead of IP diff --git a/docs/FAQ.ru.md b/docs/FAQ.ru.md index fa7d5c0..91d842d 100644 --- a/docs/FAQ.ru.md +++ b/docs/FAQ.ru.md @@ -32,6 +32,122 @@ use_middle_proxy = true hello = "ad_tag" hello2 = "ad_tag2" ``` +## Распознаваемость для DPI и сканеров + +1 апреля 2026 года нам стало известно о методе обнаружения MTProxy Fake-TLS, основанном на расширении ECH и порядке набора шифров, +а также об общем уникальном отпечатке JA3/JA4, который не встречается в современных браузерах: мы уже отправили первоначальные изменения разработчикам Telegram Desktop и работаем над обновлениями для других клиентов. + +- Мы считаем это прорывом, которому на сегодняшний день нет стабильных аналогов; +- Исходя из этого: если `telemt` настроен правильно, **режим TLS полностью идентичен реальному «рукопожатию» + обмену данными** с указанным хостом; +- Вот наши доказательства: + - 212.220.88.77 — «фиктивный» хост, на котором запущен `telemt`; + - `petrovich.ru` — хост с `tls` + `masking`, в HEX: `706574726f766963682e7275`; + - **Без MITM + без поддельных сертификатов/шифрования** = чистое прозрачное *TCP Splice* к «лучшему» исходному серверу: MTProxy или tls/mask-host: + - DPI видит легитимный HTTPS к `tls_host`, включая *достоверную цепочку доверия* и энтропию; + - Краулеры полностью удовлетворены получением ответов от `mask_host`. + + ### Клиент С секретным ключом получает доступ к ресурсу MTProxy: + + telemt + + ### Клиент БЕЗ секретного ключа получает прозрачный доступ к указанному ресурсу: + - с доверенным сертификатом; + - с исходным «рукопожатием»; + - с полным циклом запрос-ответ; + - с низкой задержкой. + +```bash +root@debian:~/telemt# curl -v -I --resolve petrovich.ru:443:212.220.88.77 https://petrovich.ru/ +* Added petrovich.ru:443:212.220.88.77 to DNS cache +* Hostname petrovich.ru was found in DNS cache +* Trying 212.220.88.77:443... +* Connected to petrovich.ru (212.220.88.77) port 443 (#0) +* ALPN: offers h2,http/1.1 +* TLSv1.3 (OUT), TLS handshake, Client hello (1): +* CAfile: /etc/ssl/certs/ca-certificates.crt +* CApath: /etc/ssl/certs +* TLSv1.3 (IN), TLS handshake, Server hello (2): +* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8): +* TLSv1.3 (IN), TLS handshake, Certificate (11): +* TLSv1.3 (IN), TLS handshake, CERT verify (15): +* TLSv1.3 (IN), TLS handshake, Finished (20): +* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1): +* TLSv1.3 (OUT), TLS handshake, Finished (20): +* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 +* ALPN: server did not agree on a protocol. Uses default. +* Server certificate: +* subject: C=RU; ST=Saint Petersburg; L=Saint Petersburg; O=STD Petrovich; CN=*.petrovich.ru +* start date: Jan 28 11:21:01 2025 GMT +* expire date: Mar 1 11:21:00 2026 GMT +* subjectAltName: host "petrovich.ru" matched cert's "petrovich.ru" +* issuer: C=BE; O=GlobalSign nv-sa; CN=GlobalSign RSA OV SSL CA 2018 +* SSL certificate verify ok. +* using HTTP/1.x +> HEAD / HTTP/1.1 +> Host: petrovich.ru +> User-Agent: curl/7.88.1 +> Accept: */* +> +* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): +* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): +* old SSL session ID is stale, removing +< HTTP/1.1 200 OK +HTTP/1.1 200 OK +< Server: Variti/0.9.3a +Server: Variti/0.9.3a +< Date: Thu, 01 Jan 2026 00:0000 GMT +Date: Thu, 01 Jan 2026 00:0000 GMT +< Access-Control-Allow-Origin: * +Access-Control-Allow-Origin: * +< Content-Type: text/html +Content-Type: text/html +< Cache-Control: no-store +Cache-Control: no-store +< Expires: Thu, 01 Jan 2026 00:0000 GMT +Expires: Thu, 01 Jan 2026 00:0000 GMT +< Pragma: no-cache +Pragma: no-cache +< Set-Cookie: ipp_uid=XXXXX/XXXXX/XXXXX==; Expires=Tue, 31 Dec 2040 23:59:59 GMT; Domain=.petrovich.ru; Path=/ +Set-Cookie: ipp_uid=XXXXX/XXXXX/XXXXX==; Expires=Tue, 31 Dec 2040 23:59:59 GMT; Domain=.petrovich.ru; Path=/ +< Content-Type: text/html +Content-Type: text/html +< Content-Length: 31253 +Content-Length: 31253 +< Connection: keep-alive +Connection: keep-alive +< Keep-Alive: timeout=60 +Keep-Alive: timeout=60 + +< +* Connection #0 to host petrovich.ru left intact + +``` +- Мы поставили перед собой задачу, не сдавались и не просто «бились в пустоту»: теперь у нас есть что вам показать. +- Не верите нам на слово? — Это прекрасно, и мы уважаем ваше решение: вы можете собрать свой собственный `telemt` или скачать готовую сборку и проверить её прямо сейчас. + +### Звонки в Telegram через MTProxy +- Архитектура Telegram **НЕ поддерживает звонки через MTProxy**, а только через SOCKS5, который невозможно замаскировать + +### Как DPI распознает TLS-соединение MTProxy? +- DPI распознает MTProxy в режиме Fake TLS (ee) как TLS 1.3 +- указанный вами SNI отправляется как клиентом, так и сервером; +- ALPN аналогичен HTTP 1.1/2; +- высокая энтропия, что нормально для трафика, зашифрованного AES; + +### Белый список по IP +- MTProxy не может работать, если: + - отсутствует IP-связь с целевым хостом: российский белый список в мобильных сетях — «Белый список»; + - ИЛИ весь TCP-трафик заблокирован; + - ИЛИ трафик с высокой энтропией/зашифрованный трафик заблокирован: контент-фильтры в университетах и критически важной инфраструктуре; + - ИЛИ весь TLS-трафик заблокирован; + - ИЛИ заблокирован указанный порт: используйте 443, чтобы сделать его «как настоящий»; + - ИЛИ заблокирован предоставленный SNI: используйте «официально одобренное»/безобидное имя; +- как и большинство протоколов в Интернете; +- такие ситуации наблюдаются: + - в Китае за Великим файрволом; + - в России в мобильных сетях, реже в проводных сетях; + - в Иране во время «активности». + ## Зачем нужен middle proxy (ME) https://github.com/telemt/telemt/discussions/167 @@ -104,7 +220,7 @@ max_connections = 10000 # 0 - без ограничений, 10000 - по у ``` ### Upstream Manager -Для настройки исходящих подключений (апстримов) добавьте соответствующие параметры в секцию `[[upstreams]]` файла конфигурации: +Для настройки исходящих подключений (Upstreams) добавьте соответствующие параметры в секцию `[[upstreams]]` файла конфигурации: #### Привязка к исходящему IP-адресу ```toml @@ -119,20 +235,20 @@ interface = "192.168.1.100" # Замените на ваш исходящий IP - Без авторизации: ```toml [[upstreams]] -type = "socks5" # Specify SOCKS4 or SOCKS5 -address = "1.2.3.4:1234" # SOCKS-server Address -weight = 1 # Set Weight for Scenarios +type = "socks5" # выбор типа SOCKS4 или SOCKS5 +address = "1.2.3.4:1234" # адрес сервера SOCKS +weight = 1 # вес enabled = true ``` - С авторизацией: ```toml [[upstreams]] -type = "socks5" # Specify SOCKS4 or SOCKS5 -address = "1.2.3.4:1234" # SOCKS-server Address -username = "user" # Username for Auth on SOCKS-server -password = "pass" # Password for Auth on SOCKS-server -weight = 1 # Set Weight for Scenarios +type = "socks5" # выбор типа SOCKS4 или SOCKS5 +address = "1.2.3.4:1234" # адрес сервера SOCKS +username = "user" # имя пользователя +password = "pass" # пароль +weight = 1 # вес enabled = true ``` diff --git a/docs/OPENBSD.en.md b/docs/Quick_start/OPENBSD_QUICK_START_GUIDE.en.md similarity index 100% rename from docs/OPENBSD.en.md rename to docs/Quick_start/OPENBSD_QUICK_START_GUIDE.en.md diff --git a/docs/QUICK_START_GUIDE.en.md b/docs/Quick_start/QUICK_START_GUIDE.en.md similarity index 100% rename from docs/QUICK_START_GUIDE.en.md rename to docs/Quick_start/QUICK_START_GUIDE.en.md diff --git a/docs/QUICK_START_GUIDE.ru.md b/docs/Quick_start/QUICK_START_GUIDE.ru.md similarity index 100% rename from docs/QUICK_START_GUIDE.ru.md rename to docs/Quick_start/QUICK_START_GUIDE.ru.md diff --git a/docs/VPS_DOUBLE_HOP.en.md b/docs/Setup_examples/VPS_DOUBLE_HOP.en.md similarity index 100% rename from docs/VPS_DOUBLE_HOP.en.md rename to docs/Setup_examples/VPS_DOUBLE_HOP.en.md diff --git a/docs/VPS_DOUBLE_HOP.ru.md b/docs/Setup_examples/VPS_DOUBLE_HOP.ru.md similarity index 100% rename from docs/VPS_DOUBLE_HOP.ru.md rename to docs/Setup_examples/VPS_DOUBLE_HOP.ru.md diff --git a/docs/XRAY-SINGBOX-ROUTING.ru.md b/docs/Setup_examples/XRAY-SINGBOX-ROUTING.ru.md similarity index 100% rename from docs/XRAY-SINGBOX-ROUTING.ru.md rename to docs/Setup_examples/XRAY-SINGBOX-ROUTING.ru.md diff --git a/docs/assets/telegram_button.png b/docs/assets/telegram_button.png new file mode 100644 index 0000000000000000000000000000000000000000..645cdc52db759fb48c7365a6f752b2ca72b33f18 GIT binary patch literal 4352 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 JztFUg_zy<++mHYN literal 0 HcmV?d00001 diff --git a/docs/assets/telemt.png b/docs/assets/telemt.png new file mode 100644 index 0000000000000000000000000000000000000000..653e383e1a4991ac4d89d05970e908c29ae73fbf GIT binary patch literal 164632 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 O` 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 literal 0 HcmV?d00001 From 2d15eb1f6dd847f496e6986e428b28c443125804 Mon Sep 17 00:00:00 2001 From: Roman <140929436+TWRoman@users.noreply.github.com> Date: Sun, 5 Apr 2026 23:15:07 +0300 Subject: [PATCH 2/3] Update README.ru.md Text block fix --- README.ru.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.ru.md b/README.ru.md index f5b0f9a..97e6cb1 100644 --- a/README.ru.md +++ b/README.ru.md @@ -2,7 +2,7 @@ ***Решает проблемы раньше, чем другие узнают об их существовании*** -> [!Примечание] +> [!NOTE] > > Исправленный TLS ClientHello доступен в **Telegram Desktop** начиная с версии **6.7.2**: для работы с EE-MTProxy обновите клиент. > From 9992456dfaf2b636810ceb92221608633b3fa6ba Mon Sep 17 00:00:00 2001 From: Roman <140929436+TWRoman@users.noreply.github.com> Date: Mon, 6 Apr 2026 14:51:05 +0300 Subject: [PATCH 3/3] Added Config_Params.ru.md from TG Chat --- docs/Config_params/CONFIG_PARAMS.ru.md | 3300 ++++++++++++++++++++++++ 1 file changed, 3300 insertions(+) create mode 100644 docs/Config_params/CONFIG_PARAMS.ru.md diff --git a/docs/Config_params/CONFIG_PARAMS.ru.md b/docs/Config_params/CONFIG_PARAMS.ru.md new file mode 100644 index 0000000..7dc15c4 --- /dev/null +++ b/docs/Config_params/CONFIG_PARAMS.ru.md @@ -0,0 +1,3300 @@ +# Справочник параметров конфигурации Telemt + +В этом документе перечислены все ключи конфигурации, принимаемые `config.toml`. + +> [!ПРИМЕЧАНИЕ] +> +> Этот справочник был составлен с помощью искусственного интеллекта и сверен с базой кода (схема конфигурации, значения по умолчанию и логика проверки). + +> [!ПРЕДУПРЕЖДЕНИЕ] +> +> Параметры конфигурации, подробно описанные в этом документе, предназначены для опытных пользователей и для целей тонкой настройки. Изменение этих параметров без четкого понимания их функции может привести к нестабильности приложения или другому неожиданному поведению. Пожалуйста, действуйте осторожно и на свой страх и риск. + +## Ключи верхнего уровня + +| Ключ | Тип | По умолчанию | +| --- | ---- | ------- | +| [`include`](#cfg-top-include) | `String` (special directive) | — | +| [`show_link`](#cfg-top-show_link) | `"*"` or `String[]` | `[]` (`ShowLink::None`) | +| [`dc_overrides`](#cfg-top-dc_overrides) | `Map` | `{}` | +| [`default_dc`](#cfg-top-default_dc) | `u8` | — (effective fallback: `2` in ME routing) | + + +- `include` + - **Ограничения / валидация**: Должна быть однострочной директивой в форме `include = "path/to/file.toml"`. Включения расширяются перед анализом TOML. Максимальная глубина включения — 10. + - **Описание**: Включает еще один файл TOML с помощью `include = "relative/or/absolute/path.toml"`; включения обрабатываются рекурсивно перед анализом. + - **Пример**: + + ```toml + include = "secrets.toml" + ``` + +- `show_link` + - **Ограничения / валидация**: Принимает `"*"` или массив имен пользователей. Пустой массив означает «не показывать ничего». + - **Описание**: Устаревший селектор видимости ссылок верхнего уровня («*»` для всех пользователей или списка явных имен пользователей). + - **Пример**: + + ```toml + # show links for all configured users + show_link = "*" + + # or: show links only for selected users + # show_link = ["alice", "bob"] + ``` + +- `dc_overrides` + - **Ограничения / валидация**: Ключ должен быть положительным целочисленным индексом DC, закодированным как строка (например, `"203"`). Значения должны анализироваться как `SocketAddr` (`ip:port`). Пустые строки игнорируются. + - **Описание**: Переопределяет конечные точки контроллера домена для нестандартных контроллеров домена; ключ — индексная строка контроллера домена, значение — один или несколько адресов `ip:port`. + - **Пример**: + + ```toml + [dc_overrides] + "201" = "149.154.175.50:443" + "203" = ["149.154.175.100:443", "91.105.192.100:443"] + ``` + +- `default_dc` + - **Ограничения / валидация**: Предполагаемый диапазон: «1..=5». Если этот параметр выходит за пределы диапазона, время выполнения возвращается к поведению DC1 в прямом реле; Маршрутизация среднего уровня возвращается к значению «2», если она не установлена. + - **Описание**: Индекс контроллера домена по умолчанию, используемый для несопоставленных нестандартных контроллеров домена. + - **Пример**: + + ```toml + # When a client requests an unknown/non-standard DC with no override, + # route it to this default cluster (1..=5). + default_dc = 2 + ``` + +## [general] + +| Ключ | Тип | По умолчанию | +| --- | ---- | ------- | +| [`data_path`](#cfg-general-data_path) | `String` | — | +| [`prefer_ipv6`](#cfg-general-prefer_ipv6) | `bool` | `false` | +| [`fast_mode`](#cfg-general-fast_mode) | `bool` | `true` | +| [`use_middle_proxy`](#cfg-general-use_middle_proxy) | `bool` | `true` | +| [`proxy_secret_path`](#cfg-general-proxy_secret_path) | `String` | `"proxy-secret"` | +| [`proxy_config_v4_cache_path`](#cfg-general-proxy_config_v4_cache_path) | `String` | `"cache/proxy-config-v4.txt"` | +| [`proxy_config_v6_cache_path`](#cfg-general-proxy_config_v6_cache_path) | `String` | `"cache/proxy-config-v6.txt"` | +| [`ad_tag`](#cfg-general-ad_tag) | `String` | — | +| [`middle_proxy_nat_ip`](#cfg-general-middle_proxy_nat_ip) | `IpAddr` | — | +| [`middle_proxy_nat_probe`](#cfg-general-middle_proxy_nat_probe) | `bool` | `true` | +| [`middle_proxy_nat_stun`](#cfg-general-middle_proxy_nat_stun) | `String` | — | +| [`middle_proxy_nat_stun_servers`](#cfg-general-middle_proxy_nat_stun_servers) | `String[]` | `[]` | +| [`stun_nat_probe_concurrency`](#cfg-general-stun_nat_probe_concurrency) | `usize` | `8` | +| [`middle_proxy_pool_size`](#cfg-general-middle_proxy_pool_size) | `usize` | `8` | +| [`middle_proxy_warm_standby`](#cfg-general-middle_proxy_warm_standby) | `usize` | `16` | +| [`me_init_retry_attempts`](#cfg-general-me_init_retry_attempts) | `u32` | `0` | +| [`me2dc_fallback`](#cfg-general-me2dc_fallback) | `bool` | `true` | +| [`me2dc_fast`](#cfg-general-me2dc_fast) | `bool` | `false` | +| [`me_keepalive_enabled`](#cfg-general-me_keepalive_enabled) | `bool` | `true` | +| [`me_keepalive_interval_secs`](#cfg-general-me_keepalive_interval_secs) | `u64` | `8` | +| [`me_keepalive_jitter_secs`](#cfg-general-me_keepalive_jitter_secs) | `u64` | `2` | +| [`me_keepalive_payload_random`](#cfg-general-me_keepalive_payload_random) | `bool` | `true` | +| [`rpc_proxy_req_every`](#cfg-general-rpc_proxy_req_every) | `u64` | `0` | +| [`me_writer_cmd_channel_capacity`](#cfg-general-me_writer_cmd_channel_capacity) | `usize` | `4096` | +| [`me_route_channel_capacity`](#cfg-general-me_route_channel_capacity) | `usize` | `768` | +| [`me_c2me_channel_capacity`](#cfg-general-me_c2me_channel_capacity) | `usize` | `1024` | +| [`me_c2me_send_timeout_ms`](#cfg-general-me_c2me_send_timeout_ms) | `u64` | `4000` | +| [`me_reader_route_data_wait_ms`](#cfg-general-me_reader_route_data_wait_ms) | `u64` | `2` | +| [`me_d2c_flush_batch_max_frames`](#cfg-general-me_d2c_flush_batch_max_frames) | `usize` | `32` | +| [`me_d2c_flush_batch_max_bytes`](#cfg-general-me_d2c_flush_batch_max_bytes) | `usize` | `131072` | +| [`me_d2c_flush_batch_max_delay_us`](#cfg-general-me_d2c_flush_batch_max_delay_us) | `u64` | `500` | +| [`me_d2c_ack_flush_immediate`](#cfg-general-me_d2c_ack_flush_immediate) | `bool` | `true` | +| [`me_quota_soft_overshoot_bytes`](#cfg-general-me_quota_soft_overshoot_bytes) | `u64` | `65536` | +| [`me_d2c_frame_buf_shrink_threshold_bytes`](#cfg-general-me_d2c_frame_buf_shrink_threshold_bytes) | `usize` | `262144` | +| [`direct_relay_copy_buf_c2s_bytes`](#cfg-general-direct_relay_copy_buf_c2s_bytes) | `usize` | `65536` | +| [`direct_relay_copy_buf_s2c_bytes`](#cfg-general-direct_relay_copy_buf_s2c_bytes) | `usize` | `262144` | +| [`crypto_pending_buffer`](#cfg-general-crypto_pending_buffer) | `usize` | `262144` | +| [`max_client_frame`](#cfg-general-max_client_frame) | `usize` | `16777216` | +| [`desync_all_full`](#cfg-general-desync_all_full) | `bool` | `false` | +| [`beobachten`](#cfg-general-beobachten) | `bool` | `true` | +| [`beobachten_minutes`](#cfg-general-beobachten_minutes) | `u64` | `10` | +| [`beobachten_flush_secs`](#cfg-general-beobachten_flush_secs) | `u64` | `15` | +| [`beobachten_file`](#cfg-general-beobachten_file) | `String` | `"cache/beobachten.txt"` | +| [`hardswap`](#cfg-general-hardswap) | `bool` | `true` | +| [`me_warmup_stagger_enabled`](#cfg-general-me_warmup_stagger_enabled) | `bool` | `true` | +| [`me_warmup_step_delay_ms`](#cfg-general-me_warmup_step_delay_ms) | `u64` | `500` | +| [`me_warmup_step_jitter_ms`](#cfg-general-me_warmup_step_jitter_ms) | `u64` | `300` | +| [`me_reconnect_max_concurrent_per_dc`](#cfg-general-me_reconnect_max_concurrent_per_dc) | `u32` | `8` | +| [`me_reconnect_backoff_base_ms`](#cfg-general-me_reconnect_backoff_base_ms) | `u64` | `500` | +| [`me_reconnect_backoff_cap_ms`](#cfg-general-me_reconnect_backoff_cap_ms) | `u64` | `30000` | +| [`me_reconnect_fast_retry_count`](#cfg-general-me_reconnect_fast_retry_count) | `u32` | `16` | +| [`me_single_endpoint_shadow_writers`](#cfg-general-me_single_endpoint_shadow_writers) | `u8` | `2` | +| [`me_single_endpoint_outage_mode_enabled`](#cfg-general-me_single_endpoint_outage_mode_enabled) | `bool` | `true` | +| [`me_single_endpoint_outage_disable_quarantine`](#cfg-general-me_single_endpoint_outage_disable_quarantine) | `bool` | `true` | +| [`me_single_endpoint_outage_backoff_min_ms`](#cfg-general-me_single_endpoint_outage_backoff_min_ms) | `u64` | `250` | +| [`me_single_endpoint_outage_backoff_max_ms`](#cfg-general-me_single_endpoint_outage_backoff_max_ms) | `u64` | `3000` | +| [`me_single_endpoint_shadow_rotate_every_secs`](#cfg-general-me_single_endpoint_shadow_rotate_every_secs) | `u64` | `900` | +| [`me_floor_mode`](#cfg-general-me_floor_mode) | `"static"` or `"adaptive"` | `"adaptive"` | +| [`me_adaptive_floor_idle_secs`](#cfg-general-me_adaptive_floor_idle_secs) | `u64` | `90` | +| [`me_adaptive_floor_min_writers_single_endpoint`](#cfg-general-me_adaptive_floor_min_writers_single_endpoint) | `u8` | `1` | +| [`me_adaptive_floor_min_writers_multi_endpoint`](#cfg-general-me_adaptive_floor_min_writers_multi_endpoint) | `u8` | `1` | +| [`me_adaptive_floor_recover_grace_secs`](#cfg-general-me_adaptive_floor_recover_grace_secs) | `u64` | `180` | +| [`me_adaptive_floor_writers_per_core_total`](#cfg-general-me_adaptive_floor_writers_per_core_total) | `u16` | `48` | +| [`me_adaptive_floor_cpu_cores_override`](#cfg-general-me_adaptive_floor_cpu_cores_override) | `u16` | `0` | +| [`me_adaptive_floor_max_extra_writers_single_per_core`](#cfg-general-me_adaptive_floor_max_extra_writers_single_per_core) | `u16` | `1` | +| [`me_adaptive_floor_max_extra_writers_multi_per_core`](#cfg-general-me_adaptive_floor_max_extra_writers_multi_per_core) | `u16` | `2` | +| [`me_adaptive_floor_max_active_writers_per_core`](#cfg-general-me_adaptive_floor_max_active_writers_per_core) | `u16` | `64` | +| [`me_adaptive_floor_max_warm_writers_per_core`](#cfg-general-me_adaptive_floor_max_warm_writers_per_core) | `u16` | `64` | +| [`me_adaptive_floor_max_active_writers_global`](#cfg-general-me_adaptive_floor_max_active_writers_global) | `u32` | `256` | +| [`me_adaptive_floor_max_warm_writers_global`](#cfg-general-me_adaptive_floor_max_warm_writers_global) | `u32` | `256` | +| [`upstream_connect_retry_attempts`](#cfg-general-upstream_connect_retry_attempts) | `u32` | `2` | +| [`upstream_connect_retry_backoff_ms`](#cfg-general-upstream_connect_retry_backoff_ms) | `u64` | `100` | +| [`upstream_connect_budget_ms`](#cfg-general-upstream_connect_budget_ms) | `u64` | `3000` | +| [`upstream_unhealthy_fail_threshold`](#cfg-general-upstream_unhealthy_fail_threshold) | `u32` | `5` | +| [`upstream_connect_failfast_hard_errors`](#cfg-general-upstream_connect_failfast_hard_errors) | `bool` | `false` | +| [`stun_iface_mismatch_ignore`](#cfg-general-stun_iface_mismatch_ignore) | `bool` | `false` | +| [`unknown_dc_log_path`](#cfg-general-unknown_dc_log_path) | `String` | `"unknown-dc.txt"` | +| [`unknown_dc_file_log_enabled`](#cfg-general-unknown_dc_file_log_enabled) | `bool` | `false` | +| [`log_level`](#cfg-general-log_level) | `"debug"`, `"verbose"`, `"normal"`, or `"silent"` | `"normal"` | +| [`disable_colors`](#cfg-general-disable_colors) | `bool` | `false` | +| [`me_socks_kdf_policy`](#cfg-general-me_socks_kdf_policy) | `"strict"` or `"compat"` | `"strict"` | +| [`me_route_backpressure_base_timeout_ms`](#cfg-general-me_route_backpressure_base_timeout_ms) | `u64` | `25` | +| [`me_route_backpressure_high_timeout_ms`](#cfg-general-me_route_backpressure_high_timeout_ms) | `u64` | `120` | +| [`me_route_backpressure_high_watermark_pct`](#cfg-general-me_route_backpressure_high_watermark_pct) | `u8` | `80` | +| [`me_health_interval_ms_unhealthy`](#cfg-general-me_health_interval_ms_unhealthy) | `u64` | `1000` | +| [`me_health_interval_ms_healthy`](#cfg-general-me_health_interval_ms_healthy) | `u64` | `3000` | +| [`me_admission_poll_ms`](#cfg-general-me_admission_poll_ms) | `u64` | `1000` | +| [`me_warn_rate_limit_ms`](#cfg-general-me_warn_rate_limit_ms) | `u64` | `5000` | +| [`me_route_no_writer_mode`](#cfg-general-me_route_no_writer_mode) | `"async_recovery_failfast"`, `"inline_recovery_legacy"`, or `"hybrid_async_persistent"` | `"hybrid_async_persistent"` | +| [`me_route_no_writer_wait_ms`](#cfg-general-me_route_no_writer_wait_ms) | `u64` | `250` | +| [`me_route_hybrid_max_wait_ms`](#cfg-general-me_route_hybrid_max_wait_ms) | `u64` | `3000` | +| [`me_route_blocking_send_timeout_ms`](#cfg-general-me_route_blocking_send_timeout_ms) | `u64` | `250` | +| [`me_route_inline_recovery_attempts`](#cfg-general-me_route_inline_recovery_attempts) | `u32` | `3` | +| [`me_route_inline_recovery_wait_ms`](#cfg-general-me_route_inline_recovery_wait_ms) | `u64` | `3000` | +| [`fast_mode_min_tls_record`](#cfg-general-fast_mode_min_tls_record) | `usize` | `0` | +| [`update_every`](#cfg-general-update_every) | `u64` | `300` | +| [`me_reinit_every_secs`](#cfg-general-me_reinit_every_secs) | `u64` | `900` | +| [`me_hardswap_warmup_delay_min_ms`](#cfg-general-me_hardswap_warmup_delay_min_ms) | `u64` | `1000` | +| [`me_hardswap_warmup_delay_max_ms`](#cfg-general-me_hardswap_warmup_delay_max_ms) | `u64` | `2000` | +| [`me_hardswap_warmup_extra_passes`](#cfg-general-me_hardswap_warmup_extra_passes) | `u8` | `3` | +| [`me_hardswap_warmup_pass_backoff_base_ms`](#cfg-general-me_hardswap_warmup_pass_backoff_base_ms) | `u64` | `500` | +| [`me_config_stable_snapshots`](#cfg-general-me_config_stable_snapshots) | `u8` | `2` | +| [`me_config_apply_cooldown_secs`](#cfg-general-me_config_apply_cooldown_secs) | `u64` | `300` | +| [`me_snapshot_require_http_2xx`](#cfg-general-me_snapshot_require_http_2xx) | `bool` | `true` | +| [`me_snapshot_reject_empty_map`](#cfg-general-me_snapshot_reject_empty_map) | `bool` | `true` | +| [`me_snapshot_min_proxy_for_lines`](#cfg-general-me_snapshot_min_proxy_for_lines) | `u32` | `1` | +| [`proxy_secret_stable_snapshots`](#cfg-general-proxy_secret_stable_snapshots) | `u8` | `2` | +| [`proxy_secret_rotate_runtime`](#cfg-general-proxy_secret_rotate_runtime) | `bool` | `true` | +| [`me_secret_atomic_snapshot`](#cfg-general-me_secret_atomic_snapshot) | `bool` | `true` | +| [`proxy_secret_len_max`](#cfg-general-proxy_secret_len_max) | `usize` | `256` | +| [`me_pool_drain_ttl_secs`](#cfg-general-me_pool_drain_ttl_secs) | `u64` | `90` | +| [`me_instadrain`](#cfg-general-me_instadrain) | `bool` | `false` | +| [`me_pool_drain_threshold`](#cfg-general-me_pool_drain_threshold) | `u64` | `32` | +| [`me_pool_drain_soft_evict_enabled`](#cfg-general-me_pool_drain_soft_evict_enabled) | `bool` | `true` | +| [`me_pool_drain_soft_evict_grace_secs`](#cfg-general-me_pool_drain_soft_evict_grace_secs) | `u64` | `10` | +| [`me_pool_drain_soft_evict_per_writer`](#cfg-general-me_pool_drain_soft_evict_per_writer) | `u8` | `2` | +| [`me_pool_drain_soft_evict_budget_per_core`](#cfg-general-me_pool_drain_soft_evict_budget_per_core) | `u16` | `16` | +| [`me_pool_drain_soft_evict_cooldown_ms`](#cfg-general-me_pool_drain_soft_evict_cooldown_ms) | `u64` | `1000` | +| [`me_bind_stale_mode`](#cfg-general-me_bind_stale_mode) | `"never"`, `"ttl"`, or `"always"` | `"ttl"` | +| [`me_bind_stale_ttl_secs`](#cfg-general-me_bind_stale_ttl_secs) | `u64` | `90` | +| [`me_pool_min_fresh_ratio`](#cfg-general-me_pool_min_fresh_ratio) | `f32` | `0.8` | +| [`me_reinit_drain_timeout_secs`](#cfg-general-me_reinit_drain_timeout_secs) | `u64` | `90` | +| [`proxy_secret_auto_reload_secs`](#cfg-general-proxy_secret_auto_reload_secs) | `u64` | `3600` | +| [`proxy_config_auto_reload_secs`](#cfg-general-proxy_config_auto_reload_secs) | `u64` | `3600` | +| [`me_reinit_singleflight`](#cfg-general-me_reinit_singleflight) | `bool` | `true` | +| [`me_reinit_trigger_channel`](#cfg-general-me_reinit_trigger_channel) | `usize` | `64` | +| [`me_reinit_coalesce_window_ms`](#cfg-general-me_reinit_coalesce_window_ms) | `u64` | `200` | +| [`me_deterministic_writer_sort`](#cfg-general-me_deterministic_writer_sort) | `bool` | `true` | +| [`me_writer_pick_mode`](#cfg-general-me_writer_pick_mode) | `"sorted_rr"` or `"p2c"` | `"p2c"` | +| [`me_writer_pick_sample_size`](#cfg-general-me_writer_pick_sample_size) | `u8` | `3` | +| [`ntp_check`](#cfg-general-ntp_check) | `bool` | `true` | +| [`ntp_servers`](#cfg-general-ntp_servers) | `String[]` | `["pool.ntp.org"]` | +| [`auto_degradation_enabled`](#cfg-general-auto_degradation_enabled) | `bool` | `true` | +| [`degradation_min_unavailable_dc_groups`](#cfg-general-degradation_min_unavailable_dc_groups) | `u8` | `2` | + + +- `data_path` + - **Ограничения / валидация**: `Строка` (необязательно). + - **Описание**: Необязательный путь к каталогу данных времени выполнения. + - **Пример**: + + ```toml + [general] + data_path = "/var/lib/telemt" + ``` + +- `prefer_ipv6` + - **Ограничения / валидация**: Устарело. Используйте `network.prefer`. + - **Описание**: Устаревший устаревший флаг предпочтения IPv6 перенесен в network.prefer. + - **Пример**: + + ```toml + [network] + prefer = 6 + ``` + +- `fast_mode` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает оптимизацию быстрого пути для обработки трафика. + - **Пример**: + + ```toml + [general] + fast_mode = true + ``` + +- `use_middle_proxy` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает транспортный режим ME; если значение false, среда выполнения возвращается к прямой маршрутизации постоянного тока. + - **Пример**: + + ```toml + [general] + use_middle_proxy = true + ``` + +- `proxy_secret_path` + - **Ограничения / валидация**: `Строка`. Если этот параметр опущен, путь по умолчанию — «proxy-secret». Пустые значения принимаются TOML/serde, но, скорее всего, во время выполнения произойдет ошибка (неверный путь к файлу). + - **Описание**: Путь к файлу кэша `proxy-secret` инфраструктуры Telegram, используемому ME-рукопожатием/аутентификацией RPC. Telemt всегда сначала пытается выполнить новую загрузку с https://core.telegram.org/getProxySecret, в случае успеха кэширует ее по этому пути и возвращается к чтению кэшированного файла (любого возраста) в случае сбоя загрузки. + - **Пример**: + + ```toml + [general] + proxy_secret_path = "proxy-secret" + ``` + +- `proxy_config_v4_cache_path` + - **Ограничения / валидация**: `Строка`. Если установлено, оно не должно быть пустым или содержать только пробелы. + - **Описание**: Необязательный путь к дисковому кэшу для необработанного снимка getProxyConfig (IPv4). При запуске Telemt сначала пытается получить свежий снимок; в случае сбоя выборки или пустого снимка он возвращается к этому файлу кэша, если он присутствует и не пуст. + - **Пример**: + + ```toml + [general] + proxy_config_v4_cache_path = "cache/proxy-config-v4.txt" + ``` + +- `proxy_config_v6_cache_path` + - **Ограничения / валидация**: `Строка`. Если установлено, оно не должно быть пустым или содержать только пробелы. + - **Описание**: Необязательный путь к дисковому кэшу для необработанного снимка getProxyConfigV6 (IPv6). При запуске Telemt сначала пытается получить свежий снимок; в случае сбоя выборки или пустого снимка он возвращается к этому файлу кэша, если он присутствует и не пуст. + - **Пример**: + + ```toml + [general] + proxy_config_v6_cache_path = "cache/proxy-config-v6.txt" + ``` + +- `ad_tag` + - **Ограничения / валидация**: `Строка` (необязательно). Если установлено, должно быть ровно 32 шестнадцатеричных символа; недопустимые значения отключаются во время загрузки конфигурации. + - **Описание**: Глобальный резервный спонсируемый канал `ad_tag` (используется, когда у пользователя нет переопределения в `access.user_ad_tags`). Тег со всеми нулями принимается, но не имеет никакого эффекта (и о нем предупреждается), пока не будет заменен реальным тегом от `@MTProxybot`. + - **Пример**: + + ```toml + [general] + ad_tag = "00112233445566778899aabbccddeeff" + ``` + +- `middle_proxy_nat_ip` + - **Ограничения / валидация**: `IpAddr` (необязательно). + - **Описание**: Ручное переопределение общедоступного IP-адреса NAT используется в качестве материала ME-адреса, если оно установлено. + - **Пример**: + + ```toml + [general] + middle_proxy_nat_ip = "203.0.113.10" + ``` + +- `middle_proxy_nat_probe` + - **Ограничения / валидация**: `бул`. Эффективное зондирование ограничивается `network.stun_use` (когда `network.stun_use = false`, STUN-зондирование отключается, даже если этот флаг имеет значение `true`). + - **Описание**: Позволяет зондировать NAT на основе STUN для обнаружения общедоступного IP-порта, используемого при получении ключа ME в средах NAT. + - **Пример**: + + ```toml + [general] + middle_proxy_nat_probe = true + ``` + +- `middle_proxy_nat_stun` + - **Ограничения / валидация**: Устарело. Используйте `network.stun_servers`. + - **Описание**: Устаревший устаревший одиночный сервер STUN для проверки NAT. Во время загрузки конфигурации он объединяется с `network.stun_servers`, если `network.stun_servers` не задан явно. + - **Пример**: + + ```toml + [network] + stun_servers = ["stun.l.google.com:19302"] + ``` + +- `middle_proxy_nat_stun_servers` + - **Ограничения / валидация**: Устарело. Используйте `network.stun_servers`. + - **Описание**: Устаревший устаревший список STUN для резервного копирования NAT. Во время загрузки конфигурации он объединяется с `network.stun_servers`, если `network.stun_servers` не задан явно. + - **Пример**: + + ```toml + [network] + stun_servers = ["stun.l.google.com:19302"] + ``` + +- `stun_nat_probe_concurrency` + - **Ограничения / валидация**: Должно быть `> 0`. + - **Описание**: Максимальное количество параллельных тестов STUN во время обнаружения NAT/публичной конечной точки. + - **Пример**: + + ```toml + [general] + stun_nat_probe_concurrency = 8 + ``` + +- `middle_proxy_pool_size` + - **Ограничения / валидация**: `использовать`. Эффективное значение — «max(value, 1)» во время выполнения (поэтому «0» ведет себя как «1»). + - **Описание**: Целевой размер активного пула устройств записи ME. + - **Пример**: + + ```toml + [general] + middle_proxy_pool_size = 8 + ``` + +- `middle_proxy_warm_standby` + - **Ограничения / валидация**: `использовать`. + - **Описание**: Количество подключений ME в теплом резерве, предварительно инициализированных. + - **Пример**: + + ```toml + [general] + middle_proxy_warm_standby = 16 + ``` + +- `me_init_retry_attempts` + - **Ограничения / валидация**: `0..=1_000_000` (`0` означает неограниченное количество повторов). + - **Описание**: Повторные попытки инициализации пула ME. + - **Пример**: + + ```toml + [general] + me_init_retry_attempts = 0 + ``` + +- `me2dc_fallback` + - **Ограничения / валидация**: `бул`. + - **Описание**: Позволяет перейти из режима ME в режим прямого постоянного тока в случае сбоя запуска ME. + - **Пример**: + + ```toml + [general] + me2dc_fallback = true + ``` + +- `me2dc_fast` + - **Ограничения / валидация**: `бул`. Активен только тогда, когда `use_middle_proxy = true` и `me2dc_fallback = true`. + - **Описание**: Fast ME->Режим прямого возврата для новых сеансов. + - **Пример**: + + ```toml + [general] + use_middle_proxy = true + me2dc_fallback = true + me2dc_fast = false + ``` + +- `me_keepalive_enabled` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает периодические дополнительные кадры поддержки активности ME. + - **Пример**: + + ```toml + [general] + me_keepalive_enabled = true + ``` + +- `me_keepalive_interval_secs` + - **Ограничения / валидация**: `u64` (секунды). + - **Описание**: Базовый интервал поддержки активности ME в секундах. + - **Пример**: + + ```toml + [general] + me_keepalive_interval_secs = 8 + ``` + +- `me_keepalive_jitter_secs` + - **Ограничения / валидация**: `u64` (секунды). + - **Описание**: Джиттер Keepalive за считанные секунды для уменьшения синхронизированных пакетов. + - **Пример**: + + ```toml + [general] + me_keepalive_jitter_secs = 2 + ``` + +- `me_keepalive_payload_random` + - **Ограничения / валидация**: `бул`. + - **Описание**: Случайным образом изменяет байты полезной нагрузки поддержки активности вместо фиксированной нулевой полезной нагрузки. + - **Пример**: + + ```toml + [general] + me_keepalive_payload_random = true + ``` + +- `rpc_proxy_req_every` + - **Ограничения / валидация**: `0` или в пределах `10..=300` (секунд). + - **Описание**: Интервал для сигналов активности службы `RPC_PROXY_REQ` для ME (`0` отключает). + - **Пример**: + + ```toml + [general] + rpc_proxy_req_every = 0 + ``` + +- `me_writer_cmd_channel_capacity` + - **Ограничения / валидация**: Должно быть `> 0`. + - **Описание**: Пропускная способность командного канала для каждого записывающего устройства. + - **Пример**: + + ```toml + [general] + me_writer_cmd_channel_capacity = 4096 + ``` + +- `me_route_channel_capacity` + - **Ограничения / валидация**: Должно быть `> 0`. + - **Описание**: Пропускная способность канала маршрута ответа ME для каждого соединения. + - **Пример**: + + ```toml + [general] + me_route_channel_capacity = 768 + ``` + +- `me_c2me_channel_capacity` + - **Ограничения / валидация**: Должно быть `> 0`. + - **Описание**: Емкость очереди команд для каждого клиента (читатель клиента -> отправитель ME). + - **Пример**: + + ```toml + [general] + me_c2me_channel_capacity = 1024 + ``` + +- `me_c2me_send_timeout_ms` + - **Ограничения / валидация**: `0..=60000` (миллисекунды). + - **Описание**: Максимальное ожидание постановки в очередь команд клиент->ME, когда очередь для каждого клиента заполнена (`0` сохраняет устаревшее неограниченное ожидание). + - **Пример**: + + ```toml + [general] + me_c2me_send_timeout_ms = 4000 + ``` + +- `me_reader_route_data_wait_ms` + - **Ограничения / валидация**: `0..=20` (миллисекунды). + - **Описание**: Ограниченное ожидание маршрутизации ME DATA в очередь для каждого соединения (`0` = нет ожидания). + - **Пример**: + + ```toml + [general] + me_reader_route_data_wait_ms = 2 + ``` + +- `me_d2c_flush_batch_max_frames` + - **Ограничения / валидация**: Должно быть в пределах `1..=512`. + - **Описание**: Макс. ME->клиентские кадры объединяются перед очисткой. + - **Пример**: + + ```toml + [general] + me_d2c_flush_batch_max_frames = 32 + ``` + +- `me_d2c_flush_batch_max_bytes` + - **Ограничения / валидация**: Должно быть в пределах `4096..=2097152` (байт). + - **Описание**: Максимальное количество байтов полезной нагрузки ME->клиента, объединенных перед сбросом. + - **Пример**: + + ```toml + [general] + me_d2c_flush_batch_max_bytes = 131072 + ``` + +- `me_d2c_flush_batch_max_delay_us` + - **Ограничения / валидация**: `0..=5000` (микросекунды). + - **Описание**: Максимальное время ожидания в микросекундах для объединения большего количества кадров ME->клиента (`0` отключает объединение по времени). + - **Пример**: + + ```toml + [general] + me_d2c_flush_batch_max_delay_us = 500 + ``` + +- `me_d2c_ack_flush_immediate` + - **Ограничения / валидация**: `бул`. + - **Описание**: Сбрасывает запись клиента сразу после записи быстрого подтверждения. + - **Пример**: + + ```toml + [general] + me_d2c_ack_flush_immediate = true + ``` + +- `me_quota_soft_overshoot_bytes` + - **Ограничения / валидация**: `0..=16777216` (байты). + - **Описание**: Дополнительные квоты для каждого маршрута (в байтах) допускаются до того, как принудительное применение квот на стороне записи отбрасывает данные маршрута. + - **Пример**: + + ```toml + [general] + me_quota_soft_overshoot_bytes = 65536 + ``` + +- `me_d2c_frame_buf_shrink_threshold_bytes` + - **Ограничения / валидация**: Должно быть в пределах `4096..=16777216` (байт). + - **Описание**: Пороговое значение для сжатия слишком больших буферов агрегации кадров ME->клиента после очистки. + - **Пример**: + + ```toml + [general] + me_d2c_frame_buf_shrink_threshold_bytes = 262144 + ``` + +- `direct_relay_copy_buf_c2s_bytes` + - **Ограничения / валидация**: Должно быть в пределах `4096..=1048576` (байт). + - **Описание**: Размер буфера копирования для направления клиент->DC в прямой ретрансляции. + - **Пример**: + + ```toml + [general] + direct_relay_copy_buf_c2s_bytes = 65536 + ``` + +- `direct_relay_copy_buf_s2c_bytes` + - **Ограничения / валидация**: Должно быть в пределах `8192..=2097152` (байт). + - **Описание**: Размер буфера копирования для направления DC->клиент при прямой ретрансляции. + - **Пример**: + + ```toml + [general] + direct_relay_copy_buf_s2c_bytes = 262144 + ``` + +- `crypto_pending_buffer` + - **Ограничения / валидация**: `использовать` (байты). + - **Описание**: Максимальный буфер ожидающего зашифрованного текста на каждого клиента-писателя (в байтах). + - **Пример**: + + ```toml + [general] + crypto_pending_buffer = 262144 + ``` + +- `max_client_frame` + - **Ограничения / валидация**: `использовать` (байты). + - **Описание**: Максимально допустимый размер кадра MTProto клиента (в байтах). + - **Пример**: + + ```toml + [general] + max_client_frame = 16777216 + ``` + +- `desync_all_full` + - **Ограничения / валидация**: `бул`. + - **Описание**: Создает полные журналы крипто-рассинхронизации для каждого события. + - **Пример**: + + ```toml + [general] + desync_all_full = false + ``` + +- `beobachten` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает сегменты криминалистического наблюдения для каждого IP-адреса. + - **Пример**: + + ```toml + [general] + beobachten = true + ``` + +- `beobachten_minutes` + - **Ограничения / валидация**: Должно быть `> 0` (минуты). + - **Описание**: Окно хранения (минуты) для сегментов наблюдения по каждому IP-адресу. + - **Пример**: + + ```toml + [general] + beobachten_minutes = 10 + ``` + +- `beobachten_flush_secs` + - **Ограничения / валидация**: Должно быть `> 0` (секунды). + - **Описание**: Интервал сброса моментального снимка (в секундах) для выходного файла наблюдения. + - **Пример**: + + ```toml + [general] + beobachten_flush_secs = 15 + ``` + +- `beobachten_file` + - **Ограничения / валидация**: Не должно быть пустым или содержать только пробелы. + - **Описание**: Путь к выходному файлу снимка наблюдения. + - **Пример**: + + ```toml + [general] + beobachten_file = "cache/beobachten.txt" + ``` + +- `hardswap` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает стратегию жесткой замены ME на основе генерации. + - **Пример**: + + ```toml + [general] + hardswap = true + ``` + +- `me_warmup_stagger_enabled` + - **Ограничения / валидация**: `бул`. + - **Описание**: Перемещает дополнительные шкалы прогрева ME, чтобы избежать всплесков соединения. + - **Пример**: + + ```toml + [general] + me_warmup_stagger_enabled = true + ``` + +- `me_warmup_step_delay_ms` + - **Ограничения / валидация**: `u64` (миллисекунды). + - **Описание**: Базовая задержка в миллисекундах между этапами набора прогрева. + - **Пример**: + + ```toml + [general] + me_warmup_step_delay_ms = 500 + ``` + +- `me_warmup_step_jitter_ms` + - **Ограничения / валидация**: `u64` (миллисекунды). + - **Описание**: Дополнительная случайная задержка в миллисекундах для шагов разминки. + - **Пример**: + + ```toml + [general] + me_warmup_step_jitter_ms = 300 + ``` + +- `me_reconnect_max_concurrent_per_dc` + - **Ограничения / валидация**: `u32`. Эффективное значение — «max(value, 1)» во время выполнения (поэтому «0» ведет себя как «1»). + - **Описание**: Ограничивает число одновременных рабочих повторных подключений на каждый контроллер домена во время восстановления работоспособности. + - **Пример**: + + ```toml + [general] + me_reconnect_max_concurrent_per_dc = 8 + ``` + +- `me_reconnect_backoff_base_ms` + - **Ограничения / валидация**: `u64` (миллисекунды). + - **Описание**: Начальная задержка повторного подключения в миллисекундах. + - **Пример**: + + ```toml + [general] + me_reconnect_backoff_base_ms = 500 + ``` + +- `me_reconnect_backoff_cap_ms` + - **Ограничения / валидация**: `u64` (миллисекунды). + - **Описание**: Максимальное ограничение задержки повторного подключения в миллисекундах. + - **Пример**: + + ```toml + [general] + me_reconnect_backoff_cap_ms = 30000 + ``` + +- `me_reconnect_fast_retry_count` + - **Ограничения / валидация**: `u32`. Эффективное значение — «max(value, 1)» во время выполнения (поэтому «0» ведет себя как «1»). + - **Описание**: Немедленный бюджет повторных попыток, прежде чем применяется поведение длительной отсрочки. + - **Пример**: + + ```toml + [general] + me_reconnect_fast_retry_count = 16 + ``` + +- `me_single_endpoint_shadow_writers` + - **Ограничения / валидация**: Должно быть в пределах `0..=32`. + - **Описание**: Дополнительные резервные модули записи для групп DC только с одной конечной точкой. + - **Пример**: + + ```toml + [general] + me_single_endpoint_shadow_writers = 2 + ``` + +- `me_single_endpoint_outage_mode_enabled` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает агрессивный режим восстановления после сбоя для групп DC только с одной конечной точкой. + - **Пример**: + + ```toml + [general] + me_single_endpoint_outage_mode_enabled = true + ``` + +- `me_single_endpoint_outage_disable_quarantine` + - **Ограничения / валидация**: `бул`. + - **Описание**: Игнорирует карантин конечной точки в режиме отключения одной конечной точки. + - **Пример**: + + ```toml + [general] + me_single_endpoint_outage_disable_quarantine = true + ``` + +- `me_single_endpoint_outage_backoff_min_ms` + - **Ограничения / валидация**: Должно быть `> 0` (миллисекунды) и `<= me_single_endpoint_outage_backoff_max_ms`. + - **Описание**: Минимальная задержка повторного подключения в режиме отключения одной конечной точки. + - **Пример**: + + ```toml + [general] + me_single_endpoint_outage_backoff_min_ms = 250 + ``` + +- `me_single_endpoint_outage_backoff_max_ms` + - **Ограничения / валидация**: Должно быть `> 0` (миллисекунды) и `>= me_single_endpoint_outage_backoff_min_ms`. + - **Описание**: Максимальная задержка повторного подключения в режиме отключения одной конечной точки. + - **Пример**: + + ```toml + [general] + me_single_endpoint_outage_backoff_max_ms = 3000 + ``` + +- `me_single_endpoint_shadow_rotate_every_secs` + - **Ограничения / валидация**: `u64` (секунды). `0` отключает периодическое вращение тени. + - **Описание**: Периодический интервал ротации теневого записывающего устройства для групп DC с одной конечной точкой. + - **Пример**: + + ```toml + [general] + me_single_endpoint_shadow_rotate_every_secs = 900 + ``` + +- `me_floor_mode` + - **Ограничения / валидация**: «статический» или «адаптивный». + - **Описание**: Режим политики пола для целей записи ME. + - **Пример**: + + ```toml + [general] + me_floor_mode = "adaptive" + ``` + +- `me_adaptive_floor_idle_secs` + - **Ограничения / валидация**: `u64` (секунды). + - **Описание**: Время простоя перед адаптивным ограничением может уменьшить целевую задачу записи с одной конечной точкой. + - **Пример**: + + ```toml + [general] + me_adaptive_floor_idle_secs = 90 + ``` + +- `me_adaptive_floor_min_writers_single_endpoint` + - **Ограничения / валидация**: Должно быть в пределах `1..=32`. + - **Описание**: Минимальная цель записи для групп DC с одной конечной точкой в ​​адаптивном режиме пола. + - **Пример**: + + ```toml + [general] + me_adaptive_floor_min_writers_single_endpoint = 1 + ``` + +- `me_adaptive_floor_min_writers_multi_endpoint` + - **Ограничения / валидация**: Должно быть в пределах `1..=32`. + - **Описание**: Минимальная цель записи для групп DC с несколькими конечными точками в адаптивном режиме пола. + - **Пример**: + + ```toml + [general] + me_adaptive_floor_min_writers_multi_endpoint = 1 + ``` + +- `me_adaptive_floor_recover_grace_secs` + - **Ограничения / валидация**: `u64` (секунды). + - **Описание**: Льготный период для сохранения статического минимума после активности в адаптивном режиме. + - **Пример**: + + ```toml + [general] + me_adaptive_floor_recover_grace_secs = 180 + ``` + +- `me_adaptive_floor_writers_per_core_total` + - **Ограничения / валидация**: Должно быть `> 0`. + - **Описание**: Глобальный бюджет записи ME на логическое ядро ​​ЦП в адаптивном режиме. + - **Пример**: + + ```toml + [general] + me_adaptive_floor_writers_per_core_total = 48 + ``` + +- `me_adaptive_floor_cpu_cores_override` + - **Ограничения / валидация**: `u16`. `0` использует автоматическое обнаружение во время выполнения. + - **Описание**: Переопределить количество логических ядер ЦП, используемое для адаптивных вычислений минимального уровня. + - **Пример**: + + ```toml + [general] + me_adaptive_floor_cpu_cores_override = 0 + ``` + +- `me_adaptive_floor_max_extra_writers_single_per_core` + - **Ограничения / валидация**: `u16`. + - **Описание**: Максимальное количество дополнительных устройств записи на ядро ​​выше базового требуемого уровня для групп DC с одной конечной точкой. + - **Пример**: + + ```toml + [general] + me_adaptive_floor_max_extra_writers_single_per_core = 1 + ``` + +- `me_adaptive_floor_max_extra_writers_multi_per_core` + - **Ограничения / валидация**: `u16`. + - **Описание**: Максимальное количество дополнительных устройств записи на ядро ​​выше базового требуемого уровня для групп DC с несколькими конечными точками. + - **Пример**: + + ```toml + [general] + me_adaptive_floor_max_extra_writers_multi_per_core = 2 + ``` + +- `me_adaptive_floor_max_active_writers_per_core` + - **Ограничения / валидация**: Должно быть `> 0`. + - **Описание**: Жесткое ограничение для активных устройств записи ME на логическое ядро ​​ЦП. + - **Пример**: + + ```toml + [general] + me_adaptive_floor_max_active_writers_per_core = 64 + ``` + +- `me_adaptive_floor_max_warm_writers_per_core` + - **Ограничения / валидация**: Должно быть `> 0`. + - **Описание**: Жесткое ограничение для теплых авторов ME на логическое ядро ​​ЦП. + - **Пример**: + + ```toml + [general] + me_adaptive_floor_max_warm_writers_per_core = 64 + ``` + +- `me_adaptive_floor_max_active_writers_global` + - **Ограничения / валидация**: Должно быть `> 0`. + - **Описание**: Жесткий глобальный лимит для активных авторов ME. + - **Пример**: + + ```toml + [general] + me_adaptive_floor_max_active_writers_global = 256 + ``` + +- `me_adaptive_floor_max_warm_writers_global` + - **Ограничения / валидация**: Должно быть `> 0`. + - **Описание**: Жесткий глобальный лимит для теплых писателей ME. + - **Пример**: + + ```toml + [general] + me_adaptive_floor_max_warm_writers_global = 256 + ``` + +- `upstream_connect_retry_attempts` + - **Ограничения / валидация**: Должно быть `> 0`. + - **Описание**: Попытки подключения для выбранного восходящего потока перед возвратом ошибки/резервного варианта. + - **Пример**: + + ```toml + [general] + upstream_connect_retry_attempts = 2 + ``` + +- `upstream_connect_retry_backoff_ms` + - **Ограничения / валидация**: `u64` (миллисекунды). `0` отключает задержку отсрочки (повторные попытки становятся немедленными). + - **Описание**: Задержка в миллисекундах между попытками восходящего соединения. + - **Пример**: + + ```toml + [general] + upstream_connect_retry_backoff_ms = 100 + ``` + +- `upstream_connect_budget_ms` + - **Ограничения / валидация**: Должно быть `> 0` (миллисекунды). + - **Описание**: Общий бюджет настенных часов в миллисекундах для одного запроса восходящего соединения при повторных попытках. + - **Пример**: + + ```toml + [general] + upstream_connect_budget_ms = 3000 + ``` + +- `upstream_unhealthy_fail_threshold` + - **Ограничения / валидация**: Должно быть `> 0`. + - **Описание**: Последовательные неудачные запросы до того, как восходящий поток будет помечен как неработоспособный. + - **Пример**: + + ```toml + [general] + upstream_unhealthy_fail_threshold = 5 + ``` + +- `upstream_connect_failfast_hard_errors` + - **Ограничения / валидация**: `бул`. + - **Описание**: Если установлено значение true, дополнительные попытки пропускаются при серьезных непереходных ошибках восходящего соединения. + - **Пример**: + + ```toml + [general] + upstream_connect_failfast_hard_errors = false + ``` + +- `stun_iface_mismatch_ignore` + - **Ограничения / валидация**: `бул`. + - **Описание**: Флаг совместимости зарезервирован для использования в будущем. В настоящее время этот ключ анализируется, но не используется средой выполнения. + - **Пример**: + + ```toml + [general] + stun_iface_mismatch_ignore = false + ``` + +- `unknown_dc_log_path` + - **Ограничения / валидация**: `Строка` (необязательно). Должен быть безопасный путь (никаких компонентов `..`, родительский каталог должен существовать); небезопасные пути отклоняются во время выполнения. + - **Описание**: Путь к файлу журнала для неизвестных (нестандартных) запросов DC, когда `unknown_dc_file_log_enabled = true`. Опустите этот ключ, чтобы отключить ведение журнала файлов. + - **Пример**: + + ```toml + [general] + unknown_dc_log_path = "unknown-dc.txt" + ``` + +- `unknown_dc_file_log_enabled` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает ведение журнала файла неизвестного DC (записывает строки `dc_idx=`). Требуется установить `unknown_dc_log_path` и на платформах, отличных от Unix, может не поддерживаться. Ведение журналов дедуплицировано и ограничено (записываются только первые ~ 1024 различных неизвестных индекса DC). + - **Пример**: + + ```toml + [general] + unknown_dc_file_log_enabled = false + ``` + +- `log_level` + - **Ограничения / валидация**: «отладка», «многословный», «нормальный» или «тихий». + - **Описание**: Уровень детализации журналирования во время выполнения (используется, если RUST_LOG не установлен). Если в среде установлен RUST_LOG, он имеет приоритет над этим параметром. + - **Пример**: + + ```toml + [general] + log_level = "normal" + ``` + +- `disable_colors` + - **Ограничения / валидация**: `бул`. + - **Описание**: Отключает цвета ANSI в журналах (полезно для файлов/systemd). Это влияет только на форматирование журнала и не меняет уровень/фильтрацию журнала. + - **Пример**: + + ```toml + [general] + disable_colors = false + ``` + +- `me_socks_kdf_policy` + - **Ограничения / валидация**: «строгий» или «совместимый». + - **Описание**: Резервная политика KDF, связанная с SOCKS, для рукопожатия среднего уровня. + - **Пример**: + + ```toml + [general] + me_socks_kdf_policy = "strict" + ``` + +- `me_route_backpressure_base_timeout_ms` + - **Ограничения / валидация**: Должно быть в пределах `1..=5000` (миллисекунд). + - **Описание**: Тайм-аут базового противодавления в миллисекундах для отправки по каналу маршрута ME. + - **Пример**: + + ```toml + [general] + me_route_backpressure_base_timeout_ms = 25 + ``` + +- `me_route_backpressure_high_timeout_ms` + - **Ограничения / валидация**: Должно быть в пределах `1..=5000` (миллисекунды) и `>= me_route_backpressure_base_timeout_ms`. + - **Описание**: Тайм-аут высокого противодавления в миллисекундах, когда занятость очереди превышает водяной знак. + - **Пример**: + + ```toml + [general] + me_route_backpressure_high_timeout_ms = 120 + ``` + +- `me_route_backpressure_high_watermark_pct` + - **Ограничения / валидация**: Должно быть в пределах `1..=100` (процентов). + - **Описание**: Пороговое значение процента занятости очереди для переключения на тайм-аут высокого противодавления. + - **Пример**: + + ```toml + [general] + me_route_backpressure_high_watermark_pct = 80 + ``` + +- `me_health_interval_ms_unhealthy` + - **Ограничения / валидация**: Должно быть `> 0` (миллисекунды). + - **Описание**: Интервал мониторинга работоспособности, когда покрытие записи ME ухудшается. + - **Пример**: + + ```toml + [general] + me_health_interval_ms_unhealthy = 1000 + ``` + +- `me_health_interval_ms_healthy` + - **Ограничения / валидация**: Должно быть `> 0` (миллисекунды). + - **Описание**: Интервал мониторинга работоспособности, пока покрытие записи ME стабильно/работоспособно. + - **Пример**: + + ```toml + [general] + me_health_interval_ms_healthy = 3000 + ``` + +- `me_admission_poll_ms` + - **Ограничения / валидация**: Должно быть `> 0` (миллисекунды). + - **Описание**: Интервал опроса для проверок состояния условного приема. + - **Пример**: + + ```toml + [general] + me_admission_poll_ms = 1000 + ``` + +- `me_warn_rate_limit_ms` + - **Ограничения / валидация**: Должно быть `> 0` (миллисекунды). + - **Описание**: Время восстановления повторяющихся журналов предупреждений ME. + - **Пример**: + + ```toml + [general] + me_warn_rate_limit_ms = 5000 + ``` + +- `me_route_no_writer_mode` + - **Ограничения / валидация**: `"async_recovery_failfast"`, `"inline_recovery_legacy"` или `"hybrid_async_persistent"`. + - **Описание**: Поведение маршрута ME, когда ни один писатель не доступен немедленно. + - **Пример**: + + ```toml + [general] + me_route_no_writer_mode = "hybrid_async_persistent" + ``` + +- `me_route_no_writer_wait_ms` + - **Ограничения / валидация**: Должно быть в пределах `10..=5000` (миллисекунд). + - **Описание**: Максимальное время ожидания, используемое в быстром режиме асинхронного восстановления перед откатом. + - **Пример**: + + ```toml + [general] + me_route_no_writer_wait_ms = 250 + ``` + +- `me_route_hybrid_max_wait_ms` + - **Ограничения / валидация**: Должно быть в пределах `50..=60000` (миллисекунд). + - **Описание**: Максимальное совокупное время ожидания в гибридном режиме без записи перед отказоустойчивым переходом. + - **Пример**: + + ```toml + [general] + me_route_hybrid_max_wait_ms = 3000 + ``` + +- `me_route_blocking_send_timeout_ms` + - **Ограничения / валидация**: Должно быть в пределах `0..=5000` (миллисекунд). `0` сохраняет устаревшее неограниченное поведение ожидания. + - **Описание**: Максимальное ожидание блокировки резервной отправки маршрутного канала. + - **Пример**: + + ```toml + [general] + me_route_blocking_send_timeout_ms = 250 + ``` + +- `me_route_inline_recovery_attempts` + - **Ограничения / валидация**: Должно быть `> 0`. + - **Описание**: Количество попыток оперативного восстановления в устаревшем режиме. + - **Пример**: + + ```toml + [general] + me_route_inline_recovery_attempts = 3 + ``` + +- `me_route_inline_recovery_wait_ms` + - **Ограничения / валидация**: Должно быть в пределах `10..=30000` (миллисекунд). + - **Описание**: Максимальное время ожидания встроенного восстановления в устаревшем режиме. + - **Пример**: + + ```toml + [general] + me_route_inline_recovery_wait_ms = 3000 + ``` + +- `fast_mode_min_tls_record` + - **Ограничения / валидация**: `использовать` (байты). `0` отключает ограничение. + - **Описание**: Минимальный размер записи TLS при включенном объединении в быстром режиме. + - **Пример**: + + ```toml + [general] + fast_mode_min_tls_record = 0 + ``` + +- `update_every` + - **Ограничения / валидация**: `u64` (секунды). Если установлено, должно быть `> 0`. Если этот ключ не установлен явно, можно использовать устаревшие `proxy_secret_auto_reload_secs` и `proxy_config_auto_reload_secs` (их эффективный минимум должен быть `> 0`). + - **Описание**: Единый интервал обновления для задач обновления ME (getProxyConfig, getProxyConfigV6, getProxySecret). Если этот параметр установлен, он переопределяет устаревшие интервалы перезагрузки прокси-сервера. + - **Пример**: + + ```toml + [general] + update_every = 300 + ``` + +- `me_reinit_every_secs` + - **Ограничения / валидация**: Должно быть `> 0` (секунды). + - **Описание**: Периодический интервал для цикла повторной инициализации ME с нулевым временем простоя. + - **Пример**: + + ```toml + [general] + me_reinit_every_secs = 900 + ``` + +- `me_hardswap_warmup_delay_min_ms` + - **Ограничения / валидация**: `u64` (миллисекунды). Должно быть `<= me_hardswap_warmup_delay_max_ms`. + - **Описание**: Нижняя граница интервала прогрева жесткой замены. + - **Пример**: + + ```toml + [general] + me_hardswap_warmup_delay_min_ms = 1000 + ``` + +- `me_hardswap_warmup_delay_max_ms` + - **Ограничения / валидация**: Должно быть `> 0` (миллисекунды). + - **Описание**: Верхняя граница интервала прогрева жесткой замены. + - **Пример**: + + ```toml + [general] + me_hardswap_warmup_delay_max_ms = 2000 + ``` + +- `me_hardswap_warmup_extra_passes` + - **Ограничения / валидация**: Должно быть в пределах `[0, 10]`. + - **Описание**: Дополнительные прогрева проходят после базового прохода за один цикл жесткой замены. + - **Пример**: + + ```toml + [general] + # default: 3 (allowed range: 0..=10) + me_hardswap_warmup_extra_passes = 3 + ``` + +- `me_hardswap_warmup_pass_backoff_base_ms` + - **Ограничения / валидация**: `u64` (миллисекунды). Должно быть `> 0`. + - **Описание**: Базовая задержка между дополнительными проходами по замене жесткого диска, когда пол еще не завершен. + - **Пример**: + + ```toml + [general] + # default: 500 + me_hardswap_warmup_pass_backoff_base_ms = 500 + ``` + +- `me_config_stable_snapshots` + - **Ограничения / валидация**: Должно быть `> 0`. + - **Описание**: Количество идентичных снимков конфигурации ME, необходимое для применения. + - **Пример**: + + ```toml + [general] + # require 3 identical snapshots before applying ME endpoint map updates + me_config_stable_snapshots = 3 + ``` + +- `me_config_apply_cooldown_secs` + - **Ограничения / валидация**: `u64`. + - **Описание**: Время восстановления между примененными обновлениями карты конечных точек ME. `0` отключает время восстановления. + - **Пример**: + + ```toml + [general] + # allow applying stable snapshots immediately (no cooldown) + me_config_apply_cooldown_secs = 0 + ``` + +- `me_snapshot_require_http_2xx` + - **Ограничения / валидация**: `бул`. + - **Описание**: Для применения снимков конфигурации ME требуется 2xx HTTP-ответа. Если установлено значение «false», ответы, отличные от 2xx, все равно могут быть проанализированы/учтены программой обновления. + - **Пример**: + + ```toml + [general] + # allow applying snapshots even when the HTTP status is non-2xx + me_snapshot_require_http_2xx = false + ``` + +- `me_snapshot_reject_empty_map` + - **Ограничения / валидация**: `бул`. + - **Описание**: Отклоняет пустые снимки конфигурации ME (без конечных точек). Если установлено значение «false», может быть применен пустой снимок (с учетом других ворот), что может временно уменьшить/очистить карту ME. + - **Пример**: + + ```toml + [general] + # allow applying empty snapshots (use with care) + me_snapshot_reject_empty_map = false + ``` + +- `me_snapshot_min_proxy_for_lines` + - **Ограничения / валидация**: Должно быть `> 0`. + - **Описание**: Минимальное количество проанализированных строк `proxy_for`, необходимое для принятия снимка. + - **Пример**: + + ```toml + [general] + # require at least 10 proxy_for rows before accepting a snapshot + me_snapshot_min_proxy_for_lines = 10 + ``` + +- `proxy_secret_stable_snapshots` + - **Ограничения / валидация**: Должно быть `> 0`. + - **Описание**: Количество идентичных снимков с секретом прокси-сервера, необходимых перед ротацией. + - **Пример**: + + ```toml + [general] + # require 2 identical getProxySecret snapshots before rotating at runtime + proxy_secret_stable_snapshots = 2 + ``` + +- `proxy_secret_rotate_runtime` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает ротацию секретов прокси-сервера во время выполнения из снимков средства обновления. + - **Пример**: + + ```toml + [general] + # disable runtime proxy-secret rotation (startup still uses proxy_secret_path/proxy_secret_len_max) + proxy_secret_rotate_runtime = false + ``` + +- `me_secret_atomic_snapshot` + - **Ограничения / валидация**: `бул`. + - **Описание**: Сохраняет селекторные и секретные байты из одного и того же снимка атомарно. Если `general.use_middle_proxy = true`, это автоматически включается во время загрузки конфигурации, чтобы обеспечить согласованность материала ME KDF. + - **Пример**: + + ```toml + [general] + # NOTE: when use_middle_proxy=true, Telemt will auto-enable this during load + me_secret_atomic_snapshot = false + ``` + +- `proxy_secret_len_max` + - **Ограничения / валидация**: Должно быть в пределах `[32, 4096]`. + - **Описание**: Верхний предел длины (в байтах) принимаемого прокси-секрета во время запуска и обновления среды выполнения. + - **Пример**: + + ```toml + [general] + # default: 256 (bytes) + proxy_secret_len_max = 256 + ``` + +- `me_pool_drain_ttl_secs` + - **Ограничения / валидация**: `u64` (секунды). `0` отключает окно дренажного TTL (и подавляет предупреждения дренажного TTL для непустых записывающих устройств дренажа). + - **Описание**: Временной интервал Drain-TTL для устаревших модулей записи ME после изменения карты конечных точек. Во время TTL устаревшие средства записи можно использовать только в качестве резерва для новых привязок (в зависимости от политики привязки). + - **Пример**: + + ```toml + [general] + # disable drain TTL (draining writers won't emit "past drain TTL" warnings) + me_pool_drain_ttl_secs = 0 + ``` + +- `me_instadrain` + - **Ограничения / валидация**: `бул`. + - **Описание**: Принудительно удаляет устаревшие записи записи при следующем такте очистки, минуя ожидание TTL/крайнего срока. + - **Пример**: + + ```toml + [general] + # default: false + me_instadrain = false + ``` + +- `me_pool_drain_threshold` + - **Ограничения / валидация**: `u64`. Установите значение «0», чтобы отключить очистку на основе пороговых значений. + - **Описание**: Максимальное количество устаревших источников записи, прежде чем самые старые из них будут принудительно закрыты в пакетном режиме. + - **Пример**: + + ```toml + [general] + # default: 32 + me_pool_drain_threshold = 32 + ``` + +- `me_pool_drain_soft_evict_enabled` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает постепенное мягкое удаление устаревших средств записи во время очистки/повторной инициализации вместо немедленного жесткого закрытия. + - **Пример**: + + ```toml + [general] + # default: true + me_pool_drain_soft_evict_enabled = true + ``` + +- `me_pool_drain_soft_evict_grace_secs` + - **Ограничения / валидация**: `u64` (секунды). Должно быть в пределах `[0, 3600]`. + - **Описание**: Дополнительная льгота (после слива TTL) перед началом этапа мягкого вытеснения. + - **Пример**: + + ```toml + [general] + # default: 10 + me_pool_drain_soft_evict_grace_secs = 10 + ``` + +- `me_pool_drain_soft_evict_per_writer` + - **Ограничения / валидация**: `1..=16`. + - **Описание**: Максимальное количество устаревших маршрутов, мягко вытесняемых на одного автора за один проход выселения. + - **Пример**: + + ```toml + [general] + # default: 2 + me_pool_drain_soft_evict_per_writer = 2 + ``` + +- `me_pool_drain_soft_evict_budget_per_core` + - **Ограничения / валидация**: `1..=64`. + - **Описание**: Бюджет на ядро ​​ограничивает совокупную работу по мягкому вытеснению за проход. + - **Пример**: + + ```toml + [general] + # default: 16 + me_pool_drain_soft_evict_budget_per_core = 16 + ``` + +- `me_pool_drain_soft_evict_cooldown_ms` + - **Ограничения / валидация**: `u64` (миллисекунды). Должно быть `> 0`. + - **Описание**: Время восстановления между повторяющимися мягкими выселениями одного и того же автора. + - **Пример**: + + ```toml + [general] + # default: 1000 + me_pool_drain_soft_evict_cooldown_ms = 1000 + ``` + +- `me_bind_stale_mode` + - **Ограничения / валидация**: «никогда», «ttl» или «всегда». + - **Описание**: Политика в отношении новых ограничений для устаревших истощающих авторов. + - **Пример**: + + ```toml + [general] + # allow stale binds only for a limited time window + me_bind_stale_mode = "ttl" + ``` + +- `me_bind_stale_ttl_secs` + - **Ограничения / валидация**: `u64`. + - **Описание**: TTL для допуска устаревшей привязки, когда устаревший режим — «ttl». + - **Пример**: + + ```toml + [general] + me_bind_stale_mode = "ttl" + me_bind_stale_ttl_secs = 90 + ``` + +- `me_pool_min_fresh_ratio` + - **Ограничения / валидация**: Должно быть в пределах `[0.0, 1.0]`. + - **Описание**: Минимальный коэффициент покрытия свежих желаемых DC, прежде чем устаревшие авторы будут истощены. + - **Пример**: + + ```toml + [general] + # require >=90% desired-DC coverage before draining stale writers + me_pool_min_fresh_ratio = 0.9 + ``` + +- `me_reinit_drain_timeout_secs` + - **Ограничения / валидация**: `u64`. `0` использует тайм-аут принудительного закрытия для обеспечения безопасности во время выполнения. Если `> 0` и `< me_pool_drain_ttl_secs`, среда выполнения увеличивает значение TTL. + - **Описание**: Тайм-аут принудительного закрытия для слива устаревших авторов. Если установлено значение «0», эффективный тайм-аут представляет собой резервный режим безопасности во время выполнения (300 секунд). + - **Пример**: + + ```toml + [general] + # use runtime safety fallback force-close timeout (300s) + me_reinit_drain_timeout_secs = 0 + ``` + +- `proxy_secret_auto_reload_secs` + - **Ограничения / валидация**: Устарело. Используйте `general.update_every`. Если `general.update_every` не задан явно, эффективный устаревший интервал обновления равен `min(proxy_secret_auto_reload_secs, proxy_config_auto_reload_secs)` и должен быть `> 0`. + - **Описание**: Устаревший устаревший интервал обновления секрета прокси-сервера. Используется только в том случае, если `general.update_every` не установлен. + - **Пример**: + + ```toml + [general] + # legacy mode: omit update_every to use proxy_*_auto_reload_secs + proxy_secret_auto_reload_secs = 600 + proxy_config_auto_reload_secs = 120 + # effective updater interval = min(600, 120) = 120 seconds + ``` + +- `proxy_config_auto_reload_secs` + - **Ограничения / валидация**: Устарело. Используйте `general.update_every`. Если `general.update_every` не задан явно, эффективный устаревший интервал обновления равен `min(proxy_secret_auto_reload_secs, proxy_config_auto_reload_secs)` и должен быть `> 0`. + - **Описание**: Устаревший интервал обновления устаревшей конфигурации ME. Используется только в том случае, если `general.update_every` не установлен. + - **Пример**: + + ```toml + [general] + # legacy mode: omit update_every to use proxy_*_auto_reload_secs + proxy_secret_auto_reload_secs = 600 + proxy_config_auto_reload_secs = 120 + # effective updater interval = min(600, 120) = 120 seconds + ``` + +- `me_reinit_singleflight` + - **Ограничения / валидация**: `бул`. + - **Описание**: Сериализует циклы повторной инициализации ME по источникам триггера. + - **Пример**: + + ```toml + [general] + me_reinit_singleflight = true + ``` + +- `me_reinit_trigger_channel` + - **Ограничения / валидация**: Должно быть `> 0`. + - **Описание**: Емкость очереди триггеров для планировщика повторной инициализации. + - **Пример**: + + ```toml + [general] + me_reinit_trigger_channel = 64 + ``` + +- `me_reinit_coalesce_window_ms` + - **Ограничения / валидация**: `u64`. + - **Описание**: Запустить окно объединения триггеров перед началом повторной инициализации (мс). + - **Пример**: + + ```toml + [general] + me_reinit_coalesce_window_ms = 200 + ``` + +- `me_deterministic_writer_sort` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает детерминированную сортировку кандидатов для пути привязки записи. + - **Пример**: + + ```toml + [general] + me_deterministic_writer_sort = true + ``` + +- `me_writer_pick_mode` + - **Ограничения / валидация**: `"sorted_rr"` или `"p2c"`. + - **Описание**: Режим выбора записывающего устройства для пути привязки маршрута. + - **Пример**: + + ```toml + [general] + me_writer_pick_mode = "p2c" + ``` + +- `me_writer_pick_sample_size` + - **Ограничения / валидация**: `2..=4`. + - **Описание**: Количество кандидатов, отобранных сборщиком в режиме p2c. + - **Пример**: + + ```toml + [general] + me_writer_pick_mode = "p2c" + me_writer_pick_sample_size = 3 + ``` + +- `ntp_check` + - **Ограничения / валидация**: `бул`. + - **Описание**: Зарезервировано для будущего использования. В настоящее время этот ключ анализируется, но не используется средой выполнения. + - **Пример**: + + ```toml + [general] + ntp_check = true + ``` + +- `ntp_servers` + - **Ограничения / валидация**: `Строка[]`. + - **Описание**: Зарезервировано для будущего использования. В настоящее время этот ключ анализируется, но не используется средой выполнения. + - **Пример**: + + ```toml + [general] + ntp_servers = ["pool.ntp.org"] + ``` + +- `auto_degradation_enabled` + - **Ограничения / валидация**: `бул`. + - **Описание**: Зарезервировано для будущего использования. В настоящее время этот ключ анализируется, но не используется средой выполнения. + - **Пример**: + + ```toml + [general] + auto_degradation_enabled = true + ``` + +- `degradation_min_unavailable_dc_groups` + - **Ограничения / валидация**: `u8`. + - **Описание**: Зарезервировано для будущего использования. В настоящее время этот ключ анализируется, но не используется средой выполнения. + - **Пример**: + + ```toml + [general] + degradation_min_unavailable_dc_groups = 2 + ``` + + +## [general.modes] + + +| Ключ | Тип | По умолчанию | +| --- | ---- | ------- | +| [`classic`](#cfg-general-modes-classic) | `bool` | `false` | +| [`secure`](#cfg-general-modes-secure) | `bool` | `false` | +| [`tls`](#cfg-general-modes-tls) | `bool` | `true` | + + +- `classic` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает классический режим MTProxy. + - **Пример**: + + ```toml + [general.modes] + classic = true + ``` + +- `secure` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает безопасный режим. + - **Пример**: + + ```toml + [general.modes] + secure = true + ``` + +- `tls` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает режим TLS. + - **Пример**: + + ```toml + [general.modes] + tls = true + ``` + + +## [general.links] + + +| Ключ | Тип | По умолчанию | +| --- | ---- | ------- | +| [`show`](#cfg-general-links-show) | `"*"` or `String[]` | `"*"` | +| [`public_host`](#cfg-general-links-public_host) | `String` | — | +| [`public_port`](#cfg-general-links-public_port) | `u16` | — | + + +- `show` + - **Ограничения / валидация**: `"*"` или `String[]`. Пустой массив означает «не показывать ничего». + - **Описание**: Выбирает пользователей, чьи прокси-ссылки `tg://` отображаются при запуске. + - **Пример**: + + ```toml + [general.links] + show = "*" + # or: + # show = ["alice", "bob"] + ``` + +- `public_host` + - **Ограничения / валидация**: `Строка` (необязательно). + - **Описание**: Переопределение общедоступного имени хоста/IP-адреса, используемое для сгенерированных ссылок `tg://` (переопределяет обнаруженный IP-адрес). + - **Пример**: + + ```toml + [general.links] + public_host = "proxy.example.com" + ``` + +- `public_port` + - **Ограничения / валидация**: `u16` (необязательно). + - **Описание**: Переопределение общедоступного порта, используемое для сгенерированных ссылок `tg://` (переопределяет `server.port`). + - **Пример**: + + ```toml + [general.links] + public_port = 443 + ``` + + +## [general.telemetry] + + +| Ключ | Тип | По умолчанию | +| --- | ---- | ------- | +| [`core_enabled`](#cfg-general-telemetry-core_enabled) | `bool` | `true` | +| [`user_enabled`](#cfg-general-telemetry-user_enabled) | `bool` | `true` | +| [`me_level`](#cfg-general-telemetry-me_level) | `"silent"`, `"normal"`, or `"debug"` | `"normal"` | + + +- `core_enabled` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает основные счетчики телеметрии горячего пути. + - **Пример**: + + ```toml + [general.telemetry] + core_enabled = true + ``` + +- `user_enabled` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает счетчики телеметрии для каждого пользователя. + - **Пример**: + + ```toml + [general.telemetry] + user_enabled = true + ``` + +- `me_level` + - **Ограничения / валидация**: «тихий», «нормальный» или «отладка». + - **Описание**: Средний уровень детализации телеметрии. + - **Пример**: + + ```toml + [general.telemetry] + me_level = "normal" + ``` + + +## [network] + + +| Ключ | Тип | По умолчанию | +| --- | ---- | ------- | +| [`ipv4`](#cfg-network-ipv4) | `bool` | `true` | +| [`ipv6`](#cfg-network-ipv6) | `bool` | `false` | +| [`prefer`](#cfg-network-prefer) | `u8` | `4` | +| [`multipath`](#cfg-network-multipath) | `bool` | `false` | +| [`stun_use`](#cfg-network-stun_use) | `bool` | `true` | +| [`stun_servers`](#cfg-network-stun_servers) | `String[]` | Built-in STUN list (13 hosts) | +| [`stun_tcp_fallback`](#cfg-network-stun_tcp_fallback) | `bool` | `true` | +| [`http_ip_detect_urls`](#cfg-network-http_ip_detect_urls) | `String[]` | `["https://ifconfig.me/ip", "https://api.ipify.org"]` | +| [`cache_public_ip_path`](#cfg-network-cache_public_ip_path) | `String` | `"cache/public_ip.txt"` | +| [`dns_overrides`](#cfg-network-dns_overrides) | `String[]` | `[]` | + + +- `ipv4` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает сеть IPv4. + - **Пример**: + + ```toml + [network] + ipv4 = true + ``` + +- `ipv6` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает/выключает сеть IPv6. Если этот параметр опущен, по умолчанию используется значение «false». + - **Пример**: + + ```toml + [network] + # enable IPv6 explicitly + ipv6 = true + + # or: disable IPv6 explicitly + # ipv6 = false + ``` + +- `prefer` + - **Ограничения / валидация**: Должно быть `4` или `6`. Если `prefer = 4`, а `ipv4 = false`, Telemt принудительно использует `prefer = 6`. Если `prefer = 6`, а `ipv6 = false`, Telemt принудительно использует `prefer = 4`. + - **Описание**: Предпочтительное семейство IP для выбора, если доступны оба семейства. + - **Пример**: + + ```toml + [network] + prefer = 6 + ``` + +- `multipath` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает многопутевое поведение, если это поддерживается платформой и средой выполнения. + - **Пример**: + + ```toml + [network] + multipath = true + ``` + +- `stun_use` + - **Ограничения / валидация**: `бул`. + - **Описание**: Глобальный переключатель STUN; если установлено значение «false», проверка STUN отключается и остается только обнаружение без STUN. + - **Пример**: + + ```toml + [network] + stun_use = false + ``` + +- `stun_servers` + - **Ограничения / валидация**: `Строка[]`. Значения обрезаются; пустые значения удаляются; список дедуплицируется. Если этот ключ **не** установлен явно, Telemt сохраняет встроенный список STUN по умолчанию. + - **Описание**: Список серверов STUN для обнаружения общедоступных IP-адресов. + - **Пример**: + + ```toml + [network] + stun_servers = [ + "stun.l.google.com:19302", + "stun.stunprotocol.org:3478", + ] + ``` + +- `stun_tcp_fallback` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает резервный TCP для STUN, когда путь UDP заблокирован/недоступен. + - **Пример**: + + ```toml + [network] + stun_tcp_fallback = true + ``` + +- `http_ip_detect_urls` + - **Ограничения / валидация**: `Строка[]`. + - **Описание**: Конечные точки HTTP, используемые для обнаружения общедоступных IP-адресов (резервный вариант после STUN). + - **Пример**: + + ```toml + [network] + http_ip_detect_urls = ["https://ifconfig.me/ip", "https://api.ipify.org"] + ``` + +- `cache_public_ip_path` + - **Ограничения / валидация**: `Строка`. + - **Описание**: Путь к файлу, используемый для кэширования обнаруженного общедоступного IP-адреса. + - **Пример**: + + ```toml + [network] + cache_public_ip_path = "cache/public_ip.txt" + ``` + +- `dns_overrides` + - **Ограничения / валидация**: `Строка[]`. Каждая запись должна использовать формат «хост:порт:ip». +- `host`: имя домена (должно быть непустым и не должно содержать `:`) +- `порт`: `u16` +- `ip`: IPv4 (`1.2.3.4`) или IPv6 в квадратных скобках (`[2001:db8::1]`). **IPv6 без скобок отклонен**. + - **Описание**: Переопределения DNS во время выполнения для целей `host:port`. Полезно для принудительного использования определенных IP-адресов для определенных вышестоящих доменов, не затрагивая системный DNS. + - **Пример**: + + ```toml + [network] + dns_overrides = [ + "example.com:443:127.0.0.1", + "example.net:8443:[2001:db8::10]", + ] + ``` + + +## [server] + + +| Ключ | Тип | По умолчанию | +| --- | ---- | ------- | +| [`port`](#cfg-server-port) | `u16` | `443` | +| [`listen_addr_ipv4`](#cfg-server-listen_addr_ipv4) | `String` | `"0.0.0.0"` | +| [`listen_addr_ipv6`](#cfg-server-listen_addr_ipv6) | `String` | `"::"` | +| [`listen_unix_sock`](#cfg-server-listen_unix_sock) | `String` | — | +| [`listen_unix_sock_perm`](#cfg-server-listen_unix_sock_perm) | `String` | — | +| [`listen_tcp`](#cfg-server-listen_tcp) | `bool` | — (auto) | +| [`proxy_protocol`](#cfg-server-proxy_protocol) | `bool` | `false` | +| [`proxy_protocol_header_timeout_ms`](#cfg-server-proxy_protocol_header_timeout_ms) | `u64` | `500` | +| [`proxy_protocol_trusted_cidrs`](#cfg-server-proxy_protocol_trusted_cidrs) | `IpNetwork[]` | `[]` | +| [`metrics_port`](#cfg-server-metrics_port) | `u16` | — | +| [`metrics_listen`](#cfg-server-metrics_listen) | `String` | — | +| [`metrics_whitelist`](#cfg-server-metrics_whitelist) | `IpNetwork[]` | `["127.0.0.1/32", "::1/128"]` | +| [`max_connections`](#cfg-server-max_connections) | `u32` | `10000` | +| [`accept_permit_timeout_ms`](#cfg-server-accept_permit_timeout_ms) | `u64` | `250` | + + +- `port` + - **Ограничения / валидация**: `u16`. + - **Описание**: Порт прослушивания основного прокси (TCP). + - **Пример**: + + ```toml + [server] + port = 443 + ``` + +- `listen_addr_ipv4` + - **Ограничения / валидация**: `Строка` (необязательно). Если установлено, это должна быть действительная строка адреса IPv4. + - **Описание**: Адрес привязки IPv4 для прослушивателя TCP (опустите этот ключ, чтобы отключить привязку IPv4). + - **Пример**: + + ```toml + [server] + listen_addr_ipv4 = "0.0.0.0" + ``` + +- `listen_addr_ipv6` + - **Ограничения / валидация**: `Строка` (необязательно). Если установлено, это должна быть действительная строка адреса IPv6. + - **Описание**: Адрес привязки IPv6 для прослушивателя TCP (опустите этот ключ, чтобы отключить привязку IPv6). + - **Пример**: + + ```toml + [server] + listen_addr_ipv6 = "::" + ``` + +- `listen_unix_sock` + - **Ограничения / валидация**: `Строка` (необязательно). Не должно быть пустым, если установлено. Только Юникс. + - **Описание**: Путь сокета Unix для прослушивателя. Если установлено, `server.listen_tcp` по умолчанию имеет значение `false` (если не указано иное явно). + - **Пример**: + + ```toml + [server] + listen_unix_sock = "/run/telemt.sock" + ``` + +- `listen_unix_sock_perm` + - **Ограничения / валидация**: `Строка` (необязательно). Если установлено, это должна быть восьмеричная строка разрешения, например `"0666"` или `"0777"`. + - **Описание**: Дополнительные разрешения для файлов сокетов Unix, применяемые после привязки (chmod). Если этот параметр опущен, разрешения не изменяются (наследует umask). + - **Пример**: + + ```toml + [server] + listen_unix_sock = "/run/telemt.sock" + listen_unix_sock_perm = "0666" + ``` + +- `listen_tcp` + - **Ограничения / валидация**: `bool` (необязательно). Если этот параметр опущен, Telemt автоматически обнаруживает: +- `true`, если `listen_unix_sock` не установлен +- «false», если установлен «listen_unix_sock». + - **Описание**: Явный прослушиватель TCP включает/отключает переопределение. + - **Пример**: + + ```toml + [server] + # force-enable TCP even when also binding a unix socket + listen_unix_sock = "/run/telemt.sock" + listen_tcp = true + ``` + +- `proxy_protocol` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает анализ протокола HAProxy PROXY при входящих соединениях (PROXY v1/v2). Если этот параметр включен, исходный адрес клиента берется из заголовка PROXY. + - **Пример**: + + ```toml + [server] + proxy_protocol = true + ``` + +- `proxy_protocol_header_timeout_ms` + - **Ограничения / валидация**: Должно быть `> 0` (миллисекунды). + - **Описание**: Таймаут чтения и анализа заголовков протокола PROXY (мс). + - **Пример**: + + ```toml + [server] + proxy_protocol = true + proxy_protocol_header_timeout_ms = 500 + ``` + +- `proxy_protocol_trusted_cidrs` + - **Ограничения / валидация**: `IpNetwork[]`. +- Если этот параметр опущен, по умолчанию используются доверительные все CIDR (`0.0.0.0/0` и `::/0`). +- Если явно задан пустой массив, все заголовки PROXY отклоняются. + - **Описание**: CIDR доверенного источника позволяют предоставлять заголовки протокола PROXY (контроль безопасности). + - **Пример**: + + ```toml + [server] + proxy_protocol = true + proxy_protocol_trusted_cidrs = ["127.0.0.1/32", "10.0.0.0/8"] + ``` + +- `metrics_port` + - **Ограничения / валидация**: `u16` (необязательно). + - **Описание**: Порт конечной точки метрик, совместимый с Prometheus. Если установлено, включает прослушиватель метрик (поведение привязки можно переопределить с помощью `metrics_listen`). + - **Пример**: + + ```toml + [server] + metrics_port = 9090 + ``` + +- `metrics_listen` + - **Ограничения / валидация**: `Строка` (необязательно). Если установлено, оно должно быть в формате IP:PORT. + - **Описание**: Полный адрес привязки метрик (`IP:PORT`) переопределяет `metrics_port` и привязывается только к указанному адресу. + - **Пример**: + + ```toml + [server] + metrics_listen = "127.0.0.1:9090" + ``` + +- `metrics_whitelist` + - **Ограничения / валидация**: `IpNetwork[]`. + - **Описание**: Белый список CIDR для доступа к конечной точке метрик. + - **Пример**: + + ```toml + [server] + metrics_port = 9090 + metrics_whitelist = ["127.0.0.1/32", "::1/128"] + ``` + +- `max_connections` + - **Ограничения / валидация**: `u32`. `0` означает неограниченный. + - **Описание**: Максимальное количество одновременных клиентских подключений. + - **Пример**: + + ```toml + [server] + max_connections = 10000 + ``` + +- `accept_permit_timeout_ms` + - **Ограничения / валидация**: `0..=60000` (миллисекунды). `0` сохраняет устаревшее неограниченное поведение ожидания. + - **Описание**: Максимальное время ожидания получения разрешения на слот подключения, прежде чем принятое соединение будет разорвано. + - **Пример**: + + ```toml + [server] + accept_permit_timeout_ms = 250 + ``` + + +Примечание. Когда `server.proxy_protocol` включен, входящие заголовки протокола PROXY анализируются с первых байтов соединения, а исходный адрес клиента заменяется на `src_addr` из заголовка. В целях безопасности IP-адрес однорангового источника (адрес прямого соединения) проверяется по `server.proxy_protocol_trusted_cidrs`; если этот список пуст, заголовки PROXY отклоняются и соединение считается ненадежным. + +## [server.conntrack_control] + +Примечание. Рабочий процесс conntrack-control работает **только в Linux**. В других операционных системах не запускается; если inline_conntrack_control имеет значение true, записывается предупреждение. Для эффективной работы также требуется **CAP_NET_ADMIN** и пригодный к использованию бэкенд (nft или iptables/ip6tables в PATH). Утилита `conntrack` используется для удаления необязательных записей таблицы под давлением. + + +| Ключ | Тип | По умолчанию | +| --- | ---- | ------- | +| [`inline_conntrack_control`](#cfg-server-conntrack_control-inline_conntrack_control) | `bool` | `true` | +| [`mode`](#cfg-server-conntrack_control-mode) | `String` | `"tracked"` | +| [`backend`](#cfg-server-conntrack_control-backend) | `String` | `"auto"` | +| [`profile`](#cfg-server-conntrack_control-profile) | `String` | `"balanced"` | +| [`hybrid_listener_ips`](#cfg-server-conntrack_control-hybrid_listener_ips) | `IpAddr[]` | `[]` | +| [`pressure_high_watermark_pct`](#cfg-server-conntrack_control-pressure_high_watermark_pct) | `u8` | `85` | +| [`pressure_low_watermark_pct`](#cfg-server-conntrack_control-pressure_low_watermark_pct) | `u8` | `70` | +| [`delete_budget_per_sec`](#cfg-server-conntrack_control-delete_budget_per_sec) | `u64` | `4096` | + + +- `inline_conntrack_control` + - **Ограничения / валидация**: `бул`. + - **Описание**: Главный переключатель для задачи conntrack-control во время выполнения: согласовывает правила сетевого фильтра **raw/notrack** для входа прослушивателя (см. `mode`), образцы загружаются каждую секунду и может запускать **`conntrack -D`** удаления для квалификации событий закрытия, пока **pressure mode** активен (см. `delete_budget_per_sec`). Если установлено значение false, правила отслеживания очищаются, а принудительное удаление отключается. + - **Пример**: + + ```toml + [server.conntrack_control] + inline_conntrack_control = true + ``` + +- `mode` + - **Ограничения / валидация**: Один из вариантов: «отслеживаемый», «без отслеживания», «гибридный» (регистронезависимый; сериализованный нижний регистр). + - **Описание**: **`tracked`**: не устанавливать правила telemt notrack (соединения остаются в состоянии conntrack). **`notrack`**: пометить совпадение входящего TCP с `server.port` как notrack — целевые объекты получаются из `[[server.listeners]]`, если таковые имеются, в противном случае из `server.listen_addr_ipv4` / `server.listen_addr_ipv6` (неуказанные адреса означают «любой» для этого семейства). **`hybrid`**: не отслеживать только адреса, перечисленные в `hybrid_listener_ips` (должно быть непустым; проверяется при загрузке). + - **Пример**: + + ```toml + [server.conntrack_control] + mode = "notrack" + ``` + +- `backend` + - **Ограничения / валидация**: Один из `auto`, `nftables`, `iptables` (без учета регистра; сериализованный нижний регистр). + - **Описание**: Какой набор команд применяет правила отслеживания. **`auto`**: используйте `nft`, если он присутствует в `PATH`, иначе `iptables`/`ip6tables`, если он присутствует. **`nftables`** / **`iptables`**: принудительно использовать этот бэкэнд; отсутствие двоичного кода означает, что правила невозможно применить. Путь nft использует таблицу `inet telemt_conntrack` и необработанный перехват предварительной маршрутизации; iptables использует цепочку TELEMT_NOTRACK в таблице raw. + - **Пример**: + + ```toml + [server.conntrack_control] + backend = "auto" + ``` + +- `profile` + - **Ограничения / валидация**: Один из «консервативных», «сбалансированных», «агрессивных» (без учета регистра; сериализованный нижний регистр). + - **Описание**: Когда **режим давления conntrack** активен (водяные знаки `pressure_*`), ограничиваются тайм-ауты простоя и активности, чтобы уменьшить отток коннтреков: например. **первый байт простоя клиента** (`client.rs`), **тайм-аут активности прямой ретрансляции** (`direct_relay.rs`) и **политика простоя среднего реле** (`middle_relay.rs` через `ConntrackPressureProfile::*_cap_secs` / `direct_activity_timeout_secs`). В более агрессивных профилях используются более короткие заглушки. + - **Пример**: + + ```toml + [server.conntrack_control] + profile = "balanced" + ``` + +- `hybrid_listener_ips` + - **Ограничения / валидация**: `IpAddr[]`. Должно быть **непустым**, когда `mode = "hybrid"`. Игнорируется для отслеживаемых/безотслеживаемых сообщений. + - **Описание**: Явные адреса прослушивателя, которые получают правила nottrack в гибридном режиме (разделенные на правила IPv4 и IPv6 в зависимости от реализации). + - **Пример**: + + ```toml + [server.conntrack_control] + mode = "hybrid" + hybrid_listener_ips = ["203.0.113.10", "2001:db8::1"] + ``` + +- `pressure_high_watermark_pct` + - **Ограничения / валидация**: Должно быть в пределах `[1, 100]`. + - **Описание**: Режим давления **входит** при любом из следующих событий: заполнение соединения или `server.max_connections` (в процентах, если `max_connections > 0`), **использование файлового дескриптора** и программное обеспечение процесса `RLIMIT_NOFILE`, **ненулевое** событие `accept_permit_timeout` в последнем окне примера или дельта счетчика **ME c2me send-full**. Ввод сравнивает соответствующие проценты с этой верхней отметкой (см. update_pressure_state в conntrack_control.rs). + - **Пример**: + + ```toml + [server.conntrack_control] + pressure_high_watermark_pct = 85 + ``` + +- `pressure_low_watermark_pct` + - **Ограничения / валидация**: Должно быть **строго меньше** `pressure_high_watermark_pct`. + - **Описание**: Режим давления **сбрасывается** только после **трех** последовательных односекундных выборок, когда все сигналы находятся на уровне этой нижней границы или ниже, а дельты времени ожидания приема/ME-очереди равны нулю (гистерезис). + - **Пример**: + + ```toml + [server.conntrack_control] + pressure_low_watermark_pct = 70 + ``` + +- `delete_budget_per_sec` + - **Ограничения / валидация**: Должно быть `> 0`. + - **Описание**: Максимальное количество попыток **`conntrack -D`** **в секунду** при активном режиме давления (корзина токенов пополняется каждую секунду). Удаление выполняется только для событий закрытия по причинам **тайм-аут**, **давление** или **сброс**; каждая попытка потребляет токен независимо от результата. + - **Пример**: + + ```toml + [server.conntrack_control] + delete_budget_per_sec = 4096 + ``` + + +## [server.api] + +Примечание. В этом разделе также принимается устаревший псевдоним `[server.admin_api]` (та же схема, что и `[server.api]`). + + +| Ключ | Тип | По умолчанию | +| --- | ---- | ------- | +| [`enabled`](#cfg-server-api-enabled) | `bool` | `true` | +| [`listen`](#cfg-server-api-listen) | `String` | `"0.0.0.0:9091"` | +| [`whitelist`](#cfg-server-api-whitelist) | `IpNetwork[]` | `["127.0.0.0/8"]` | +| [`auth_header`](#cfg-server-api-auth_header) | `String` | `""` | +| [`request_body_limit_bytes`](#cfg-server-api-request_body_limit_bytes) | `usize` | `65536` | +| [`minimal_runtime_enabled`](#cfg-server-api-minimal_runtime_enabled) | `bool` | `true` | +| [`minimal_runtime_cache_ttl_ms`](#cfg-server-api-minimal_runtime_cache_ttl_ms) | `u64` | `1000` | +| [`runtime_edge_enabled`](#cfg-server-api-runtime_edge_enabled) | `bool` | `false` | +| [`runtime_edge_cache_ttl_ms`](#cfg-server-api-runtime_edge_cache_ttl_ms) | `u64` | `1000` | +| [`runtime_edge_top_n`](#cfg-server-api-runtime_edge_top_n) | `usize` | `10` | +| [`runtime_edge_events_capacity`](#cfg-server-api-runtime_edge_events_capacity) | `usize` | `256` | +| [`read_only`](#cfg-server-api-read_only) | `bool` | `false` | + + +- `enabled` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает REST API плоскости управления. + - **Пример**: + + ```toml + [server.api] + enabled = true + ``` + +- `listen` + - **Ограничения / валидация**: `Строка`. Должен быть в формате IP:PORT. + - **Описание**: Адрес привязки API в формате IP:PORT. + - **Пример**: + + ```toml + [server.api] + listen = "0.0.0.0:9091" + ``` + +- `whitelist` + - **Ограничения / валидация**: `IpNetwork[]`. + - **Описание**: Белый список CIDR разрешил доступ к API. + - **Пример**: + + ```toml + [server.api] + whitelist = ["127.0.0.0/8"] + ``` + +- `auth_header` + - **Ограничения / валидация**: `Строка`. Пустая строка отключает проверку заголовка аутентификации. + - **Описание**: Точное ожидаемое значение заголовка `Authorization` (статический общий секрет). + - **Пример**: + + ```toml + [server.api] + auth_header = "Bearer MY_TOKEN" + ``` + +- `request_body_limit_bytes` + - **Ограничения / валидация**: Должно быть `> 0` (байты). + - **Описание**: Максимальный принимаемый размер тела HTTP-запроса (в байтах). + - **Пример**: + + ```toml + [server.api] + request_body_limit_bytes = 65536 + ``` + +- `minimal_runtime_enabled` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает минимальную логику конечной точки снимков времени выполнения. + - **Пример**: + + ```toml + [server.api] + minimal_runtime_enabled = true + ``` + +- `minimal_runtime_cache_ttl_ms` + - **Ограничения / валидация**: `0..=60000` (миллисекунды). `0` отключает кеш. + - **Описание**: Срок жизни кэша для минимальных снимков времени выполнения (мс). + - **Пример**: + + ```toml + [server.api] + minimal_runtime_cache_ttl_ms = 1000 + ``` + +- `runtime_edge_enabled` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает конечные точки границ среды выполнения. + - **Пример**: + + ```toml + [server.api] + runtime_edge_enabled = false + ``` + +- `runtime_edge_cache_ttl_ms` + - **Ограничения / валидация**: `0..=60000` (миллисекунды). + - **Описание**: Срок жизни кэша для полезных данных агрегации границ во время выполнения (мс). + - **Пример**: + + ```toml + [server.api] + runtime_edge_cache_ttl_ms = 1000 + ``` + +- `runtime_edge_top_n` + - **Ограничения / валидация**: `1..=1000`. + - **Описание**: Размер Top-N для таблицы лидеров краевых соединений. + - **Пример**: + + ```toml + [server.api] + runtime_edge_top_n = 10 + ``` + +- `runtime_edge_events_capacity` + - **Ограничения / валидация**: `16..=4096`. + - **Описание**: Емкость кольцевого буфера для пограничных событий во время выполнения. + - **Пример**: + + ```toml + [server.api] + runtime_edge_events_capacity = 256 + ``` + +- `read_only` + - **Ограничения / валидация**: `бул`. + - **Описание**: Отклоняет изменение конечных точек API, если оно включено. + - **Пример**: + + ```toml + [server.api] + read_only = false + ``` + + +## [[server.listeners]] + + +| Ключ | Тип | По умолчанию | +| --- | ---- | ------- | +| [`ip`](#cfg-server-listeners-ip) | `IpAddr` | — | +| [`announce`](#cfg-server-listeners-announce) | `String` | — | +| [`announce_ip`](#cfg-server-listeners-announce_ip) | `IpAddr` | — | +| [`proxy_protocol`](#cfg-server-listeners-proxy_protocol) | `bool` | — | +| [`reuse_allow`](#cfg-server-listeners-reuse_allow) | `bool` | `false` | + + +- `ip` + - **Ограничения / валидация**: Обязательное поле. Должен быть IPAddr. + - **Описание**: IP-адрес привязки прослушивателя. + - **Пример**: + + ```toml + [[server.listeners]] + ip = "0.0.0.0" + ``` + +- `announce` + - **Ограничения / валидация**: `Строка` (необязательно). Не должно быть пустым, если установлено. + - **Описание**: Публичный IP-адрес/домен, объявленный в прокси-ссылках для этого прослушивателя. Имеет приоритет над announce_ip. + - **Пример**: + + ```toml + [[server.listeners]] + ip = "0.0.0.0" + announce = "proxy.example.com" + ``` + +- `announce_ip` + - **Ограничения / валидация**: `IpAddr` (необязательно). Устарело. Используйте «объявить». + - **Описание**: Устаревший устаревший IP-адрес объявления. Во время загрузки конфигурации он переводится в «announce», если «announce» не установлен. + - **Пример**: + + ```toml + [[server.listeners]] + ip = "0.0.0.0" + announce_ip = "203.0.113.10" + ``` + +- `proxy_protocol` + - **Ограничения / валидация**: `bool` (необязательно). Если установлено, переопределяет `server.proxy_protocol` для этого прослушивателя. + - **Описание**: Переопределение протокола PROXY для каждого слушателя. + - **Пример**: + + ```toml + [server] + proxy_protocol = false + + [[server.listeners]] + ip = "0.0.0.0" + proxy_protocol = true + ``` + +- `reuse_allow` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает `SO_REUSEPORT` для совместного использования привязки нескольких экземпляров (позволяет нескольким экземплярам telemt прослушивать один и тот же `ip:port`). + - **Пример**: + + ```toml + [[server.listeners]] + ip = "0.0.0.0" + reuse_allow = false + ``` + + +## [timeouts] + + +| Ключ | Тип | По умолчанию | +| --- | ---- | ------- | +| [`client_handshake`](#cfg-timeouts-client_handshake) | `u64` | `30` | +| [`relay_idle_policy_v2_enabled`](#cfg-timeouts-relay_idle_policy_v2_enabled) | `bool` | `true` | +| [`relay_client_idle_soft_secs`](#cfg-timeouts-relay_client_idle_soft_secs) | `u64` | `120` | +| [`relay_client_idle_hard_secs`](#cfg-timeouts-relay_client_idle_hard_secs) | `u64` | `360` | +| [`relay_idle_grace_after_downstream_activity_secs`](#cfg-timeouts-relay_idle_grace_after_downstream_activity_secs) | `u64` | `30` | +| [`tg_connect`](#cfg-timeouts-tg_connect) | `u64` | `10` | +| [`client_keepalive`](#cfg-timeouts-client_keepalive) | `u64` | `15` | +| [`client_ack`](#cfg-timeouts-client_ack) | `u64` | `90` | +| [`me_one_retry`](#cfg-timeouts-me_one_retry) | `u8` | `12` | +| [`me_one_timeout_ms`](#cfg-timeouts-me_one_timeout_ms) | `u64` | `1200` | + + +- `client_handshake` + - **Ограничения / валидация**: Должно быть `> 0`. Значение указано в секундах. Также используется в качестве верхней границы некоторых задержек эмуляции TLS (см. `censorship.server_hello_delay_max_ms`). + - **Описание**: Тайм-аут установления связи клиента (в секундах). + - **Пример**: + + ```toml + [timeouts] + client_handshake = 30 + ``` + +- `relay_idle_policy_v2_enabled` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает политику простоя клиента среднего/жесткого промежуточного реле. + - **Пример**: + + ```toml + [timeouts] + relay_idle_policy_v2_enabled = true + ``` + +- `relay_client_idle_soft_secs` + - **Ограничения / валидация**: Должно быть `> 0`; должно быть `<=lay_client_idle_hard_secs`. + - **Описание**: Порог мягкого простоя (в секундах) для неактивности восходящей линии связи клиента среднего ретранслятора. Достижение этого порога отмечает сеанс как бездействующего кандидата (в зависимости от политики он может подлежать очистке). + - **Пример**: + + ```toml + [timeouts] + relay_client_idle_soft_secs = 120 + ``` + +- `relay_client_idle_hard_secs` + - **Ограничения / валидация**: Должно быть `> 0`; должно быть `>=lay_client_idle_soft_secs`. + - **Описание**: Порог жесткого простоя (в секундах) для неактивности восходящей линии связи клиента среднего ретранслятора. Достижение этого порога закрывает сессию. + - **Пример**: + + ```toml + [timeouts] + relay_client_idle_hard_secs = 360 + ``` + +- `relay_idle_grace_after_downstream_activity_secs` + - **Ограничения / валидация**: Должно быть `<=lay_client_idle_hard_secs`. + - **Описание**: Дополнительный льготный период жесткого простоя (в секундах), добавленный после недавней активности в нисходящем направлении. + - **Пример**: + + ```toml + [timeouts] + relay_idle_grace_after_downstream_activity_secs = 30 + ``` + +- `tg_connect` + - **Ограничения / валидация**: `u64`. Значение указано в секундах. + - **Описание**: Тайм-аут восходящего соединения Telegram (в секундах). + - **Пример**: + + ```toml + [timeouts] + tg_connect = 10 + ``` + +- `client_keepalive` + - **Ограничения / валидация**: `u64`. Значение указано в секундах. + - **Описание**: Тайм-аут поддержки активности клиента (в секундах). + - **Пример**: + + ```toml + [timeouts] + client_keepalive = 15 + ``` + +- `client_ack` + - **Ограничения / валидация**: `u64`. Значение указано в секундах. + - **Описание**: Таймаут подтверждения клиента (в секундах). + - **Пример**: + + ```toml + [timeouts] + client_ack = 90 + ``` + +- `me_one_retry` + - **Ограничения / валидация**: `u8`. + - **Описание**: Бюджет попыток быстрого повторного подключения для сценариев DC с одной конечной точкой. + - **Пример**: + + ```toml + [timeouts] + me_one_retry = 12 + ``` + +- `me_one_timeout_ms` + - **Ограничения / валидация**: `u64`. Значение указано в миллисекундах. + - **Описание**: Тайм-аут на быструю попытку (мс) для логики повторного подключения постоянного тока с одной конечной точкой. + - **Пример**: + + ```toml + [timeouts] + me_one_timeout_ms = 1200 + ``` + + +## [censorship] + + +| Ключ | Тип | По умолчанию | +| --- | ---- | ------- | +| [`tls_domain`](#cfg-censorship-tls_domain) | `String` | `"petrovich.ru"` | +| [`tls_domains`](#cfg-censorship-tls_domains) | `String[]` | `[]` | +| [`unknown_sni_action`](#cfg-censorship-unknown_sni_action) | `"drop"` or `"mask"` | `"drop"` | +| [`tls_fetch_scope`](#cfg-censorship-tls_fetch_scope) | `String` | `""` | +| [`tls_fetch`](#cfg-censorship-tls_fetch) | `Table` | built-in defaults | +| [`mask`](#cfg-censorship-mask) | `bool` | `true` | +| [`mask_host`](#cfg-censorship-mask_host) | `String` | — | +| [`mask_port`](#cfg-censorship-mask_port) | `u16` | `443` | +| [`mask_unix_sock`](#cfg-censorship-mask_unix_sock) | `String` | — | +| [`fake_cert_len`](#cfg-censorship-fake_cert_len) | `usize` | `2048` | +| [`tls_emulation`](#cfg-censorship-tls_emulation) | `bool` | `true` | +| [`tls_front_dir`](#cfg-censorship-tls_front_dir) | `String` | `"tlsfront"` | +| [`server_hello_delay_min_ms`](#cfg-censorship-server_hello_delay_min_ms) | `u64` | `0` | +| [`server_hello_delay_max_ms`](#cfg-censorship-server_hello_delay_max_ms) | `u64` | `0` | +| [`tls_new_session_tickets`](#cfg-censorship-tls_new_session_tickets) | `u8` | `0` | +| [`tls_full_cert_ttl_secs`](#cfg-censorship-tls_full_cert_ttl_secs) | `u64` | `90` | +| [`alpn_enforce`](#cfg-censorship-alpn_enforce) | `bool` | `true` | +| [`mask_proxy_protocol`](#cfg-censorship-mask_proxy_protocol) | `u8` | `0` | +| [`mask_shape_hardening`](#cfg-censorship-mask_shape_hardening) | `bool` | `true` | +| [`mask_shape_hardening_aggressive_mode`](#cfg-censorship-mask_shape_hardening_aggressive_mode) | `bool` | `false` | +| [`mask_shape_bucket_floor_bytes`](#cfg-censorship-mask_shape_bucket_floor_bytes) | `usize` | `512` | +| [`mask_shape_bucket_cap_bytes`](#cfg-censorship-mask_shape_bucket_cap_bytes) | `usize` | `4096` | +| [`mask_shape_above_cap_blur`](#cfg-censorship-mask_shape_above_cap_blur) | `bool` | `false` | +| [`mask_shape_above_cap_blur_max_bytes`](#cfg-censorship-mask_shape_above_cap_blur_max_bytes) | `usize` | `512` | +| [`mask_relay_max_bytes`](#cfg-censorship-mask_relay_max_bytes) | `usize` | `5242880` | +| [`mask_classifier_prefetch_timeout_ms`](#cfg-censorship-mask_classifier_prefetch_timeout_ms) | `u64` | `5` | +| [`mask_timing_normalization_enabled`](#cfg-censorship-mask_timing_normalization_enabled) | `bool` | `false` | +| [`mask_timing_normalization_floor_ms`](#cfg-censorship-mask_timing_normalization_floor_ms) | `u64` | `0` | +| [`mask_timing_normalization_ceiling_ms`](#cfg-censorship-mask_timing_normalization_ceiling_ms) | `u64` | `0` | + + +- `tls_domain` + - **Ограничения / валидация**: Должно быть непустое доменное имя. Не должно содержать пробелов или `/`. + - **Описание**: Основной домен TLS, используемый в профиле подтверждения FakeTLS и в качестве домена SNI по умолчанию. + - **Пример**: + + ```toml + [censorship] + tls_domain = "example.com" + ``` + +- `tls_domains` + - **Ограничения / валидация**: `Строка[]`. Если установлено, значения объединяются с tls_domain и дедуплицируются (первичный tls_domain всегда остается первым). + - **Описание**: Дополнительные домены TLS для создания нескольких прокси-ссылок. + - **Пример**: + + ```toml + [censorship] + tls_domain = "example.com" + tls_domains = ["example.net", "example.org"] + ``` + +- `unknown_sni_action` + - **Ограничения / валидация**: «капля» или «маска». + - **Описание**: Действие для TLS ClientHello с неизвестным/ненастроенным SNI. + - **Пример**: + + ```toml + [censorship] + unknown_sni_action = "drop" + ``` + +- `tls_fetch_scope` + - **Ограничения / валидация**: `Строка`. Значение обрезается во время загрузки; whitespace-only становится пустым. + - **Описание**: Тег области восходящего потока, используемый для выборки метаданных TLS-фронт. Пустое значение сохраняет поведение восходящей маршрутизации по умолчанию. + - **Пример**: + + ```toml + [censorship] + tls_fetch_scope = "fetch" + ``` + +- `tls_fetch` + - **Ограничения / валидация**: Стол. См. раздел «[censorship.tls_fetch]» ниже. + - **Описание**: Настройки стратегии выборки метаданных TLS (начальная загрузка + поведение обновления для данных эмуляции TLS). + - **Пример**: + + ```toml + [censorship.tls_fetch] + strict_route = true + attempt_timeout_ms = 5000 + total_budget_ms = 15000 + ``` + +- `mask` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает режим маскировки/переднего реле. + - **Пример**: + + ```toml + [censorship] + mask = true + ``` + +- `mask_host` + - **Ограничения / валидация**: `Строка` (необязательно). +- Если установлена ​​маска_unix_sock, маска_хост должна быть опущена (взаимоисключающая). +- Если `mask_host` не установлен и `mask_unix_sock` не установлен, Telemt по умолчанию устанавливает для `mask_host` значение `tls_domain`. + - **Описание**: Хост восходящей маски для фронтального реле TLS. + - **Пример**: + + ```toml + [censorship] + mask_host = "www.cloudflare.com" + ``` + +- `mask_port` + - **Ограничения / валидация**: `u16`. + - **Описание**: Восходящий порт маски для фронтального реле TLS. + - **Пример**: + + ```toml + [censorship] + mask_port = 443 + ``` + +- `mask_unix_sock` + - **Ограничения / валидация**: `Строка` (необязательно). +- Не должно быть пустым, если установлено. +- Только Unix; отклонено на платформах, отличных от Unix. +- В Unix должно быть \(\le 107\) байт (ограничение длины пути). +- Взаимоисключающий с `mask_host`. + - **Описание**: Путь сокета Unix для серверной части маски вместо TCP `mask_host`/`mask_port`. + - **Пример**: + + ```toml + [censorship] + mask_unix_sock = "/run/telemt/mask.sock" + ``` + +- `fake_cert_len` + - **Ограничения / валидация**: `использовать`. Когда `tls_emulation = false` и используется значение по умолчанию, Telemt может рандомизировать его при запуске для обеспечения вариативности. + - **Описание**: Длина полезных данных синтетического сертификата, когда данные эмуляции недоступны. + - **Пример**: + + ```toml + [censorship] + fake_cert_len = 2048 + ``` + +- `tls_emulation` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает эмуляцию поведения сертификата/TLS из кэшированных реальных фронтов. + - **Пример**: + + ```toml + [censorship] + tls_emulation = true + ``` + +- `tls_front_dir` + - **Ограничения / валидация**: `Строка`. + - **Описание**: Путь к каталогу для хранения переднего кэша TLS. + - **Пример**: + + ```toml + [censorship] + tls_front_dir = "tlsfront" + ``` + +- `server_hello_delay_min_ms` + - **Ограничения / валидация**: `u64` (миллисекунды). + - **Описание**: Минимальная задержка server_hello для защиты от отпечатков пальцев (мс). + - **Пример**: + + ```toml + [censorship] + server_hello_delay_min_ms = 0 + ``` + +- `server_hello_delay_max_ms` + - **Ограничения / валидация**: `u64` (миллисекунды). Должно быть \(<\) `timeouts.client_handshake * 1000`. + - **Описание**: Максимальная задержка `server_hello` для защиты от отпечатков пальцев (мс). + - **Пример**: + + ```toml + [timeouts] + client_handshake = 30 + + [censorship] + server_hello_delay_max_ms = 0 + ``` + +- `tls_new_session_tickets` + - **Ограничения / валидация**: `u8`. + - **Описание**: Количество сообщений NewSessionTicket, отправляемых после рукопожатия. + - **Пример**: + + ```toml + [censorship] + tls_new_session_tickets = 0 + ``` + +- `tls_full_cert_ttl_secs` + - **Ограничения / валидация**: `u64` (секунды). + - **Описание**: TTL для отправки полной полезной нагрузки сертификата для каждого кортежа (домен, IP-адрес клиента). + - **Пример**: + + ```toml + [censorship] + tls_full_cert_ttl_secs = 90 + ``` + +- `alpn_enforce` + - **Ограничения / валидация**: `бул`. + - **Описание**: Обеспечивает поведение эха ALPN в зависимости от предпочтений клиента. + - **Пример**: + + ```toml + [censorship] + alpn_enforce = true + ``` + +- `mask_proxy_protocol` + - **Ограничения / валидация**: `u8`. `0` = отключено, `1` = v1 (текст), `2` = v2 (двоичный). + - **Описание**: Отправляет заголовок протокола PROXY при подключении к серверной части маски, позволяя серверной части видеть реальный IP-адрес клиента. + - **Пример**: + + ```toml + [censorship] + mask_proxy_protocol = 0 + ``` + +- `mask_shape_hardening` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает усиление жесткости канала формы клиента->маски путем применения контролируемого заполнения хвоста к границам сегмента при отключении реле маски. + - **Пример**: + + ```toml + [censorship] + mask_shape_hardening = true + ``` + +- `mask_shape_hardening_aggressive_mode` + - **Ограничения / валидация**: Требуется «mask_shape_hardening = true». + - **Описание**: Включите агрессивный профиль формирования (более сильное антиклассификаторское поведение с различной семантикой формирования). + - **Пример**: + + ```toml + [censorship] + mask_shape_hardening = true + mask_shape_hardening_aggressive_mode = false + ``` + +- `mask_shape_bucket_floor_bytes` + - **Ограничения / валидация**: Должно быть `> 0`; должно быть `<= Mask_shape_bucket_cap_bytes`. + - **Описание**: Минимальный размер ковша, используемый при закалке в форме канала. + - **Пример**: + + ```toml + [censorship] + mask_shape_bucket_floor_bytes = 512 + ``` + +- `mask_shape_bucket_cap_bytes` + - **Ограничения / валидация**: Должно быть `>= Mask_shape_bucket_floor_bytes`. + - **Описание**: Максимальный размер ковша, используемый при фасонно-канальной закалке; трафик, превышающий ограничение, не дополняется дальше. + - **Пример**: + + ```toml + [censorship] + mask_shape_bucket_cap_bytes = 4096 + ``` + +- `mask_shape_above_cap_blur` + - **Ограничения / валидация**: Требуется «mask_shape_hardening = true». + - **Описание**: Добавляет ограниченные рандомизированные хвостовые байты, даже если пересылаемый размер уже превышает ограничение. + - **Пример**: + + ```toml + [censorship] + mask_shape_hardening = true + mask_shape_above_cap_blur = false + ``` + +- `mask_shape_above_cap_blur_max_bytes` + - **Ограничения / валидация**: Должно быть `<= 1048576`. Должно быть `> 0`, когда `mask_shape_above_cap_blur = true`. + - **Описание**: Максимальное количество случайных дополнительных байтов, добавляемых выше ограничения, если включено размытие выше ограничения. + - **Пример**: + + ```toml + [censorship] + mask_shape_above_cap_blur = true + mask_shape_above_cap_blur_max_bytes = 64 + ``` + +- `mask_relay_max_bytes` + - **Ограничения / валидация**: Должно быть `> 0`; должно быть `<= 67108864`. + - **Описание**: Максимальное количество ретранслируемых байтов в каждом направлении по резервному пути маскировки без аутентификации. + - **Пример**: + + ```toml + [censorship] + mask_relay_max_bytes = 5242880 + ``` + +- `mask_classifier_prefetch_timeout_ms` + - **Ограничения / валидация**: Должно быть в пределах `[5, 50]` (миллисекунды). + - **Описание**: Бюджет тайм-аута (мс) для расширения фрагментированного начального окна классификатора при откате маскирования. + - **Пример**: + + ```toml + [censorship] + mask_classifier_prefetch_timeout_ms = 5 + ``` + +- `mask_timing_normalization_enabled` + - **Ограничения / валидация**: Если задано значение true, требуется маска_timing_normalization_floor_ms > 0 и маска_timing_normalization_ceiling_ms >= Mask_timing_normalization_floor_ms. Потолок должен быть `<= 60000`. + - **Описание**: Включает нормализацию временного конверта для результатов маскировки. + - **Пример**: + + ```toml + [censorship] + mask_timing_normalization_enabled = false + ``` + +- `mask_timing_normalization_floor_ms` + - **Ограничения / валидация**: Должно быть `> 0`, если нормализация времени включена; должно быть `<= Mask_timing_normalization_ceiling_ms`. + - **Описание**: Нижняя граница (мс) для маскировки цели нормализации результата. + - **Пример**: + + ```toml + [censorship] + mask_timing_normalization_floor_ms = 0 + ``` + +- `mask_timing_normalization_ceiling_ms` + - **Ограничения / валидация**: Должно быть `>= Mask_timing_normalization_floor_ms`; должно быть `<= 60000`. + - **Описание**: Верхняя граница (мс) для маскировки цели нормализации результата. + - **Пример**: + + ```toml + [censorship] + mask_timing_normalization_ceiling_ms = 0 + ``` + + +## [censorship.tls_fetch] + + +| Ключ | Тип | По умолчанию | +| --- | ---- | ------- | +| [`profiles`](#cfg-censorship-tls_fetch-profiles) | `String[]` | `["modern_chrome_like", "modern_firefox_like", "compat_tls12", "legacy_minimal"]` | +| [`strict_route`](#cfg-censorship-tls_fetch-strict_route) | `bool` | `true` | +| [`attempt_timeout_ms`](#cfg-censorship-tls_fetch-attempt_timeout_ms) | `u64` | `5000` | +| [`total_budget_ms`](#cfg-censorship-tls_fetch-total_budget_ms) | `u64` | `15000` | +| [`grease_enabled`](#cfg-censorship-tls_fetch-grease_enabled) | `bool` | `false` | +| [`deterministic`](#cfg-censorship-tls_fetch-deterministic) | `bool` | `false` | +| [`profile_cache_ttl_secs`](#cfg-censorship-tls_fetch-profile_cache_ttl_secs) | `u64` | `600` | + + +- `profiles` + - **Ограничения / валидация**: `Строка[]`. Пустой список возвращает значения по умолчанию; значения дедуплицируются с сохранением порядка. + - **Описание**: Упорядоченная резервная цепочка профиля ClientHello для выборки метаданных TLS-фронт. + - **Пример**: + + ```toml + [censorship.tls_fetch] + profiles = ["modern_chrome_like", "compat_tls12"] + ``` + +- `strict_route` + - **Ограничения / валидация**: `бул`. + - **Описание**: Если true и восходящий маршрут настроен, выборка TLS не закрывается из-за ошибок восходящего соединения вместо возврата к прямому TCP. + - **Пример**: + + ```toml + [censorship.tls_fetch] + strict_route = true + ``` + +- `attempt_timeout_ms` + - **Ограничения / валидация**: Должно быть `> 0` (миллисекунды). + - **Описание**: Бюджет таймаута на одну попытку получения профиля TLS (мс). + - **Пример**: + + ```toml + [censorship.tls_fetch] + attempt_timeout_ms = 5000 + ``` + +- `total_budget_ms` + - **Ограничения / валидация**: Должно быть `> 0` (миллисекунды). + - **Описание**: Общий бюджет настенных часов для всех попыток TLS-выборки (мс). + - **Пример**: + + ```toml + [censorship.tls_fetch] + total_budget_ms = 15000 + ``` + +- `grease_enabled` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает случайные значения в стиле GREASE в выбранных расширениях ClientHello для получения трафика. + - **Пример**: + + ```toml + [censorship.tls_fetch] + grease_enabled = false + ``` + +- `deterministic` + - **Ограничения / валидация**: `бул`. + - **Описание**: Включает детерминированную случайность ClientHello для отладки/тестирования. + - **Пример**: + + ```toml + [censorship.tls_fetch] + deterministic = false + ``` + +- `profile_cache_ttl_secs` + - **Ограничения / валидация**: `u64` (секунды). `0` отключает кеш. + - **Описание**: TTL для записей кэша профиля победителя, используемых путем выборки TLS. + - **Пример**: + + ```toml + [censorship.tls_fetch] + profile_cache_ttl_secs = 600 + ``` + + +### Shape-channel hardening notes (`[censorship]`) + +Эти параметры предназначены для уменьшения одного конкретного источника отпечатков пальцев во время маскировки: точного количества байтов, отправленных с прокси-сервера на «mask_host» для недействительного или пробного трафика. + +Без усиления цензор часто может очень точно сопоставить входную длину зонда с длиной, наблюдаемой серверной частью (например: `5 + body_sent` на ранних путях отклонения TLS). Это создает сигнал классификатора на основе длины. + +When `mask_shape_hardening = true`, Telemt pads the **client->mask** stream tail to a bucket boundary at relay shutdown: + +- Сначала измеряется общее количество байтов, отправленных в маску. +- Ведро выбирается с использованием степеней двойки, начиная с «mask_shape_bucket_floor_bytes». +— Заполнение добавляется только в том случае, если общее количество байтов меньше «mask_shape_bucket_cap_bytes». +- Если байты уже превышают ограничение, дополнительное дополнение не добавляется. + +Это означает, что несколько близлежащих размеров зондов объединяются в один и тот же класс размеров, наблюдаемый серверной частью, что усложняет активную классификацию. + +Что каждый параметр меняет на практике: + +- `mask_shape_hardening` +Включает или отключает весь этот этап формирования длины на резервном пути. +Если установлено значение «false», длина, наблюдаемая серверной частью, остается близкой к реальной длине пересылаемого зонда. +Если задано значение true, при чистом отключении реле могут добавляться случайные байты заполнения для перемещения итоговой суммы в корзину. +- `mask_shape_bucket_floor_bytes` +Устанавливает первую границу сегмента, используемую для небольших зондов. +Пример: с этажом «512» некорректный зонд, который в противном случае пересылал бы «37» байтов, может быть расширен до «512» байтов в чистом EOF. +Большие минимальные значения лучше скрывают очень маленькие зонды, но увеличивают стоимость выхода. +- `mask_shape_bucket_cap_bytes` +Устанавливает самый большой сегмент, который Telemt будет дополнять логикой сегмента. +Пример: с ограничением `4096` общее количество пересылаемых байтов `1800` может быть дополнено до `2048` или `4096` в зависимости от лестницы сегментов, но общее количество, уже превышающее `4096`, не будет дополняться дальше. +Большие значения ограничения увеличивают диапазон, в котором сворачиваются классы размеров, но также увеличивают накладные расходы в худшем случае. +- Чистый EOF имеет значение в консервативном режиме. +В профиле по умолчанию заполнение формы намеренно консервативно: оно применяется при чистом отключении реле, а не при каждом тайм-ауте или пути утечки. +Это позволяет избежать появления новых артефактов тайм-аута, которые некоторые серверные части или тесты интерпретируют как отдельные отпечатки пальцев. + +Практические компромиссы: + +- Улучшена защита от отпечатков пальцев на канале размера/формы. +- Немного выше выходные накладные расходы для небольших зондов из-за заполнения. +- Поведение намеренно консервативно и включено по умолчанию. + +Рекомендуемый стартовый профиль: + +- `mask_shape_hardening = true` (default) +- `mask_shape_bucket_floor_bytes = 512` +- `mask_shape_bucket_cap_bytes = 4096` + +### Aggressive mode notes (`[censorship]`) + +«mask_shape_hardening_aggressive_mode» — это дополнительный профиль для более высокого давления антиклассификатора. + +- По умолчанию установлено значение «false», чтобы сохранить консервативное поведение по тайм-ауту/без хвоста. +- Requires `mask_shape_hardening = true`. +- Если этот параметр включен, могут формироваться бесшумные пути маскировки без EOF. +- При включении вместе с размытием над верхним пределом случайный дополнительный хвост использует `[1, max]` вместо `[0, max]`. + +Что меняется при включении агрессивного режима: + +- Могут быть сформированы пути тайм-аута, не требующие бэкенда. +В режиме по умолчанию клиент, который держит сокет полуоткрытым и имеет тайм-аут, обычно не будет получать заполнение формы по этому пути. +В агрессивном режиме Telemt все равно может формировать этот сеанс без звука, если никакие байты серверной части не были возвращены. +Это специально предназначено для активных зондов, которые пытаются избежать EOF, чтобы сохранить точную наблюдаемую длину. +- Размытие над заглавной буквой всегда добавляет хотя бы один байт. +В режиме по умолчанию для размытия над пределом может быть выбрано значение «0», поэтому некоторые зонды слишком большого размера по-прежнему попадают на точную базовую длину пересылки. +В агрессивном режиме эта базовая выборка удаляется автоматически. +- Компромисс +Агрессивный режим повышает устойчивость к активным классификаторам длины, но он более упрям ​​и менее консервативен. +Если в вашем развертывании приоритетом является строгая совместимость с семантикой тайм-аута/без хвоста, оставьте ее отключенной. +Если ваша модель угроз включает в себя повторяющиеся активные проверки цензором, этот режим является более сильным профилем. + +Используйте этот режим только в том случае, если ваша модель угроз отдает приоритет устойчивости классификатора над строгой совместимостью с консервативной семантикой маскировки. + +### Above-cap blur notes (`[censorship]`) + +«mask_shape_above_cap_blur» добавляет размытие второго этапа для очень больших зондов, которые уже находятся выше «mask_shape_bucket_cap_bytes». + +- В режиме по умолчанию добавляется случайный хвост в `[0, Mask_shape_above_cap_blur_max_bytes]`. +— В агрессивном режиме случайный хвост становится строго положительным: `[1, Mask_shape_above_cap_blur_max_bytes]`. +- Это уменьшает утечку точного размера выше ограничения при ограниченных накладных расходах. +— Сохраняйте «mask_shape_above_cap_blur_max_bytes» консервативным, чтобы избежать ненужного роста выходного сигнала. + +Операционное значение: + +- Без размытия над шапкой +Зонд, который пересылает 5005 байтов, по-прежнему будет выглядеть как 5005 байт на серверную часть, если он уже превышает ограничение. +- С включенным размытием над шапкой +Тот же самый зонд может выглядеть как любое значение в ограниченном окне, превышающем его базовую длину. + Example with `mask_shape_above_cap_blur_max_bytes = 64`: +наблюдаемый на сервере размер становится «5005..5069» в режиме по умолчанию или «5006..5069» в агрессивном режиме. +- Выбор `mask_shape_above_cap_blur_max_bytes` +Небольшие значения снижают затраты, но сохраняют большую степень разделения между удаленными друг от друга негабаритными классами. +Большие значения размывают слишком большие классы более агрессивно, но добавляют больше исходящих издержек и большую дисперсию выходных данных. + +### Timing normalization envelope notes (`[censorship]`) + +`mask_timing_normalization_enabled` сглаживает разницу во времени между результатами маскировки, применяя целевой диапазон длительности. + +- Случайная цель выбирается в `[mask_timing_normalization_floor_ms, Mask_timing_normalization_ceiling_ms]`. +- Быстрые пути задерживаются до выбранной цели. +- Медленные пути не обязательно заканчиваются у потолка (огибающая формируется с максимальной эффективностью, а не усекается). + +Рекомендуемый стартовый профиль для формирования тайминга: + +- `mask_timing_normalization_enabled = true` +- `mask_timing_normalization_floor_ms = 180` +- `mask_timing_normalization_ceiling_ms = 320` + +Если ваша серверная часть или сеть сильно ограничена в пропускной способности, сначала уменьшите ограничение. Если датчики все еще слишком различимы в вашей среде, постепенно увеличивайте минимальное значение. + +## [access] + + +| Ключ | Тип | По умолчанию | +| --- | ---- | ------- | +| [`users`](#cfg-access-users) | `Map` | `{"default": "000…000"}` | +| [`user_ad_tags`](#cfg-access-user_ad_tags) | `Map` | `{}` | +| [`user_max_tcp_conns`](#cfg-access-user_max_tcp_conns) | `Map` | `{}` | +| [`user_max_tcp_conns_global_each`](#cfg-access-user_max_tcp_conns_global_each) | `usize` | `0` | +| [`user_expirations`](#cfg-access-user_expirations) | `Map>` | `{}` | +| [`user_data_quota`](#cfg-access-user_data_quota) | `Map` | `{}` | +| [`user_max_unique_ips`](#cfg-access-user_max_unique_ips) | `Map` | `{}` | +| [`user_max_unique_ips_global_each`](#cfg-access-user_max_unique_ips_global_each) | `usize` | `0` | +| [`user_max_unique_ips_mode`](#cfg-access-user_max_unique_ips_mode) | `"active_window"`, `"time_window"`, or `"combined"` | `"active_window"` | +| [`user_max_unique_ips_window_secs`](#cfg-access-user_max_unique_ips_window_secs) | `u64` | `30` | +| [`replay_check_len`](#cfg-access-replay_check_len) | `usize` | `65536` | +| [`replay_window_secs`](#cfg-access-replay_window_secs) | `u64` | `120` | +| [`ignore_time_skew`](#cfg-access-ignore_time_skew) | `bool` | `false` | + + +- `users` + - **Ограничения / валидация**: Не должно быть пустым (должен существовать хотя бы один пользователь). Каждое значение должно состоять **ровно из 32 шестнадцатеричных символов**. + - **Описание**: Карта учетных данных пользователя, используемая для аутентификации клиента. Ключи — это имена пользователей; значения являются секретами MTProxy. + - **Пример**: + + ```toml + [access.users] + alice = "00112233445566778899aabbccddeeff" + bob = "0123456789abcdef0123456789abcdef" + ``` + +- `user_ad_tags` + - **Ограничения / валидация**: Каждое значение должно содержать **ровно 32 шестнадцатеричных символа** (тот же формат, что и `general.ad_tag`). Тег со всеми нулями разрешен, но регистрирует предупреждение. + - **Описание**: Переопределение рекламного тега спонсируемого канала для каждого пользователя. Когда у пользователя есть запись здесь, она имеет приоритет над `general.ad_tag`. + - **Пример**: + + ```toml + [general] + ad_tag = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + + [access.user_ad_tags] + alice = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + ``` + +- `user_max_tcp_conns` + - **Ограничения / валидация**: `Карта`. + - **Описание**: Максимальное количество одновременных TCP-соединений для каждого пользователя. + - **Пример**: + + ```toml + [access.user_max_tcp_conns] + alice = 500 + ``` + +- `user_max_tcp_conns_global_each` + - **Ограничения / валидация**: `использовать`. `0` отключает унаследованный лимит. + - **Описание**: Глобальное максимальное количество одновременных TCP-соединений для каждого пользователя, применяется, когда у пользователя **нет положительной** записи в `[access.user_max_tcp_conns]` (отсутствующий ключ или значение `0` подпадают под этот параметр). Ограничения на пользователя, превышающие «0» в «user_max_tcp_conns», имеют приоритет. + - **Пример**: + + ```toml + [access] + user_max_tcp_conns_global_each = 200 + + [access.user_max_tcp_conns] + alice = 500 # uses 500, not the global cap + # bob has no entry → uses 200 + ``` + +- `user_expirations` + - **Ограничения / валидация**: `Карта>`. Каждое значение должно быть допустимой датой и временем RFC3339/ISO-8601. + - **Описание**: Временные метки истечения срока действия учетной записи пользователя (UTC). + - **Пример**: + + ```toml + [access.user_expirations] + alice = "2026-12-31T23:59:59Z" + ``` + +- `user_data_quota` + - **Ограничения / валидация**: `Карта`. + - **Описание**: Квота трафика на пользователя в байтах. + - **Пример**: + + ```toml + [access.user_data_quota] + alice = 1073741824 # 1 GiB + ``` + +- `user_max_unique_ips` + - **Ограничения / валидация**: `Карта`. + - **Описание**: Ограничения на уникальные исходные IP-адреса для каждого пользователя. + - **Пример**: + + ```toml + [access.user_max_unique_ips] + alice = 16 + ``` + +- `user_max_unique_ips_global_each` + - **Ограничения / валидация**: `использовать`. `0` отключает унаследованный лимит. + - **Описание**: Глобальный лимит уникального IP-адреса для каждого пользователя применяется, когда у пользователя нет индивидуального переопределения в `[access.user_max_unique_ips]`. + - **Пример**: + + ```toml + [access] + user_max_unique_ips_global_each = 8 + ``` + +- `user_max_unique_ips_mode` + - **Ограничения / валидация**: Должно быть одно из «active_window», «time_window», «combined». + - **Описание**: Режим учета лимита уникальных IP-адресов источника. + - **Пример**: + + ```toml + [access] + user_max_unique_ips_mode = "active_window" + ``` + +- `user_max_unique_ips_window_secs` + - **Ограничения / валидация**: Должно быть `> 0`. + - **Описание**: Размер окна (в секундах), используемый режимами учета уникальных IP-адресов, включающими временное окно («time_window» и «комбинированный»). + - **Пример**: + + ```toml + [access] + user_max_unique_ips_window_secs = 30 + ``` + +- `replay_check_len` + - **Ограничения / валидация**: `использовать`. + - **Описание**: Длина хранилища для защиты от повторения (количество записей, отслеживаемых на предмет обнаружения дубликатов). + - **Пример**: + + ```toml + [access] + replay_check_len = 65536 + ``` + +- `replay_window_secs` + - **Ограничения / валидация**: `u64`. + - **Описание**: Временное окно защиты от повтора в секундах. + - **Пример**: + + ```toml + [access] + replay_window_secs = 120 + ``` + +- `ignore_time_skew` + - **Ограничения / валидация**: `бул`. + - **Описание**: Отключает проверку перекоса временных меток клиента и сервера при проверке воспроизведения, если она включена. + - **Пример**: + + ```toml + [access] + ignore_time_skew = false + ``` + + +## [[upstreams]] + + +| Ключ | Тип | По умолчанию | +| --- | ---- | ------- | +| [`type`](#cfg-upstreams-type) | `"direct"`, `"socks4"`, `"socks5"`, or `"shadowsocks"` | — | +| [`weight`](#cfg-upstreams-weight) | `u16` | `1` | +| [`enabled`](#cfg-upstreams-enabled) | `bool` | `true` | +| [`scopes`](#cfg-upstreams-scopes) | `String` | `""` | +| [`interface`](#cfg-upstreams-interface) | `String` | — | +| [`bind_addresses`](#cfg-upstreams-bind_addresses) | `String[]` | — | +| [`url`](#cfg-upstreams-url) | `String` | — | +| [`address`](#cfg-upstreams-address) | `String` | — | +| [`user_id`](#cfg-upstreams-user_id) | `String` | — | +| [`username`](#cfg-upstreams-username) | `String` | — | +| [`password`](#cfg-upstreams-password) | `String` | — | + + +- `type` + - **Ограничения / валидация**: Обязательное поле. Должен быть одним из: `"direct"`, `"socks4"`, `"socks5"`, `"shadowsocks"`. + - **Описание**: Выбирает реализацию восходящего транспорта для этой записи `[[upstreams]]`. + - **Пример**: + + ```toml + [[upstreams]] + type = "direct" + + [[upstreams]] + type = "socks5" + address = "127.0.0.1:9050" + + [[upstreams]] + type = "shadowsocks" + url = "ss://2022-blake3-aes-256-gcm:BASE64PASSWORD@127.0.0.1:8388" + ``` + +- `weight` + - **Ограничения / валидация**: `u16` (0..=65535). + - **Описание**: Базовый вес, используемый взвешенно-случайным выбором в восходящем направлении (выше = выбирается чаще). + - **Пример**: + + ```toml + [[upstreams]] + type = "direct" + weight = 10 + ``` + +- `enabled` + - **Ограничения / валидация**: `бул`. + - **Описание**: Если установлено значение false, эта запись игнорируется и не используется для выбора в восходящем направлении. + - **Пример**: + + ```toml + [[upstreams]] + type = "socks5" + address = "127.0.0.1:9050" + enabled = false + ``` + +- `scopes` + - **Ограничения / валидация**: `Строка`. Список, разделенный запятыми; пробелы обрезаются во время сопоставления. + - **Описание**: Теги области, используемые для восходящей фильтрации на уровне запроса. Если в запросе указана область, могут быть выбраны только восходящие потоки, чьи `области` содержат этот тег. Если в запросе не указана область, допускаются только восходящие потоки с пустыми «областями». + - **Пример**: + + ```toml + [[upstreams]] + type = "socks4" + address = "10.0.0.10:1080" + scopes = "me, fetch, dc2" + ``` + +- `interface` + - **Ограничения / валидация**: `Строка` (необязательно). +- Для «прямого»: может быть IP-адрес (используемый как явная локальная привязка) или имя интерфейса ОС (преобразующееся в IP-адрес во время выполнения; только для Unix). +- Для `"socks4"`/`"socks5"`: поддерживается только тогда, когда `address` является литералом`IP:port`; когда `address` является именем хоста, привязка интерфейса игнорируется. +- Для `"shadowsocks"`: передается в коннектор Shadowsocks как необязательная подсказка для исходящей привязки. + - **Описание**: Необязательный исходящий интерфейс/подсказка локальной привязки для восходящего сокета подключения. + - **Пример**: + + ```toml + [[upstreams]] + type = "direct" + interface = "eth0" + + [[upstreams]] + type = "socks5" + address = "203.0.113.10:1080" + interface = "192.0.2.10" # explicit local bind IP + ``` + +- `bind_addresses` + - **Ограничения / валидация**: `String[]` (необязательно). Применяется только к `type = "direct"`. +- Каждая запись должна представлять собой строку IP-адреса. +- Во время выполнения Telemt выбирает адрес, соответствующий целевому семейству (IPv4 или IPv6). Если установлен параметр «bind_addresses», и ни один из них не соответствует целевому семейству, попытка подключения не удалась. + - **Описание**: Явные локальные адреса источника для исходящих прямых TCP-подключений. Если указано несколько адресов, выбор осуществляется по кругу. + - **Пример**: + + ```toml + [[upstreams]] + type = "direct" + bind_addresses = ["192.0.2.10", "192.0.2.11"] + ``` + +- `url` + - **Ограничения / валидация**: Применяется только к `type = "shadowsocks"`. +- Должен быть действительный URL-адрес Shadowsocks, принятый ящиком Shadowsocks. +- Плагины Shadowsocks не поддерживаются. + - Requires `general.use_middle_proxy = false` (shadowsocks upstreams are rejected in ME mode). + - **Описание**: URL-адрес сервера Shadowsocks, используемый для подключения к Telegram через ретранслятор Shadowsocks. + - **Пример**: + + ```toml + [general] + use_middle_proxy = false + + [[upstreams]] + type = "shadowsocks" + url = "ss://2022-blake3-aes-256-gcm:BASE64PASSWORD@127.0.0.1:8388" + ``` + +- `address` + - **Ограничения / валидация**: Требуется для `type = "socks4"` и `type = "socks5"`. Должно быть `host:port` или `ip:port`. + - **Описание**: Конечная точка прокси-сервера SOCKS, используемая для восходящих подключений. + - **Пример**: + + ```toml + [[upstreams]] + type = "socks5" + address = "127.0.0.1:9050" + ``` + +- `user_id` + - **Ограничения / валидация**: `Строка` (необязательно). Только для `type="socks4"`. + - **Описание**: Идентификатор пользователя SOCKS4 CONNECT. Примечание. Когда выбрана область запроса, Telemt может переопределить ее с помощью выбранного значения области. + - **Пример**: + + ```toml + [[upstreams]] + type = "socks4" + address = "127.0.0.1:1080" + user_id = "telemt" + ``` + +- `username` + - **Ограничения / валидация**: `Строка` (необязательно). Только для `type="socks5"`. + - **Описание**: Имя пользователя SOCKS5 (для аутентификации по имени пользователя и паролю). Примечание. Когда выбрана область запроса, Telemt может переопределить ее с помощью выбранного значения области. + - **Пример**: + + ```toml + [[upstreams]] + type = "socks5" + address = "127.0.0.1:9050" + username = "alice" + ``` + +- `password` + - **Ограничения / валидация**: `Строка` (необязательно). Только для `type="socks5"`. + - **Описание**: Пароль SOCKS5 (для аутентификации по имени пользователя и паролю). Примечание. Когда выбрана область запроса, Telemt может переопределить ее с помощью выбранного значения области. + - **Пример**: + + ```toml + [[upstreams]] + type = "socks5" + address = "127.0.0.1:9050" + username = "alice" + password = "secret" + ``` + +