Telegram с B4
B4 может сохранять работу Telegram в сети с цензурой двумя способами. Они независимы и могут работать одновременно:
- MTProto прокси-сервер - клиент добавляет B4 как MTProto-прокси в самом приложении Telegram (по секрету). Подходит, когда устройство должно подключаться к B4, например телефон в сотовой сети достучивается до домашнего B4.
- Telegram через WebSocket (прозрачный мост) - режим маршрутизации на уровне сета, который перехватывает трафик Telegram от устройств в локальной сети и ретранслирует его за них. Без прокси в приложении и без секрета. Подходит, чтобы починить Telegram сразу для всех устройств за B4.
Оба способа опираются на одни и те же настройки Транспорт к Telegram (как сам B4 достигает дата-центров Telegram), поэтому этот раздел описан один раз и относится к любому из режимов.
| Параметр | Прокси-сервер | WebSocket-мост |
|---|---|---|
| Где настраивается | Settings → MTProto | Режим маршрутизации сета |
| Настройка на устройстве | Добавить прокси и секрет в Telegram | Не нужна (прозрачно) |
| Для чего | Одно устройство достучивается до B4 (в т.ч. удалённо/домой) | Все устройства локальной сети сразу |
| Нужен включённый MTProto | Да | Нет (независим) |
Транспорт к Telegram (общий)
Settings → MTProto Proxy → Telegram upstream. Определяет, как B4 достигает дата-центров Telegram. Используется и прокси-сервером, и режимом WebSocket-моста, поэтому действует даже когда прокси-сервер выключен.
Режим транспорта
- Прямой TCP - самый быстрый. Подходит, если хост с B4 может напрямую достучаться до
149.154.0.0/16(например, VPS за границей). - Авто (WebSocket → TCP) - сначала WebSocket через
kws*.web.telegram.org, при неудаче - прямой TCP. Рекомендуется для сетей с цензурой. - Только WebSocket - жёсткий WebSocket-транспорт, без TCP-резерва.
Выбор режима транспорта касается только прокси-сервера. Режим маршрутизации WebSocket-мост всегда использует Авто (сначала WebSocket, затем TCP).
Домен Cloudflare Worker (рекомендуемый резерв)
Домен Cloudflare Worker - это бесплатный персональный WebSocket-релей, который вы разворачиваете на собственном аккаунте Cloudflare (*.workers.dev). Через него B4 достаёт любой дата-центр, поэтому он выручает те DC, до которых из вашей сети не дотягивается общий пул. Пробуется он последним среди WebSocket-маршрутов - после родного узла Telegram и после общего пула CF, - потому что Cloudflare забирает stateless-воркер посреди сессии: замерено из цензурируемой сети до DC 1, воркер ответил на 8 раундов рукопожатия и замолчал на 8.7 секунде, а домен из пула ответил на 100 раундов за две минуты на той же машине. Этого хватает, чтобы пройти проверку соединения, и совершенно не хватает на видео, так что впереди пула он выигрывал бы дозвон и уносил сессию с собой.
Коротко о настройке:
- Заведите бесплатный аккаунт Cloudflare.
- В Compute → Workers & Pages создайте Worker из шаблона по умолчанию и задеплойте его.
- Замените код воркера на скрипт прокси и задеплойте снова.
- Скопируйте домен воркера вида
name-1234.username.workers.devв поле домен Cloudflare Worker. Несколько воркеров указывайте через запятую.
Убедитесь, что cloudflare.com, cloudflare.dev и workers.dev доступны (не заблокированы) в вашей сети.
Подробная пошаговая инструкция со скриншотами поддерживается проектом tg-ws-proxy: CfWorker.md. B4 просит у воркера только адрес дата-центра, никогда порт: Telegram отдаёт один и тот же узел на 80, 443 и 5222, слушают везде именно 443, а DC 203 на 5222 не отвечает вовсе. Развёрнутый по той странице воркер работает и так, но скрипт ниже ретранслирует дольше, прежде чем Cloudflare его заберёт - об этом ниже.
Поставьте воркеру compatibility date 2026-04-07 или новее. С этой даты рантайм сам отвечает на закрывающий кадр, а это задокументированная причина ошибки The Workers runtime canceled this request because it detected that your Worker's code had hung.
От скрипта tg-ws-proxy отличий два, и оба про то, сколько Cloudflare позволяет релею прожить:
- Цикл, который несёт данные от Telegram обратно в браузер, передаётся в
ctx.waitUntil(). Промис, который не ждут, не возвращают и не отдают вwaitUntil, - висячий, и рантайм вправе отменить его в тот же момент, когда обработчик вернул ответ, а этот воркер возвращает его сразу после принятия WebSocket. Замерено на живом воркере под нагрузкой: 47 сессий из 58 отменены, половина - быстрее 400 мс, и Telegram оставался с половиной фотографии. - У
socket.closedи уclosedчитателя и писателя появляется пустойcatch. Их никто не ждёт, поэтому когда Cloudflare забирает сокет, каждый всплывает необработанным отказом - три на сессию в логе воркера, и за ними не видно ничего настоящего.
Хорошим местом для долгой сессии stateless-воркер от этого не становится. waitUntil по документации продлевает выполнение примерно на 30 секунд, а сессия Telegram живёт минутами, так что большая загрузка всё ещё может оборваться. Ответ Cloudflare для соединения, которое должно пережить запрос, - Durable Object с гибернацией WebSocket. Считайте воркер одним маршрутом из нескольких, а не единственным: B4 держит за ним родной узел Telegram и общий пул Cloudflare как раз поэтому.
import { connect } from "cloudflare:sockets";
function toBytes(data) {
if (data instanceof ArrayBuffer) {
return new Uint8Array(data);
}
if (typeof data === "string") {
return new TextEncoder().encode(data);
}
if (data && typeof data.arrayBuffer === "function") {
return data.arrayBuffer().then((ab) => new Uint8Array(ab));
}
return new Uint8Array();
}
const ignore = () => {};
export default {
async fetch(request, env, ctx) {
if ((request.headers.get("Upgrade") || "").toLowerCase() !== "websocket") {
return new Response("Expected websocket", { status: 426 });
}
const url = new URL(request.url);
if (url.pathname !== "/apiws") {
return new Response("Not found", { status: 404 });
}
const dst = url.searchParams.get("dst");
const pair = new WebSocketPair();
const client = pair[0];
const server = pair[1];
server.accept();
const socket = connect({ hostname: dst, port: 443 });
const tcpReader = socket.readable.getReader();
const tcpWriter = socket.writable.getWriter();
socket.closed.catch(ignore);
tcpReader.closed.catch(ignore);
tcpWriter.closed.catch(ignore);
server.addEventListener("message", async (event) => {
try {
await tcpWriter.write(await toBytes(event.data));
} catch {
try {
server.close(1011, "tcp write failed");
} catch {}
}
});
server.addEventListener("close", async () => {
try {
await tcpWriter.close();
} catch {}
try {
socket.close();
} catch {}
});
const pump = (async () => {
try {
while (true) {
const { value, done } = await tcpReader.read();
if (done) {
break;
}
if (value) {
server.send(value);
}
}
} catch {
} finally {
try {
server.close();
} catch {}
try {
tcpReader.releaseLock();
} catch {}
try {
socket.close();
} catch {}
}
})();
ctx.waitUntil(pump);
return new Response(null, { status: 101, webSocket: client });
},
};
Worker - это резерв, а не основная дорога. Замерено на бесплатном Worker из цензурируемой сети: один WebSocket переносил порядка 13-17 КБ, после чего переставал передавать данные и держал соединение открытым в тишине, тогда как родной WebSocket-узел Telegram по тому же каналу переносил мегабайт. B4 замечает замолчавший посреди сессии Worker и на десять минут ставит его ниже остальных маршрутов, но дата-центру без родного узла (1, 3 и 5) деваться некуда - поэтому там и важен прямой маршрут.
Резерв через CF-прокси
Ротируемый пул проксированных через Cloudflare доменов, который используется как резерв, когда родной узел Telegram не может достучаться до дата-центра (особенно DC 1, нужного для медиа во внешних каналах). Пул обновляется раз в час.
Проверка
- Проверить соединение пробует достучаться до DC 2 настроенным транспортом (или транспортами) и измеряет задержку.
- Проверить прямой TCP пробует DC 2 по прямому TCP, минуя DC Relay, чтобы понять, в чём проблема - в реле или в самом Telegram.
Вариант 1: MTProto прокси-сервер
Telegram-прокси, к которому клиенты подключаются по секрету. B4 маскирует трафик под обычное HTTPS-соединение к популярному сайту.

Шаг 1: Настройка B4
В веб-интерфейсе B4 → Settings → MTProto Proxy:
- Enable MTProto Proxy - включить
- Port - порт для подключений (рекомендуется
443) - Fake SNI Domain - домен для маскировки (например
storage.googleapis.com) - Нажать Generate Secret
- Скопировать значение из поля Secret
- Сохранить настройки и перезапустить B4
Режим Транспорт к Telegram (см. выше) выбирается по тому, где работает B4:
- B4 на VPS за границей - Прямой TCP. B4 достигает Telegram напрямую; поле DC Relay оставить пустым.
- B4 на роутере внутри России - Авто (WebSocket → TCP). B4 достигает Telegram через WebSocket-узел, и VPS-реле не требуется. Если WebSocket в вашей сети тоже заблокирован, используйте DC Relay (ниже).
Шаг 2: Настройка Telegram
- Открыть Telegram → Настройки → Данные и память → Прокси
- Нажать Добавить прокси
- Выбрать тип MTProto
- Заполнить:
- Сервер: IP-адрес или домен B4 (локальный IP для устройств в сети; публичный IP или DDNS для удалённого доступа, с пробросом портов)
- Порт: порт из шага 1
- Секрет: скопированный секрет
- Нажать Готово и включить прокси

Можно также воспользоваться кнопкой Share connection link, чтобы сгенерировать ссылку tg://proxy или QR-код для другого устройства.
Вариант 2: Telegram через WebSocket (прозрачный мост)
Режим маршрутизации на уровне сета, который чинит Telegram для всех устройств за B4 - без прокси в приложении и без VPS. Когда устройство подключается к дата-центру Telegram, B4 прозрачно перехватывает сессию и ретранслирует её через WebSocket-узел Telegram (с запасным вариантом через Cloudflare).
Этот режим работает самостоятельно. MTProto прокси-сервер в разделе Settings → MTProto включать не требуется.
Настройка
- Создайте или откройте сет и задайте ему цели
telegramв категориях geosite и geoip (чтобы сет совпадал и с доменами, и с диапазонами IP Telegram). - На вкладке Routing сета включите маршрутизацию и выберите Режим маршрутизации → Telegram через WebSocket (встроенный).
- Выберите source-интерфейсы (интерфейсы локальной сети, чьи устройства нужно переправлять). Если не выбрать ни одного, под мост попадают все устройства.
- Сохраните.
Минимальный сет для этого режима:
{
"name": "telegram-ws",
"targets": {
"geosite_categories": ["telegram"],
"geoip_categories": ["telegram"]
},
"enabled": true,
"routing": { "enabled": true, "mode": "mtproto-ws" }
}
Здесь действуют общие настройки Транспорт к Telegram (Settings → MTProto), поэтому при проблемах с загрузкой медиа укажите там домен Cloudflare Worker.
Переправляются только TCP MTProto-сессии. Голосовые звонки и транспорты, для которых B4 не может определить дата-центр, идут напрямую (fail-open).
DC Relay (VPS + socat)
DC Relay нужен только когда B4 работает внутри цензурированной зоны и WebSocket-транспорт тоже заблокирован, так что прямые соединения к Telegram по IP приходится пускать через VPS.
Телефон ──────▶ B4 (роутер) ──────▶ VPS ──────▶ Telegram
ТСПУ видит ТСПУ видит
«HTTPS к google.com» «трафик к VPS»
(не блокирует) (не блокирует)
На VPS достаточно простой пересылки TCP (socat) - без ключей и MTProto-специфичного ПО.
Шаг 1: Установка socat на VPS
apt install -y socat
Шаг 2: Указать адрес DC Relay
В Settings → MTProto Proxy укажите в поле DC Relay адрес VPS с базовым портом (например my-vps.com:7007). Поле появляется, когда режим транспорта - Прямой TCP или Авто.
При Авто с настроенным DC Relay сначала пробуется реле по TCP, а WebSocket используется как резерв.
Шаг 3: Получить команды socat
Нажать кнопку ? рядом с полем DC Relay. Откроется окно «Настройка socat для DC Relay» со списком серверов Telegram и готовыми командами socat для каждого DC.

Нажать Копировать всё, перейти на VPS и выполнить вставленные команды.
Каждый socat пересылает порт relay на публичный адрес дата-центра, к которому B4 подключается напрямую (базовый_порт + DC - 1 → адрес DC на :443). Медиа-DC 203 использует порт DC 2, поэтому отдельная команда для него не нужна.
Открыть на VPS все порты, которые показывает помощник (строка «Откройте эти порты в firewall VPS» внизу окна). Это 5 портов, по одному на каждый основной DC (1-5).
Для автозапуска socat добавить команды в /etc/rc.local или создать systemd-сервис.
IPv4 или IPv6
В окне есть переключатель Версия адресов - он задаёт, к каким адресам Telegram подключаются сгенерированные команды. Пригодится, когда VPS достаёт Telegram по IPv6, но не по IPv4.
Переключатель меняет только исходящую сторону команды:
# IPv4
socat TCP-LISTEN:7007,fork,reuseaddr TCP:149.154.175.50:443 &
# IPv6
socat TCP-LISTEN:7007,fork,reuseaddr TCP6:[2001:b28:f23d:f001::a]:443 &
Сторона прослушивания зависит не от него, а от адреса в поле DC Relay. Если это литерал IPv6, записывайте его в квадратных скобках ([2001:db8::1]:7007) - тогда помощник выдаёт TCP6-LISTEN, и VPS принимает соединение от B4 тоже по IPv6.
Стороны независимы: адрес relay по IPv4 вместе с исходящими подключениями по IPv6 - рабочее и распространённое сочетание.
Адреса дата-центров по IPv6 встроены в B4. Кнопка Обновить их не меняет, так как в публичном proxy config Telegram перечислены только адреса IPv4.
У медиа-DC 203 адреса IPv6 нет, и он использует порт relay для DC 2, поэтому медиа-трафик идёт туда, куда указывает команда DC 2. Если после переключения на IPv6 медиа перестало загружаться, верните на IPv4 только эту команду, остальные оставьте на IPv6.
Выбор домена для маскировки
Домен должен быть:
- популярным в России
- незаблокированным
- критически важным (блокировка такого домена нарушит работу других сервисов)
При подключении к порту B4 без правильного секрета - B4 прозрачно перенаправляет на настоящий сайт (указанный в Fake SNI). Сканер видит обычный сайт, а не прокси.
Устранение неполадок
Telegram показывает «Подключение…»
- Если используется WebSocket-транспорт, нажмите Проверить соединение, чтобы убедиться, что B4 достаёт DC.
- Если используется DC Relay, убедитесь, что
socatзапущен на VPS и порты доступны, и проверьте адрес VPS. - В логах B4 должны быть строки
MTProto fake-TLS handshake OKиMTProto relay.
Не загружаются медиа, стикеры или реакции
- Укажите домен Cloudflare Worker в настройках «Транспорт к Telegram». Обычно виноват DC 1 (медиа во внешних каналах), и резерв через CF Worker / CF-прокси его вытягивает.
Неправильный секрет
В логах: HMAC verification failed. Секрет в Telegram не совпадает с секретом в B4.
Расхождение времени
В логах: timestamp out of range. Часы на устройстве и на машине с B4 расходятся. Необходимо синхронизировать время (NTP).
VPS недоступен (DC Relay)
В логах: dial DC ... i/o timeout.
- VPS выключен или
socatне запущен - Firewall на VPS блокирует входящие соединения на нужных портах
Нет ответа от Telegram
В логах: DC->client: 0 bytes.
- Прямой TCP и без реле: серверы Telegram заблокированы по IP. Переключите транспорт на Авто/WebSocket или настройте DC Relay.
- DC Relay настроен:
socatна VPS не запущен или указан неправильный порт.
Благодарности
WebSocket-транспорт и релей через Cloudflare Worker вдохновлены проектом tg-ws-proxy.