1. Зачем свой прокси
Публичные MTProto-прокси из интернета — удобны, но непредсказуемы: они падают без предупреждения, перегружаются, а иногда собирают метаданные. Собственный прокси на VPS лишён этих проблем:
🔒 Приватность
Только вы контролируете сервер. Никаких третьих сторон, никакой телеметрии.
⚡ Скорость
Публичные прокси перегружены. Ваш — только для вас и тех, кому вы дали ссылку.
🛡️ Надёжность
Не исчезнет завтра. Работает, пока работает ваш VPS.
👥 Для всей семьи
Поделитесь ссылкой с друзьями — прокси выдержит сотни пользователей.
2. Как работает mtg и FakeTLS
mtg (github.com/9seconds/mtg) — неофициальная реализация MTProto-прокси на Go от независимого разработчика. Официальный прокси Telegram (TelegramMessenger/MTProxy) написан на C — он тоже поддерживает FakeTLS, но развивается значительно медленнее (единственный релиз v1 в 2018, последние коммиты — ноябрь 2025). mtg написан на Go, активно обновляется и де-факто стал стандартом для самостоятельного развёртывания MTProto-прокси.
Поддерживает режим FakeTLS: при подключении клиент и прокси имитируют TLS-хендшейк с SNI-именем легитимного сайта (например, google.com). Для большинства DPI по сигнатурам протокола соединение выглядит как обычный HTTPS к google.com. Продвинутые системы (ТСПУ, корпоративные NGFW) могут детектировать FakeTLS по JA3-отпечатку и статистике трафика — 100% «невидимости» FakeTLS не даёт (см. раздел 11).
Секрет — строка, которая авторизует клиентов и содержит имя домена для маскировки. Секрет в формате ee... (начинается с ee) — это FakeTLS-режим. Простой hex-секрет (без ee) — обычный MTProto без маскировки, хуже проходит DPI.
Выбор домена для маскировки
Домен в секрете — только имя хоста для TLS-хендшейка, реального соединения с ним нет. Используйте крупные популярные сайты: google.com, cloudflare.com, microsoft.com. Их TLS-трафик точно не блокируется ни одним провайдером.
3. Требования
| Параметр | Минимум | Примечание |
|---|---|---|
| ОС | Ubuntu 22.04 / 20.04 | Или любой Debian-based |
| CPU / RAM | 1 vCPU / 512 МБ | mtg: ~20–50 МБ idle, до 100–150 МБ под нагрузкой |
| Трафик | 100 ГБ/мес | При 50 активных пользователях |
| Порт | 443 (рекомендуется) | Или любой другой открытый порт |
| Расположение VPS | За пределами РФ | Нидерланды, Германия, Финляндия |
| Docker или wget/curl | Docker — для способа 1 | wget/curl — для способа 2 (бинарник) |
Конфликт порта 443 с Nginx
Если на VPS уже работает Nginx или Apache на порту 443 — используйте порт 8443 вместо 443. Он тоже хорошо проходит через корпоративные сети и редко блокируется. Всё что описано ниже — просто замените 443 на 8443.
4. Способ 1: Docker (рекомендуется)
Docker-способ проще всего: не нужно следить за версиями, обновления делаются одной командой. Используем образ от автора mtg: nineseconds/mtg:2.
Перед началом: проверьте что порт 443 свободен
sudo ss -tlnp | grep ':443 'Если вывод пустой — порт свободен, продолжайте. Если что-то слушает (Nginx, Apache, Caddy и т. п.) — используйте порт 8443 вместо 443 во всех командах ниже, иначе контейнер уйдёт в перезапуск с ошибкой address already in use.
Шаг 1: установить Docker
curl -fsSL https://get.docker.com | sudo shПроверьте что Docker работает:
docker --versionШаг 2: сгенерировать секрет
Секрет — ваш «пароль» прокси. Команда ниже генерирует FakeTLS-секрет с маскировкой под google.com. Запустите один раз и сохраните вывод.
docker run --rm nineseconds/mtg:2 generate-secret --hex google.comВывод будет одной строкой, примерно такой (ваш секрет будет другим):
ee4a7b3f1c8d2e9a5f6c0b4d8e1a3f7b2c676f6f676c652e636f6dСекрет начинается с ee — признак FakeTLS-режима. Последние символы (676f6f676c652e636f6d) — hex-кодировка домена google.com. Итого ~54 символа.
Шаг 3: создать конфигурацию
Создайте директорию и файл конфига одной командой. Замените ВАШ_СЕКРЕТна значение из шага 2:
sudo mkdir -p /etc/mtg
sudo tee /etc/mtg/config.toml << 'EOF'
secret = "ВАШ_СЕКРЕТ"
bind-to = "0.0.0.0:443"
EOFШаг 4: запустить контейнер
docker run -d --name mtg --restart unless-stopped -v /etc/mtg/config.toml:/config.toml -p 443:443 nineseconds/mtg:2Убедитесь что контейнер запустился:
docker ps --filter name=mtg
docker logs mtgВ колонке STATUS должно быть Up N seconds. Если в статусе Restarting — смотрите логи: чаще всего проблема в занятом порту или неправильном формате секрета.
Флаг --restart unless-stopped
Контейнер автоматически перезапустится после перезагрузки VPS и при падении. Флаг unless-stopped отличается от always тем, что не запускается, если вы вручную остановили контейнер командой docker stop mtg.
5. Способ 2: бинарник + systemd
Если Docker не нужен или не установлен — скачайте готовый бинарник и настройте systemd-сервис. Не нужно ничего компилировать.
Шаг 1: скачать бинарник
VERSION=$(curl -s https://api.github.com/repos/9seconds/mtg/releases/latest | grep tag_name | cut -d'"' -f4 | sed 's/^v//')
echo "Будет установлена версия: $VERSION"
wget -O /tmp/mtg.tar.gz "https://github.com/9seconds/mtg/releases/download/v${VERSION}/mtg-${VERSION}-linux-amd64.tar.gz"
tar -xf /tmp/mtg.tar.gz -C /tmp
sudo install -m 755 /tmp/mtg-${VERSION}-linux-amd64/mtg /usr/local/bin/mtg
rm -rf /tmp/mtg.tar.gz /tmp/mtg-${VERSION}-linux-amd64mtg --versionШаг 2: сгенерировать секрет
mtg generate-secret --hex google.comШаг 3: создать конфиг
sudo mkdir -p /etc/mtg
sudo tee /etc/mtg/config.toml << 'EOF'
secret = "ВАШ_СЕКРЕТ"
bind-to = "0.0.0.0:443"
EOFШаг 4: создать systemd-сервис
sudo tee /etc/systemd/system/mtg.service << 'EOF'
[Unit]
Description=MTG MTProto Proxy
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/mtg run /etc/mtg/config.toml
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOFsudo systemctl daemon-reload
sudo systemctl enable --now mtgsudo systemctl status mtgВ выводе должно быть Active: active (running).
LimitNOFILE
Параметр LimitNOFILE=65536 увеличивает лимит открытых файловых дескрипторов. Каждое соединение потребляет 2 дескриптора (клиент ↔ mtg и mtg ↔ Telegram). Без этого параметра при 500+ пользователях могут возникнуть ошибки «too many open files».
6. Спонсорский канал (adtag)
Telegram позволяет операторам MTProto-прокси привязать спонсорский канал: пользователи, подключённые через прокси, видят продвигаемый канал с меткой «Прокси-спонсор». Управляется через бот @MTProxybot.
mtg v2 не поддерживает adtag
Функция adtag есть только в официальной C-реализации Telegram — TelegramMessenger/MTProxy. В mtg v2 её нет: параметра в конфиге не существует. Если спонсорский канал нужен — придётся использовать официальный MTProxy вместо mtg.
Официальный MTProxy с adtag
Официальный MTProxy написан на C. Единственный релиз v1 от 2018 года, коммиты после этого нечастые (последние правки — ноябрь 2025, поддержка минимальная). Тег :latest на Docker Hub не обновлялся с 2020 года — используйте только тег :2.0beta, это актуальная сборка (2026). Образ telegrammessenger/proxy генерирует простой 16-байтовый секрет, без FakeTLS-маскировки. Для FakeTLS секрет придётся сформировать вручную (см. ниже).
Шаг 1. Сформируйте FakeTLS-секрет и сразу запустите контейнер с ним. Переменная $SECRET будет содержать ee + 16 случайных байт + hex-кодировку домена. Используются только базовые утилиты (openssl, od), они есть на любой Ubuntu без доустановки.
SECRET="ee$(openssl rand -hex 16)$(printf 'google.com' | od -An -tx1 | tr -d ' \n')"
echo "Ваш FakeTLS-секрет: $SECRET"
docker run -d \
--name mtproxy \
--restart unless-stopped \
-p 443:443 \
-e SECRET="$SECRET" \
telegrammessenger/proxy:2.0beta
docker logs mtproxyСохраните значение секрета из вывода echo — оно понадобится в шаге 2 для регистрации и в шаге 3 при перезапуске контейнера.
Шаг 2. Зарегистрируйте прокси в @MTProxybot, чтобы получить TAG. Бот ведёт диалог пошагово:
- В диалоге с @MTProxybot отправьте
/newproxy - Бот запросит адрес — отправьте
IP_VPS:443 - Бот запросит секрет — отправьте тот же
ee...-секрет из шага 1 - Бот выдаст TAG (32 hex-символа) — это ваш adtag
Шаг 3. Перезапустите контейнер с TAG (замените ВАШ_EE_СЕКРЕТ и ВАШ_TAG на полученные значения):
docker stop mtproxy && docker rm mtproxy
docker run -d \
--name mtproxy \
--restart unless-stopped \
-p 443:443 \
-e SECRET=ВАШ_EE_СЕКРЕТ \
-e TAG=ВАШ_TAG_ИЗ_MTPROXYBOT \
telegrammessenger/proxy:2.0betaСравнение: mtg vs официальный MTProxy
| Параметр | mtg v2 | Официальный MTProxy |
|---|---|---|
| FakeTLS | ✅ из коробки | ⚠️ только с ручным ee-секретом |
| Adtag (спонсор) | ❌ нет | ✅ есть |
| Язык / поддержка | Go, активные релизы | C, v1 2018, поддержка минимальная |
| Установка | Просто (Docker или бинарник) | Просто (только Docker) |
7. Настройка UFW
Если на сервере включён фаервол UFW — откройте порт прокси. Если UFW не используется, пропустите этот шаг.
sudo ufw allow 443/tcp
sudo ufw statusЕсли используете порт 8443 вместо 443 — замените в команде выше.
Что делать с UFW в зависимости от способа установки
- Docker-способ: правило UFW не обязательно (Docker сам пробрасывает порт через iptables в обход UFW), но лучше добавить — для единообразия и документирования открытых портов.
- Бинарник + systemd: правило UFW обязательно, иначе 443 снаружи будет закрыт.
Важно: UFW работает внутриVPS. Если ваш провайдер использует отдельный сетевой firewall на уровне панели (Hetzner, Selectel, AWS, Vultr и др.) — там порт тоже надо открыть. Подробнее — в разделе «Если не подключается».
8. Ссылка для подключения
mtg умеет автоматически определить внешний IP и сформировать готовую ссылку.
Docker-способ
docker run --rm -v /etc/mtg/config.toml:/config.toml nineseconds/mtg:2 access /config.tomlБинарник-способ
mtg access /etc/mtg/config.tomlВывод — JSON. IP определяется автоматически через внешний сервис. Ищите поле tme_url в блоке ipv4:
{
"ipv4": {
"ip": "1.2.3.4",
"port": 443,
"tg_url": "tg://proxy?server=1.2.3.4&port=443&secret=7iBa...",
"tg_qrcode": "https://api.qrserver.com/...",
"tme_url": "https://t.me/proxy?server=1.2.3.4&port=443&secret=7iBa...",
"tme_qrcode": "https://api.qrserver.com/..."
},
"secret": { "hex": "ee...", "base64": "7iBa..." }
}Скопируйте значение tme_url — ссылка вида https://t.me/proxy?... работает на всех платформах.
Почему секрет в ссылке выглядит иначе
В URL секрет приведён в base64 (7iBa...), а в конфиге mtg — в hex (ee...). Это одно и то же значение в разных кодировках. Telegram принимает оба формата, специально конвертировать ничего не нужно.
Ссылка вручную
Если команда access показала неправильный IP или не сработала — составьте ссылку вручную:
https://t.me/proxy?server=IP_ВАШЕГО_VPS&port=443&secret=ВАШ_СЕКРЕТУзнать внешний IP VPS: curl -4 ifconfig.me
9. Подключение в Telegram
Самый простой способ — перейти по ссылке https://t.me/proxy?... с устройства, где открыт Telegram. Он автоматически откроет приложение с готовым диалогом добавления прокси.
Нажмите на ссылку t.me/proxy?... — Telegram откроется с кнопкой Подключить.
Ввести вручную
Настройки → Данные и память → Настройка прокси → Добавить прокси → MTProto → ввести сервер, порт, секрет.
Откройте ссылку t.me/proxy?... в браузере → Открыть в Telegram → Подключить.
Ввести вручную
Настройки → Данные и хранилище → Прокси → Добавить прокси → MTProto → ввести сервер, порт, секрет.
Откройте ссылку https://t.me/proxy?... в браузере — откроется страница t.me с кнопкой Open in Telegram, после нажатия клиент покажет диалог добавления прокси.
Ввести вручную
Настройки → Продвинутые настройки → Тип соединения → Использовать прокси → Добавить прокси → MTProto → ввести данные.
Проверка что прокси работает
После подключения в настройках прокси Telegram покажет статус «Подключено» и задержку в миллисекундах. Нормальная задержка — 30–150 мс. Если статус «Не удаётся подключиться» — проверьте что порт открыт в UFW и контейнер/сервис запущен.
10. Мониторинг и обновление
Просмотр логов
docker logs -f mtgdocker logs --tail 50 mtgsudo journalctl -u mtg -fsudo journalctl -u mtg --since todayВ логах mtg нет ничего лишнего — только служебные сообщения о запуске и остановке. Это сделано намеренно: логи не должны содержать информацию о пользователях.
Обновление mtg (Docker)
docker pull nineseconds/mtg:2
docker stop mtg
docker rm mtg
docker run -d --name mtg --restart unless-stopped -v /etc/mtg/config.toml:/config.toml -p 443:443 nineseconds/mtg:2Обновление mtg (бинарник)
VERSION=$(curl -s https://api.github.com/repos/9seconds/mtg/releases/latest | grep tag_name | cut -d'"' -f4 | sed 's/^v//')
wget -O /tmp/mtg.tar.gz "https://github.com/9seconds/mtg/releases/download/v${VERSION}/mtg-${VERSION}-linux-amd64.tar.gz"
tar -xf /tmp/mtg.tar.gz -C /tmp
sudo systemctl stop mtg
sudo install -m 755 /tmp/mtg-${VERSION}-linux-amd64/mtg /usr/local/bin/mtg
sudo systemctl start mtg
rm -rf /tmp/mtg.tar.gz /tmp/mtg-${VERSION}-linux-amd6411. Если не подключается
В 90% случаев «прокси не работает» дело не в mtg, а в одной из пяти причин ниже. Проверяйте по порядку.
1. Firewall в панели провайдера
Это причина номер один. У Hetzner Cloud, Selectel, Yandex Cloud, AWS, DigitalOcean, Vultr и многих других есть отдельный сетевой firewall на уровне панели управления — он работает до того, как трафик достигнет UFW внутри ОС. Правило ufw allow 443/tcp на VPS его не открывает. Зайдите в панель провайдера → Firewall / Security Groups / Правила сети → добавьте входящее правило TCP 443 из 0.0.0.0/0.
Проверить доступность порта снаружи (с домашнего компьютера или другого сервера):
nc -zv IP_ВАШЕГО_VPS 443Test-NetConnection -ComputerName IP_ВАШЕГО_VPS -Port 443Успешный вывод nc: Connection to IP 443 port [tcp/*] succeeded!. PowerShell должен показать TcpTestSucceeded : True. Если видите Connection refused / TcpTestSucceeded : False с быстрым ответом — сервис на VPS не запущен. Если Connection timed out / долгое зависание — блокирует firewall (скорее всего в панели провайдера).
2. Блокировка в РФ (TSPU)
Честная оговорка про Россию
С 2024 года «Технические средства противодействия угрозам» (ТСПУ) целенаправленно блокируют MTProto/FakeTLS-трафик к IP-адресам дата-центров за пределами РФ. FakeTLS маскирует трафик, но не маскирует сам IP — и TSPU использует список IP-подсетей популярных хостинг-провайдеров для блокировки.
Что делать: пробовать другой порт (2053, 8443), перевыпустить IP, сменить регион/провайдера на менее «засвеченный». 100% стабильности из РФ никто не гарантирует.
3. Порт 443 уже занят другим сервисом
Если вы пропустили проверку в начале раздела 4 — контейнер уйдёт в перезапуск, systemd-сервис упадёт с bind: address already in use. Проверьте, что слушает порт:
sudo ss -tlnp | grep ':443 'Вариант 1 — остановить конфликтующий сервис.
Вариант 2 — сменить порт mtg на 8443. Отредактируйте конфиг:
sudo sed -i 's|bind-to = "0.0.0.0:443"|bind-to = "0.0.0.0:8443"|' /etc/mtg/config.tomlПересоздайте контейнер с новым пробросом порта (Docker-способ):
docker stop mtg && docker rm mtg
docker run -d \
--name mtg \
--restart unless-stopped \
-v /etc/mtg/config.toml:/config.toml \
-p 8443:8443 \
nineseconds/mtg:2Или перезапустите systemd-сервис (бинарник-способ):
sudo systemctl restart mtgНе забудьте открыть новый порт в firewall VPS и в панели провайдера, а также перегенерировать ссылку подключения (в ней теперь &port=8443).
4. VPS за NAT (серый IP)
У некоторых дешёвых тарифов VPS нет публичного IPv4 — вы получаете только «серый» адрес за NAT провайдера. curl -4 ifconfig.me в таком случае вернёт адрес NAT-шлюза, а порт снаружи не проброшен. Сверьте:
ip -4 addr show | grep inet
curl -4 ifconfig.meЕсли IP на сетевом интерфейсе начинается с 10., 172.16–31. или 192.168., а ifconfig.me показывает другой адрес — у вас NAT. Либо попросите провайдера выдать «белый» IP, либо смените тариф.
5. Telegram-клиент предпочитает IPv6
Актуально редко, но встречается: если у клиента IPv6-сеть и он приоритетно идёт по v6, а bind-to = "0.0.0.0:443" слушает только IPv4 — соединения не будет.
Сначала проверьте, есть ли у вашего VPS публичный IPv6:
ip -6 addr show scope globalЕсли вывод пустой — у сервера нет IPv6, этот пункт не применим. Если есть адреса (не начинающиеся с fe80:) — действуйте по своему способу установки.
Способ 1 (Docker): по умолчанию -p 443:443 пробрасывает порт только на IPv4 (для IPv6-проброса нужен Docker с ip6tables и --enable-ipv6, что редко включено). Плюс mtg внутри контейнера слушает только 0.0.0.0:443. Надёжный способ принять IPv6-клиентов — убрать прослойку Docker через --network host и слушать сразу на обоих стеках:
sudo sed -i 's|bind-to = "0.0.0.0:443"|bind-to = "[::]:443"|' /etc/mtg/config.toml
docker stop mtg && docker rm mtg
docker run -d \
--name mtg \
--restart unless-stopped \
--network host \
-v /etc/mtg/config.toml:/config.toml \
nineseconds/mtg:2--network host отключает сетевую изоляцию контейнера — для MTProto-прокси это безопасно, потому что mtg слушает только заданный порт. Флаг -p с host-network не используется. Перед пересозданием убедитесь, что порт 443 на хосте свободен (sudo ss -tlnp | grep ':443 ').
Способ 2 (бинарник + systemd): меняете конфиг и перезапускаете сервис.
sudo sed -i 's|bind-to = "0.0.0.0:443"|bind-to = "[::]:443"|' /etc/mtg/config.toml
sudo systemctl restart mtgНа Linux сокет [::] по умолчанию принимает и IPv4 тоже (net.ipv6.bindv6only = 0).