HTTP/HTTPS туннели
Описание
Общее описание функционала
Функциональность отвечает за публичный доступ к вашим HTTP- и HTTPS-приложениям через туннель: внешний клиент обращается к поддомену URL туннеля на домене сервиса (например label.fortunnels.ru), а запрос перенаправляется на целевой хост и порт, который вы указали при создании туннеля. Для одноуровневого поддомена URL туннеля на домене сервиса для туннелей зарегистрированных пользователей нужен владелец, администратор или гостевой туннель; сессия или токен должны позволять сервису определить пользователя (cookie сессии на родительском домене или Authorization: Bearer). Для привязанного пользовательского домена по-прежнему допускается публичный доступ по знанию имени хоста — без проверки владения сессией, как «ссылка-возможность»; после этого по-прежнему применяются списки доступа по IP, лимиты и тариф. Проверка владельца, гостевого режима и администратора для поддомена на домене сервиса выполняется до списков доступа по IP и лимитов. Сервис проверяет, существует ли туннель и разрешён ли запрос. Дополнительно могут применяться ограничения по IP, частоте запросов и условиям тарифа (квоты и включённые возможности). При недоступности целевого приложения или срабатывании ограничений клиент получает понятный по смыслу ответ об ошибке вместо успешного ответа от вашего приложения.
Если обязательный скрипт, стиль, сетевое соединение или другой критичный ресурс заблокирован политикой Content Security Policy (CSP) самого приложения, Fortunnels может показать в этом браузере отдельную страницу с объяснением. Политика приложения при этом остаётся неизменной: исправлять её нужно в самом приложении.
Как пользователь может использовать
- Разработчик поднимает API или веб-интерфейс локально и открывает его коллегам или тестовой среде по выданному URL туннеля, не выставляя машину в интернет напрямую.
- Интегратор проверяет вебхуки или OAuth-редиректы: внешний сервис шлёт запросы на адрес туннеля, а трафик доходит до локального стенда.
- Владелец туннеля делится URL туннеля на поддомене сервиса с коллегами и интеграциями.
- Владелец на платном тарифе в дашборде туннелей переключает колонку «Публичный», чтобы скрыть HTTP/HTTPS-туннель от анонимных посетителей или снова открыть его; подробнее — приватные HTTP-туннели.
- Для приложений на Next.js и похожих SPA URL туннеля на поддомене обычно работает прозрачно для типовых запросов, включая загрузку
_next-ресурсов,fetch,WebSocket,EventSourceиsendBeacon. - Пользователь с гостевым туннелем (доступный всем) демонстрирует прототип заказчикам без входа в аккаунт у них; при этом приватные туннели остаются доступны только владельцу и уполномоченным ролям.
- Администратор в личном кабинете (
/dashboard/tunnels) видит в списке только свои туннели; полный обзор всех пользователей — в админ-консоли на выделенном админ-хосте. Отладка чужого туннеля через Inspector по прямой ссылке из админ-консоли по-прежнему доступна. - Клиент API или скрипт автоматизации дергает те же URL туннелей, что и браузер, для проверки поведения за прокси (заголовки, редиректы, тело ответа).
- Разработчик видит пустую или неполную страницу из-за CSP, перезагружает её после отправки отчёта браузером и получает понятную диагностику. После исправления политики кнопка Try again возвращает его на тот же адрес туннеля.
- Пользователь сталкивается с временной приостановкой туннеля и видит, что сервис недоступен до возобновления, вместо устаревшего ответа.
- Владелец плана с лимитами отслеживает, что при исчерпании квоты или отключённой возможности запросы к туннелю отклоняются с явным сигналом, а не проксируются «в никуда».
- Пользователь с ограничениями по IP или частоте запросов понимает по ответу сервиса, что доступ временно или постоянно ограничён политикой безопасности или защитой от злоупотреблений.
- Посетитель основного сайта сервиса и посетитель URL туннеля получают согласованное поведение по протоколу (например, ожидаемые редиректы на HTTPS там, где это задумано продуктом).
- Поддерживаются долгоживущие соединения WebSocket через тот же обратный прокси, при условии корректных таймаутов на публичном входе.
- Если приложение критически зависит от service worker, офлайн-кэша или фонового перехвата запросов, убедитесь, что оно корректно обслуживается с корневого пути на выданном публичном хосте.
- Нужны формализованные истории уровня продукта — см. пользовательские истории HTTP/HTTPS.
Как это реализовано в сервисе
Входящий HTTP-запрос сначала попадает на публичную точку входа: по заголовку Host определяется, к какому туннелю относится запрос; затем проверяется, что туннель существует и находится в состоянии, допускающем обработку. Для одноуровневого поддомена на домене сервиса (URL туннеля вида label.<домен_сервиса>) для туннелей с владельцем выполняется проверка доступа (владелец, гость, администратор) до списков доступа по IP. Для хоста, привязанного как пользовательский домен, публичный доступ по знанию имени хоста сохраняется; затем по-прежнему применяются списки доступа по IP, лимиты и тарифные проверки владельца. В API списков и чтения туннелей для гостей может использоваться скрытие факта существования чужих туннелей (404), что не отменяет описанную модель прокси. После этого учитываются сетевые списки доступа, ограничение интенсивности запросов и условия тарифа владельца. Если все проверки пройдены, сервис пересылает запрос на целевой адрес туннеля и возвращает ответ приложения. При ошибке маршрутизации, доступа, лимита, подключения или тайм-ауте ответ формирует Fortunnels.
Для CSP-диагностики сервис добавляет к подходящему HTML-ответу отдельную политику только для отчётов и не меняет политику, которую применяет браузер. После критичного нарушения браузер асинхронно отправляет отчёт. Следующая перезагрузка или переход верхнего уровня в том же браузере может получить диагностическую страницу. Другие браузеры продолжают получать исходный ответ приложения, даже если его CSP мешает отображению; запросы к API, ресурсам и WebSocket также не заменяются этой страницей.
Как использовать через CLI-клиент
HTTP- или HTTPS-туннель запускается из CLI с указанием локального адреса приложения. Краткая форма — порт как позиционный аргумент; для неё клиент использует localhost:<порт>. Явный адрес через -local сохраняется без изменений.
Пример для локального веб-сервера на порту 8080:
fortunnels http 8080
или:
fortunnels -protocol http -local 127.0.0.1:8080
Если приложение слушает только IPv6, подойдут ./bin/client http localhost:4321 или ./bin/client -protocol http -local '[::1]:4321'.
После успешного создания клиент выводит URL туннеля; процесс остаётся активным, пока вы его не остановите. Для доступа от имени аккаунта передайте токен (-token), логин и пароль (-login) или заранее сохраните CLI-токен (fortunnels config add-authtoken …). Режим отслеживания состояния туннеля — флаг -watch. Полный перечень флагов транспорта и протоколов — в документации CLI-клиента.
Справочник API
Публичное проксирование
GET https://{subdomain}.{domain}/*— проксирование HTTP-запросов к целевому туннелю по поддомену из URL туннеля (в ответе API — полеpublic_url)GET https://{custom_domain}/*— маршрутизация по привязанному пользовательскому домену
Поддерживаются все HTTP-методы (GET, POST, PUT, DELETE и др.). Заголовки, тело и параметры запроса сохраняются при пересылке.
Управление туннелями (API)
POST /api/tunnels— создание туннеля с протоколом HTTP/HTTPSGET /api/tunnels?id=<id>— получение информации о туннеле (илиGET /api/tunnelsсо списком)PATCH /api/tunnels— обновление конфигурации туннеля; в теле JSON укажитеidи действие (пауза, транспорт, TLS, регенерация URL, редиректы и т.д.)DELETE /api/tunnels?id=<id>— удаление туннеля
Для HTTP/HTTPS-туннелей поддерживается действие set_public_subdomain: в теле JSON указываются id, action: "set_public_subdomain" и поле public_subdomain (метка поддомена). Ограничения: валидация метки, уникальность хоста, зарезервированные имена, при включённых тарифах — возможность custom-public-subdomain, отдельный лимит частоты смены метки, максимальный размер тела PATCH. Коды ответов: см. раздел Ошибки возможности «Свой поддомен» в документации.
Для зарегистрированных пользователей с тарифными планами при создании туннеля возможны ответы 403 с JSON-кодами: user_suspended (аккаунт заблокирован) или quota_exceeded с полем quota: max_concurrent_tunnels (превышен лимит одновременных туннелей). Поле expires_at в ответе может отражать ограничение срока жизни туннеля по плану.
Запрос создания туннеля
{
"protocol": "http",
"target_addr": "127.0.0.1:8000"
}
Владелец определяется сессией или Bearer-токеном; идентификатор владельца не передаётся клиентом в теле запроса.
Ответ создания туннеля
{
"id": "a1b2c3d4e5f6g7h8",
"protocol": "http",
"target_addr": "127.0.0.1:8000",
"public_url": "http://xyz789.fortunnels.ru",
"created_at": "2024-01-01T12:00:00Z",
"expires_at": "2024-01-01T14:00:00Z"
}
Поддомен URL туннеля генерируется независимо от id туннеля для повышения безопасности (в ответе API — поле public_url).
Список и детали туннеля (GET /api/tunnels, GET /api/tunnels?id=<id>)
Ответ списка и одиночного туннеля включает поля created_at, expires_at, bytes_used, traffic_limit_bytes и объект limit_indicators — компактные индикаторы лимитов для интерфейса (без отдельного запроса на строку).
limit_indicators
| Поле | Описание |
|------|----------|
| as_of | Момент расчёта на сервере (RFC3339) |
| lifetime | Оставшееся время жизни туннеля из created_at / expires_at |
| traffic | Per-tunnel трафик из bytes_used / traffic_limit_bytes (для гостевых туннелей); для зарегистрированных владельцев — unavailable (месячный egress аккаунта не показывается как per-tunnel cap) |
| http_rpm | Оставшаяся ёмкость HTTP-запросов в минуту по плану в текущем окне |
Состояния каждого индикатора: limited, unlimited, unavailable, zero_limit, exhausted, expired.
Снимок http_rpm носит информационный характер и не расходует лимит запросов при чтении; фактическое ограничение применяется при обработке HTTP-запросов к туннелю.
Для не-админов поля user_id и owner_login по-прежнему опускаются в теле туннеля; limit_indicators не содержит owner/account/plan идентификаторов.
Область списка для администратора
Один и тот же endpoint GET /api/tunnels возвращает разный набор туннелей в зависимости от того, откуда администратор открыл интерфейс:
| Контекст | Где в продукте | Что в списке |
|----------|----------------|--------------|
| Личный кабинет | /dashboard/tunnels на основном домене | Только туннели, принадлежащие этому администратору (как у обычного пользователя) |
| Админ-консоль | /tunnels на выделенном админ-хосте (например admin.fortunnels.ru; в локальной разработке — /admin/tunnels) | Все туннели всех пользователей |
В личном кабинете администратор не видит чужие туннели в списке, счётчиках и пагинации. В админ-консоли по-прежнему доступен полный обзор флота; в списке для чужих туннелей могут отображаться поля владельца (owner_login, user_id).
Исключение: открытие конкретного туннеля или Inspector по прямой ссылке (в том числе переход из админ-консоли на /dashboard/tunnels/{id}/inspector для чужого туннеля) по-прежнему разрешено администратору — это не расширяет список в личном кабинете.
CLI и прочие API-клиенты без контекста админ-консоли получают лично-кабинетный список (только свои туннели).
Пример фрагмента:
{
"limit_indicators": {
"as_of": "2026-06-05T12:00:00Z",
"lifetime": {
"state": "limited",
"used_seconds": 120,
"remaining_seconds": 480,
"total_seconds": 600,
"reset_at": "2026-06-05T14:00:00Z"
},
"traffic": {
"state": "limited",
"used_bytes": 256,
"remaining_bytes": 768,
"total_bytes": 1024
},
"http_rpm": {
"state": "limited",
"used_requests": 3,
"remaining_requests": 7,
"total_requests": 10,
"reset_at": "2026-06-05T12:01:00Z"
}
}
}
Поле remaining_requests в http_rpm — оставшаяся ёмкость HTTP requests/min в текущем окне (не current_http_requests_per_minute).
Ошибки
413 Payload Too Large
Когда возникает: Тело запроса PATCH /api/tunnels/{id} превышает лимит размера (внутренний порог для JSON-действий с туннелем).
Что делать: Уменьшить тело запроса; для set_public_subdomain достаточно компактного JSON с полями id, action, public_subdomain.
400 Bad Request
Когда возникает: Невалидный формат ID туннеля, некорректный запрос, попытки path traversal (../ в путях), невалидная метка public_subdomain, зарезервированное имя поддомена, действие только для HTTP/HTTPS.
Что делать: Проверить корректность URL и ID туннеля. Убедиться, что путь не содержит недопустимых последовательностей.
403 Forbidden
Когда возникает: ACL запретил доступ, требуется аутентификация, пользователь обращается к чужому туннелю.
Что делать: Проверить права доступа и настройки ACL туннеля. Убедиться, что аутентификация валидна и пользователь имеет право доступа к туннелю.
404 Not Found
Когда возникает: Туннель не найден, невалидный путь или ID туннеля.
Что делать: Проверить корректность ID туннеля и URL. Убедиться, что туннель существует и не истёк.
429 Too Many Requests
Когда возникает: Превышен лимит запросов (глобальный, на пользователя или на туннель).
Что делать: Снизить частоту запросов. Заголовок Retry-After указывает, когда можно повторить запрос.
502 Bad Gateway
Когда возникает: Целевой сервис недоступен, подключение не удалось или истёк таймаут. Сообщение connection refused часто означает, что адрес выбран не для той версии IP: приложение может слушать ::1, но не 127.0.0.1. Ещё один случай — диагностическая страница после того, как этот браузер сообщил о критичном нарушении CSP приложения.
Что делать: Убедиться, что локальный сервис запущен и доступен по адресу туннеля. Сравните:
curl -I http://localhost:<порт>/
curl -I http://127.0.0.1:<порт>/
Если первый запрос успешен, а второй нет, создайте HTTP-, HTTPS- или TCP-туннель с localhost:<порт> либо явно укажите [::1]:<порт>. Туннель остаётся активным; ответ 502 временный, и следующий публичный запрос повторит подключение после восстановления приложения.
Если на странице указана CSP-ошибка, проверьте названную директиву и разрешённый источник в настройках самого приложения. Затем нажмите Try again. Кнопка сбрасывает отметку только для текущего браузера и возвращает на тот же адрес туннеля. Если политика исправлена, приложение загрузится; Fortunnels не отключает и не ослабляет CSP. Другой браузер эта отметка не затрагивает.
503 Service Unavailable
Когда возникает: Туннель приостановлен; туннель возобновлён в панели, но клиент ещё не переподключился («Туннель возобновляется»); или временные проблемы на стороне сервера.
Что делать: Проверить статус туннеля через API. Если туннель возобновлён — подождать несколько секунд (клиент переподключается после паузы). Возобновить туннель при необходимости.
504 Gateway Timeout
Когда возникает: Превышен таймаут запроса к целевому сервису.
Что делать: Проверить доступность и нагрузку локального сервиса. Увеличить таймаут в конфигурации туннеля при необходимости.
Ограничения
- Доступность туннеля зависит от состояния локального приложения и сетевого соединения клиента.
- Долгоживущие WebSocket-соединения зависят от таймаутов клиента, сервиса и целевого приложения.
- Приложения, которые жёстко ожидают корневой путь исходного домена или используют service worker, могут требовать отдельной настройки; для таких случаев предпочтительнее отдельный публичный хост.
- Ограничения тарифа, частоты запросов, размера запроса и IP-доступа применяются до передачи запроса в локальное приложение.
- CSP-диагностика работает по принципу «сначала отчёт, затем перезагрузка». Отчёт отправляется асинхронно, поэтому первый показ страницы может остаться пустым или неполным. Диагностика появляется при следующей перезагрузке или другом переходе верхнего уровня в том же браузере.
- В текущей версии учитывается только применяемая браузером CSP из заголовка ответа подходящей HTML-страницы. Политика, заданная только через HTML-метатег, и отдельная политика только для отчётов сами по себе не включают диагностику.
- Диагностическая страница предназначена только для переходов верхнего уровня. Фреймы, скачивания, перенаправления, API-запросы, ресурсы страницы и WebSocket-соединения продолжают обрабатываться как обычно.
- Диагностика поддерживает директивы скриптов
script-src,script-src-elemиscript-src-attr; стилейstyle-src,style-src-elemиstyle-src-attr; соединенийconnect-src; фоновых процессовworker-src; а такжеrequire-trusted-types-forиtrusted-types. Резервная директиваchild-srcучитывается только тогда, когда браузер связывает нарушение сworker-src. Другие нарушения, например блокировка необязательного изображения или шрифта, не включают диагностическую страницу. - Состояние диагностики хранится только в браузере, который отправил отчёт. Оно не отключает туннель для остальных посетителей и не меняет CSP приложения.
Дополнения
Пауза туннеля
Общее описание функционала
Пауза HTTP-туннеля временно закрывает публичный доступ, не удаляя сам туннель и его адрес. Уже запущенный клиент может автоматически переподключаться и отправлять сигналы активности, но запросы всё равно не проходят, пока владелец не возобновит туннель. После возобновления тот же туннель может снова принимать запросы без перезапуска клиента.
Как пользователь может использовать
- Разработчик ставит туннель на паузу на ночь, чтобы временно закрыть доступ к локальному сервису.
- Владелец оставляет клиент запущенным во время паузы и возобновляет тот же туннель, когда доступ снова нужен.
- Пользователь видит в дашборде статус «Приостановлен» и понимает, что публичный вход намеренно отключён.
- Команда прерывает долгий HTTP-запрос паузой и знает, что сервис не повторит его автоматически после возобновления.
- Администратор приостанавливает туннель пользователя при инциденте.
- После возобновления пользователь повторяет запрос; если связь с клиентом ещё восстанавливается, сервис временно сообщает об ожидании переподключения.
- Владелец управляет паузой при наличии нужных прав и функции в тарифе; администратор сохраняет отдельные административные полномочия.
Как это реализовано в сервисе
Команда паузы сохраняет состояние «Приостановлен», прекращает передачу публичных HTTP-запросов и завершает запросы, которые уже выполнялись. Переподключения и сигналы активности клиента не отменяют паузу. Команда возобновления возвращает прежний публичный адрес в работу. Если соединение клиента готово, новые запросы сразу идут к локальному сервису; если нет, сервис до 60 секунд отвечает сообщением о переподключении, а затем обычным ответом о временной недоступности. Проверки прав и тарифа для паузы и возобновления остаются теми же.
Пауза и возобновление
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
Нет прав изменять туннель.
503 Service Unavailable (HTTP после resume)
Кратковременно после возобновления, пока клиент данных не переподключился — вместо прокси к цели может отдаваться ответ о ожидании переподключения в пределах настроенного окна.
Ограничения
- На паузе HTTP-туннель возвращает
503 Service Unavailable, в том числе после автоматического переподключения клиента и его сигналов активности. - HTTP-запрос, который выполнялся в момент паузы, завершается. Сервис не сохраняет его данные и не повторяет запрос после возобновления.
- Если соединение клиента ещё не готово, после возобновления сервис может до 60 секунд показывать сообщение о переподключении. Затем он возвращает обычный ответ
503 Service Unavailable, пока связь не восстановится. - Истёкший или закрытый туннель нельзя возобновить; вместо него нужно создать новый.
Свой поддомен
Общее описание функционала
Функция «Свой поддомен» позволяет владельцу HTTP/HTTPS-туннеля задать стабильную метку в адресе вида https://{метка}.{домен_сервиса}/… вместо случайного поддомена, чтобы делиться одной и той же ссылкой с командой и интеграциями. Метка должна быть корректной DNS-меткой, не входить в зарезервированный список и быть уникальной в системе. На тарифах без этой возможности панель и API возвращают отказ с указанием функции; администраторы при управлении чужими туннелями ограничения тарифа обычно не испытывают.
Как пользователь может использовать
- Разработчик после создания туннеля в дашборде задаёт свой поддомен в карточке туннеля или через API PATCH с действием
set_public_subdomain. - Пользователь делится коротким брендированным URL с заказчиком на поддомене домена сервиса. Каноническая ссылка для HTTP/HTTPS — URL туннеля вида
https://{метка}.{домен_сервиса}/…. - Интегратор настраивает OAuth redirect URI на постоянный хост туннеля.
- Владелец переименовывает поддомен в пределах правил уникальности (старое имя освобождается для других после успешного перехода).
- Пользователь на бесплатном плане пытается включить метку и получает понятный отказ с предложением сменить тариф.
- Администратор правит поддомен для туннеля пользователя при операционной необходимости.
Как это реализовано в сервисе
Запрос на смену метки приходит на плоскость управления вместе с идентификатором туннеля. Сервер проверяет владельца (или администратора), правила тарифа для обычных пользователей, формат метки, уникальность и частоту смены (защита от злоупотреблений). После успеха обновляется запись туннеля с новым URL туннеля и обновляется соответствие имя хоста → туннель, чтобы входящие запросы по новому имени сразу попадали в тот же туннель. Дальнейшая обработка запроса совпадает с обычной HTTP-маршрутизацией: проверки доступа, лимиты и обратный прокси к локальному сервису.
Смена своего поддомена
PATCH /api/tunnels (тот же маршрут, что и для других действий над туннелем).
Тело JSON (поля уточняйте по актуальному контракту API создания/изменения туннеля):
id— идентификатор туннеля (должен совпадать с объектом изменения).action:set_public_subdomainpublic_subdomain: строка — метка поддомена (только допустимые символы DNS-метки, без точек).
Успех: туннель возвращается с обновлённым URL туннеля (в ответе API — поле public_url) и полями хоста (как в ответе вашего API PATCH).
Ошибки: 400 (неверная метка, зарезервировано, не HTTP(S) туннель), 403 (нет функции в тарифе для не-админа), 409 (метка занята), 429 (слишком частые переименования), 413 (слишком большое тело запроса).
Авторизация
Требуется вход в дашборд или Bearer-токен. Не-владелец (кроме администратора) не может менять чужой туннель.
400 Bad Request
Недопустимая метка (длина, символы, дефисы), метка в зарезервированном списке, или туннель не HTTP/HTTPS — в теле JSON указано сообщение об ошибке.
401 Unauthorized
Пользователь не аутентифицирован.
403 Forbidden
Нет прав на изменение туннеля или у пользователя нет функции custom-public-subdomain в тарифе (код вроде feature_disabled в JSON).
409 Conflict
Такой поддомен уже используется другим туннелем.
413 Payload Too Large
Тело PATCH превышает лимит сервера.
429 Too Many Requests
Превышен лимит частоты переименований поддомена для пользователя.
Ограничения
- Доступно только для туннелей с протоколом HTTP или HTTPS.
- Метка — одна DNS-метка без точек; полноценный произвольный домен — отдельная возможность продукта (кастомные домены).
- Смена поддомена ограничена по частоте на пользователя.
- Уникальность проверяется глобально в пределах окружения: занятая метка недоступна другому туннелю, пока не освобождена.
Приватные HTTP-туннели
Общее описание функционала
Приватные HTTP-туннели позволяют владельцу скрыть туннель от анонимного доступа по URL туннеля. Пока туннель помечен как приватный, входящие запросы без действующего токена доступа (ссылка-приглашение или cookie после перехода по такой ссылке) получают отказ. В публичном режиме (по умолчанию) любой, кто знает URL туннеля, может обратиться к нему с учётом общих ограничений сервиса (лимиты, списки IP и тариф). Владелец может вернуть туннель в публичный режим; при этом все ранее выданные ссылки доступа отзываются. Функция доступна только для протоколов HTTP/HTTPS и на тарифах с правом приватных туннелей.
Панель управления
В личном кабинете на странице Туннели у каждого активного HTTP- или HTTPS-туннеля отображается колонка «Публичный» с переключателем:
| Положение | Режим | Кто может открыть URL туннеля |
|-----------|--------|-------------------------------|
| Включено | Публичный (по умолчанию) | Любой посетитель по известному URL (с учётом лимитов и политик доступа) |
| Выключено | Приватный | Владелец, администратор и гости с действующей ссылкой доступа; анонимные запросы отклоняются |
Тариф: перевести туннель из публичного в приватный могут пользователи с правом «приватные туннели» на платном тарифе. На бесплатном тарифе переключатель в положении «публичный» заблокирован; при наведении показывается подсказка со ссылкой на смену тарифа. Вернуть приватный туннель в публичный режим можно на любом тарифе.
Подтверждение: при переключении приватный → публичный сервис запрашивает подтверждение, потому что все активные ссылки доступа будут отозваны. Переход публичный → приватный выполняется сразу, без дополнительного диалога.
Тот же переключатель доступен в админ-консоли в списке всех туннелей.
Как пользователь может использовать
- Разработчик на платном тарифе создаёт HTTP-туннель и в дашборде выключает «Публичный», чтобы случайные посетители не видели локальный сервис.
- Владелец выдаёт коллеге ссылку доступа через API (см. справочник API) и отзывает её после демо.
- Пользователь возвращает туннель в публичный режим для открытого тестирования — после подтверждения в дашборде.
- Пользователь на бесплатном тарифе видит заблокированный переключатель и подсказку о смене тарифа; при создании туннель остаётся публичным.
Как это реализовано в сервисе
При создании или изменении туннеля сервер применяет эффективную видимость: без права на тарифе запрос на приватность принудительно переводит туннель в публичный режим. Команда смены видимости через API или переключатель в дашборде меняет флаг публичности; переход в приватный режим проверяет тариф. Прокси для приватного туннеля проверяет токен в параметре запроса, заголовке или cookie. Ссылки создаются и отзываются через API. При смене тарифа без права сервер синхронизирует приватные туннели в публичные и очищает токены.
API (приватные туннели)
Смена видимости
Через дашборд: колонка «Публичный» на странице Туннели (то же в админ-консоли). Переключатель вызывает ту же операцию, что и API ниже.
PATCH /api/tunnels с телом:
{
"id": "<tunnel_id>",
"action": "set_visibility",
"is_public": false
}
is_public: false— сделать туннель приватным (только HTTP/HTTPS).is_public: true— вернуть публичный режим; все share-токены отзываются.
Требуется аутентификация владельца или администратора. На тарифе без private-tunnels — 403 с code: feature_disabled.
Ссылки доступа
GET /api/tunnels/{id}/share-links— список активных ссылок (только владелец).POST /api/tunnels/{id}/share-links— создать ссылку (тело:label, опциональноexpires_at).DELETE /api/tunnels/{id}/share-links/{token_id}— отозвать ссылку.
Создание ссылок разрешено только для приватных HTTP/HTTPS туннелей.
Доступ гостя
Гость открывает URL с параметром токена или проходит bootstrap; сервис выставляет cookie доступа до истечения срока ссылки.
Ошибки (приватные туннели)
| Ситуация | HTTP | Сообщение / код |
|----------|------|-----------------|
| Тариф без приватных туннелей (PATCH set_visibility → private) | 403 | feature_disabled, feature_id: private-tunnels |
| Приватность для TCP/UDP | 400 | private visibility requires http or https tunnel |
| Создание share-link для публичного туннеля | 400 | share links only for private tunnels |
| Анонимный доступ к приватному туннелю | 403 | forbidden (без валидного токена) |
| Просроченный или отозванный токен | 403 | forbidden |
При понижении тарифа приватные туннели автоматически переводятся в публичный режим без отдельного запроса пользователя.
Известные ограничения
- Приватный режим поддерживается только для HTTP и HTTPS; TCP-туннели всегда публичны по политике сервиса.
- Переключатель «Публичный» в дашборде показывается только для активных HTTP/HTTPS-туннелей; для туннелей на паузе или неактивных колонка пуста.
- На тарифе без права приватных туннелей новый туннель при создании остаётся публичным; переключатель в дашборде не позволяет сделать его приватным.
- Переход в публичный режим безвозвратно отзывает все активные ссылки доступа для туннеля.
- Управление ссылками доступа (создание и отзыв) в дашборде не предусмотрено — только через API; в интерфейсе доступна смена режима публичный/приватный.