mirror of https://github.com/telemt/telemt.git
279 lines
8.6 KiB
Markdown
279 lines
8.6 KiB
Markdown
# TLS-F и TCP-S в Telemt
|
||
|
||
## Общая архитектура
|
||
|
||
**Telemt** - это прежде всего реализация **MTProxy**, через которую проходит payload Telegram
|
||
|
||
Подсистема **TLS-Fronting / TCP-Splitting** служит **маскировочным транспортным слоем**, задача которого - сделать MTProxy-соединение внешне похожим на обычное TLS-подключение к легитимному сайту
|
||
|
||
Таким образом:
|
||
|
||
- **MTProxy** - основной функциональный слой Telemt для обработки Telegram-трафика
|
||
- **TLS-Fronting / TCP-Splitting** - подсистема маскировки транспорта
|
||
|
||
С точки зрения сети Telemt ведёт себя как **TLS-сервер**, но фактически:
|
||
|
||
- валидные MTProxy-клиенты остаются внутри контура Telemt
|
||
- любые другие TLS-клиенты проксируются на обычный HTTPS-сервер-заглушку
|
||
|
||
# Базовый сценарий / Best-practice
|
||
|
||
Предположим, у вас есть домен:
|
||
|
||
```
|
||
umweltschutz.de
|
||
```
|
||
|
||
### 1 DNS
|
||
|
||
Вы создаёте A-запись:
|
||
|
||
```
|
||
umweltschutz.de -> A-запись 198.18.88.88
|
||
```
|
||
|
||
где `198.18.88.88` - IP вашего сервера с telemt
|
||
|
||
### 2 TLS-домен
|
||
|
||
В конфигурации Telemt:
|
||
|
||
```toml
|
||
[censorship]
|
||
tls_domain = "umweltschutz.de"
|
||
```
|
||
|
||
Этот домен используется клиентом как SNI в ClientHello
|
||
|
||
### 3 Сервер-заглушка
|
||
|
||
Вы поднимаете обычный HTTPS-сервер, например **nginx**, с сертификатом для этого домена.
|
||
|
||
Он может работать:
|
||
|
||
- на том же сервере
|
||
- на другом сервере
|
||
- на другом порту
|
||
|
||
В конфигурации Telemt:
|
||
|
||
```toml
|
||
[censorship]
|
||
mask_host = "127.0.0.1"
|
||
mask_port = 8443
|
||
```
|
||
|
||
где `127.0.0.1` - IP сервера-заглушки, а 8443 - порт, который он слушает
|
||
|
||
Этот сервер нужен **для обработки любых non-MTProxy запросов**
|
||
|
||
### 4 Работа Telemt
|
||
|
||
После запуска Telemt действует следующим образом:
|
||
|
||
1) принимает входящее TCP-соединение
|
||
2) анализирует TLS-ClientHello
|
||
3) пытается определить, является ли соединение валидным **MTProxy FakeTLS**
|
||
|
||
Далее работают два варианта логики:
|
||
|
||
---
|
||
|
||
# Сценарий 1 - MTProxy клиент с валидным ключом
|
||
|
||
Если клиент предъявил **валидный MTProxy-ключ**:
|
||
|
||
- соединение **остаётся внутри Telemt**
|
||
- TLS используется только как **транспортная маскировка**
|
||
- далее запускается обычная логика **MTProxy**
|
||
|
||
Для внешнего наблюдателя это выглядит как:
|
||
|
||
```
|
||
TLS connection -> umweltschutz.de
|
||
```
|
||
|
||
Хотя внутри передаётся **MTProto-трафик Telegram**
|
||
|
||
# Сценарий 2 - обычный TLS-клиент - crawler / scanner / browser
|
||
|
||
Если Telemt не обнаруживает валидный MTProxy-ключ:
|
||
|
||
соединение **переключается в режим TCP-Splitting / TCP-Splicing**.
|
||
|
||
В этом режиме Telemt:
|
||
|
||
1. открывает новое TCP-соединение к
|
||
|
||
```
|
||
mask_host:mask_port
|
||
```
|
||
|
||
2. начинает **проксировать TCP-трафик**
|
||
|
||
Важно:
|
||
|
||
* клиентский TLS-запрос **НЕ модифицируется**
|
||
* **ClientHello передаётся "как есть", без изменений**
|
||
* **SNI остаётся неизменным**
|
||
* Telemt **не завершает TLS-рукопожатие**, а только перенаправляет его на более низком уровне сетевого стека - L4
|
||
|
||
Таким образом upstream-сервер получает **оригинальное TLS-соединение клиента**:
|
||
|
||
- если это nginx-заглушка, он просто отдаёт обычный сайт
|
||
- для внешнего наблюдателя это выглядит как обычный HTTPS-сервер
|
||
|
||
# TCP-S / TCP-Splitting / TCP-Splicing
|
||
|
||
Ключевые свойства механизма:
|
||
|
||
**Telemt работает как TCP-переключатель:**
|
||
|
||
1) принимает соединение
|
||
2️) определяет тип клиента
|
||
3) либо:
|
||
|
||
- обрабатывает MTProxy внутри
|
||
- либо проксирует TCP-поток
|
||
|
||
При проксировании:
|
||
|
||
- Telemt **разрешает `mask_host` в IP**
|
||
- устанавливает TCP-соединение
|
||
- начинает **bidirectional TCP relay**
|
||
|
||
При этом:
|
||
|
||
- TLS-рукопожатие происходит **между клиентом и `mask_host`**
|
||
- Telemt выступает только **на уровне L4 - как TCP-релей**, такой же как HAProxy в TCP-режиме
|
||
|
||
# Использование чужого домена
|
||
|
||
Можно использовать и внешний сайт.
|
||
|
||
Например:
|
||
|
||
```toml
|
||
[censorship]
|
||
tls_domain = "github.com"
|
||
mask_host = "github.com"
|
||
mask_port = 443
|
||
```
|
||
|
||
или
|
||
|
||
```toml
|
||
[censorship]
|
||
mask_host = "140.82.121.4"
|
||
```
|
||
|
||
В этом случае:
|
||
|
||
- цензор видит **TLS-подключение к github.com**
|
||
- обычные клиенты/краулер действительно получают **настоящий GitHub**
|
||
|
||
Telemt просто **проксирует TCP-соединение на GitHub**
|
||
|
||
# Что видит анализатор трафика?
|
||
|
||
Для DPI это выглядит так:
|
||
|
||
```
|
||
client -> TLS -> github.com
|
||
```
|
||
|
||
или
|
||
|
||
```
|
||
client -> TLS -> umweltschutz.de
|
||
```
|
||
|
||
TLS-handshake выглядит валидным, SNI соответствует домену, сертификат корректный - от целевого `mask_host:mask_port`
|
||
|
||
# Что видит сканер / краулер?
|
||
|
||
Если сканер попытается подключиться:
|
||
|
||
```
|
||
openssl s_client -connect 198.18.88.88:443 -servername umweltschutz.de
|
||
```
|
||
|
||
он получит **обычный HTTPS-сайт-заглушку**
|
||
|
||
Потому что:
|
||
|
||
- он не предъявил MTProxy-ключ
|
||
- Telemt отправил соединение на `mask_host:mask_port`, на котором находится nginx
|
||
|
||
# Какую проблему решает TLS-Fronting / TCP-Splitting?
|
||
|
||
Эта архитектура решает сразу несколько проблем обхода цензуры.
|
||
|
||
## 1 Закрытие плоскости MTProxy от активного сканирования
|
||
|
||
Многие цензоры:
|
||
|
||
- сканируют IP-адреса
|
||
- проверяют известные сигнатуры прокси
|
||
|
||
Telemt отвечает на такие проверки **обычным HTTPS-сайтом**, поэтому прокси невозможно обнаружить простым сканированием
|
||
|
||
---
|
||
|
||
## 2 Маскировка трафика под легитимный TLS
|
||
|
||
Для DPI-систем соединение выглядит как:
|
||
|
||
```
|
||
обычный TLS-трафик к популярному домену
|
||
```
|
||
|
||
Это делает блокировку значительно сложнее и непредсказуемее
|
||
|
||
---
|
||
|
||
## 3 Устойчивость к протокольному анализу
|
||
|
||
MTProxy трафик проходит **внутри TLS-like-потока**, поэтому:
|
||
|
||
- не видны характерные сигнатуры MTProto
|
||
- соединение выглядит как обычный HTTPS
|
||
|
||
---
|
||
|
||
## 4 Правдоподобное поведение сервера
|
||
|
||
Даже если краулер:
|
||
|
||
- подключится сам
|
||
- выполнит TLS-handshake
|
||
- попытается получить HTTP-ответ
|
||
|
||
он увидит **реальный сайт**, а не telemt
|
||
|
||
Это устраняет один из главных признаков для антифрод-краулеров мобильных операторов
|
||
|
||
# Схема
|
||
|
||
```text
|
||
Client
|
||
│
|
||
│ TCP
|
||
│
|
||
V
|
||
Telemt
|
||
│
|
||
├── valid MTProxy key
|
||
│ │
|
||
│ V
|
||
│ MTProxy logic
|
||
│
|
||
└── обычный TLS клиент
|
||
│
|
||
V
|
||
TCP-Splitting
|
||
│
|
||
V
|
||
mask_host:mask_port
|
||
```
|