Перейти к основному содержимому

HTTP туннель

Начиная с версии 0.36.0 tuna показывает в терминале полноэкранный интерфейс с лентой запросов, их деталями и повтором.

HTTP туннель открывает доступ из интернета к сайту, API, GraphQL или WebSocket-серверу, запущенному у вас локально. Туннели работают на всех тарифах без ограничения по времени. На бесплатном тарифе доступны динамический адрес и один бесплатный постоянный поддомен.

Быстрый старт​

tuna http 8080

В консоли появится публичный HTTPS-адрес вида https://4l7mqf-212-49-103-2.ru.tuna.am — запросы на него попадут в приложение на localhost:8080. Рядом будет ссылка на инспектор запросов, где видно каждый запрос и ответ.

примечание

Все флаги с подсказками — в справке:

tuna http --help

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

Готовые сценарии​

Флаги свободно комбинируются. Несколько типовых задач:

ЗадачаКоманда
Показать сайт заказчику под паролем по постоянному адресуtuna http 3000 --subdomain=brave-otter-4821 --basic-auth="client:s3cret"
Принимать вебхуки GitLab только с верной подписьюtuna http 8080 --subdomain=brave-otter-4821 --verify-webhook=gitlab --verify-webhook-secret=s3cret
Открыть API фронтендеру на другом доменеtuna http 8080 --cors --key-auth="dev-key"
Проверить вёрстку с телефонаtuna http 5173 --qr
Передать коллеге папку с файламиtuna http --file-server ./share --basic-auth="team:s3cret"
Открыть сервис, который проверяет заголовок Hosttuna http 11434 --request-header="host:localhost:11434"
Опубликовать собранный SPA (React, Vue)tuna http --file-server-spa ./dist

В Docker, CI и systemd удобнее передавать те же настройки переменными окружения:

TUNA_TOKEN=tt_*** TUNA_SUBDOMAIN=brave-otter-4821 TUNA_INSPECT=false tuna http 8080

Что можно опубликовать​

Первый аргумент tuna http — адрес приложения, которое нужно открыть:

АргументКуда уйдёт запрос
8080http://localhost:8080
localhost:8080, 10.0.0.1:8080указанный хост и порт, в том числе другая машина в вашей сети
https://localhost:443приложение, которое само принимает HTTPS
unix:///run/gunicorn.sockприложение на unix-сокете

Вместо адреса можно раздать каталог встроенным сервером: --file-server, --file-server-spa или --webdav.

Приложение на HTTPS​

tuna http https://localhost:443

По умолчанию сертификат приложения не проверяется, подойдёт и самоподписанный. Включить проверку — --tls-skip-verify=false.

Unix-сокет​

Если приложение принимает HTTP на unix-сокете, как, например, gunicorn, укажите путь к сокету с префиксом unix://:

tuna http unix:///run/gunicorn.sock

Инспектор, повтор запросов и политики трафика работают так же, как с портом. TLS к приложению за сокетом не поддерживается, флаг --tls-skip-verify к нему не применяется. Если приложение не отвечает, на странице ошибки 502 будет указан путь к сокету (unix:///run/gunicorn.sock), а не localhost с портом.

Требования к пути, права доступа и поведение при отсутствии сокета те же, что у TCP-туннеля.

Файловый сервер​

Отдаёт файлы из каталога и показывает список файлов:

tuna http --file-server ./

Одностраничное приложение (SPA)​

Для собранных одностраничных приложений (React, Vue, Angular): на любой несуществующий путь отдаётся index.html, поэтому работает клиентский роутинг.

tuna http --file-server-spa ./dist

WebDAV​

Каталог можно подключить как сетевой диск по протоколу WebDAV — с чтением и записью:

tuna http --webdav ./
warning

Файловый сервер и WebDAV открывают каталог всему интернету. Закройте доступ паролем или ключом.

Адрес туннеля​

АдресКак получитьТариф
Динамический, 4l7mqf-212-49-103-2.ru.tuna.amбез флаговлюбой
Бесплатный постоянный, brave-otter-4821.ru.tuna.am--subdomain=<ваш-поддомен>любой, один на аккаунт
Любой свободный поддомен, billing.ru.tuna.am--subdomain=billingподписка
Собственный домен, api.example.com--domain=api.example.comподписка
Защита от злоупотреблений

На бесплатном тарифе посетитель из браузера при первом заходе видит страницу-предупреждение о том, что сайт открыт через tuna. API-клиентов и вебхуки она не касается, а пропустить её можно заголовком tuna-skip-browser-warning. Зачем это нужно и как мы в целом боремся с фишингом и вредоносным контентом — на странице Злоупотребления и жалобы.

Динамический адрес​

Выдаётся автоматически при каждом запуске и меняется при переподключении. Адрес строится по схеме <случайная-часть>-<ваш-IP>.<локация>.tuna.am: IP-адрес источника виден в ссылке, так что анонимно разместить вредоносный контент не получится — подробнее в разделе Анонимность. В постоянном поддомене IP-адреса нет. Подходит для разовой демонстрации или отладки. Если нужен адрес, который не изменится, — для вебхуков, колбэков платёжных систем, закладки в браузере — используйте постоянный поддомен.

Бесплатный постоянный поддомен​

У каждого пользователя есть один постоянный поддомен — бесплатно и на любом тарифе. Имя выдаётся случайно в формате <прилагательное>-<существительное>-<4 цифры>, например brave-otter-4821, и одинаково во всех локациях: brave-otter-4821.ru.tuna.am и brave-otter-4821.nl.tuna.am.

Свой поддомен можно посмотреть в личном кабинете: он отмечен меткой «Бесплатный», рядом готовая команда запуска. Также его подсказывает клиент при запуске туннеля без флагов:

Your permanent free domain: brave-otter-4821.ru.tuna.am. Use it with --subdomain=brave-otter-4821

По умолчанию туннель, как и раньше, получает динамический адрес — постоянный поддомен нужно указать явно:

tuna http 8080 --subdomain=brave-otter-4821

В другой локации:

tuna http 8080 --subdomain=brave-otter-4821 --location=nl

Или полным именем:

tuna http 8080 --domain=brave-otter-4821.ru.tuna.am
Нужен токен

Поддомен привязан к вашему аккаунту, поэтому клиент должен быть авторизован вашим токеном. Сохраните его один раз командой tuna login или tuna config save-token <ТОКЕН> (токен есть на отдельной странице), либо передавайте через переменную окружения TUNA_TOKEN — например, в Docker и CI. Без токена или с токеном другого аккаунта поддомен не заработает.

  • Выбрать или сменить имя нельзя — поддомен с любым именем доступен по подписке.
  • Удалить поддомен или передать его другому пользователю нельзя, tuna domain clear его пропускает.
  • При смене тарифа поддомен сохраняется и не расходует лимит доменов подписки.
  • Если вы зарегистрировались раньше, поддомен появится при первом открытии раздела Домены или при первом запуске туннеля без флагов.

Зарезервированный поддомен​

По подписке можно занять любой свободный поддомен — после перезапуска туннеля адрес останется прежним:

tuna http 8080 --subdomain=billing

То же через переменную окружения:

TUNA_SUBDOMAIN="billing" tuna http 8080

Поддомен резервируется автоматически при первом запуске с флагом. Все ваши домены — в личном кабинете.

Внимание

Ошибка Domain already reserved означает, что поддомен в этой локации уже занят другим пользователем — выберите другое имя.

Собственный домен​

Добавьте свой домен следуя инструкциям в личном кабинете, после проверки DNS и выпуска Let's Encrypt сертификата можно пользоваться:

tuna http 8080 --domain=my-api-project.example.com

Пошагово — в статье Подключение своего домена.

Локация​

Туннель поднимается в локации ru, если не указано иное. Выберите ближайшую к пользователям сайта:

tuna http 8080 --location=nl

QR-код​

Флаг --qr печатает в консоли QR-код со ссылкой на туннель — удобно, чтобы открыть сайт на телефоне.

tuna http 5173 --qr

Защита доступа​

Туннель доступен всему интернету. Проверки ниже выполняются в клиенте tuna — запрос, который их не прошёл, до приложения не дойдёт.

ФлагКого пропускает
--basic-authзнающих логин и пароль
--key-authзапросы с ключом в заголовке X-Token
--cidr-allow, --cidr-denyзапросы из разрешённых подсетей
--ua-allow, --ua-denyзапросы с подходящим User-Agent
--verify-webhookвебхуки с верной подписью
--rate-limitне больше N запросов в секунду
--https-redirectтолько HTTPS, HTTP перенаправляется

Флаги со списками (--basic-auth, --key-auth, --cidr-*, --ua-*, --*-header) можно повторять. В переменных окружения значения перечисляются через запятую.

Пароль (basic auth)​

Браузер покажет окно ввода логина и пароля:

tuna http 8080 --basic-auth="login:password"

Несколько пользователей — повторите флаг:

tuna http 8080 --basic-auth="anna:pass1" --basic-auth="ivan:pass2"

Из скрипта:

curl -u login:password https://brave-otter-4821.ru.tuna.am/

Ключ в заголовке (API token)​

Для API и сервисов без браузера. Запрос пройдёт, только если в заголовке X-Token передан один из ключей:

tuna http 8080 --key-auth="my-secret-key"
curl -H "X-Token: my-secret-key" https://brave-otter-4821.ru.tuna.am/

Доступ по подсетям IP​

Белый список подсетей в CIDR-формате — остальным доступ закрыт:

tuna http 8080 --cidr-allow="203.0.113.0/24" --cidr-allow="198.51.100.7/32"

Или, наоборот, закрыть доступ отдельным подсетям:

tuna http 8080 --cidr-deny="10.0.0.1/32"

Доступ по User-Agent​

Совпадение ищется по подстроке. Запретить curl и разрешить всех остальных:

tuna http 8080 --ua-deny=curl

Разрешить только Chrome:

tuna http 8080 --ua-allow=Chrome
примечание

User-Agent легко подделать — используйте этот фильтр против ботов и случайных сканеров, а не как защиту.

Проверка подписи вебхуков​

tuna пропустит только вебхуки, подписанные секретом, который вы задали у провайдера. Остальные запросы получат 401 Unauthorized.

tuna http 8080 --verify-webhook=gitlab --verify-webhook-secret=1234

Поддерживаемые провайдеры: gitlab, github, sentry, linear. Для других сервисов и более сложной логики используйте политики трафика.

Ограничение частоты запросов (rate limit)​

Защитит локальное приложение от перегрузки — не больше N запросов в секунду:

tuna http 8080 --rate-limit=2

При превышении лимита клиент получит 429 Too Many Requests.

Только HTTPS​

Туннель по умолчанию отвечает и по HTTP, и по HTTPS. С флагом --https-redirect запросы по HTTP перенаправляются на HTTPS:

tuna http 8080 --https-redirect

Заголовки и CORS​

Заголовки запроса​

Добавить или заменить заголовок до того, как запрос попадёт в приложение. Частый случай — сервис принимает запросы только со «своим» Host, как Ollama или dev-серверы:

tuna http 11434 --request-header="host:localhost:11434"

Заголовки ответа​

Добавить или заменить заголовок в ответе клиенту:

tuna http 8080 --response-header="env:test" --response-header="x-robots-tag:noindex"

CORS​

Флаг --cors или переменная TUNA_CORS=true добавит CORS заголовки ко всем ответам. По умолчанию выставляются следующие заголовки:

Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Accept, Accept-Language, Content-Language, Origin
Access-Control-Allow-Methods: GET, HEAD, POST
Access-Control-Allow-Origin: *

Их можно переопределить с помощью флага --response-header.

Запросы типа OPTIONS обрабатываются автоматически 200 OK, не доходя до проксируемого сервера.

примечание

Если у вас возникают сложности в работе с CORS, рекомендуем ознакомиться с данной статьёй. Так же рекомендуем CORS Tester для проверки ваших CORS заголовков.

Другие возможности​

Политики трафика​

Когда флагов не хватает — маршрутизация по путям, условия, свои ответы — опишите правила в файле политик трафика. По умолчанию читается .tuna.yml из текущего каталога, другой путь — --policy-file. Флаг --policy-url загружает правила по ссылке. Ошибка в политике останавливает запуск туннеля, подробнее — в разделе Ошибки политики.

Инспектор запросов​

Включён по умолчанию и доступен на http://127.0.0.1:4040. Инспектор хранит запросы в памяти, поэтому на серверах и встраиваемых устройствах его лучше выключать: --inspect=false. Подробнее — на странице инспектора.

Отчёты об ошибках​

Флаг --capture-key встраивает в HTML-страницы виджет отчётов: тестировщик отправляет баг со скриншотом, не меняя код сайта.

tuna http 3000 --capture-key=YOUR_CAPTURE_KEY

Токен​

Обычно токен сохраняется один раз командой tuna login. Указать другой токен можно флагом --token или переменной TUNA_TOKEN, переопределение идёт по очерёдности конфигурации:

tuna http 8080 --token=tt_***

Справочник флагов​

ФлагПеременная окруженияОписание
-s, --subdomainTUNA_SUBDOMAINПоддомен в зоне tuna.am
-d, --domainTUNA_DOMAINПолное имя домена
-l, --locationTUNA_LOCATIONЛокация: ru (по умолчанию), nl
-f, --file-serverTUNA_FILE_SERVERРаздать каталог
-F, --file-server-spaTUNA_FILE_SERVER_SPAРаздать SPA
--webdavTUNA_WEBDAVWebDAV-сервер для каталога
--basic-authTUNA_BASIC_AUTHЛогин и пароль, login:password
--key-authTUNA_KEY_AUTHКлюч в заголовке X-Token
--cidr-allowTUNA_CIDR_ALLOWРазрешённые подсети
--cidr-denyTUNA_CIDR_DENYЗапрещённые подсети
--ua-allowTUNA_UA_ALLOWРазрешённые User-Agent
--ua-denyTUNA_UA_DENYЗапрещённые User-Agent
--verify-webhookTUNA_VERIFY_WEBHOOKПровайдер вебхуков
--verify-webhook-secretTUNA_VERIFY_WEBHOOK_SECRETСекрет подписи вебхуков
--rate-limitTUNA_RATE_LIMITЗапросов в секунду
--https-redirectTUNA_HTTPS_REDIRECTПеренаправлять HTTP на HTTPS
--request-headerTUNA_REQUEST_HEADERЗаголовок запроса, key:value
--response-headerTUNA_RESPONSE_HEADERЗаголовок ответа, key:value
--corsTUNA_CORSCORS-заголовки и ответ на OPTIONS
--policy-fileTUNA_POLICY_FILEФайл политик, по умолчанию .tuna.yml
--policy-urlTUNA_POLICY_URLСсылка на политики, только https
--inspectTUNA_INSPECTИнспектор, по умолчанию включён
--tls-skip-verifyTUNA_TLS_SKIP_VERIFYНе проверять сертификат приложения, по умолчанию true
--qrTUNA_QR_CODEQR-код со ссылкой
--capture-keyTUNA_CAPTURE_KEYВиджет отчётов
--tokenTUNA_TOKENТокен авторизации

Поведение​

Hop-by-hop​

НЕ поддерживаются hop-by-hop заголовки за исключением заголовка Connection: upgrade, необходимого для работы Websocket соединений.

WebSocket​

Поддерживается протокол с двусторонним соединением между клиентом (например, браузером) и сервером, дополнительные настройки не требуются. Передаваемые данные НЕ будут отображены в инспекторе.

Server-sent events​

Поддерживается технология отправки уведомлений от сервера к веб-браузеру, никакие дополнительные настройки не требуются. Передаваемые данные НЕ будут отображены в инспекторе.

примечание

При включенном инспекторе важно, что бы клиент отправлял заголовок Accept: text/event-stream, иначе инспектор будет пытаться перехватить запрос и это вызовет задержки. Браузер передаёт этот заголовок по умолчанию.

HTTP и HTTPS​

При старте туннеля отображается ссылка на HTTPS, но обращаться можно и по HTTP. Запретить обращение по HTTP можно добавив флаг --https-redirect.

Порядок обработки флагов и правил​

Флаги влияющие на поведение обработки трафика всегда выполняются в определённой последовательности, вне зависимости от того в какой очерёдности они переданы в аргументах.

  1. https-redirect
  2. cors
  3. cidr-allow
  4. cidr-deny
  5. ua-allow
  6. ua-deny
  7. rate-limit
  8. key-auth
  9. basic-auth
  10. policy-file / policy-url
  11. verify-webhook
  12. request-header
  13. response-header

Самостоятельное управление CORS заголовками​

Если вы хотите управлять CORS заголовками самостоятельно на нижестоящем сервере и при этом используете авторизацию в tuna при помощи --basic-auth или --key-auth. То Preflight запросы - не будут работать, так как эти OPTIONS запросы не содержат Authorization, X-Token и любые другие специфичные заголовки.

Решение на выбор:

  1. Не использовать авторизацию в tuna.
  2. Управлять CORS заголовками в tuna, а не самостоятельно.
  3. Обрабатывать OPTIONS и авторизацию отдельно при помощи более гибких политик трафика.
❓ Как это выглядит на схеме

Случай 1​

Вы управляете CORS на нижестоящем Caddy сервере и включаете авторизацию в tuna.

Схема изобращающая Случай 1

Случай 2​

Вы управляете CORS на нижестоящем Caddy сервере и НЕ включаете авторизацию в tuna.

Схема изобращающая Случай 2

Случай 3​

Вы управляете CORS и авторизацией в tuna.

Схема изобращающая Случай 3