MTProto-прокси и SOCKS5: что скрывает IP, а что просто ускоряет
Содержание
- Что вообще происходит на уровне транспорта
- Что видит прокси-сервер в каждом случае
- Секрет MTProto и почему он не «пароль»
- первые 16 байт — HMAC-SHA256 от остального заголовка с секретом
- SOCKS5: где заканчивается анонимность
- Почему MTProto-прокси «прячет» лучше — и где это не так
- Кейс: nginx 1.24 как фронт для SOCKS5 и MTProto
- ожидаем: mtproto на 443, danted на 1080
- Кейс: утечка DNS через SOCKS5
- Кейс: MTProto-прокси с fake TLS и падающий handshake
- если 100% loss — уменьшать до 1400, 1350, 1300
- Сравнение по задержке и пропускной способности
- Что выбрать под задачу
Telegram умеет работать через две принципиально разные штуки — MTProto-прокси и SOCKS5. Их часто путают, ставят «на всякий случай» оба, а потом удивляются, почему один пользователь видит чужой IP в логах, а другой нет. Разница не в скорости и не в удобстве. Разница в том, что именно прокси видит и что он передаёт дальше.
Ниже — разбор на уровне протокола, с реальными конфигами, цифрами и грабельками, на которые наступают при миграции.
Что вообще происходит на уровне транспорта
Telegram-клиент говорит с серверами MTProto по TCP (порт 443, 80, 5222 и ещё пачке портов). Поверх TCP — либо plaintext MTProto (старый режим), либо обфускация (fake TLS, random padding). Клиент не использует системный HTTP-прокси и не умеет в обычный SOCKS5 «из коробки» — точнее, умеет, но через отдельный механизм, который называется SOCKS5-прокси в настройках Telegram.
MTProto-прокси — это отдельный протокол. Клиент устанавливает TCP-соединение с прокси-сервером, отправляет 64-байтный заголовок с секретом, и дальше весь трафик до дата-центров Telegram идёт внутри этого туннеля. Прокси-сервер видит только зашифрованный MTProto-поток. Дата-центр Telegram видит IP прокси, а не клиента.
SOCKS5 — это RFC 1928. Клиент говорит «подключи меня к 149.154.167.51:443», прокси открывает соединение и перекладывает байты. Всё. Никакой криптографии, никакого знания о том, что внутри. Telegram поверх SOCKS5 шлёт тот же самый MTProto, что и напрямую.
Отсюда первое следствие: SOCKS5 сам по себе ничего не шифрует. Шифрование обеспечивает MTProto, и оно одинаковое в обоих случаях. Разница — в том, кто и что видит по бокам.
Что видит прокси-сервер в каждом случае
MTProto-прокси видит: IP клиента, время подключения, объём переданных байт, примерный паттерн активности (когда клиент онлайн, когда ушёл). Всё содержимое — внутри шифрованного канала. Прокси не может прочитать сообщения, не может определить, с кем вы переписываетесь (кроме самого факта соединения с дата-центром Telegram).
SOCKS5 видит то же самое плюс кое-что важное: SNI, если клиент использует TLS-обфускацию, и целевой IP:порт. То есть SOCKS5-провайдер знает, что вы подключились именно к серверам Telegram. MTProto-прокси этого не знает — он видит только «клиент пришёл, сказал секрет, начал гнать байты».
Есть нюанс с fake TLS. Когда Telegram включает обфускацию, клиент шлёт ClientHello с SNI вида `www.google.com` или случайный домен. SOCKS5 этот SNI видит. MTProto-прокси — нет, потому что обфускация происходит уже внутри туннеля.
| Что видно | MTProto-прокси | SOCKS5 |
|---|---|---|
| IP клиента | да | да |
| Целевой IP (дата-центр TG) | нет | да |
| SNI / домен | нет | да (при fake TLS) |
| Содержимое сообщений | нет | нет |
| Размер и тайминг пакетов | да | да |
| Возможность MITM | нет (секрет) | теоретически да |
Секрет MTProto и почему он не «пароль»
Секрет MTProto-прокси — это 16 байт, которые клиент и сервер знают заранее. Бывает в двух видах: обычный (`dd` + 16 байт) и fake-TLS (`ee` + 16 байт + домен). Клиент шлёт заголовок, где первые байты совпадают с секретом, и прокси понимает «свой». Дальше — туннель.
Секрет не аутентифицирует пользователя в смысле «кто ты». Он аутентифицирует сам факт доступа к прокси. Все, кто знает секрет, равны. В логах прокси вы увидите IP, но не имя пользователя. Если секрет утёк — прокси открыт для всех, кто его знает, и отличить злоумышленника от владельца нельзя.
Вот как выглядит проверка секрета на стороне простого MTProto-прокси (упрощённо, на Python, чтобы была понятна логика):
```python
import hmac
import hashlib
SECRET = bytes.fromhex("dd0123456789abcdef0123456789abcdef")
def check_header(header: bytes) -> bool:
if len(header) < 64:
return False
первые 16 байт — HMAC-SHA256 от остального заголовка с секретом
sig = header[:16]
rest = header[16:]
expected = hmac.new(SECRET, rest, hashlib.sha256).digest()[:16]
return hmac.compare_digest(sig, expected)
```
Это не полный протокол, но принцип виден: секрет — ключ HMAC, а не пароль. Подделать заголовок без секрета нельзя.
SOCKS5: где заканчивается анонимность
SOCKS5-прокси может быть публичным, приватным, с авторизацией по логину-паролю (метод 0x02) или без. Telegram умеет и то, и другое. Если прокси без авторизации и торчит наружу — через него пойдёт кто угодно, включая ботов. Ваш IP в логах Telegram будет соседствовать с чужими.
Проверить, что SOCKS5 реально работает и не палит ваш настоящий IP, можно так:
```bash
curl --socks5-hostname user:pass@10.0.0.5:1080 https://api.ipify.org
curl --socks5 10.0.0.5:1080 https://api.ipify.org
```
Первая команда резолвит DNS на стороне прокси (`--socks5-hostname`), вторая — локально. Для Telegram важна первая: клиент не должен светить DNS-запросы. Если используете вторую — ваш провайдер видит DNS-запросы к доменам Telegram, даже если сам трафик идёт через прокси.
И ещё: SOCKS5 не шифрует. Если между вами и прокси нет TLS (а в Telegram его нет на этом уровне — TLS только внутри MTProto), провайдер видит, что вы шлёте бинарный поток на IP прокси. Он не знает содержимого, но знает факт.
Почему MTProto-прокси «прячет» лучше — и где это не так
MTProto-прокси не сообщает наружу целевой адрес. Провайдер видит: соединение с IP прокси на порт 443 (или другой). Всё. Куда дальше прокси гонит трафик — не его дело. Это и есть главное отличие от SOCKS5: SOCKS5-прокси знает, что вы идёте в Telegram, и это знание может утечь (логи, биллинг, суд).
Но есть обратная сторона. MTProto-прокси — это один сервер, который видит весь ваш трафик и знает ваш IP. Если прокси скомпрометирован, злоумышленник видит метаданные: когда вы онлайн, сколько трафика, с каких IP. Содержимое — нет, но паттерн уже многое говорит.
Плюс MTProto-прокси хуже масштабируется. Один секрет — один прокси (или пул с общим секретом). Для команды из 50 человек нужен либо общий секрет (все видят всех), либо отдельные прокси на каждого (дорого). SOCKS5 с авторизацией решает это проще: один сервер, разные логины.
Кейс: nginx 1.24 как фронт для SOCKS5 и MTProto
Пример: сервер на Ubuntu 22.04, nginx 1.24.0, стоит на 443/tcp. Хотим и MTProto-прокси, и SOCKS5 на одном IP, но на разных портах. Проблема — nginx не умеет проксировать SOCKS5, он работает с HTTP. Значит, SOCKS5 идёт мимо nginx, напрямую (dante или 3proxy на 1080/tcp). MTProto — тоже мимо nginx, потому что это не HTTP.
Реальный конфиг nginx тут нужен только для маскировки: отдавать заглушку на 80/tcp, чтобы сканеры видели «обычный сайт». MTProto-прокси слушает 443/tcp напрямую. Вот кусок для заглушки:
```nginx
server {
listen 80 default_server;
server_name _;
location / {
return 200 "OK\n";
add_header Content-Type text/plain;
}
}
```
MTProto-прокси при этом на 443. SOCKS5 — на 1080, закрыт файрволом, доступен только с доверенных IP. Проверка:
```bash
ss -tlnp | grep -E ':(443|1080)\s'
ожидаем: mtproto на 443, danted на 1080
```
Цифры: dante на 1080/tcp держит около 3000 одновременных соединений на 2 vCPU без деградации. MTProto-прокси (например, официальный `mtprotoproxy` на Python) на тех же 2 vCPU тянет примерно 1500–2000 соединений, дальше упирается в GIL. Разница в 1.5–2 раза — не критична для команды, критична для публичного прокси.
Кейс: утечка DNS через SOCKS5
Была ситуация: пользователь настроил SOCKS5 в Telegram, указал `10.0.0.5:1080`, всё вроде работает. Но при проверке через `tcpdump` на шлюзе видно DNS-запросы к `149.154.167.51` с его машины — то есть клиент резолвит адреса Telegram локально, а не через прокси.
Причина: Telegram на десктопе при SOCKS5 без явного флага «resolve via proxy» резолвит часть адресов сам. В настройках это не всегда очевидно. Решение — либо использовать MTProto-прокси (там резолв не нужен вообще, целевой адрес зашит в протокол), либо поднять локальный DNS-резолвер, который гонит запросы через SOCKS5 (`dnscrypt-proxy` с `force_tcp` и upstream через прокси).
Цифры: один DNS-запрос — 40–80 байт, но их сотни за сессию. Утечка даёт провайдеру карту ваших подключений к дата-центрам Telegram, даже если сам трафик идёт через прокси.
Кейс: MTProto-прокси с fake TLS и падающий handshake
Сервер на `mtprotoproxy` с секретом `ee...` (fake TLS) и доменом `cdn.example.com`. Часть клиентов (Telegram Desktop 4.8 на Windows) подключается, часть (мобильный Android 10.2) — нет. В логах прокси — обрыв на этапе handshake, клиент шлёт ClientHello, прокси отвечает, дальше тишина.
Причина: fake TLS в MTProto требует, чтобы домен в секрете совпадал с SNI, который шлёт клиент, и чтобы TLS-сертификат на прокси был валидным для этого домена (или самоподписанным, но тогда клиент должен игнорировать проверку — а Telegram этого не делает в некоторых версиях). Плюс MTU: если между клиентом и прокси MTU 1500, а внутри туннеля пакеты фрагментируются, handshake рвётся на размере ~1400 байт.
Решение: держать обычный секрет (`dd...`) для старых клиентов, fake TLS — только для тех, кто точно поддерживает. Проверить MTU:
```bash
ping -M do -s 1472 -c 3 proxy.example.com
если 100% loss — уменьшать до 1400, 1350, 1300
```
На практике 1400 байт проходит почти везде, 1472 — только на чистом Ethernet без PPPoE.
Сравнение по задержке и пропускной способности
Оба варианта добавляют один хоп. MTProto-прокси добавляет шифрование поверх (HMAC на заголовок — копейки), SOCKS5 — почти ничего. На практике разница в RTT — 1–3 мс на нормальном канале, если прокси рядом.
Пропускная способность упирается в CPU прокси. MTProto-прокси на Python — 50–80 Мбит/с на ядро. SOCKS5 (dante на C) — 300–500 Мбит/с на ядро. Если качаете большие файлы через Telegram — SOCKS5 выигрывает в 3–5 раз по потолку. Для текстовых сообщений разницы нет.
| Метрика | MTProto-прокси | SOCKS5 (dante) |
|---|---|---|
| Добавленный RTT | 1–3 мс | 0.5–1 мс |
| Потолок на ядро | 50–80 Мбит/с | 300–500 Мбит/с |
| Соединений на 2 vCPU | 1500–2000 | ~3000 |
| Шифрование канала | своё (секрет) | нет (полагается на MTProto) |
| Знание целевого адреса | нет | да |
Что выбрать под задачу
Если задача — скрыть от провайдера факт использования Telegram и не палить целевые IP: MTProto-прокси. Он не сообщает наружу, куда идёт трафик, и провайдер видит только соединение с вашим прокси.
Если задача — ускорить соединение для команды, раздать доступ по логинам и не городить отдельный прокси на каждого: SOCKS5 с авторизацией. Проще в обслуживании, выше потолок, но провайдер SOCKS5 знает, что вы идёте в Telegram.
Если задача — и то, и другое: ставьте оба. MTProto на 443 для «скрытности», SOCKS5 на 1080 для «скорости и управления». Клиенты переключаются в настройках за 10 секунд. Главное — не оставлять SOCKS5 без авторизации и не забывать про DNS-утечки.
Для инфраструктуры с несколькими регионами удобно держать MTProto-прокси на дешёвом VPS в нужной стране, а тяжёлый трафик гнать через SOCKS5 на нормальном канале. Разделение ролей снимает обе проблемы: скрытность там, где она нужна, скорость — там, где она важна.