Видеозвонок с демонстрацией экрана плохо подходит для совместной работы в консоли: картинка тормозит, текст не скопировать, вносить правки может только владелец машины. Tmate, форк tmux с открытым кодом, решает задачу напрямую: один запускает сессию, второй подключается к ней по ssh, и оба работают в одном терминале с настоящим текстом, общей историей и живым копипастом. Поток идёт внутри зашифрованной ssh-сессии, а сессии гостей изолированы друг от друга на уровне узла. Ниже настройка инструмента в актуальных условиях, когда рассчитывать на чужую инфраструктуру уже нельзя, и порядок действий для типового разбора проблемы вдвоём.
Что даёт tmate по сравнению с демонстрацией экрана
В шеринг-сессии гость получает ровно то же изображение, что и владелец, только без потерь: шрифт чёткий при любой связи, команды копируются из истории одним выделением, длинные выводы листаются. Ввод доступен обоим: правки вносит не только хозяин сессии, курсоры свободно двигаются по одному экрану, и беседа превращается в совместную работу, а не в диктовку. Есть и нюанс: одновременный ввод двух людей перемешивает команды, поэтому участники проговаривают вслух, кто что запускает. Трафик измеряется килобайтами, поэтому соединение живёт даже на слабой связи, где видеозвонок рассыпается на квадраты. И это настоящий tmux с панелями и горячими клавишами, так что привычки переносятся один в один: кто знает tmux, знает tmate.
Отдельный плюс для обучения: младший коллега видит команды целиком, включая опечатки и их исправление, а не конечный результат из чужой головы. Записи видео такое не передаёт, а живая сессия передаёт без усилий, причём без камеры и микрофона, то есть работает даже в шумном опенспейсе или при перегруженной связи.
Сравнение с классическим вариантом совместного tmux на общем аккаунте тоже не в пользу последнего: там один пароль на двоих, нет ролей, нет наблюдателей и нет изоляции, а отключить гостя отдельно от владельца не получится. В tmate у каждого свой токен и свой уровень прав, а владелец в любой момент закрывает сессию целиком.
Судьба публичных серверов и переход на свой узел
Долгие годы tmate работал почти без настройки: клиент сам подключался к публичным серверам проекта и сразу выдавал готовые строки приглашения для гостя. В июле 2025 года публичные серверы были отключены, о чём команда сообщила в репозитории: серверную часть переписывают на Rust, а возвращение хостингового сервиса обещают позже. Старые версии клиента после этого показывают лишь таймауты подключения, а ssh на адреса публичных узлов обрывается. Проверка текущего состояния простая: клиент без конфига не подключается, и это сигнал, что пора поднимать свой узел. Скрипты автозапуска tmate в старых наработках тоже стоит пересмотреть, чтобы они не висели в ожидании мёртвых адресов.
Практический вывод для текущей работы: узел нужно поднимать самому. Внутри корпоративного контура это даже правильнее: сессии не покидают сеть компании, сервер становится единой точкой входа для всех шерингов, а администратор видит, кто и когда подключался. Для команд с требованиями к размещению кода и терминалов внутри собственной инфраструктуры такой расклад вообще единственно возможный. Клиенту достаточно достучаться до сервера по ssh: ничего наружу открывать не требуется, и сложные сетевые сценарии с NAT проходят сами собой, потому что соединение инициирует клиент. Для небольшой команды без собственной инфраструктуры узлом становится недорогая виртуальная машина у любого хостера. Отдельный сценарий: учебный класс, где каждый студент открывает свою сессию, а преподаватель обходит read-only ссылками и видит прогресс всех сразу. Проект распространяется по свободной лицензии BSD и построен на коде tmux, так что аудит доступен обычным путём.
Подъём сервера tmate в контейнере
Официальный docker-образ поднимается одной командой:
docker run -d --name tmate-ssh-server \
--restart unless-stopped \
-p 2200:2200 \
-v /etc/tmate:/etc/tmate \
-e SSH_KEYS_PATH=/etc/tmate \
-e SSH_HOSTNAME=tmate.example.com \
tmate/tmate-ssh-server
Переменная SSH_KEYS_PATH обязательна: там живут ключи хоста, и каталог стоит закрепить за постоянным томом, чтобы отпечатки не менялись при пересоздании контейнера. SSH_HOSTNAME сообщает клиентам, по какому имени подключаться. Пара SSH_PORT_LISTEN и SSH_PORT_ADVERTISE разделяет порт прослушивания и объявляемый порт, что пригождается за балансировщиком. Режим HAS_WEBSOCKET=1 включает веб-терминал через отдельный сервис tmate-websocket для гостей из браузера, а настройка поддержки протокола балансировщика пригодится, когда перед сервером стоит балансировщик, передающий реальные адреса клиентов.
Контейнеру нужен capability SYS_ADMIN: он используется для изоляции сессий в отдельных namespaces, что не даёт гостям вмешиваться в чужие сессии на одном узле. Нагрузка от текстовых сессий копеечная, поэтому узлу хватает скромной виртуальной машины, а для команды из пары десятков инженеров одного экземпляра достаточно надолго. Ключи хоста можно сгенерировать заранее утилитой ssh-keygen и положить в каталог до запуска, тогда отпечатки известны ещё до первого старта. После запуска сервер печатает отпечатки в журнал, а на межсетевом экране достаточно открыть TCP-порт 2200 или свой, если переназначили: ни UDP, ни переадресации портов на клиенте не нужно. Посмотреть журнал узла можно привычным способом: