telemt
установка с нуля

Полный гайд: ставим telemt (Rust MTProxy) на чистый Ubuntu, поднимаем несколько инстансов на разных портах, настраиваем systemd, открываем порты и вешаем защиту от DPI на UFW. С генерацией секретов и проверкой.

OS Ubuntu 20.04 / 22.04 / 24.04 telemt 3.4.15+ root required ~20 мин
1

Что такое telemt и зачем

telemt — реализация Telegram MTProxy на Rust. Главное преимущество перед классическим MTG: настоящий TLS-фронтинг — прокси реально подтягивает сертификат маскировочного домена (apple.com, cloudflare.com и т.п.) и эмулирует его, а не подделывает. Снаружи трафик выглядит как обычный визит на популярный сайт.

Слой защитыПротив чего работает
TLS-фронтингдетекция по TLS-хендшейку
client_mssанализ размера TCP-сегментов (DPI ТСПУ)
UFW rate-limitактивное зондирование прокси
План: поставим telemt, поднимем 3 инстанса на разных портах с разными маскировочными доменами (apple / microsoft / cloudflare), настроим автозапуск и фаервол. Несколько инстансов — это запас на случай если один порт начнут душить.

Почему 3 инстанса на разных портах

Это не дублирование «на всякий случай» — каждый инстанс намеренно сопоставляет порт + маскировочный домен так, чтобы трафик сливался с реальным, повседневным трафиком ОС и сервисов. DPI видит не «подозрительное соединение на странный порт», а то что и так постоянно ходит с любого телефона и компьютера.

ПортДомен (SNI)Подо что маскируется
443www.cloudflare.comобычный HTTPS / CDN
5223www.apple.comApple Push Notification Service
8530www.microsoft.comWindows Update / WSUS
Главная фишка — порт 5223. Это настоящий порт Apple Push Notification Service (APNs): каждый iPhone, iPad и Mac держит на нём постоянное живое соединение к серверам Apple, чтобы получать пуш-уведомления. Наш инстанс на 5223 с сертификатом apple.com в этом потоке неотличим — для DPI это просто «ещё один айфон, который держит связь с Apple».

Аналогично остальные пары подобраны под фоновый трафик, который есть у всех и который странно блокировать:

Зачем именно три, а не один:

Важно: маскировка работает только потому, что telemt подтягивает настоящий сертификат каждого домена (apple/microsoft/cloudflare) и эмулирует реальное TLS-рукопожатие. Это не подделка — DPI видит валидную цепочку доверия конкретного сайта. Поэтому домены берутся крупные и повсеместные: чем привычнее трафик к ним, тем незаметнее в нём прокси.
2

Подготовка системы

Обновляем пакеты, ставим зависимости (нужны для скачивания, JSON-обработки и фаервола).

bash
apt update
apt install -y wget tar jq ufw python3 iptables

Создаём отдельного системного пользователя telemt (без shell, без логина) и рабочие директории — так демон не работает под root:

bash
id telemt &>/dev/null || useradd -r -s /usr/sbin/nologin -d /opt/telemt telemt
mkdir -p /opt/telemt /etc/telemt
chown -R telemt:telemt /opt/telemt /etc/telemt
3

Установка бинарника

Скачиваем последний релиз telemt с GitHub, кладём в /bin/telemt.

bash
cd /tmp
wget -qO- "https://github.com/telemt/telemt/releases/latest/download/telemt-x86_64-linux-gnu.tar.gz" | tar -xz
mv /tmp/telemt /bin/telemt
chmod +x /bin/telemt

# проверка
/bin/telemt --version
Должно вывести что-то вроде telemt 3.4.15. Если так — бинарник на месте.
4

Генерация секретов

Секрет MTProxy — это 16 байт = 32 hex-символа. На каждый инстанс нужен свой. Генерируем три штуки:

bash
# 3 случайных секрета по 32 hex
for i in 1 2 3; do echo "user$i = $(openssl rand -hex 16)"; done
Запиши вывод. Каждая строка вида user1 = a1b2c3... пойдёт в конфиг соответствующего инстанса. В клиентской ссылке telemt сам соберёт полный секрет: ee + эти 32 hex + hex домена — но тебе с этим возиться не нужно, ссылку отдаёт API.
5

Конфиги инстансов

Создаём 3 конфига одной python-командой. Подставь свои секреты из шага 4 в блок configs. Порты и домены можно оставить или поменять.

Почему python, а не heredoc: в некоторых терминалах (особенно мобильных SSH-клиентах) cat << EOF склеивает строки и обрывается. python пишет файлы надёжно.
генерирует /etc/telemt/telemt{1,2,3}.toml
python3
python3 << 'PYEOF'
# номер: (порт, домен, api_порт, секрет_32hex) — ПОДСТАВЬ СВОИ СЕКРЕТЫ
configs = {
    1: (443,  "www.cloudflare.com", 9091, "СЕКРЕТ_1"),
    2: (5223, "www.apple.com",      9092, "СЕКРЕТ_2"),
    3: (8530, "www.microsoft.com",  9093, "СЕКРЕТ_3"),
}
for n, (port, domain, api, secret) in configs.items():
    cfg = f"""[general]
fast_mode = true
use_middle_proxy = false

[general.modes]
classic = false
secure = false
tls = true

[network]
ipv4 = true
ipv6 = false
prefer = 4

[server]
port = {port}
listen_addr_ipv4 = "0.0.0.0"
client_mss = "tspu"

[server.api]
enabled = true
listen = "127.0.0.1:{api}"
whitelist = ["127.0.0.1/32"]

[censorship]
tls_domain = "{domain}"
mask = true
mask_port = 443
tls_emulation = true
unknown_sni_action = "reject_handshake"
fake_cert_len = 2048

[access]
replay_check_len = 65536
ignore_time_skew = false

[access.users]
user{n} = "{secret}"
"""
    open(f"/etc/telemt/telemt{n}.toml", "w").write(cfg)
    print(f"telemt{n}: порт {port}, {domain}, api {api} — OK")
PYEOF
chown -R telemt:telemt /etc/telemt
ПараметрЧто делает
client_mss = "tspu"MSS=92, маскирует размер пакетов под браузер (анти-DPI)
tls_emulationподтягивает реальный серт домена и эмулирует его
unknown_sni_actionна «левый» SNI отвечает как обычный веб-сервер
server.apiлокальный API для статистики и ссылок (только 127.0.0.1)
6

systemd-сервисы

Создаём по сервису на каждый инстанс — с автозапуском, перезапуском при падении и нужными капабилити (для bind на привилегированные порты вроде 443).

генерирует /etc/systemd/system/telemt{1,2,3}.service
python3
python3 << 'PYEOF'
descs = {1: "443 cloudflare", 2: "5223 apple", 3: "8530 microsoft"}
for n, d in descs.items():
    svc = f"""[Unit]
Description=Telemt Proxy {n} ({d})
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=telemt
Group=telemt
WorkingDirectory=/opt/telemt
ExecStart=/bin/telemt /etc/telemt/telemt{n}.toml
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
NoNewPrivileges=true

[Install]
WantedBy=multi-user.target
"""
    open(f"/etc/systemd/system/telemt{n}.service", "w").write(svc)
    print(f"telemt{n}.service — OK")
PYEOF
systemctl daemon-reload
7

UFW: порты + защита от зондирования

Сначала базовые правила фаервола — обязательно разреши SSH до включения UFW, иначе отрежешь себе доступ.

ВНИМАНИЕ. Поменяй 22 на свой SSH-порт если он нестандартный. Проверь что строка SSH есть, прежде чем делать ufw enable.
bash — открыть порты
# SSH — критично, первым делом
ufw allow 22/tcp

# порты прокси (свои)
ufw allow 443/tcp
ufw allow 5223/tcp
ufw allow 8530/tcp

# включаем фаервол (если ещё не включён)
ufw --force enable
ufw status

Теперь rate-limit — не больше 1 нового SYN/сек с одного IP на каждый порт. Это отбивает активное зондирование РКН. Модуль ядра + закрепление после ребута + бэкап:

bash — подготовка
modprobe xt_recent
echo xt_recent > /etc/modules-load.d/xt_recent.conf
cp /etc/ufw/before.rules /etc/ufw/before.rules.bak.$(date +%s)

# ПРОВЕРЬ что модуль реально загрузился — должна быть строка:
lsmod | grep xt_recent
Критично: модуль xt_recent. Если lsmod | grep xt_recent ничего не вывел — модуль не загружен, и UFW при reload молча выбросит правила с -m recent (не подтянутся, grep покажет пустоту). Сначала добейся чтобы modprobe xt_recent прошёл без ошибок и lsmod показал модуль, и только потом делай ufw reload.

Вставка правил в /etc/ufw/before.rules (в цепочку ufw-before-input, после established). Каждому порту — свой список, иначе переключение между прокси в Telegram будет рвать соединение.

правит /etc/ufw/before.rules
python3 — rate-limit per-port
python3 << 'PYEOF'
PORTS = [443, 5223, 8530]   # ← СВОИ ПОРТЫ
path = "/etc/ufw/before.rules"
lines = open(path).readlines()
if any("MTProto rate-limit" in l for l in lines):
    print("правила уже есть, пропуск"); raise SystemExit
idx = None
for i, l in enumerate(lines):
    if "ufw-before-input -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT" in l:
        idx = i + 1; break
if idx is None:
    print("ОШИБКА: точка вставки не найдена"); raise SystemExit
block = ["\n# === MTProto rate-limit (1 SYN/сек на IP per-port) ===\n"]
for p in PORTS:
    block.append(f"-A ufw-before-input -p tcp --dport {p} --syn -m recent --name mtp{p} --rcheck --seconds 1 -j DROP\n")
    block.append(f"-A ufw-before-input -p tcp --dport {p} --syn -m recent --name mtp{p} --set -j ACCEPT\n")
block.append("# === конец MTProto rate-limit ===\n")
lines[idx:idx] = block
open(path, "w").writelines(lines)
print("вставлено после строки", idx)
PYEOF

ufw reload
Тонкость per-port. Если сделать один общий список на все порты — Telegram при переключении между прокси шлёт SYN на них одновременно с одного IP в одну секунду, лимит рубит лишние, и прокси «отваливается». Раздельные списки (mtp443, mtp5223...) это решают.
8

Запуск и проверка

Включаем автозапуск, стартуем все инстансы:

bash
systemctl enable telemt1 telemt2 telemt3
systemctl start telemt1 telemt2 telemt3
sleep 3
systemctl is-active telemt1 telemt2 telemt3

Проверяем что всё на месте — порты слушаются, фаервол с правилами, TLS-серты подтянулись:

bash — диагностика
# порты прокси
ss -tlnp | grep -E ':443|:5223|:8530'

# rate-limit в живом фаерволе
iptables -L ufw-before-input -n | grep recent

# TLS-эмуляция подтянула реальные серты? (3 json'а доменов)
ls -la /opt/telemt/tlsfront/

# ошибки в логах?
journalctl -u telemt1 -n 20 --no-pager | grep -iE "error|panic|bind"
Признаки успеха: три active, порты держит telemt, в /opt/telemt/tlsfront/ лежат www.apple.com.json и др. размером в десятки КБ. Предупреждение Skipping IPv6 listener — норма (IPv6 отключён).

Если правил rate-limit не видно (grep по recent пустой) — самая частая причина в том, что не загружен модуль xt_recent, и UFW тихо выбросил правила. Диагностика:

bash — если правил нет
# 1. модуль загружен? (если пусто — вот она, причина)
lsmod | grep xt_recent

# 2. правила реально в файле?
grep -n "mtp\|recent" /etc/ufw/before.rules

# 3. на nft-системах (Ubuntu 22.04+) iptables -L может не показать —
#    проверь через nft напрямую:
nft list chain inet filter ufw-before-input 2>/dev/null | grep -i recent

# ЛЕЧЕНИЕ если модуль не загружен:
modprobe xt_recent
echo xt_recent > /etc/modules-load.d/xt_recent.conf
ufw reload
iptables -L ufw-before-input -n | grep recent   # теперь должно появиться
Две частые причины «тишины» после grep: (1) модуль xt_recent не был загружен на момент ufw reload — UFW молча отбросил правила; лечится modprobe + повторный reload. (2) система на nftables — правило работает, просто iptables -L его не показывает в привычном виде, смотри через nft list chain.
9

Ссылки для клиентов

Ссылки telemt собирает сам — получаем их из API каждого инстанса. Берём только IPv4-вариант (без server=::).

bash
for p in 9091 9092 9093; do
  curl -s http://127.0.0.1:$p/v1/users \
  | python3 -c "import sys,json; print(json.load(sys.stdin)['data'][0]['links']['tls'][0])"
done
Вывод — готовые tg://proxy?server=IP&port=...&secret=ee.... Отправляешь их клиентам, открываются в один тап. Можно заменить IP на домен если он у тебя указывает на сервер.
10

Управление и обновление

Полезные команды на каждый день:

bash — статистика
# текущие подключения по инстансу
curl -s http://127.0.0.1:9091/v1/users | jq '.data[] | {user:.username, conns:.current_connections, ips:.active_unique_ips}'

# общая сводка (uptime, всего соединений)
curl -s http://127.0.0.1:9091/v1/stats/summary | jq '.data'
bash — обновление telemt
cd /tmp
wget -qO- "https://github.com/telemt/telemt/releases/latest/download/telemt-x86_64-linux-gnu.tar.gz" | tar -xz
systemctl stop telemt1 telemt2 telemt3
mv /tmp/telemt /bin/telemt && chmod +x /bin/telemt
systemctl start telemt1 telemt2 telemt3
/bin/telemt --version
bash — рестарт / логи
systemctl restart telemt1            # перезапуск одного
systemctl restart telemt{1,2,3}      # всех сразу
journalctl -u telemt1 -f             # логи в реальном времени
После правки конфига делай systemctl restart telemtN. Учти: активные клиенты переподключатся не сразу — возможно придётся переоткрыть Telegram. Ссылки при этом не меняются (если не трогал секрет/порт/домен).