Yandex Metrika

TCP туннели

Описание

Общее описание функционала

TCP-туннелирование открывает локальный TCP-сервис (SSH, база данных, произвольный бинарный протокол) для доступа с интернета через инфраструктуру туннеля. Трафик передаётся как поток байт с мультиплексированием по надёжному транспорту между клиентом и сервером; поддерживаются режим публичного порта на стороне сервиса и сценарий expose-local (внешний порт на сервере), когда внешние клиенты подключаются к выделенному порту, а агент пробрасывает соединение на локальную машину. Для протоколов с TLS на стороне приложения платформа не расшифровывает полезную нагрузку на границе (в отличие от HTTP(S)-туннеля с терминацией TLS на входе).

Как пользователь может использовать

  • Разработчик открывает SSH к домашней машине для удалённой отладки.
  • Команда подключается к общей базе данных на стенде разработчика через выданный host:port.
  • Пользователь поднимает туннель к промышленному устройству или SCADA по TCP.
  • Пользователь использует режим expose-local (внешний порт на сервере), чтобы внешний партнёр подключился к порту на сервере туннелей, а трафик ушёл на 127.0.0.1 у владельца.
  • Пользователь полагается на автоматические повторы при кратковременных обрывах транспорта между CLI и сервером.
  • Пользователь входит в бесплатную учётную запись перед созданием TCP-туннеля; платный CLI-токен для этого не нужен.
  • Входящие и исходящие данные TCP расходуют общий месячный лимит всех туннелей этой учётной записи.
  • Администратор ограничивает доступ списками IP на уровне туннеля.
  • Пользователь сравнивает с HTTP(S)-туннелем: для «короткой ссылки в браузере» чаще подходит HTTP-маршрут; для сквозного TLS приложения — TCP-туннель (см. пользовательские истории TCP).
  • На macOS пользователь может сочетать expose-local TCP с локальным слушателем на 127.0.0.1 (например nc или опционально socat) для интерактивной TCP-сессии поддержки и отладки (см. US-12 и раздел Ограничения).

Как это реализовано в сервисе

Клиент сначала подтверждает зарегистрированную учётную запись, затем регистрирует туннель и получает публичный адрес:порт или инструкции для режима expose-local. Бесплатного тарифа достаточно, если его лимиты не исчерпаны. Плоскость данных устанавливает защищённый канал между сервером и CLI, через который байты копируются между сокетом в интернете и локальным приложением. Сервер выделяет порты из настроенного диапазона, применяет ограничения и учитывает полезные данные в обоих направлениях в общей месячной квоте владельца.

Как использовать через CLI-клиент

TCP-туннель создаётся с протоколом tcp и адресом локального TCP-сервиса. Пример для SSH на порту 22:

fortunnels tcp 22

или:

fortunnels -protocol tcp -local 127.0.0.1:22

Для входа без пароля в истории команд используйте стандартный ввод:

fortunnels tcp 22 -login user@example.test -pass-stdin

При исчерпании общего месячного трафика клиент завершает работу с подсказкой. Повторное создание туннеля не сбрасывает использование; дождитесь нового месяца или попросите администратора увеличить лимит.

Транспорт данных по умолчанию — WebSocket; альтернативы -dp quic и -dp dtls описаны в документации CLI-клиента.

Справочник API

Создание туннеля

POST /api/tunnels

Пример тела:

{
  "protocol": "tcp",
  "target_addr": "127.0.0.1:22"
}

Ответ содержит id, public_addr (или эквивалент host:port) и метаданные создания.

Требуется действующая сессия или Bearer-токен зарегистрированной учётной записи. Бесплатного тарифа достаточно в пределах его лимитов; гостевой TCP-режим недоступен.

Чтение и удаление

  • GET /api/tunnels?id={id} — получить один туннель (или GET /api/tunnels для списка).
  • PATCH /api/tunnels — обновить туннель; в теле JSON укажите id и поля/действие.
  • DELETE /api/tunnels?id={id} — удалить туннель.

Публичный вход

Внешний клиент открывает TCP на выданный public host:port; сервер сопоставляет поток с туннелем и клиентским агентом.

CLI

См. справку fortunnels для режима tcp и expose-local; глобальные флаги сервера, аутентификации и транспорта (-dp ws/quic/dtls) общие с другими протоколами.

Ошибки

Отказ в подключении

Целевой localhost порт закрыт — внешний клиент или CLI получают обрыв или сообщение об ошибке прокси в зависимости от стадии.

Превышен лимит одновременных соединений

Новые подключения к туннелю отклоняются или ожидают освобождения слота согласно политике сервера и тарифа.

ACL

Подключение с заблокированного IP отклоняется на входе туннеля.

Квоты и тариф

Создание или использование туннеля может быть отклонено с JSON 403 (квота, функция недоступна) по тем же правилам, что и HTTP-туннели.

Аутентификация

401 при обращении к API без учётных данных там, где они обязательны.

Ограничения

  • Дополнительная задержка и джиттер по сравнению с прямым TCP неизбежны из-за туннелирования.
  • Пул публичных портов ограничен настройками сервиса; исчерпание диапазона блокирует новые TCP-туннели.
  • При паузе туннеля публичные соединения не обслуживаются до возобновления и переподключения клиента.
  • Режим expose-local зависит от поддержки в CLI и на сервере; сетевой путь отличается от классического «публичный порт на сервере → локальный сервис».
  • Не гарантируется сохранение долгих idle-соединений при агрессивных таймаутах NAT и прокси на пути.
  • На macOS поведение интерактивной TCP-сессии зависит от выбранных утилит (BSD nc vs GNU netcat, опционально socat): это не SSH; полноценный TTY и сигналы не гарантируются. Рекомендуется слушать только 127.0.0.1, а не 0.0.0.0. Типовой порядок: (1) запустить локальный слушатель, например nc -l 127.0.0.1 7777; (2) поднять TCP-туннель на этот порт; (3) удалённый клиент подключается к выданному публичному host:port.

Дополнения

Пауза туннеля

Общее описание функционала

Пауза TCP-туннеля временно закрывает публичный порт и завершает текущие соединения, не удаляя сам туннель и его адрес. Уже запущенный клиент может автоматически переподключаться и отправлять сигналы активности, но новые TCP-соединения не проходят до возобновления. После возобновления тот же туннель может снова работать без перезапуска клиента. Для владельца функция доступна на тарифе, который включает паузу; администратор сохраняет предусмотренные права управления.

Как пользователь может использовать

  • Разработчик ставит туннель на паузу на ночь, чтобы временно закрыть публичный порт локального сервиса.
  • Владелец оставляет клиент запущенным во время паузы и возобновляет тот же туннель, когда доступ снова нужен.
  • Пользователь на Free видит пункт «Пауза» в меню действий неактивным и может перейти к смене тарифа из подсказки.
  • Пользователь видит в дашборде статус «Приостановлен» и понимает, что новые подключения намеренно отключены.
  • Команда прерывает долгую TCP-сессию паузой и открывает новое соединение после возобновления; прерванные данные автоматически не повторяются.
  • Администратор приостанавливает туннель пользователя при инциденте.
  • После возобновления пользователь подключается по тому же публичному адресу, когда автоматическое соединение клиента готово.

Как это реализовано в сервисе

Команда паузы сохраняет состояние «Приостановлен», закрывает публичный TCP-порт для новых подключений и завершает текущие соединения. Переподключения и сигналы активности клиента не отменяют паузу. Команда возобновления возвращает прежний публичный порт в работу и использует восстановившееся соединение клиента; если оно ещё не готово, порт остаётся недоступным до автоматического переподключения. Проверки прав и тарифа не меняются, а смена публичного адреса приостановленного TCP-туннеля по-прежнему требует сначала его возобновить.

Пауза и возобновление

PATCH /api/tunnels

Тело JSON включает идентификатор туннеля и поле действия:

  • action: pause — приостановить туннель.
  • action: resume — возобновить туннель.

Успех: ответ с обновлённым объектом туннеля (в т.ч. поле статуса paused / active) в формате вашего API.

Права: владелец туннеля или администратор.

Связанное действие

action: regenerate_url — для TCP в активном состоянии перевыделяет публичный порт; для приостановленного TCP может возвращаться ошибка с просьбой сначала выполнить resume (сообщение в теле ответа).

400 Bad Request

Недопустимое действие для текущего состояния (например, regenerate_url для TCP на паузе) — в теле JSON текст с подсказкой сначала resume.

401 / 403

Нет прав изменять туннель.

При code: feature_disabled и feature_id: tunnel-pause — функция Пауза туннеля не входит в текущий тариф (tunnel pause requires a paid plan). Нужно сменить тариф или обратиться к администратору.

TCP после resume

Пока клиент данных не восстановил готовое соединение, новое TCP-подключение не передаётся к локальной цели. Клиенту нужно повторить подключение после восстановления туннеля; HTTP-ответ 503 к TCP-входу не относится.

Ограничения

  • На паузе новые TCP-подключения не принимаются, в том числе после автоматического переподключения клиента и его сигналов активности.
  • TCP-соединения, открытые в момент паузы, завершаются. Сервис не сохраняет и не повторяет прерванные данные после возобновления.
  • Если соединение клиента ещё не готово, после возобновления публичный порт остаётся недоступным до автоматического переподключения. Перезапуск клиента обычно не требуется.
  • Публичный адрес приостановленного TCP-туннеля нельзя сменить до возобновления.
  • Истёкший или закрытый туннель нельзя возобновить; вместо него нужно создать новый.