Teleproxy в Docker за 5 минут

В предыдущей статье мы ставили MTProxy из RPM — это самый быстрый путь на RHEL-семействе. Но если сервер уже работает на Docker или дистрибутив не из RPM-мира, удобнее запустить прокси в контейнере. Для этого есть Teleproxy — продолжение того же форка MTProxy с собственным официальным образом.

Teleproxy и MTProxy: что общего

Teleproxy — это переименованный и развитый дальше форк MTProxy от того же мейнтейнера. Совместимость по протоколу полная: те же ссылки tg://proxy?..., те же режимы (DD, EE/Fake-TLS, Direct-to-DC), но контейнерная сборка, Prometheus-метрики, динамический размер TLS-записей и встроенное E2E-тестирование против реальных серверов Telegram.

Для Docker-сценария важно одно: образ собирается из текущего кода Teleproxy и публикуется на GitHub Container Registry.

Зачем Docker, а не RPM

RPM выигрывает на классических CentOS/RHEL-серверах: systemd-юнит, cron-обновления конфигурации, обновление через yum update. Docker уместен в других случаях:

  • Дистрибутив не из RPM-мира (Debian, Ubuntu, Alpine)
  • Сервер уже работает под управлением Docker Compose, Portainer или Swarm
  • Нужно быстро поднять прокси на VPS «на час» без правки системных файлов
  • Хочется изолировать процесс от хоста

Образ ghcr.io/teleproxy/teleproxy

Образ собирается на основе Alpine 3.21 в multi-stage сборке и весит около 8 МБ — примерно в семь раз меньше типичных Docker-образов MTProto-прокси. Поддерживаются amd64 и arm64.

Скачать вручную:

docker pull ghcr.io/teleproxy/teleproxy:latest

Никакой регистрации или авторизации в ghcr не требуется — образ публичный.

Быстрый старт через docker run

Сгенерировать секрет и запустить контейнер:

SECRET=$(head -c 16 /dev/urandom | xxd -ps)
echo "Secret: $SECRET"

docker run -d \
  --name teleproxy \
  --restart unless-stopped \
  -p 443:443 \
  -p 8888:8888 \
  -e SECRET=$SECRET \
  -e PORT=443 \
  -e STATS_PORT=8888 \
  -e WORKERS=1 \
  ghcr.io/teleproxy/teleproxy:latest

Этого достаточно, чтобы прокси заработал в обычном DD-режиме. Порт 443 выбран не случайно: он почти всегда открыт у клиентов и реже фильтруется по номеру.

Проверка, что контейнер слушает порт:

ss -tlnp | grep -E '443|8888'
docker logs teleproxy --tail 20

Конфигурация через docker-compose

Для постоянного развёртывания удобнее compose-файл. Минимальный docker-compose.yml:

version: '3.8'

services:
  teleproxy:
    image: ghcr.io/teleproxy/teleproxy:latest
    ports:
      - "443:443"
      - "8888:8888"
    ulimits:
      nofile:
        soft: 65536
        hard: 65536
    environment:
      - SECRET=${SECRET}
      - PORT=443
      - STATS_PORT=8888
      - WORKERS=1
      - PROXY_TAG=${PROXY_TAG:-}
      - RANDOM_PADDING=${RANDOM_PADDING:-false}
      - EE_DOMAIN=${EE_DOMAIN:-}
    volumes:
      - ./data:/opt/teleproxy/data
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:${STATS_PORT:-8888}/stats || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s

Секрет лучше держать в файле .env рядом с compose-файлом:

echo "SECRET=$(head -c 16 /dev/urandom | xxd -ps)" > .env
docker compose up -d

Переменные окружения

ПеременнаяНазначение
SECRETСекретный ключ (32 hex-символа). Можно указать несколько через запятую
PORTПорт для клиентских подключений
STATS_PORTПорт статистики и Prometheus-метрик (наружу не публиковать)
WORKERSКоличество воркеров. На одно-двухъядерных VPS оставлять 1
PROXY_TAGТег от @MTProxybot для продвижения канала
RANDOM_PADDINGВключает дополнительный паддинг против анализа размеров пакетов
EE_DOMAINДомен для маскировки Fake-TLS. Например, www.google.com
IP_BLOCKLISTПуть внутри контейнера к CIDR-блоклисту
IP_ALLOWLISTПуть внутри контейнера к CIDR-вайтлисту

Для включения Fake-TLS достаточно задать EE_DOMAIN — режим EE активируется автоматически, и весь трафик начинает выглядеть как обычный HTTPS к указанному домену.

Healthcheck и логи

Compose-файл уже содержит healthcheck, который раз в 30 секунд дёргает /stats внутри контейнера. Статус виден через:

docker compose ps
docker inspect --format='{{.State.Health.Status}}' teleproxy

Логи прокси выводятся в stdout контейнера:

docker compose logs -f teleproxy

Каталог ./data смонтирован в /opt/teleproxy/data и хранит автоматически обновляемые файлы конфигурации серверов Telegram. Удалять его между перезапусками не нужно — иначе при каждом старте придётся заново скачивать proxy-multi.conf.

Файрвол

Снаружи должен быть открыт только клиентский порт. Для firewalld:

sudo firewall-cmd --permanent --add-port=443/tcp
sudo firewall-cmd --reload

Для iptables:

sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT

Порт статистики (8888) наружу публиковать не следует — он нужен только для локального healthcheck и сборщика метрик. В compose-файле выше он биндится на все интерфейсы для простоты; в продакшене лучше заменить "8888:8888" на "127.0.0.1:8888:8888".

Ссылка для подключения

Формат тот же, что и для RPM-сборки:

tg://proxy?server=IP_СЕРВЕРА&port=443&secret=ddSECRET_HEX

Префикс dd обязателен — он указывает Telegram-клиенту, что нужно использовать обфускацию случайным паддингом. Для EE/Fake-TLS префикс отличается: ee + secret + hex от домена. Удобнее не собирать ссылку вручную, а воспользоваться /stats-эндпоинтом или сгенерировать её через любой публичный конструктор ссылок MTProxy.

Альтернативный формат для браузера: https://t.me/proxy?server=...&port=...&secret=... — оба открывают настройки прокси в Telegram одним кликом.

Что дальше

В следующих статьях разберём отдельно режим Fake-TLS (как выбрать домен и подружить с TLS-фингерпринтом), Direct-to-DC без relay-серверов и подключение Prometheus к встроенному эндпоинту /stats для мониторинга подключений.