Полный гайд: ставим telemt (Rust MTProxy) на чистый Ubuntu, поднимаем несколько инстансов на разных портах, настраиваем systemd, открываем порты и вешаем защиту от DPI на UFW. С генерацией секретов и проверкой.
telemt — реализация Telegram MTProxy на Rust. Главное преимущество перед классическим MTG: настоящий TLS-фронтинг — прокси реально подтягивает сертификат маскировочного домена (apple.com, cloudflare.com и т.п.) и эмулирует его, а не подделывает. Снаружи трафик выглядит как обычный визит на популярный сайт.
| Слой защиты | Против чего работает |
|---|---|
| TLS-фронтинг | детекция по TLS-хендшейку |
| client_mss | анализ размера TCP-сегментов (DPI ТСПУ) |
| UFW rate-limit | активное зондирование прокси |
Это не дублирование «на всякий случай» — каждый инстанс намеренно сопоставляет порт + маскировочный домен так, чтобы трафик сливался с реальным, повседневным трафиком ОС и сервисов. DPI видит не «подозрительное соединение на странный порт», а то что и так постоянно ходит с любого телефона и компьютера.
| Порт | Домен (SNI) | Подо что маскируется |
|---|---|---|
| 443 | www.cloudflare.com | обычный HTTPS / CDN |
| 5223 | www.apple.com | Apple Push Notification Service |
| 8530 | www.microsoft.com | Windows Update / WSUS |
apple.com в этом потоке неотличим — для DPI это просто «ещё один айфон, который держит связь с Apple».
Аналогично остальные пары подобраны под фоновый трафик, который есть у всех и который странно блокировать:
Зачем именно три, а не один:
Обновляем пакеты, ставим зависимости (нужны для скачивания, JSON-обработки и фаервола).
apt update apt install -y wget tar jq ufw python3 iptables
Создаём отдельного системного пользователя telemt (без shell, без логина) и рабочие директории — так демон не работает под root:
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
Скачиваем последний релиз telemt с GitHub, кладём в /bin/telemt.
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. Если так — бинарник на месте.Секрет MTProxy — это 16 байт = 32 hex-символа. На каждый инстанс нужен свой. Генерируем три штуки:
# 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.Создаём 3 конфига одной python-командой. Подставь свои секреты из шага 4 в блок configs. Порты и домены можно оставить или поменять.
cat << EOF склеивает строки и обрывается. python пишет файлы надёжно.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) |
Создаём по сервису на каждый инстанс — с автозапуском, перезапуском при падении и нужными капабилити (для bind на привилегированные порты вроде 443).
генерирует /etc/systemd/system/telemt{1,2,3}.servicepython3 << '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
Сначала базовые правила фаервола — обязательно разреши SSH до включения UFW, иначе отрежешь себе доступ.
22 на свой SSH-порт если он нестандартный. Проверь что строка SSH есть, прежде чем делать ufw enable.# 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 на каждый порт. Это отбивает активное зондирование РКН. Модуль ядра + закрепление после ребута + бэкап:
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
lsmod | grep xt_recent ничего не вывел — модуль не загружен, и UFW при reload молча выбросит правила с -m recent (не подтянутся, grep покажет пустоту). Сначала добейся чтобы modprobe xt_recent прошёл без ошибок и lsmod показал модуль, и только потом делай ufw reload.Вставка правил в /etc/ufw/before.rules (в цепочку ufw-before-input, после established). Каждому порту — свой список, иначе переключение между прокси в Telegram будет рвать соединение.
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
mtp443, mtp5223...) это решают.Включаем автозапуск, стартуем все инстансы:
systemctl enable telemt1 telemt2 telemt3 systemctl start telemt1 telemt2 telemt3 sleep 3 systemctl is-active telemt1 telemt2 telemt3
Проверяем что всё на месте — порты слушаются, фаервол с правилами, TLS-серты подтянулись:
# порты прокси 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 тихо выбросил правила. Диагностика:
# 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 # теперь должно появиться
xt_recent не был загружен на момент ufw reload — UFW молча отбросил правила; лечится modprobe + повторный reload. (2) система на nftables — правило работает, просто iptables -L его не показывает в привычном виде, смотри через nft list chain.Ссылки telemt собирает сам — получаем их из API каждого инстанса. Берём только IPv4-вариант (без server=::).
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 на домен если он у тебя указывает на сервер.Полезные команды на каждый день:
# текущие подключения по инстансу 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'
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
systemctl restart telemt1 # перезапуск одного systemctl restart telemt{1,2,3} # всех сразу journalctl -u telemt1 -f # логи в реальном времени
systemctl restart telemtN. Учти: активные клиенты переподключатся не сразу — возможно придётся переоткрыть Telegram. Ссылки при этом не меняются (если не трогал секрет/порт/домен).