В прошедшие выходные меня посетило непреодолимое желание. Желание наконец повысить свой сисадминский скилл. И перестать расстраиваться при отправке фото, а тем более видео в наш любимый мессенжер. Чудесно, что эта реальность так мотивирует к саморазвитию.

Недавно на глаза попалась интересная статья про новый проект TeleMT. И я бы наверно не стал заморачиваться. И тоже настроил бы его за 5 минут. По шагам из статьи. Если бы не пара "но". Во-первых, я болен хроническим неприятием засовывания докера где следует и где не следует. А во-вторых – 443 порт на моем подопытном сервере уже занят предыдущим "экспериментом".

На нестандартный порт вешать второй "эксперимент" мне не хотелось. Покупать второй айпишник или хостинг – тем более. Требовалось сотворить чутка новой дичи магии. О результатах сего докладываю в этой статье. Вдруг кому и пригодится.

Описанный в статье конфиг не претендует на идеальность. Это рабочий пример, который решает мои задачи. Если вы видите, что хорошо бы поправить – welcome в комменты.

Что мы хотим получить

Чтобы на существующем экспериментальном сервере, с уже работающим на домене one.mydomain.ru полезном сервисе на 443 порту, появился дополнительный сервис TeleMT, работающий также на 443 порту второго домена two.mydomain.ru. В рамках одного IP-адреса.

Как это будет организовано

0.0.0.0:443 – SNI-роутинг на базе NGINX Stream. Слушает 443 порт внешнего IP и маршрутизирует трафик между внутренним NGINX и TeleMT.

127.0.0.1:1443 – TeleMT Backend.

127.0.0.1:9091 – TeleMT API.

127.0.0.1:8443 – NGINX маскировочный сайт + гейт в первый сервис по веб-сокету на URL.

127.0.0.1:10000 – полезный сервис из первого эксперимента.

Настройка TeleMT

Не буду пересказывать вполне внятный документ из репозитория проекта https://github.com/telemt/telemt/blob/main/docs/QUICK_START_GUIDE.ru.md

Установка делается по нему, а вот конфиги сервисов можно взять и отсюда.

Конфигурация TeleMT /etc/telemt/telemt.toml:

[general]
use_middle_proxy = false

[general.links]
public_host = "two.mydomain.ru" # Домен для генератора ссылок в API
public_port = 443
show = []

[server]
port = 1443 # Порт, который слушает TeleMT

[[server.listeners]]
ip = "127.0.0.1" # IP, который слушает TeleMT

[general.modes]
classic = false
secure = false
tls = true # Нам нужны только TLS-режим, самый "модный"

[server.api]
enabled = true
listen = "127.0.0.1:9091" # API доступен только из локалки
read_only = true # Без функции записи

[censorship]
tls_domain = "two.mydomain.ru" # Домен для маскировки

[access.users]
# format: "username" = "32_hex_chars_secret"
# openssl rand -hex 16 --- команда для генерации секрета
user1 = "1934e0e3d893310712ab96d6bcbdeaef"
user2 = "cefeee711c931425dfadd1584b65da63"

[access.user_max_tcp_conns]
user1 = 15 # Ограничиваем одновременные сессии, чтобы ссылками не делились
user2 = 15

Для примера здесь заведено два юзера. Новые заводятся добавлением строк по аналогии. Секрет для каждого нового юзера генерируется новый. Указанной командой.

Настройка NGINX

Чтобы на одном NGINX на одном айпишнике на одном 443 порту сидело несколько разных сервисов, нам понадобится организовать SNI-роутинг.

На сервере уже сконфигурирован первый сервис на домене one.mydomain.ru. Сгенерирован SSL-сертификат через CertBot LetsEncrypt. Настроен NGINX на коннект к сервису через WebSocket. И на отдачу статического сайта просто при обращении по HTTPS.

Перегенерируем SSL-сертификат. Добавляем в него второй домен two.mydomain.ru:

certbot certonly -d one.mydomain.ru -d two.mydomain.ru

Выбираем 2, 2. На вопрос про webroot path отвечаем /var/www/html.

Добавляем модуль NGINX Stream, его нет в дефолтовой поставке на Debian 13:

apt install libnginx-mod-stream

После этого в /etc/nginx/modules-enabled появится файл 50-mod-stream.conf.

Настраиваем SNI-роутинг NGINX /etc/nginx/modules-enabled/60-stream-sni.conf

stream {
    map $ssl_preread_server_name $backend_mydomain {
        ~^one\.mydomain\.ru$        127.0.0.1:8443;
        ~^two\.mydomain\.ru$   127.0.0.1:1443;
        default               127.0.0.1:8443;
    }

    server {
        listen 443;
        listen [::]:443;
        proxy_pass $backend_mydomain;
        ssl_preread on;
        proxy_connect_timeout 5s;
        proxy_timeout 24h;
    }
}

Этот конфиг должен попасть на самый верхний уровень файла конфигурации NGINX. Поэтому он лежит в этой папке. И должен быть включен после подключения динамического модуля Stream. Поэтому его название начинается с 60-.

Конфигурируем виртуальный хост NGINX /etc/nginx/sites-enabled/default:

server {
	listen 127.0.0.1:8443 ssl http2;
	listen [::1]:8443 ssl http2;

	ssl_certificate /etc/letsencrypt/live/one.mydomain.ru/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/one.mydomain.ru/privkey.pem;
	ssl_protocols TLSv1.2 TLSv1.3;
	ssl_ciphers HIGH:!aNULL:!MD5;
	ssl_prefer_server_ciphers off;

	root /var/www/html;

	index index.html index.htm index.nginx-debian.html;

	server_name one.mydomain.ru two.mydomain.ru;

	# Regular HTTP requests - serve static files (camouflage)
	location / {
		try_files $uri $uri/ =404;
	}

	location /api/delta/stream {
		proxy_pass http://127.0.0.1:10000;
		proxy_http_version 1.1;
		proxy_set_header Upgrade $http_upgrade;
		proxy_set_header Connection "upgrade";
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Forwarded-Proto $scheme;
		proxy_read_timeout 86400;
	}

	location ~ /\.ht {
		deny all;
	}
}

server {
	listen 80 default_server;
	listen [::]:80 default_server;
	server_name one.mydomain.ru two.mydomain.ru;
	
	location ^~ /.well-known/acme-challenge/ {
		root /var/www/html;
		default_type "text/plain";
		try_files $uri =404;
	}
	
	# Redirect all other HTTP requests to HTTPS
	location / {
		return 301 https://$server_name$request_uri;
	}
}

Запуск добра

service nginx restart
service telemt start

Получение прокси-ссылок

curl -s http://127.0.0.1:9091/v1/users | jq

Копируем ссылки. Отрываем их в браузере. Наслаждаемся невиданной скоростью работы мессенжера. Профит.

P.S. Экспериментальным путем выяснилось, что второй эксперимент прекрасно работает в большинстве случаев. Но не работает на мобильной связи МегаФона. Причем рядом живущий первый эксперимент нормально работает и в мобильной сети. Если вас коснулась такая проблема – она лечится переключением на IPv4 в настройках APN смартфона.

А еще я веду ТГ-канал @itmancan про хобби айтишника. Показываю, что конструирую. Как применяю сконструированное. Экспериментирую с нейронками. Подробно рассказываю, как получаю результаты. Пытаюсь заинтересовать темой читателей. Иногда получается. Заглядывайте в гости. Вдруг что-то заинтересует.

Комментарии (23)


  1. David_Osipov
    17.03.2026 22:29

    Про докер хорошо написал. Лично слышал о людях, которые докер ставили ради 1 приложухи, что считаю крайне странным.


    1. poige
      17.03.2026 22:29

      Ставить docker нужно не из-за одной приложухи, а из-за compose — как способа задания повторяемой текстовой конфигурации и самой приложухи, и среды её выполнения. А иначе, конечно, можно и podman'ом обойтись. ;)


    1. Hadis
      17.03.2026 22:29

      Я тот человек, который ставил докер ради 1 приложухи (потом добавилась ещё куча приложений) :)

      Философия моя проста – ОС на VPS это внешняя платформа, песочница для быстрого запуска и быстрого удаления разных приложений. Я могу что-то поставить, посмотреть, понять что мне это не нравится, и снести. И мне не хочется, чтобы последствия моих экспериментов вносили изменения в ОС, оставляли там следы, какие-то файлы конфигов, каталоги, и прочее. Хочется, чтобы система была всегда чистой и стабильной. Использование докера эту задачу полностью решает.


      1. webself Автор
        17.03.2026 22:29

        Нормальный сценарий. Тут оправдано.

        А вот когда опытный вроде разраб разворачивает проект в десятке контейнеров по-модному и потом сам же не может это дело как надо донастроить на уровне докера – это уже маразм. Я такое не раз и не два наблюдал.


        1. pavia
          17.03.2026 22:29

          Ваш разраб не может донастроить - это по вашему проблемы докера? Ваша критика решений с использованием докера свелась к вкусовщине, суеверию, не знаю, к религиозной неприязни. Сделали вы нативно, хорошо, но надо пнуть докер, показать какой вы крутой, потому что прогрессивно не перености все эти ваши докеры на дух. Так себя это говорит о ваших компетенциях.


          1. webself Автор
            17.03.2026 22:29

            Причем тут мой разраб. Просто я видел такую ситуацию не раз. И именно к докеру вообще нет претензий. Претензии к людям, которые на ровном месте усложняют систему. Это далеко не только докеров касается в современной разработке, если что.


            1. pavia
              17.03.2026 22:29

              В современной разработке говорите? Ну да, вот раньше было без всяких этих ваших докеров и реактов... Насколько я понимаю докер предназначен не для усложнения, а наборот, для упрощения, нет?


    1. opusmode
      17.03.2026 22:29

      Какая разница, сколько приложух? Суть докера в том, что ты один раз описал конфиг и одной командой поднял то. что ожидаешь


  1. c46fd3da
    17.03.2026 22:29

    Для подобных вещей стоит посмотреть в сторону Caddy с модулем L4.

    Там это все настраивается существенно короче и интуитивнее.


    1. webself Автор
      17.03.2026 22:29

      Еще проще, чем здесь? Вроде и так не сложно.

      Позже узнал, что такое через haproxy лучше делать. Что он ресурсов меньше ест. Но мне не нужен какой-то массовый сервис. Поэтому дальше ковыряться не пойду.


      1. Kenya-West
        17.03.2026 22:29

        Я вот этим пользуюсь, но через Docker. Возможно, без него тоже заведётся: https://github.com/homeall/caddy-reverse-proxy-cloudflare


    1. tarielx
      17.03.2026 22:29

      Caddy по моим наблюдениям (и по некоторым бенчмаркам) использует чуть больше памяти, чем nginx/haproxy при малом rps. Оптимизация может быть на спичках, но вместе с отказом от докера, при малой нагрузке можно запустить пару "экспериментов" даже на 512 мб озу.


  1. fronik
    17.03.2026 22:29

    Как сейчас дела со скоростью у Telemt? Ставил его ранее, и скорость загрузки файлов в Telegram не превышала 3Мбит/с


    1. webself Автор
      17.03.2026 22:29

      Честно, не измерял особо. Разница между "никак" и "любая другая скорость" – огромна)


  1. express
    17.03.2026 22:29

    Очень муторно, докеры, нджинксы... MTG (https://github.com/9seconds/mtg) - один бинарный и конфиг на 2 строки. Собирается под винду, хотя и не выложен в секции релизов.

    Не тестировал производительность, но её хватает для меня и нескольких людей


    1. webself Автор
      17.03.2026 22:29

      Ну TeleMT тоже один бинарный. А зачем вам этот мтж под виндой?


      1. express
        17.03.2026 22:29

        Сервер есть под виндой, заказывать отдельный сервер под это не хотелось. Искал варианты без питонов, докеров, node.js'ов и прочей херни, чтобы работало самостоятельно, короче.

        Подошёл mtg в плане лёгкой сборки под винду - исходя из богатого списка поддерживаемых платформ пришёл к выводу, что наверное и под неё можно и не ошибся.

        Возможно у TeleMT тоже так можно (и запустить без бубнов на любом порту без nginx и скомпилировать под винду), но из статьи это неочевидно.


    1. L1Navy
      17.03.2026 22:29

      Пробовали, скорость загрузки контента грусть, печаль


      1. express
        17.03.2026 22:29

        Это сколько? Может у нас разные представления какой должна быть скорость? Видосики с картинками грузятся как раньше, по ощущениям.


        1. L1Navy
          17.03.2026 22:29

          0-100 кб/сек :) Грузятся только сообщения можно сказать


          1. express
            17.03.2026 22:29

            Не сказать, что супербыстро, но и не 100 килобит. К тому же у меня нет премиума, возможно добавляются ограничения со стороны телеграма.

            Скрытый текст


  1. Morgan55555
    17.03.2026 22:29

    ...или как хроническое неприятие докера превратить в сношение мозгов.

    У меня домашний сервер на docker с полностью автоматическим получением и обновлением сертификатов через traefik. Для каждого нового сервиса мне необходимо просто указать в docker-compose внешнюю сеть traefik и прописать labels, буквально 8 строк. Всё, трафик завёрнут в https, сертификат получен и обновлён.

    А ещё докер - это когда всё максимально упорядочено и лежит на своих местах. Всегда знаешь, где лежат данные, просто бэкапить, просто разворачивать копию на любом другом хосте. При грамотной настройке ещё и дополнительный уровень безопасности. Обособленность от ОС хоста, свобода экспериментировать, менять версии. Есть контроль над ресурсами при отсутствии падения скорости, как в случае с виртуализацией.

    Что может не получится настроить в контейнере - тоже вопрос открытый. По факту, Dockerfile - это просто пошаговый процесс билда и установки требуемого софта. Compose - инструкция для запуска всего полученного.

    Не понимаю вот этого вот неприятия, особенно для серверов.


    1. webself Автор
      17.03.2026 22:29

      Ну ведь и славно, что у вас так все хорошо и замечательно. Кто спорит. )