# Tuna Документация > Документация сервиса туннелей tuna.am ## Aup ### Правила допустимого использования **Редакция от: 13 августа 2026 г.** #### 1. Общие положения 1.1. Настоящие Правила определяют, какое использование сервисов платформы Tuna является допустимым, и применяются ко всем пользователям независимо от тарифа. 1.2. Правила являются неотъемлемой частью [Договора-оферты](https://tuna.am/tos.md) (п. 12.1). Термины используются в значениях, определённых Договором. 1.3. Правила распространяются на действия Заказчика, участников его Организации и любых лиц, которым Заказчик предоставил доступ к сервисам или к результатам их работы. 1.4. Заказчик отвечает за соблюдение Правил всеми указанными лицами как за собственные действия. #### 2. Общие требования 2.1. Использование сервисов должно быть правомерным по законодательству Республики Армения, законодательству страны Заказчика и законодательству страны размещения используемой инфраструктуры. 2.2. Заказчик обязан обеспечивать наличие прав на данные и контент, публикуемые или обрабатываемые через сервисы, а также на используемые доменные имена и TLS-сертификаты. 2.3. Заказчик обязан не создавать своими действиями рисков для работоспособности платформы, её инфраструктуры и других пользователей. #### 3. Запрещённая деятельность ##### 3.1. Незаконный и вредоносный контент Запрещается размещать, распространять и передавать через сервисы: * материалы, оборот которых запрещён применимым законодательством; * материалы с сексуальной эксплуатацией несовершеннолетних — такие обращения обрабатываются в приоритетном порядке с немедленной блокировкой; * материалы, призывающие к насилию, терроризму и разжиганию ненависти; * контент, нарушающий авторские и смежные права, товарные знаки и иные права третьих лиц; * персональные данные, распространяемые без правового основания. ##### 3.2. Атаки и вредоносное ПО Запрещается использовать сервисы для: * распространения вредоносного программного обеспечения, включая вирусы, трояны, шифровальщики, эксплойты и загрузчики; * фишинга и подделки сайтов, форм авторизации и платёжных страниц любых организаций; * спуфинга, перехвата и подмены трафика третьих лиц; * организации управляющей инфраструктуры вредоносного ПО (command and control); * атак на отказ в обслуживании, сканирования портов, перебора паролей и иных атак на любые системы; * обхода средств защиты и систем фильтрации третьих лиц. ##### 3.3. Спам и нежелательные рассылки Запрещается использовать сервисы для рассылки нежелательных сообщений, в том числе через SMTP-туннели и вебхуки, а также для размещения инфраструктуры, обслуживающей такие рассылки. ##### 3.4. Злоупотребление ресурсами Запрещается: * обходить лимиты тарифа, в том числе регистрацией нескольких аккаунтов, автоматическим пересозданием ресурсов и техническими способами обхода тарификации; * использовать сервисы для майнинга криптовалют и иных вычислений, направленных на извлечение выгоды из ресурсов инфраструктуры Исполнителя; * использовать туннели и шлюзы как анонимизирующий прокси или VPN для проксирования трафика третьих лиц, не связанного с собственными ресурсами Заказчика; * использовать сервисы для организации файлообменных сетей и раздачи трафикоёмкого контента, не связанного с разработкой и эксплуатацией собственных приложений Заказчика; * создавать нагрузку, существенно превышающую типичную для выбранного тарифа и препятствующую работе других пользователей. ##### 3.5. Действия в отношении платформы Запрещается: * проводить нагрузочное тестирование, сканирование и тестирование на проникновение в отношении инфраструктуры Исполнителя без предварительного письменного согласия; * эксплуатировать обнаруженные уязвимости; об уязвимостях следует сообщать на ; * вмешиваться в работу платформы, декомпилировать и модифицировать клиентское ПО за пределами случаев, прямо разрешённых законом; * выдавать сервисы Tuna за собственные, если это не предусмотрено условиями тарифа или отдельным соглашением. #### 4. Особенности отдельных сервисов 4.1. **Туннели и шлюзы** предназначены для предоставления доступа к собственным ресурсам Заказчика — приложениям, которые он разрабатывает или эксплуатирует. Предоставление через них доступа к чужой инфраструктуре без согласия её владельца запрещено. 4.2. Для бесплатных аккаунтов при обращении из браузера показывается промежуточная страница-предупреждение. Обход этой страницы допускается только заголовком, описанным в [документации](https://tuna.am/docs/abuse.md), и только для собственных запросов Заказчика. 4.3. В адресах динамических доменов присутствует IP-адрес источника — это антифрод-мера, описанная в разделе [Злоупотребления](https://tuna.am/docs/abuse.md). Действия, направленные на её обход, рассматриваются как нарушение настоящих Правил. 4.4. **Пароли и Секреты** предназначены для хранения учётных данных и конфигураций Заказчика. Ограничения на состав размещаемых данных установлены разделом 14 [Договора-оферты](https://tuna.am/tos.md). 4.5. **Встречи, доски и отчёты** не предназначены для обработки специальных категорий персональных данных. Запись и публикация материалов встреч допускаются только при наличии правового основания и с уведомлением участников. 4.6. **Мониторы** должны быть направлены на ресурсы, принадлежащие Заказчику либо на проверку которых он получил согласие владельца. Использование мониторов для сканирования чужих систем запрещено. #### 5. Жалобы на злоупотребления 5.1. Жалобы направляются на адрес с указанием проблемного адреса, описания нарушения и подтверждающих материалов. Порядок подачи и обработки описан в разделе [Злоупотребления и жалобы](https://tuna.am/docs/abuse.md). 5.2. Заявитель получает подтверждение о принятии обращения. Срок рассмотрения зависит от характера нарушения; обращения, связанные с непосредственной угрозой безопасности, рассматриваются в приоритетном порядке. 5.3. Организациям, регулярно направляющим обращения, доступна интеграция через [API](https://tuna.am/docs/guides/api.md). #### 6. Меры реагирования 6.1. При нарушении настоящих Правил применяются меры, предусмотренные п. 12.6 [Договора-оферты](https://tuna.am/tos.md): требование устранить нарушение, ограничение или приостановление работы ресурса, сервиса либо аккаунта, удаление размещённого с нарушением контента, расторжение договора и блокировка аккаунта. 6.2. Мера выбирается соразмерно характеру нарушения, его последствиям и наличию повторности. 6.3. Немедленная блокировка без предварительного уведомления применяется при нарушениях, создающих непосредственную угрозу безопасности или третьим лицам: фишинг, распространение вредоносного ПО, материалы с сексуальной эксплуатацией несовершеннолетних, атаки на чужие системы, спам. 6.4. Во всех остальных случаях Заказчику направляется уведомление с указанием основания и предоставляется разумный срок для устранения нарушения. #### 7. Обжалование 7.1. Заказчик вправе направить возражение на адрес , приложив пояснения и подтверждающие материалы. 7.2. Возражение рассматривается в течение 10 рабочих дней. Если нарушение не подтвердилось, доступ восстанавливается. 7.3. При расторжении договора по основаниям настоящих Правил уплаченные суммы возврату не подлежат (п. 12.9 [Договора-оферты](https://tuna.am/tos.md)). #### 8. Изменение Правил 8.1. Исполнитель вправе изменять настоящие Правила в порядке, предусмотренном разделом 22 [Договора-оферты](https://tuna.am/tos.md). Актуальная редакция публикуется по адресу [/aup/](https://tuna.am/aup.md) с указанием даты. --- ## Blog ### Блог #### [🦎 Туннели стали высокодоступными](https://tuna.am/blog/high-availability.md) 15 октября 2026 г. · 10 мин. чтения ![Анимация: один из трёх дата-центров горит, а запросы посетителей идут через два оставшихся по туннелю в home lab, и сайт продолжает работать](/blog/img/2026-10-15-high-availability/cover.svg) С рождения сервиса туннели Tuna жили на простой схеме. Адрес туннеля вёл прямо на конкретный сервер, и этот сервер делал всё сразу: принимал трафик из интернета, держал подключения клиентов и передавал одно в другое. Для запуска это было разумно. Но Tuna выросла. Сегодня у нас одновременно онлайн больше тысячи туннелей, а туннельные ноды принимают десятки тысяч подключений в сутки. Для такого сервиса схема «всё на одном сервере» уже не годилась. Стоило серверу уйти на перезагрузку или потерять сеть, и все туннели на нём лежали вместе с ним. 14 октября мы закончили переезд, который готовили с лета, и **туннели наших пользователей стали по-настоящему высокодоступными**. Без преувеличения, это самое большое изменение в инфраструктуре Tuna с момента запуска. Ни один сервер и ни один дата-центр больше не является единственной точкой отказа. Делать для этого ничего не нужно. Адреса и сертификаты переехали сами. **Теги:** * [release](https://tuna.am/blog/tags/release) * [tuna](https://tuna.am/blog/tags/tuna) [**Читать дальше**](https://tuna.am/blog/high-availability.md) --- ### 📒 Туннель для 1С — база в интернете одной командой 6 октября 2026 г. · 4 мин. чтения База 1С стоит на компьютере в офисе, а поработать с ней нужно из дома, из командировки или показать её заказчику. Обычно выбирают между удалённым рабочим столом, VPN и публикацией базы на веб-сервере. Последний вариант самый удобный для пользователей — база открывается прямо в браузере, — но и самый хлопотный: нужно поставить Apache или IIS, подключить к нему модуль 1С, пробросить порт на роутере, получить «белый» IP и выпустить сертификат. В tuna-cli 0.37 появилась команда **`tuna 1c`**, которая делает всё это сама. Одна команда — и база доступна по HTTPS-адресу: ```shell tuna 1c "Моя база" --basic-auth="login:password" ``` #### Как это работает У 1С нет собственного HTTP-сервера: веб-клиент и тонкий клиент по HTTP обслуживает модуль расширения веб-сервера, который загружается в Apache или IIS. `tuna 1c` берёт всю цепочку на себя: 1. находит установленную платформу 1С и её модуль расширения веб-сервера; 2. при первом запуске скачивает Apache httpd в свой кэш; 3. запускает его на `127.0.0.1` и публикует в нём базу; 4. открывает к этому веб-серверу [HTTP-туннель](https://tuna.am/docs/tunnels/http.md). Веб-сервер слушает только локальный адрес — наружу базу отдаёт туннель. Остановили команду — публикация пропала вместе с ним. #### Быстрый старт Один раз выберите установку 1С и базу в мастере: ```shell tuna 1c setup ``` Мастер сохранит выбор в [конфигурационный файл](https://tuna.am/docs/guides/config-file.md), и дальше базу можно публиковать без аргументов: ```shell tuna 1c --basic-auth="login:password" ``` Базу можно указать и явно — именем из списка стартера 1С, каталогом файловой базы или строкой подключения к серверной: ```shell tuna 1c "Моя база" tuna 1c "C:\Bases\MyBase" tuna 1c "Srvr=localhost;Ref=MyBase" ``` #### Веб-клиент и тонкий клиент Откройте адрес туннеля в браузере — tuna перенаправит на `/1c/`, и вы попадёте в веб-клиент: ![Веб-клиент 1С, открытый по адресу туннеля](/docs/img/tuna_1c_web_client.png) Для тонкого клиента в шапке [интерфейса в терминале](https://tuna.am/docs/tunnels/tui.md) есть строка `1C client` с готовым параметром запуска: ```shell 1cv8c.exe ENTERPRISE /WS"https://<адрес туннеля>/1c" ``` Тот же адрес можно добавить в список баз стартера как базу «На веб-сервере». Чтобы пользователям не пришлось менять ссылку и параметр `/WS` после каждого перезапуска, задайте постоянный адрес — поддомен (`--subdomain=my-1c`) или свой домен (`--domain=1c.example.com`). #### База в интернете — закройте её `tuna 1c` открывает базу всему интернету, и между посторонним и вашими данными остаётся только окно входа 1С. Поэтому публикацию стоит закрыть ещё на уровне туннеля — тогда лишний запрос до 1С просто не дойдёт: | Флаг | Что делает | | ------------------------------- | --------------------------------------------------------- | | `--basic-auth="login:password"` | Спрашивает логин и пароль раньше, чем запрос попадёт в 1С | | `--key-auth="my-secret-key"` | Пропускает только запросы с ключом в заголовке `X-Token` | | `--cidr-allow="203.0.113.0/24"` | Пускает только из указанных подсетей | | `--rate-limit=20` | Ограничивает частоту запросов | Если запустить команду без `--basic-auth` и `--key-auth`, tuna покажет предупреждение. И проверьте пароли самих пользователей базы: учётная запись без пароля, особенно с правами администратора, — это открытая дверь. Все запросы к базе видны в [инспекторе](https://tuna.am/docs/tunnels/http/inspect.md), так что всегда понятно, кто и когда к ней обращался. #### Что понадобится * **[Подписка](https://tuna.am/#pricing) tuna.** На бесплатном тарифе опубликовать базу не получится. * **Windows x64.** Команда есть только в сборке tuna для Windows x64, сама платформа 1С при этом может быть и 32-, и 64-битной. * **Компонент «Модули расширения веб-сервера»** в установке 1С. По умолчанию он может быть не отмечен — в документации есть [инструкция со скриншотами](https://tuna.am/docs/tunnels/1c.md#web-module). * **Лицензия 1С, допускающая подключение через веб-сервер.** Учебная версия не подойдёт, а для пробы хватит бесплатной [лицензии для разработчиков](https://tuna.am/docs/tunnels/1c.md#community). Если 1С или база не находится, команда `tuna 1c discover` покажет, какие установки, модули и базы tuna видит на компьютере. #### Кому пригодится * **Удалённым сотрудникам** — бухгалтер или менеджер открывает базу из дома в браузере, без VPN и удалённого рабочего стола. * **Разработчикам и внедренцам 1С** — показать заказчику доработку прямо со своего компьютера, не разворачивая отдельный стенд. * **Небольшим офисам** — доступ к базе без «белого» IP, настройки роутера и собственного веб-сервера. * **Интеграциям** — файл публикации `default.vrd` можно править вручную: например, включить OData или HTTP-сервисы и отладить обмен с внешней системой. #### Команда новая Мы проверяли её на Windows 11 с 32-битной платформой 1С 8.3.27 и файловой базой. Серверные базы на рабочем кластере, 64-битная платформа и 1С 8.5 пока не проверены — полный список в [документации](https://tuna.am/docs/tunnels/1c.md#limitations). Если что-то не работает у вас, [напишите нам](https://t.me/tuna_support) — поможем разобраться. `tuna 1c` доступна по [подписке](https://tuna.am/#pricing) начиная с **tuna-cli 0.37.0**. Все флаги и подробности — в [документации](https://tuna.am/docs/tunnels/1c.md), обновить клиент можно по [инструкции](https://tuna.am/docs/guides/update.md). #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) * [tuna](https://tuna.am/blog/tags/tuna) * [cli](https://tuna.am/blog/tags/cli) --- ### 🆕 Приложения — Zero Trust доступ к вашим сервисам 29 мая 2026 г. · 5 мин. чтения Мы рады представить новый компонент платформы Tuna — **Приложения**. Это защищённый reverse proxy, который закрывает любой ваш веб-сервис авторизацией, SSO и гранулярным контролем доступа — без единой строчки изменений в самом сервисе. [Перейти к разделу Приложения в документации](https://tuna.am/docs/apps.md) ![Главная страница приложений](/docs/img/apps/main.png) #### Зачем это нужно? Представьте: у вас есть внутренний сервис — админка, staging-окружение, Grafana, внутренний API. Вы хотите дать к нему доступ только нужным людям, из нужных стран, с подтверждением через корпоративный SSO. Раньше это означало возню с nginx, oauth2-proxy, сертификатами и списками доступа. С **Приложениями** Tuna проверяет каждый входящий запрос: кто пользователь, как он аутентифицировался, откуда пришёл и имеет ли право видеть запрашиваемый путь. Всё это настраивается через веб-интерфейс за пару минут. Что можно сделать: * закрыть любой веб-сервис авторизацией без изменений в коде; * гранулярно разграничить доступ — например, `/admin/*` только для администраторов из России, а `/api/health` открыть без аутентификации; * подключить корпоративный SSO (Google, Yandex, GitHub, GitLab, VK, любой OIDC-совместимый провайдер); * требовать MFA или ручное одобрение администратора для чувствительных операций; * опубликовать сервис без публичного IP через туннель — достаточно одной команды; * выдать машинный доступ через сервисные токены для CI/CD, мониторинга и автоматизации. #### Два режима доставки трафика При создании приложения вы выбираете, как Tuna будет доходить до вашего сервиса. | Режим | Когда использовать | | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- | | **Прокси** | Сервис уже доступен по сети — в Kubernetes, облачной VM или той же сети, что и нода. Можно указать несколько upstream с балансировкой по весам | | **Туннель** | Сервис без публичного IP — за NAT, на dev-машине или в корпоративной сети. Бэкенд сам подключается к Tuna через клиент-агент | В режиме туннеля после создания приложения вы получаете готовую команду: ```shell tuna app <имя> --url=http://127.0.0.1:8080 ``` Запустите её на машине с сервисом — и приложение станет доступно через защищённый домен. #### Политики доступа — сердце системы Каждый запрос проходит через цепочку **политик**. Первая политика, чей шаблон пути совпал, определяет судьбу запроса: пропустить, потребовать MFA, запросить одобрение или отказать. По умолчанию доступ запрещён. ![Список политик приложения](/docs/img/apps/policies_list.png) Каждая политика — это **паттерн пути** (glob-шаблон вроде `/admin/*`) и **действие**: * **Разрешить** — доступ при прохождении правил; * **Требовать MFA** — то же плюс второй фактор (TOTP или код на email); * **Запретить** — безусловная блокировка; * **Пропустить** — путь без аутентификации (health check, webhook-эндпоинты). Внутри политики настраиваются **правила** — *кто именно* получит доступ. Их можно комбинировать по режимам OR / AND / NOT и собирать из разных типов: | Тип правила | Пример | | ------------------------------ | ----------------------- | | Команда / Email / Email RegExp | `.*@company\.com$` | | IP / CIDR | `10.0.0.0/8` | | Страна (GeoIP) | `RU`, `US`, `DE` | | Способ входа | `oidc`, `otp`, `mfa` | | Провайдер | `google` | | Service Token | машинная аутентификация | Например, чтобы открыть `/admin/*` только участникам команды и только из России, достаточно одной политики с правилами «Команда» (or) и «Страна: RU» (and). ##### Тестирование без риска Прежде чем применять конфигурацию, её можно проверить инструментом **Тест политик** — смоделировать запрос с любыми параметрами и увидеть, какое решение примет система. Без создания реальных сессий. ![Тестирование политик](/docs/img/apps/policy_test.png) #### Вход через корпоративный SSO Способы входа комбинируются — пользователь увидит их все на странице входа: * **Email OTP** — одноразовый код на email, удобно для внешних подрядчиков; * **Аккаунты tuna.am** — вход через личный аккаунт; * **Провайдеры команды** — внешние Identity Provider (Google, Yandex, GitHub, GitLab, VK, любой OIDC). ![Страница входа с провайдерами](/docs/img/apps/auth_page_providers.png) #### Ещё больше контроля **Запросы доступа** — для чувствительных ресурсов включите ручное одобрение. Пользователь объяснит причину, администратор одобрит доступ на нужный срок (от 15 минут до бессрочного). **Сервисные токены** — машинная аутентификация для CI/CD, мониторинга и скриптов. Пара Client ID + Client Secret, передаётся в заголовках. Поддерживается ротация с grace-периодом — обновляйте секрет без простоя. ```shell curl -H 'Tuna-Access-Client-Id: sat_...' \ -H 'Tuna-Access-Client-Secret: ...' \ https://your-app.example.com/ ``` **Сессии** — пользователи видят свои активные сессии, администраторы — сессии всей команды с полной информацией (IP, страна, User-Agent, последняя активность). Любую сессию можно отозвать, а кнопка «Закрыть все сессии» завершает их разом. **Гибкие настройки прокси** — заголовки запроса и ответа, переписывание путей, CORS, лимит размера тела, TLS до upstream и клиентский сертификат (mTLS). #### Полный аудит Все действия с приложениями записываются в [аудит-лог](https://my.tuna.am/team_audit_events): создание и изменение приложений, входы пользователей, одобрения и отклонения запросов доступа, отзыв сессий. Каждое событие содержит детали — кто, когда, откуда и что именно произошло. ![Аудит-лог событий приложений](/docs/img/apps/audit_events.png) #### Попробуйте прямо сейчас Перейдите в раздел [Приложения](https://my.tuna.am/team_apps), нажмите **+ Добавить приложение** — и закройте свой первый сервис авторизацией за пару минут. Подробное описание всех возможностей — в [документации](https://tuna.am/docs/apps.md): * [Политики доступа](https://tuna.am/docs/apps/policies.md) * [Запросы доступа](https://tuna.am/docs/apps/access_requests.md) * [Сервисные токены](https://tuna.am/docs/apps/service_tokens.md) * [Сессии](https://tuna.am/docs/apps/sessions.md) * [Настройки приложения](https://tuna.am/docs/apps/settings.md) #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) * [tuna](https://tuna.am/blog/tags/tuna) * [cli](https://tuna.am/blog/tags/cli) --- ### Кто может зайти в ваш внутренний сервис? 5 способов закрыться авторизацией 2 июля 2026 г. · 6 мин. чтения Внутренние сервисы иногда нужно открывать — сотруднику, подрядчику или заказчику. Например, открыть staging, служебную панель, внутреннюю админку или API для интеграций. Или HTTP-сервис без собственной авторизации, вроде Prometheus или Alertmanager. Возникает задача: не встраивать логин в каждый сервис отдельно, а поставить перед ним слой доступа и решить, кого пускать, каким способом и к каким путям. Способов решить эту задачу несколько, и каждый хорош для своей ситуации. Разберём от самых простых к более гибким по контролю. В конце — сравнительная таблица. [Перейти к разделу Приложения в документации](https://tuna.am/docs/apps.md) ![Главная страница приложений](/docs/img/apps/policies_list.png) #### Способ 1. VPN: не выставлять сервис наружу вообще Классика: сервис живёт в приватной сети, доступ — только через VPN. ![VPN](/blog/img/2026-07-02-apps-access-methods/VPN.webp) **Когда работает.** В компании уже есть поднятый и поддерживаемый VPN, все пользователи — штатные сотрудники с настроенными клиентами, и никого извне пускать не нужно. **Ограничения:** * Контроль на уровне сети, а не на уровне пользователя и пути. Настроить так, чтобы разработчики имели полный доступ, а дизайнеры — только к /dashboards, не получится. * VPN кто-то должен поднимать и поддерживать. Избыточен для небольших проектов. Разворачивать всё это ради одной Grafana и пяти человек — стрельба из пушки по воробьям. #### Способ 2. Basic auth: логин-пароль на прокси Самый быстрый вариант: повесить HTTP basic auth на nginx или прямо на туннель — в Tuna это делается флагом при запуске: ```bash tuna http 3000 --basic-auth="user:password" ``` ![Basic auth](/blog/img/2026-07-02-apps-access-methods/basic_auth.png) **Когда работает.** Нужно на день-два показать демо заказчику или прикрыть тестовый стенд от случайных глаз и ботов. Одна пара логин-пароль, ноль настройки. **Ограничения.** * Не видно, кто заходил. Пароль один на всех, его пересылают в чатах — персональной привязки нет, и вы не узнаете, кто именно был внутри. * Доступ нельзя отозвать у одного человека — только сменить пароль сразу всем. * Нет ролей, второго фактора и журнала. Basic auth просто спрашивает пароль, но не дает разграничить права или посмотреть историю входов. По сути это замок для честных людей: подходит для демо на пару дней, но не для постоянного доступа к админке. #### Способ 3. IP-фильтры: пускать только со своих адресов Дать доступ списку IP или подсетей на файрволе, в nginx или на туннеле. ![IP filters](/blog/img/2026-07-02-apps-access-methods/ip_filter.png) **Когда работает.** Доступ нужен из офиса со статическим адресом или с конкретных серверов (мониторинг, CI). Для машинного трафика с известных адресов — нормальное решение. **Ограничения:** * Когда люди работают из дома, с мобильного интернета и из поездок, и их адреса меняются. * Нет персональной привязки. Фильтр отвечает на вопрос, откуда пришли, но не кто пришёл. #### Способ 4. Собрать самому: nginx + oauth2-proxy Полноценная авторизация перед сервисом без правок его кода: реверс-прокси, перед ним oauth2-proxy, OIDC-провайдер, сертификаты. ![Nginx + oauth2-proxy](/blog/img/2026-07-02-apps-access-methods/OAuth2_Proxy_horizontal.svg) **Когда работает.** У вас есть DevOps-ресурс, нестандартные требования и желание полностью контролировать каждый слой. Так работают многие инфраструктурные команды. **Ограничения:** * Выше порог входа. До запуска нужно связать прокси с провайдером, разобраться с cookie-доменами и редиректами, настроить обновление сертификатов. * Нужна поддержка. Связку нужно обслуживать и переделывать при каждой смене требований. * Тонкие правила собираются вручную. Чтобы открыть путь только одной группе пользователей и только с MFA, нужно использовать несколько инструментов. Для одного-двух внутренних сервисов такие трудозатраты редко окупаются. #### Способ 5. Zero Trust реверс-прокси: готовый слой авторизации Идея та же, что в способе 4 — проверять каждый запрос до того, как он дойдёт до приложения, — но всю инфраструктуру авторизации берёт на себя готовая платформа. Этот подход называют [Zero Trust](https://en.wikipedia.org/wiki/Zero_trust_architecture). По нему работают корпоративные продукты вроде Cloudflare Access, а в **Tuna** это сервис [Приложения](https://tuna.am/docs/apps/). ![Zero Trust](/docs/img/apps/auth_page.png) Как это выглядит на практике. Вы создаёте приложение в веб-интерфейсе и описываете правила доступа: какие пути кому открыты, где требовать второй фактор, кого не пускать вовсе. Проверка происходит на стороне Tuna — до вашего сервиса доходят только запросы, прошедшие все правила. В коде приложения ничего менять не нужно. Несколько вещей, которые в самосборном варианте потребовали бы отдельных инструментов, здесь есть из коробки: * **разные способы входа под разных людей** — корпоративный SSO для команды (Google, Yandex, GitHub, GitLab, VK или любой OIDC-провайдер) и одноразовый код на email для внешнего подрядчика, которому не нужно заводить аккаунт; * **правила на уровне путей** — например, служебный `/api/health` оставить открытым для проверок, а всё остальное закрыть; правила комбинируются по email, команде, стране, IP и способу входа; * **управление доступом** — режим запроса доступа с ручным одобрением (человек объясняет, зачем ему вход, а вы решаете, пускать ли), видимость активных сессий и отзыв доступа в любой момент: в разделе сессий видно, кто сейчас внутри, и любую сессию можно закрыть точечно или все разом; * **сервисные токены** для CI/CD и мониторинга — машинный трафик ходит отдельно от человеческого и так же подчиняется правилам; * **журнал и сессии** — в аудит-лог пишется, кто и откуда заходил, кто менял правила и выдавал доступ; видно историю входов и действий администраторов. Если у сервиса нет публичного IP — он на ноутбуке, за NAT, в закрытом контуре — его можно опубликовать через туннель одной командой: ```bash tuna app my-service --url=http://127.0.0.1:8080 ``` Подробный разбор настройки — в [документации](https://tuna.am/docs/apps/), анонс с обзором возможностей — [в блоге](https://tuna.am/blog/apps/). **Ограничения:** * Это решение для веб-сервисов и HTTP API. Доступ к базе данных или SSH-доступ к серверам — отдельные задачи, для них есть [TCP-туннели с IP-фильтрами](https://tuna.am/docs/tunnels/tcp/) и [Бастион](https://tuna.am/docs/bastion/). * Как любой SaaS, платформа — это внешняя зависимость: если политика компании требует держать контроль доступа строго внутри контура, ваш путь — способ 4. #### Сравнение | | Известен пользователь | Правила доступа | MFA | Отзыв доступа | Сложность запуска | Поддержка | | ---------------------------- | ------------------------- | ---------------------- | -------------- | ------------------------ | ----------------- | -------------------- | | VPN | частично (на уровне сети) | нет | зависит от VPN | вручную, профиль | средняя–высокая | постоянная | | Basic auth | нет | нет | нет | нельзя точечно | минуты | нулевая | | IP-фильтры | нет (только откуда) | нет | нет | правкой списка | минуты | рутина со списками | | nginx + oauth2-proxy | да | да, собирается вручную | да | вручную | дни | на вашей стороне | | Zero Trust proxy (Tuna Apps) | да | да, из интерфейса | да | в один шаг из интерфейса | минуты | на стороне платформы | #### Итог: как выбрать Показываете демо на пару дней → хватит basic auth на туннеле. Пускаете только серверы и офис со статическим IP → достаточно IP-фильтров. Вся команда штатная, VPN уже работает и есть кому его обслуживать → оставайтесь на VPN. Нужен контроль на уровне пользователей и путей, видно, кто заходил, и доступ нужно забирать точечно — но нет ресурса собирать и поддерживать связку прокси с OIDC — берите Zero Trust proxy. А если требования запрещают выносить авторизацию из своего контура → собирайте способ 4 и закладывайте время на поддержку. #### Попробуйте прямо сейчас Перейдите в раздел [Приложения](https://my.tuna.am/team_apps), нажмите **+ Добавить приложение** — и закройте свой первый сервис авторизацией за пару минут. Подробное описание всех возможностей — в [документации](https://tuna.am/docs/apps.md): * [Политики доступа](https://tuna.am/docs/apps/policies.md) * [Запросы доступа](https://tuna.am/docs/apps/access_requests.md) * [Сервисные токены](https://tuna.am/docs/apps/service_tokens.md) * [Сессии](https://tuna.am/docs/apps/sessions.md) * [Настройки приложения](https://tuna.am/docs/apps/settings.md) #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [apps](https://tuna.am/blog/tags/apps) * [security](https://tuna.am/blog/tags/security) * [vpn](https://tuna.am/blog/tags/vpn) * [reverse-proxy](https://tuna.am/blog/tags/reverse-proxy) --- ### Новый инспектор запросов, шлюзы, IP политики и бастион 26 марта 2025 г. · 3 мин. чтения В этом релизе мы привнесли множество новшеств, переработали инспектор запросов, ещё больше сосредоточились на безопасности и продолжаем развивать функции туннелей. #### Новый инспектор запросов Инспектор с более интуитивным дизайном, чтением тела запроса и функцией повтора, нас очень много просили и вот мы рады его представить. А для большего удобства мы встроили инструменты разработчика вроде **Base64 Encode/Decode** или **URL Encode/Decode** прямо в инспектор. *Если вы не нашли нужный инструмент, [напишите нам](mailto:info@tuna.am) и мы рассмотрим запрос.* #### Шлюзы [Шлюзы](https://tuna.am/docs/gateways.md) - это новая функция дополняющая функции туннелей и предназначена для создания всегда доступного облачного балансировщика или WEB сервера с гибкими политиками обработки трафика. ![gateways-main](/assets/images/main-19b8b7724c36ce8fe4c771d5447f65ea.png) Туннели это хорошо, но бывает окружение состоит из нескольких сервисов часть из которых запущено у вас, у вашего коллеги и в тестовом контуре. Но благодаря гибким [политикам трафика](https://tuna.am/docs/traffic-policy.md) вы можете распределять запросы в нужные точки, управлять заголовками, авторизацией, временем работы и много другое. к сведению На текущий момент функция доступна только в тарифе **Легенда**, но позже мы планируем это и для **Профи**. #### IP политики Если вы хотите быть уверенным, что все туннели и шлюзы доступны только для определённых подсетей, вы можете создать глобальные на команду IP политики и запретить или разрешить те или иные подсети по CIDR. ![team_ip_policies_1](/assets/images/team_ip_policies_1-b6efb1916fbb84bbbcc4e979cba39ceb.png) к сведению [Функция](https://tuna.am/docs/team/ip_policies.md) рассчитана только на использование в **Командах**. #### Бастион Кардинально новый функционал нацеленный на безопасный доступ к серверам и простую настройку. [Бастион](https://tuna.am/docs/bastion.md) - это SSH-сервер с ролевой мандатной моделью доступа, использующий принципы [нулевого доверия (Zero Trust)](https://en.wikipedia.org/wiki/Zero_trust_architecture). В отличие от классических SSH-серверов, бастион делает акцент на идентификацию пользователей, временные сертификаты и ролевую модель доступа, обеспечивая повышенную безопасность доступа к вашим серверам в купе с простой настройки. ![bastion](/assets/images/scheme-aeeed643ed226b44f550ed63551bc21f.png) ##### Зачем? Обычно предоставляя доступ коллегам к серверам по SSH вы просите их публичный RSA ключ и кладёте на сервер в `~/.ssh/authorized_keys` к нужному пользователю. Да, само по себе подключение безопасно, но без специальной подготовки и автоматизации инфраструктуры вы не можете узнать кто и когда подключался, отозвать доступ в любой момент, вы не знаете насколько надёжно сотрудники хранят свои приватные ключи, и не сделали ли они закладки чтобы иметь доступ даже в случае номинального отзыва доступа. С бастионом же, имеет ли пользователь доступ контролируется централизованно. Пользователь не может подключиться даже если незаметно положил свой ключ в `~/.ssh/authorized_keys` в обход вас, так как бастион использует иной подход. В первую очередь пользователю нужно пройти авторизацию на портале Tuna, получить временный сертификат и уже с ним подключаться к серверу. к сведению [Функция](https://tuna.am/docs/bastion.md) рассчитана только на использование в **Командах**. #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) * [tuna](https://tuna.am/blog/tags/tuna) * [cli](https://tuna.am/blog/tags/cli) --- ### 🆕 Доски, Встречи и другие обновления на платформе 24 марта 2026 г. · 4 мин. чтения Это большой релиз! Мы добавили два новых, крупных сервиса - Доски и Встречи, новые функции в Мониторах и Отчётах, улучшили инспектор запросов и улучшения в sshd туннелях. #### Доски Хедлайнер релиза! [![Boards](/blog/img/2026-03-24/boards.png)](https://my.tuna.am/boards) Как и многие наши инструменты, [Tuna Доски](https://my.tuna.am/boards) выросли из инструмента для внутреннего использования. Первые его версии были крайне примитивные и простые, но для нас этого всегда было достаточно. Вот так проект выглядел исторически ... ![Plato история 1](/blog/img/2026-03-24/boards_history_1.png) ![Plato история 2](/blog/img/2026-03-24/boards_history_2.png) ![Plato история 3](/blog/img/2026-03-24/boards_history_3.png) Поэтому мы никогда не использовали другие аналоги вроде Miro и всегда старались использовать свой внутренний продукт. Если вы заметили, какие-либо схемы и фирменные рисунки сделаны именно в этом инструменте. Сегодня мы рады представить **Доски** как часть нашей платформы для разработчиков. Здесь вы можете зарисовать схему инфраструктуры, планировать новые функции, проектировать новый UX и UI, а также использовать встроенный голосовой чат, таймер и другие возможности. *** #### Встречи Видео звонки давно стали неотъемлемой частью любых онлайн-встреч, каждый уважающий себя разработчик, ненавидит эти проклятые созвоны, но теперь вы можете делать это на нашей платформе! Встречайте, [Tuna Встречи](https://my.tuna.am/meet). [![Встречи](/blog/img/2026-03-24/meets.png)](https://my.tuna.am/meet) Функционал достаточно стандартный, есть режим докладчика, презентации, размытие фона и так далее. Интерфейс полностью адаптирован под мобильные устройства, поэтому вы можете созваниваться как за компьютером, так и в дороге. *** #### Интеграции с трекерами задач После того, как у нас появились [Отчеты](https://tuna.am/docs/reports.md) и [Мониторы](https://tuna.am/docs/monitors.md), нам стало сразу понятно, что было бы удобно по инциденту в мониторах либо по новому отчету иметь возможность одной кнопкой создать задачу в GitLab, Jira или Яндекс.Трекере. Поэтому мы сделали интеграцию с основными популярными трекерами задач для того, чтобы вы могли быстро создавать задачи в вашем любимом трекере. ![Интеграции 1](/blog/img/2026-03-24/intagrations_1.png) ![Интеграции 2](/blog/img/2026-03-24/intagrations_2.png) ![Интеграции 3](/blog/img/2026-03-24/intagrations_3.png) *** #### Фильтр в инспекторе запросов В инспекторе запросов добавилась строка фильтрации запросов по множеству параметров: тип запроса, статуса ответа, заголовки, IP-адрес и многое другое. Чтобы начать использовать, обновитесь до последней версии [tuna-cli](https://tuna.am/docs/guides/update.md). [![Фильтры в инспекторе запросов](/blog/img/2026-03-24/inspector_filter.png)](https://tuna.am/docs/tunnels/http/inspect.md) *** #### Улучшения в SSHd туннелях Не забываем развивать и [туннели](https://tuna.am/docs/tunnels/ssh.md). 1. Добавлена поддержка **Windows 11+**, пользователь получит терминал PWSH. 2. Авто обнаружение *$HOME*, *$SHELL* и настроек профиля пользователя из под которого запущен SSHd туннель. 3. Переход на asciinema формат в ssh-sessions. Так, что сессии теперь пишут всё, включая работу в тестовых редакторах, запуск TUI утилит и т.д. Записи можно смотреть в терминале, встроить на сайт стандартным плеером или конвертировать в GIF командой `tuna ssh-session export`. **Asciinema плеер** **GIF** ![ssh_session_asciinema](/blog/img/2026-03-24/ssh_session_asciinema.gif) *** #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [customer-portal](https://tuna.am/blog/tags/customer-portal) --- ### 🖥️ tuna-cli 0.36 — интерфейс в терминале и большое обновление 30 сентября 2026 г. · 6 мин. чтения За последние два релиза консольный клиент **tuna-cli** изменился сильнее, чем за весь предыдущий год. Главное — у туннелей появился **полноэкранный интерфейс в терминале**: вместо бегущего текстового лога вы видите ленту запросов, метрики, сессии баз данных и SSH и можете разобрать любой запрос, не выходя из консоли. Обновиться до **0.36.1** можно по [инструкции](https://tuna.am/docs/guides/update.md), а сам клиент теперь подскажет нужную команду — об этом ниже. #### Интерфейс в терминале Интерфейс включается сам, когда вы запускаете `tuna http`, `tuna tcp`, `tuna ssh`, `tuna postgres`, `tuna redis` или `tuna kubernetes` в терминале. В шапке всегда видны аккаунт, адрес туннеля и локальный адрес, куда он ведёт, ссылка на [инспектор](https://tuna.am/docs/tunnels/http/inspect.md) и статус подключения. Если туннель запущен с ограничениями доступа или опциями, в шапке появляются строки **Access** и **Options** — например, `basic auth (1) · cidr deny 203.0.113.0/24` и `rate limit 20/s · cors`, так что видно, с какими настройками туннель работает прямо сейчас. Пароли и ключи не показываются, только их количество. Основная часть экрана зависит от типа туннеля. ##### HTTP: лента запросов и метрики Новые запросы появляются сверху, над лентой — счётчики: всего запросов, rpm, p50 и p90 времени ответа, число ответов 4xx и 5xx. По `Enter` открываются детали запроса с заголовками и отформатированным JSON-телом, `r` повторяет запрос, а `/` фильтрует ленту по методу, пути или статусу. Отлаживать вебхук или API стало заметно удобнее: не нужно переключаться в браузер, чтобы понять, что именно пришло. ##### Postgres и Redis: сессии и запросы Слева список сессий, справа — события выбранной: запросы с подсветкой, число строк в ответе, ошибки. `y` копирует запрос в буфер обмена. Видно, какие запросы шлёт ваше приложение или коллега, подключившийся к базе через туннель. ##### SSH: живой просмотр и запись сессий Для `tuna ssh` интерфейс показывает инструкцию для подключения и ленту сессий, включая отказы в доступе. `Enter` на активной сессии открывает её просмотр **в реальном времени**, на завершённой — воспроизведение записи. ##### Горячие клавиши | Клавиша | Действие | | ------------------ | -------------------------------------------------------- | | `c` | Скопировать адрес туннеля | | `i` | Открыть инспектор в браузере | | `Q` | Показать QR-код адреса — удобно открыть сайт на телефоне | | `l` | Показать или скрыть лог | | `↑` `↓`, `g` / `G` | Навигация по ленте | | `Ctrl+C` | Остановить туннель и выйти | Полный список клавиш для каждого типа туннеля — в [документации](https://tuna.am/docs/tunnels/tui.md). ##### Если нужен старый добрый лог Интерфейс не мешает автоматизации: он не включается, если вывод перенаправлен в файл или пайп, туннель запущен [как сервис](https://tuna.am/docs/tunnels/guides/service.md), задана переменная `CI` или `NONINTERACTIVE`, а также когда tuna запускает ИИ-агент — Claude Code, Cursor и другие. Вернуть текстовый лог вручную можно флагом `--log=stdout` или переменной `TUNA_TUI=0`: ```shell tuna http 8080 --log=stdout ``` #### Туннели ##### Unix-сокеты `tuna http` и `tuna tcp` умеют публиковать приложение, которое слушает не порт, а [unix-сокет](https://tuna.am/docs/tunnels/http.md#unix-socket) — например, gunicorn или php-fpm за прокси: ```shell tuna http unix:///run/gunicorn.sock ``` Инспектор, повтор запросов и политики трафика работают так же, как с портом. Через [TCP-туннель](https://tuna.am/docs/tunnels/tcp.md#unix-socket) можно, например, временно открыть Docker API — только обязательно ограничьте доступ своим IP через `--cidr-allow`: доступ к `docker.sock` равносилен root-доступу к хосту. ##### Политика трафика по ссылке и сжатие ответов [Политику трафика](https://tuna.am/docs/traffic-policy.md) для `tuna http` теперь можно загрузить по https-ссылке — одна политика в репозитории на все машины команды: ```shell tuna http 8080 --policy-url=https://gitlab.com/example/policies/-/raw/main/policy.yml ``` Новое действие [`compress_response`](https://tuna.am/docs/traffic-policy.md#compress_response) сжимает ответ приложения в `br`, `zstd`, `gzip` или `deflate`, если оно не сделало этого само. Ответ сжимается на лету, поэтому SSE и потоковые ответы продолжают работать. Заодно политика стала строже: если файл из `--policy-file` не найден, политика не парсится или у аккаунта нет подписки Team, туннель **не запустится** — раньше клиент выводил предупреждение и продолжал работу. Подробнее — в разделе [Ошибки политики](https://tuna.am/docs/traffic-policy.md#policy-errors). ##### Trigger получает данные события [`tuna trigger`](https://tuna.am/docs/tunnels/trigger.md) раньше просто запускал команду на входящий вебхук или письмо. Теперь команда получает само событие: тело запроса или письмо приходит на stdin, а метод, путь, query и заголовки — в переменных окружения `TUNA_REQUEST_*` и `TUNA_MAIL_*`. Так можно, например, запускать деплой только по push в `main`: deploy.sh ```shell #!/bin/sh set -e [ "$TUNA_REQUEST_HEADER_X_GITLAB_EVENT" = "Push Hook" ] || exit 0 jq -e '.ref == "refs/heads/main"' > /dev/null || exit 0 /opt/app/deploy.sh ``` SMTP-триггер теперь срабатывает на каждое принятое письмо, а не один раз на соединение, а локальный адрес SMTP-сервера задаётся флагом `--listen-address`. ##### Проверка подписи вебхуков GitHub и Sentry `--verify-webhook=github` и `--verify-webhook=sentry` теперь проверяют HMAC-SHA256 от тела запроса так, как описано в документации провайдеров. Раньше настоящие доставки от GitHub и Sentry получали `401` — если вы из-за этого отключали проверку, самое время включить её обратно. #### Секреты в консоли В tuna-cli 0.35 сильно вырос [CLI секретов](https://tuna.am/docs/secrets/cli.md): работа с отдельными секретами, управление проектами и окружениями, секреты файлом без записи на диск, офлайн-режим и отпечатки значений. Об этом — [отдельный пост](https://tuna.am/blog/secrets-cli.md). #### Мелочи, которые экономят время * **Подсказка по обновлению.** Когда выходит новая версия, клиент показывает готовую команду обновления для вашего способа установки: brew, winget, apt, dnf, zypper, скрипт установки или Docker. `tuna version` показывает способ установки и проверяет наличие новой версии. * **Подсветка справки.** В `--help` выделены команды, флаги и примеры. * **Подтверждение удаления.** Перед удалением доменов, портов, туннелей, API-ключей, секретов и проектов клиент переспрашивает. Пропустить вопрос — флаг `--yes`. * **`tuna whoami`** показывает, под каким аккаунтом авторизован клиент. #### Что проверить при обновлении * **Удаление в скриптах требует `--yes`.** Если команду удаления, например `tuna domain clear` или `tuna secrets delete`, запускают без терминала — в CI или cron, — без флага `--yes` она сразу завершится ошибкой. * **API-ключи выпускаются только в личном кабинете.** Команды `tuna api-key create` и `tuna session terminate` удалены: сервер больше не позволяет выпускать ключи и завершать веб-сессии по API-ключу. Ключи создаются в [личном кабинете](https://my.tuna.am/api_keys). * **Новый репозиторий пакетов.** Пакеты для Linux переехали в реестр `code.tuna.am`, а пакет называется `tuna-cli`. На Debian и Ubuntu обычный `apt upgrade` сам переключит репозиторий, на RHEL, Fedora и openSUSE репозиторий нужно один раз сменить вручную — команды есть в [инструкции по обновлению](https://tuna.am/docs/guides/update.md). * **Сроки поддержки старых версий.** Для пользователей без подписки версии **0.32.x** перестают работать 1 октября 2026 года, **0.33.x** — 1 ноября, **0.34.x** — 1 декабря, **0.35.x** — 1 января 2027 года. Полная таблица — в [политике обновления](https://tuna.am/docs/guides/update.md). Полный список изменений по версиям — в [журнале изменений](https://tuna.am/changelog.md). #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) * [tuna](https://tuna.am/blog/tags/tuna) * [cli](https://tuna.am/blog/tags/cli) --- ### Ошибка ERR_NGROK_9040. Ngrok закрыл доступ для всех российских IP-адресов 2 апреля 2025 г. · 1 мин. чтения Пользователи массово столкнулись с проблемами в работе ngrok в России — при попытке запустить туннель отображается ошибка `ERR_NGROK_9040`: "We do not allow agents to connect to ngrok from your IP address". Это связано с санкциями, которые запрещают предоставление сервиса пользователям из России. ```sh ERROR: authentication failed: We do not allow agents to connect to ngrok from your IP address (198.51.100.55). ERROR: ERROR: ERR_NGROK_9040 ERROR: https://ngrok.com/docs/errors/err_ngrok_9040 ERROR: ``` В качестве решения проблемы с ошибкой `ERR_NGROK_9040` мы предлагаем воспользоваться нашим сервисом [Tuna](https://my.tuna.am/sign_up/?utm_source=blog&utm_medium=organic&utm_campaign=err_ngrok_9040) – простой интерфейс, понятный функционал, в целом, всё, как надо. [![demo](/assets/images/demo-5f3d687ab6fd177c90ef62d6fd811a1a.webp)](https://my.tuna.am/sign_up/?utm_source=blog&utm_medium=organic&utm_campaign=err_ngrok_9040) **Теги:** * [tuna](https://tuna.am/blog/tags/tuna) --- ### 🎁 Бесплатный тариф без таймера и с постоянным поддоменом 2 октября 2026 г. · 3 мин. чтения У бесплатного тарифа Tuna было два ограничения, на которые жаловались чаще всего: туннель жил только **30 минут**, а адрес при каждом запуске был новым. Оба ограничения мы убрали: * HTTP-туннель на бесплатном тарифе работает **без ограничения по времени** — сколько нужно; * у каждого пользователя есть **собственный постоянный поддомен** вида `brave-otter-4821.ru.tuna.am`, который не меняется между запусками. #### Туннели без таймера Раньше туннель на бесплатном тарифе отключался через полчаса, и его приходилось перезапускать — а вместе с ним менялся и адрес. Для быстрой демонстрации этого хватало, для чего-то длиннее — уже нет. Теперь таймера нет: туннель работает, пока вы его не остановите. Одновременно на бесплатном тарифе по-прежнему доступен один HTTP-туннель. #### Постоянный поддомен для каждого Динамический адрес вида `4l7mqf-212-49-103-2.ru.tuna.am` хорош для разовой отладки, но неудобен там, где адрес нужно куда-то записать: в настройки вебхука, в колбэк платёжной системы, в закладку браузера или в сообщение коллеге. Поэтому теперь у каждого аккаунта есть один постоянный поддомен — бесплатно и на любом тарифе. Как он устроен: * **имя выдаётся автоматически** в формате `<прилагательное>-<существительное>-<4 цифры>`, например `brave-otter-4821`; * **одно имя во всех локациях**: `brave-otter-4821.ru.tuna.am` и `brave-otter-4821.nl.tuna.am`; * **закреплён за вашим аккаунтом навсегда**: удалить его или передать другому пользователю нельзя, `tuna domain clear` его пропускает; * **выбрать или сменить имя нельзя** — поддомен с любым свободным именем, например `billing.ru.tuna.am`, по-прежнему доступен по [подписке](https://tuna.am/#pricing). Если у вас подписка Бесплатный поддомен есть и на платных тарифах, и он **не расходует лимит доменов подписки**: он идёт в дополнение к поддоменам, которые входят в ваш тариф. При смене тарифа — в любую сторону — поддомен сохраняется. #### Где найти свой поддомен Поддомен показан в разделе [Домены](https://my.tuna.am/domains) личного кабинета с меткой «Бесплатный», рядом лежит готовая команда запуска. Ещё его подсказывает сам клиент, если запустить туннель без флагов: ```text Your permanent free domain: brave-otter-4821.ru.tuna.am. Use it with --subdomain=brave-otter-4821 ``` Если вы зарегистрировались раньше, поддомен появится при первом открытии раздела **Домены** или при первом запуске туннеля без флагов. #### Как им пользоваться По умолчанию туннель, как и раньше, получает динамический адрес — постоянный поддомен нужно указать явно: ```shell tuna http 8080 --subdomain=brave-otter-4821 ``` В другой локации: ```shell tuna http 8080 --subdomain=brave-otter-4821 --location=nl ``` Поддомен привязан к аккаунту, поэтому клиент должен быть авторизован **вашим** токеном. Сохраните его один раз командой `tuna login` или передайте через переменную окружения `TUNA_TOKEN` — например, в Docker и CI. Без токена или с токеном другого аккаунта поддомен не заработает. Постоянный адрес особенно пригодится, чтобы: * принимать вебхуки GitLab, GitHub или Telegram-бота без перенастройки после каждого перезапуска; * показывать заказчику сайт по одной и той же ссылке; * держать на телефоне закладку на свой dev-сервер. Все подробности, включая таблицу видов адресов и тарифов, — в [документации по HTTP-туннелям](https://tuna.am/docs/tunnels/http.md#free-subdomain). #### Что остаётся по подписке * поддомены с любым свободным именем и собственные домены; * несколько туннелей одновременно и остальные типы туннелей — TCP, SSH, Postgres, Redis, Kubernetes и другие; * защита туннеля паролем, ключом и фильтрами по IP, [политики трафика](https://tuna.am/docs/traffic-policy.md), [шлюзы](https://tuna.am/docs/gateways.md) и прочие возможности платных тарифов. Сравнить тарифы можно на [главной странице](https://tuna.am/#pricing). #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) * [tuna](https://tuna.am/blog/tags/tuna) --- ### Helm chart для запуска tuna в Kubernetes 5 февраля 2025 г. · 3 мин. чтения Мы подготовили Helm chart для запуска tuna в Kubernetes.
В этой статье мы опишем случаи применения когда tuna может помочь вам в работе с приложениями в Kubernetes. #### Обзор В большинстве случаев вы можете обойтись штатными инструментами **kubectl**, опубликовать сервис просто создав Ingress, создать Service LoadBalancer у облачного провайдера для публикации доступа к базе данных, ну или просто запустить port-forward. Но не всегда штатные инструменты позволяют решать наши запросы достаточно быстро, удобно или дёшево. ##### Подключение репозитория Прежде чем начать, [установите Helm](https://helm.sh/docs/intro/install/).
Подключите репозиторий и обновите манифесты: ```shell helm repo add tuna https://releases.tuna.am/charts/ helm repo update tuna ``` ##### Основные значения (values) * `type` - [тип туннеля](https://tuna.am/docs/tunnels.md), передаётся как 1й аргумент к команде, доступные значения - `http, tcp, ssh`. * `to` - адрес назначения, это обязательный аргумент для типов `http, tcp`. Значение `to` передаётся в [переменную](https://tuna.am/docs/guides/environment-variables.md) `TUNA_PORT` Вы можете указать адрес сервиса в вашем кластере, например - `my-service:80` или `postgres-postgresql.postgres.svc:5432`. * `token` - ваш [токен](https://my.tuna.am/token) для создания туннелей, если передать его в это поле, то он будет сохранён в секрет и передан в tuna как переменная окружения `TUNA_TOKEN`. Но это не обязательно, вы можете и просто передать его в `env.TUNA_TOKEN=` или в `args[0]='--token='`. Также скорее всего вы захотите задать дополнительные конфигурации: * `env: {}` - Конфигурация через [переменные окружения](https://tuna.am/docs/guides/environment-variables.md). * `args: []` - Конфигурация через [аргументы командной строки](https://tuna.am/docs/tunnels.md). Более подробно читайте в [отдельном разделе](https://tuna.am/docs/tunnels/examples/kubernetes.md). ##### Публикация сервиса Базовый пример это просто публикация сервиса. Например вы хотите получить доступ какой то админке или метрикам. Tuna также поможет открыть доступ к сервису в minikube в серой сети. ```shell helm install tuna --set to=my-service:80 --set token= tuna/tuna ``` ##### Доступ к базе данных и другим TCP ресурсам Допустим у нас есть Redis или MongoDB или Postgres, и нужно открыть доступ к нему всем на какой то промежуток времени. Создать Service LoadBalancer можно, но это дороже. Создать роль и раздать всем разработчикам доступ в Kubernetes, чтобы каждый сам запуска у себя kubectl port-forward тоже можно, но это значительно дольше и ещё всех надо научить. C Tuna же организовать это можно самостоятельно буквально за 5 минут, раздать всем адрес подключения и вот уже все могут подключаться к вашим TCP приложениям. Создайте `values.yml` файл: ```yaml type: tcp to: postgres-postgresql.postgres.svc:5432 token: ``` Запустите приложение: ```shell helm install tuna -f values.yml tuna/tuna ``` ##### SSH доступ Вы можете запустить Tuna с встроенным SSHd сервером и подключиться в контейнер, напрямую через ssh. Добавьте привилегии `securityContext` если нужно установить дополнительное ПО в контейнере, или используйте свой образ. Создайте `values.yml` файл: ```yaml type: ssh token: securityContext: capabilities: {} readOnlyRootFilesystem: false runAsNonRoot: false runAsUser: 0 ``` Запустите приложение: ```shell helm install tuna -f values.yml tuna/tuna ``` #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [customer-stories](https://tuna.am/blog/tags/customer-stories) --- ### 🦎 Туннели стали высокодоступными 15 октября 2026 г. · 10 мин. чтения ![Анимация: один из трёх дата-центров горит, а запросы посетителей идут через два оставшихся по туннелю в home lab, и сайт продолжает работать](/blog/img/2026-10-15-high-availability/cover.svg) С рождения сервиса туннели Tuna жили на простой схеме. Адрес туннеля вёл прямо на конкретный сервер, и этот сервер делал всё сразу: принимал трафик из интернета, держал подключения клиентов и передавал одно в другое. Для запуска это было разумно. Но Tuna выросла. Сегодня у нас одновременно онлайн больше тысячи туннелей, а туннельные ноды принимают десятки тысяч подключений в сутки. Для такого сервиса схема «всё на одном сервере» уже не годилась. Стоило серверу уйти на перезагрузку или потерять сеть, и все туннели на нём лежали вместе с ним. 14 октября мы закончили переезд, который готовили с лета, и **туннели наших пользователей стали по-настоящему высокодоступными**. Без преувеличения, это самое большое изменение в инфраструктуре Tuna с момента запуска. Ни один сервер и ни один дата-центр больше не является единственной точкой отказа. Делать для этого ничего не нужно. Адреса и сертификаты переехали сами. Коротко * Точка, где трафик входит в Tuna, и нода, к которой подключён клиент, теперь разные серверы. Отказ любого из них не роняет туннели. * Точки входа и туннельные ноды стоят в нескольких дата-центрах двух провайдеров в России, Германии и Нидерландах. * Запрос попадает на ближайшую к отправителю точку входа, а не туда, куда подключён клиент. Поэтому вебхуки от Telegram доходят до туннеля, где бы ни работал клиент. * Для новых имён, портов и доменов регион больше не нужно выбирать. * Бесплатные поддомены из `ru.tuna.am` и `nl.tuna.am` переезжают в зону `a.tuna.free`, старый адрес после переезда перестаёт работать. * Высокая доступность работает для HTTP- и TCP-туннелей, для поддоменов в новых зонах и для собственных доменов, подключённых через CNAME. #### Как было В первой версии архитектуры было два региона, `ru` и `nl`. Имя туннеля в DNS указывало прямо на IP туннельной ноды. На ней же работал фронтенд на [Traefik](https://traefik.io/traefik), который принимал запросы из интернета и отдавал их в туннель. ![Анимация старой схемы: CLI получает адрес сервера у API и поднимает туннель до tuna-node; запросы посетителей идут через Traefik на том же сервере; при отказе сервера недоступны все туннели](/blog/img/2026-10-15-high-availability/before.svg) Раньше Traefik и tuna-node жили на одном сервере. Если он падал, туннели на нём становились недоступны. У такой схемы три слабых места, и все три мы ощущали на себе: * **Отказ сервера бил по всем его клиентам.** Обновление ядра, сбой у провайдера или проблемы в дата-центре делали недоступными все туннели на ноде, пока она не вернётся. * **Регион приходилось выбирать.** Вход трафика и подключение клиента были жёстко связаны: туннель в регионе `ru` принимал трафик только через российский сервер. * **Доступность зависела от маршрута до одного сервера.** Если путь от отправителя до ноды ломался, туннель становился для него недоступен. Так весной [вебхуки от Telegram](https://tuna.am/blog/tunnel-location.md) перестали доходить до туннелей в регионе `ru`. Обойти это можно было только одним путём: переключить туннель в другой регион и поменять адрес вебхука. #### Почему именно сейчас Слабые места старой схемы мы понимали давно, но по-настоящему ощутили их летом. В июне и июле в дата-центре в Нидерландах, где стояла наша нода региона `nl`, несколько раз случались крупные аварии. Нода была недоступна по несколько дней, и вместе с ней лежали сайты всех клиентов, чьи туннели работали через неё. Перенести туннели на другой сервер технически было можно, но проблему это решало лишь частично. Туннели на наших поддоменах переехали бы сразу. А больше половины туннелей на этой ноде работали на собственных доменах вида `example.com`, подключённых через A-запись. У нового сервера был бы новый IP-адрес, и каждому такому клиенту пришлось бы менять DNS у себя. Скорее всего, это заняло бы больше времени, чем восстановление дата-центра, поэтому разумнее было ждать. Это был первый звоночек. После него мы сели за схемы и планы того, как должны выглядеть высокодоступные туннели, и начали работу. Торопиться не хотели и всё проверяли на тестовом стенде. Роняли ноды, выключали точки входа и смотрели, как быстро клиенты переподключаются. А потом, с 8 по 11 октября, беспилотники повредили три дата-центра Яндекса, и работу площадки во Владимире [пришлось полностью остановить](https://www.kommersant.ru/doc/9023925). Вместе с сервисами Яндекса легли сайты компаний, которые жили в его облаке. Стало понятно, что откладывать больше нельзя, тем более что решение к тому моменту было уже хорошо проверено. Переключение 14 октября заняло почти целый день и закончилось ночью, а туннели за всё это время были недоступны около пяти минут. #### Как стало Мы разделили сервис на два слоя, и каждый из них теперь живёт на своих серверах. **Точки входа** принимают трафик из интернета и терминируют TLS. Вместо Traefik здесь теперь [Envoy](https://www.envoyproxy.io/). Точки входа собраны в российскую и европейскую группы. DNS отправляет запросы из России в российскую группу, а из остальных стран в европейскую и внутри группы выбирает ближайшую исправную точку. **Туннельные ноды** держат подключения клиентов. Их тоже несколько, они стоят в России и Европе. Клиента сервер подключает к ноде поближе к нему и с учётом загрузки, а точки входа знают, где сейчас находится каждый туннель, и доставляют запрос туда. ![Анимация новой схемы: точки входа RU и EU отдельно от туннельных нод; запрос из России и вебхук Telegram входят через разные точки входа и приходят на ноду с туннелем; при отказе ноды CLI перепод�ключается к соседней, при отказе точки входа трафик уходит на соседнюю](/blog/img/2026-10-15-high-availability/after.svg) Теперь точки входа отделены от нод, и отказ любой из них означает переподключение за секунды, а не простой. Что это даёт на практике: * **Отказ точки входа почти незаметен.** DNS исключает неработающую точку, и трафик уходит на соседнюю за несколько секунд. * **Отказ туннельной ноды больше не означает простой.** Клиент сам переходит на другую ноду, адрес туннеля при этом не меняется. Обычно на это уходят секунды, а при массовом переезде сотен туннелей до минуты. * **Где работает клиент, больше не важно.** Вебхук от Telegram попадает на ближайшую к Telegram точку входа, а оттуда на ноду, к которой подключён ваш клиент, хоть в России, хоть за её пределами. Проблема из весеннего поста решена архитектурой, а не обходным путём. #### Регионы больше не нужно выбирать Раз вход трафика не привязан к ноде подключения, выбор региона потерял смысл. Случайные имена, в том числе на бесплатном тарифе, и закреплённые имена теперь выдаются в зоне `a.2na.am`, TCP-адреса выглядят как `a.2na.am:<порт>`. Регион для новых адресов выбирать не нужно, в личном кабинете этого выбора больше нет. Закреплённые имена и TCP-порты в `ru.tuna.am` и `nl.tuna.am` остаются на месте, как и собственные домены с CNAME на эти зоны. Всё это работает как раньше и теперь тоже идёт через новые точки входа. Флаг `--location` и переменная `TUNA_LOCATION` теперь нужны только для них и указывают, в какой из старых зон искать закреплённое имя или порт. На новые зоны они не влияют. ##### Бесплатные поддомены Бесплатный постоянный поддомен теперь один, в зоне `a.tuna.free`, а не пара в `ru` и `nl`. Старые бесплатные поддомены переезжают туда сами. Когда через оба имени сутки не идёт ни одного туннеля и к ним не привязаны App или шлюз, пара в `ru.tuna.am` и `nl.tuna.am` заменяется одним именем в `a.tuna.free`. Поддомен сохраняется, если он там свободен: `free-example-1234.ru.tuna.am` становится `free-example-1234.a.tuna.free`. Если занят, выдаётся случайный. Пока имена в работе, они остаются на месте. Старые имена при переезде удаляются, вернуть их нельзя. Старый адрес отвечает 404, а запуск с `--domain=free-example-1234.ru.tuna.am` заканчивается ошибкой `Domain does not exist`. Если старый адрес записан в QR-кодах, закладках или настройках вебхуков, замените его на новый. Новое имя видно в личном кабинете. Чтобы запустить туннель на новом имени, хватит флага `-s` (`--subdomain`) с одним поддоменом, без зоны и без `--location`: ```bash tuna http 127.0.0.1:5192 -s=free-example-1234 ``` Менять имена в `a.tuna.free` мы не планируем, их можно считать постоянными. #### Где работает высокая доступность * **Поддомены в зонах `a.2na.am` и `a.tuna.free`** и TCP-порты, в том числе SSH, Postgres и Redis поверх TCP. WebSocket, HTTP/2 и SSE мы тоже проверили. * **Закреплённые имена и TCP-порты в старых зонах `ru.tuna.am` и `nl.tuna.am`**. Сами эти зоны теперь указывают на `a.2na.am` через CNAME. * **Собственные поддомены** вроде `app.example.com` или `www.example.com`, подключённые через CNAME на `a.2na.am` или на старые зоны `ru.tuna.am` и `nl.tuna.am`. Так же это устроено у ngrok и Cloudflare Tunnel. CNAME указывает на инфраструктуру целиком, а не на конкретный сервер. * **Собственная зона команды**, подключённая через CNAME `*.<зона>` на `a.2na.am`, `ru.tuna.am` или `nl.tuna.am`. Если ваш домен или зона уже подключены через CNAME на `ru.tuna.am` или `nl.tuna.am`, менять ничего не нужно. #### Где высокой доступности нет Высокой доступности нет у доменов, подключённых через A-запись, потому что она указывает на конкретные адреса. Поддомен для этого достаточно перевести на CNAME. А корневой домен вроде `example.com`, то есть сам домен без `www` и других поддоменов, так не перевести, потому что CNAME на него по стандарту DNS не поставить. Такой домен работает, но полной отказоустойчивости у него нет, и личный кабинет об этом предупреждает. Мы рекомендуем перенести сайт на поддомен с CNAME: лендинг на `www.example.com`, личный кабинет или веб-приложение на `app.example.com` или `my.example.com`. С корневого домена настройте постоянный редирект с кодом 301 или 308 через [шлюз](https://tuna.am/docs/gateways.md) с действием [`redirect`](https://tuna.am/docs/traffic-policy.md#redirect). Сам редирект останется без отказоустойчивости, но сайт за ним будет отказоустойчивым. Браузеры запоминают постоянный редирект, поэтому посетители, которые уже заходили на сайт, дальше идут сразу на поддомен. #### Что ещё ушло в прошлое Минимальная конфигурация копила проблемы два года, и переезд закрыл многие из них разом: * падение одного сервера больше не роняет туннели всех его клиентов; * вебхуки от Telegram доходят до туннелей независимо от того, где работает клиент; * собственный домен через CNAME больше не привязан к одному IP; * если проверка DNS для своего домена не прошла, личный кабинет сразу называет причину, например чужой адрес, лишнюю запись AAAA или отсутствие записи, а не молчит до следующих суток; * регион не нужно выбирать, а бесплатный поддомен один вместо двух. #### Теперь можно держать сервер дома История с дата-центром Яндекса хорошо напоминает, что любой дата-центр может однажды исчезнуть целиком и без предупреждения. Если ваш проект доступен из интернета через сервис, который живёт на одном сервере в одном дата-центре, доступность проекта ровно такая же, как у этого сервера. У Tuna так больше не получится. Точки входа и туннельные ноды разнесены по разным дата-центрам и странам, и потеря одного из них не остановит трафик наших пользователей. Поэтому, если у вас не высоконагруженный проект и вы давно хотели держать его дома в home lab, на мини-ПК или старом ноутбуке, сейчас для этого хорошее время. Со стороны Tuna ваш сайт будет доступен. От настоящей высокой доступности вас отделяют только электричество дома и интернет-провайдер, а они от нас не зависят. От перебоев с электричеством спасает ИБП, а от проблем у провайдера резервный канал. #### Что нужно сделать вам Закреплённые имена, порты и собственные домены работают как раньше, переходить на новый домен не нужно. Если вы пользовались бесплатным поддоменом в `ru.tuna.am` или `nl.tuna.am`, замените старый адрес на новый в `a.tuna.free` везде, где он записан. Подробности [выше](#%D0%B1%D0%B5%D1%81%D0%BF%D0%BB%D0%B0%D1%82%D0%BD%D1%8B%D0%B5-%D0%BF%D0%BE%D0%B4%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D1%8B). Ещё три вещи мы рекомендуем: * **Обновите клиент** до свежей версии. Версии старше 0.28 не замечают зависшую ноду и ждут её возвращения вместо того, чтобы переподключиться. В версии 0.35.0 есть ошибка, которая мешает переподключению. * **Переведите свой домен с A-записи на CNAME** `a.2na.am`. Старые A-записи продолжают работать, но отказоустойчивость даёт только CNAME. Что делать с доменом вроде `example.com`, мы описали [выше](#%D0%B3%D0%B4%D0%B5-%D0%B2%D1%8B%D1%81%D0%BE%D0%BA%D0%BE%D0%B9-%D0%B4%D0%BE%D1%81%D1%82%D1%83%D0%BF%D0%BD%D0%BE%D1%81%D1%82%D0%B8-%D0%BD%D0%B5%D1%82). * **Обновите списки разрешённых IP**, если вы прописывали у себя адрес ноды или туннеля. У TCP-адреса теперь несколько IP. Если что-то работает не так, как вы ожидаете, напишите нам в [Telegram-сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) или на . #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) * [tuna](https://tuna.am/blog/tags/tuna) --- ### 🕵️ AIOps: наш опыт внедрения HolmesGPT на трёх проектах 7 октября 2026 г. · 28 мин. чтения ![Окно Slack: алерт KubernetesJobFailed от Alertmanager и под ним разбор Holmes с вердиктом и шагами проверки](/blog/img/2026-10-07-holmesgpt-aiops/slack-window.png) Это пример алерта и его разбора Holmes в Slack. Алерт приходит в чат без контекста. «Pod перезапускается», «очередь переполнена», «Job упал» — и дежурный начинает с одного и того же: открыть дашборд, найти Pod, полистать логи, вспомнить, что выкатывали накануне. Это первичное расследование почти всегда одинаково по форме, и именно его мы отдали агенту. Мы внедрили [HolmesGPT](https://github.com/HolmesGPT/holmesgpt) — open-source SRE-агента — в шести Kubernetes-кластерах: в собственном кластере Tuna и в пяти кластерах наших клиентов, которые у нас на DevOps-сопровождении. Клиентских проектов два: один живёт в российском облаке, другой — зарубежный, на двух облаках. По ходу внедрения нам пришлось написать собственный инструмент — [holmes-alert-bridge](https://gitlab.com/yuccastream/holmes-alert-bridge): готовой связки с Alertmanager в открытой версии HolmesGPT нет. Он принимает алерт, отсеивает лишнее, передаёт агенту вместе с контекстом и приносит разбор в чат; код мы открыли. Теперь через несколько минут после алерта рядом с ним лежит гипотеза: что происходит, почему и что проверить. Ниже — как это устроено, сколько стоит и чему мы научились за первый месяц. Коротко * HolmesGPT — open-source SRE-агент из CNCF Sandbox: сам ходит в Kubernetes, метрики и логи и формулирует гипотезу о причине алерта. * Штатной push-интеграции с Alertmanager в открытой версии нет, поэтому мы написали и открыли [holmes-alert-bridge](https://gitlab.com/yuccastream/holmes-alert-bridge). * Агент у нас только читает и только строит гипотезы. Чинить он ничего не может — мы не дали. * Разбор занимает 2–3 минуты и стоит несколько рублей или 10–30 центов, в зависимости от модели. * До внедрения проверьте свои логи на пароли, токены и персональные данные: всё, что прочитает агент, уйдёт провайдеру модели. #### Зачем это нужно Правило алерта знает только то, что написано в его выражении: метрика пересекла порог. Почему — оно не знает, а аннотация с советом «поднимите лимит» написана один раз и на все случаи. Дежурный получает сигнал и тратит первые минуты на сбор контекста, прежде чем начать думать. HolmesGPT закрывает именно этот отрезок. Получив алерт, человек не начинает расследование с нуля: у него уже есть версия происходящего, список проверенного и два-три шага, чтобы версию подтвердить или опровергнуть. По свежим эпизодам от срабатывания алерта до готового отчёта в чате проходит около четырёх минут по медиане — вместе с задержкой группировки в Alertmanager. Вот как это выглядит на одном реальном эпизоде в Tuna — подробно он разобран ниже, в [кейсах](#tcp-listen-queue). График построен в нашей Grafana по обычным метрикам: выражение из правила алерта, серия `ALERTS` и счётчики bridge. ![График из Grafana: всплеск отброшенных соединений, состояние алерта pending и firing, период работы Holmes и момент появления гипотезы в чате](/blog/img/2026-10-07-holmesgpt-aiops/alert-timeline.png) Сверху — выражение из правила алерта и его порог (пунктир). Снизу — состояние алерта, работа Holmes и то, что в этот момент видит дежурный в чате. | Время | Что произошло | | -------- | -------------------------------------------------------------------------------------- | | 14:34:49 | метрика пересекла порог, алерт перешёл в `pending`: у правила `for: 5m` | | 14:39:49 | алерт сработал; через 10 секунд Alertmanager отправил сообщение в чат и копию в bridge | | 14:39:59 | Holmes начал расследование | | 14:42 | всплеск закончился, алерт погас | | 14:44:07 | разбор с гипотезой в чате — через 4 минуты 17 секунд после срабатывания алерта | От начала проблемы до гипотезы прошло чуть больше девяти минут, и пять из них — ожидание самого правила. Алерт к этому моменту уже погас, но теперь понятно, что это было и нужно ли что-то делать. Три решения, которые мы приняли сразу. **Только гипотезы, без автопочинки.** Сам HolmesGPT умеет больше: если дать ему права на запись и описать действия в skills, он будет не только искать причину, но и устранять её. Мы этого сознательно не включаем: у агента права только на чтение, а его ответ помечен как гипотеза, а не диагноз. **Оценка качества — честно оценка.** По нашему опыту гипотеза оказывается верной в 90–95 % случаев. Это именно оценка по ощущениям от дежурств, а не результат замера: систематически сверять разборы с реальными причинами инцидентов мы пока не начинали. **Каждый алерт стоит денег.** Это неожиданно полезный побочный эффект. Когда у повторяющегося алерта появляется строчка расходов, его гораздо сильнее хочется починить системно, а не закрывать глазами в сотый раз. Контуры получились разными, и это удобно для сравнения: | | Tuna | Проект в российском облаке | Зарубежный проект на двух облаках | | -------------------- | ------------------------------------ | --------------------------------------------------------- | --------------------------------- | | Кластеров | 1 | 2 | 3 | | Модель | DeepSeek V4.1 Flash | DeepSeek V4.1 Flash | Claude Sonnet 5 | | Как подключена | [OpenRouter](https://openrouter.ai/) | [ИИ-роутер Selectel](https://promo.selectel.ru/ai-router) | напрямую у провайдера модели | | Куда приходит разбор | Telegram | Slack | Slack | #### Что такое HolmesGPT [HolmesGPT](https://holmesgpt.dev) — агент для расследования проблем в облачной инфраструктуре. Лицензия Apache 2.0, проект создан в Robusta.dev и развивается при заметном участии Microsoft, с октября 2025 года входит в CNCF Sandbox. На GitHub у него около 3,5 тысячи звёзд, релизы выходят раз в одну-две недели — за последние четыре месяца их было тринадцать. Мы используем версии 0.41–0.42. Внутри — классический агентный цикл: модель получает вопрос, решает, какой инструмент вызвать, читает результат, вызывает следующий — и так до ответа. На один алерт уходит два-три десятка вызовов инструментов, в запутанных случаях — под сотню. Из чего это собрано: * **Toolsets** — наборы инструментов: Kubernetes (ресурсы, логи Pod'ов, метрики), Prometheus, VictoriaLogs, ArgoCD, Grafana, проверки сетевой доступности и другие. Свой набор описывается YAML-файлом со скриптами, кодом на Python или подключается как MCP-сервер. * **Skills** — то, что раньше называлось runbooks: файл `SKILL.md` с именем и описанием. Агент видит только описания, а сам текст подгружает по необходимости. Здесь живёт знание о вашем проекте. * **Модель** — любая, до которой дотягивается litellm: Anthropic, OpenAI, Azure, Bedrock, Gemini, Ollama, OpenRouter и любой OpenAI-совместимый API. * **Способы запуска** — CLI с интерактивной консолью, HTTP-сервер с Helm-чартом, оператор для Kubernetes (пока alpha), Python SDK. ![Архитектура HolmesGPT: алерты и вопросы на входе, модель и runbooks сверху, данные наблюдаемости снизу, анализ причин на выходе](/blog/img/2026-10-07-holmesgpt-aiops/holmesgpt-architecture.png) Схема из [README HolmesGPT](https://github.com/HolmesGPT/holmesgpt), лицензия Apache 2.0. ##### Как мы его ставим Основной сценарий — внутри Kubernetes, **отдельная инсталляция на каждый кластер**. Так не нужно строить сложную авторизацию: агент работает под ServiceAccount своего кластера с правами на чтение и ничего, кроме этого кластера, не видит. Запустить Holmes на выделенном сервере тоже можно — из CLI или docker-compose с kubeconfig, — но в кластере проще. Минимальный `values.yaml`: ```yaml additionalEnvVars: - name: MODEL # ключ записи из modelList value: fast - name: OVERRIDE_MAX_CONTENT_SIZE # окно контекста, см. «Грабли» value: "400000" - name: OPENROUTER_API_KEY valueFrom: secretKeyRef: name: holmes-llm key: OPENROUTER_API_KEY modelList: fast: model: openrouter/deepseek/deepseek-v4.1-flash api_key: "{{ env.OPENROUTER_API_KEY }}" temperature: 0.5 extra_body: provider: zdr: true # см. «Данные и безопасность» toolsets: kubernetes/core: enabled: true kubernetes/logs: enabled: true prometheus/metrics: enabled: true # + config с адресом Prometheus victorialogs: enabled: true # + config с адресом и доступом skills: enabled: true # всё, что умеет писать или ходить наружу, выключаем явно bash: enabled: false internet: enabled: false robusta: enabled: false enableTelemetry: false ``` ```bash helm repo add robusta https://robusta-charts.storage.googleapis.com helm upgrade --install holmes robusta/holmes -n holmes --create-namespace -f values.yaml ``` По ресурсам это скромно: Holmes у нас занимает около полугигабайта памяти, всплески дают инструменты вроде `kubectl` на больших списках. ##### Не только алерты Агента можно спрашивать и руками — это удобно, когда алерта нет, а вопрос есть. Через CLI (`holmes ask "..."`) или прямо у инсталляции в кластере: ```bash kubectl -n holmes port-forward svc/holmes-holmes 8080:80 curl -s localhost:8080/api/chat -H 'Content-Type: application/json' \ -d '{"ask": "Почему Pod checkout в namespace shop перезапускается?"}' | jq -r .analysis ``` В консоли это выглядит так: ![Консольная сессия HolmesGPT: вызовы инструментов kubectl и итоговый ответ агента](/blog/img/2026-10-07-holmesgpt-aiops/holmesgpt-cli-demo.gif) Запись из [документации HolmesGPT](https://holmesgpt.dev): агент вызывает инструменты и формулирует ответ. #### Мост к Alertmanager Здесь нас ждал сюрприз. В открытой версии HolmesGPT умеет только *забирать* алерты: команда `holmes investigate alertmanager` разово читает активные алерты и разбирает их. Приёмника вебхуков в HTTP-сервере нет, у оператора триггер по алертам пока в планах, а автоматический разбор в продукте Robusta идёт через их SaaS-платформу. Нам же нужно было простое: Alertmanager шлёт вебхук, через пару минут в том же чате появляется разбор. Так появился [holmes-alert-bridge](https://gitlab.com/yuccastream/holmes-alert-bridge) — небольшой сервис на Go под лицензией Apache 2.0. ![Логотип holmes-alert-bridge](/blog/img/2026-10-07-holmesgpt-aiops/holmes-alert-bridge-logo.svg) Путь алерта: обычное оповещение уходит в чат как раньше, копия — в bridge, а оттуда, если пройдёт фильтры, к агенту. Почти всё, что делает bridge, — это защита бюджета и нервов: * **Сразу отвечает 200.** Holmes думает минуты, Alertmanager столько не ждёт. Расследование идёт в фоне. * **Allowlist по имени алерта.** Пустой список — сервис откажется стартовать: расследовать всё подряд означает счёт от провайдера за каждый флапающий алерт. * **Дедупликация по эпизоду.** Эпизод — это имя алерта, namespace и время начала. Повторные доставки того же эпизода игнорируются. Для упавших CronJob'ов ключом служит имя CronJob'а, иначе каждый новый запуск был бы новым эпизодом. * **Троттлинг.** По умолчанию не больше двух расследований в час и десяти в сутки. Это не тюнинг производительности, а потолок расходов. * **Один воркер.** Расследования идут строго по очереди, реплика у сервиса всегда одна. * **Таймаут с разрывом стрима.** Ответ агента читается потоком, поэтому через 15 минут bridge рвёт соединение, и Holmes останавливается на границе текущего шага, а не дорешивает задачу в фоне за ваш счёт. * **Состояние в базе.** Отметки дедупликации и троттлинга переживают рестарт: SQLite по умолчанию, PostgreSQL или MySQL — если база уже есть. * **Доставка.** Slack, Telegram, почта, произвольный вебхук. Markdown от агента переводится в разметку канала, длинный разбор не обрезается, а разбивается на части. Под разбором — длительность, стоимость, модель и ссылка на полную запись в VictoriaLogs. Насколько это отсекает: в Tuna за первый месяц Alertmanager доставил в bridge 645 алертов, а до агента дошёл 41 — остальное сняли дедупликация, allowlist и троттлинг. В других контурах картина та же: больше 90 % доставок расследования не запускают. Готовый отчёт выглядит так — это та же картинка, что в начале статьи: ![Окно Slack: алерт KubernetesJobFailed от Alertmanager и под ним разбор Holmes с вердиктом и шагами проверки](/blog/img/2026-10-07-holmesgpt-aiops/slack-window.png) Это пример сообщения ##### Установка Нужен работающий HolmesGPT в кластере и список алертов, которые имеет смысл расследовать. ```bash helm repo add holmes-alert-bridge \ https://gitlab.com/api/v4/projects/yuccastream%2Fholmes-alert-bridge/packages/helm/stable helm upgrade --install holmes-alert-bridge holmes-alert-bridge/holmes-alert-bridge \ -n holmes -f values.yaml ``` ```yaml config: alertAllowlist: - KubernetesPodCrashLooping - KubernetesJobFailed - InstanceDown holmesUrl: http://holmes-holmes.holmes.svc:80 holmesModel: fast # ключ из modelList Holmes promptLang: ru clusterName: prod environment: production costCurrency: USD maxPerHour: 2 maxPerDay: 10 telegram: chatId: "-1001234567890" victoriaLogs: uiUrl: https://logs.example.com streamFilter: '{app="holmes-alert-bridge",cluster="prod"}' existingSecret: holmes-alert-bridge-secrets # TELEGRAM_BOT_TOKEN и остальные ``` На стороне Alertmanager — получатель и маршрут с `continue: true`, чтобы разбор дополнял обычное оповещение, а не заменял его: ```yaml receivers: - name: holmes webhook_configs: - url: http://holmes-alert-bridge.holmes.svc:8080/webhook send_resolved: false route: routes: - receiver: holmes matchers: - severity =~ "warning|critical" continue: true ``` Если в вашем дереве маршрутов нет явного catch-all, `continue` может отнять доставку у алертов, которые раньше падали в корневой получатель. Тогда проще добавить bridge вторым `webhook_configs` к уже существующим получателям — у нас так сделано в четырёх кластерах из шести, а отбор целиком лежит на allowlist. Остальное — каналы, секреты, свои шаблоны промптов и сообщений — описано в [INSTALL.md](https://gitlab.com/yuccastream/holmes-alert-bridge/-/blob/master/INSTALL.md). #### Модели и бюджет ##### Как выбирали Пилот начался в проекте в российском облаке, и первый же прогон — на `glm-5.2` — отрезвил: на один вопрос ушло больше миллиона входных токенов, а расследование обошлось в десятки рублей. Агент делает десятки ходов, и каждый ход заново пересылает модели всю накопленную историю. Тогда мы устроили отбор: восемь моделей, 52 прогона в три волны, включая задачу с заранее известным ответом. Смотрели в первую очередь на недорогие модели: мониторинг не должен стоить дороже того, за чем он следит. Пару моделей классом выше добавили для сравнения. | Модель | Прогонов | Падений | Задача с известным ответом | Цена прогона | | ---------------------------- | -------- | ------- | -------------------------- | ------------ | | `qwen3.7-flash` | 6 | 1 | 0 из 1 | ≈ 3 ₽ | | `gpt-5.6-luna` | 4 | 0 | 0,5 из 2 | ≈ 6 ₽ | | **`deepseek-v4-flash-0731`** | 16 | 0 | 4 из 4 | ≈ 16 ₽ | | `minimax-m3` | 6 | 1 | 0 из 1 | ≈ 24 ₽ | | `gemini-3.7-flash` | 4 | 1 | 1 из 1 | ≈ 41 ₽ | | `longcat-2.0` | 4 | 0 | 0 из 2 | ≈ 42 ₽ | | `glm-5.2` | 6 | 0 | 2 из 2 | ≈ 54 ₽ | | `deepseek-v4-pro-0813` | 6 | 0 | 2 из 2 | ≈ 77 ₽ | Цена прогона — оценка сверху, без учёта кэша: с кэшем разбор обходится в разы дешевле. Половина балла — частично верный ответ. Выборка небольшая: от 4 до 16 прогонов на модель. Что из этого вышло: * **По одному прогону сравнивать нельзя.** Разница в цене, которая на первом прогоне выглядела как порядок, на полусотне сжалась до нескольких раз: разброс внутри одной модели оказался больше разницы между моделями. * **Дешёвая модель — не значит дешёвый разбор.** Половина кандидатов провалила задачу с известным ответом, причём одинаково: уверенно сообщила, что нужного компонента в кластере нет. Это был управляемый автоскейлер, которого среди Pod'ов действительно не видно. * **Победила `deepseek-v4-flash`**: 16 прогонов без единого падения и верный ответ во всех четырёх попытках. Она не самая дешёвая в списке, но обе модели дешевле неё задачу с известным ответом не решили. В продакшене первая версия продержалась недолго. В одном контуре примерно каждый пятый разбор не укладывался в 15 минут. В другом модель зацикливалась на повторных вызовах инструментов и уходила в таймаут, а её версию к тому же сняли с поддержки у провайдера. В середине сентября мы переехали на DeepSeek V4.1 Flash. По прайсу она в разы дороже, средний разбор тоже подорожал — зато разборы стали заканчиваться, и заканчиваться быстро. Оговорка: чистого сравнения «до и после» у нас нет. В те же дни мы поправили инструкции для инструментов и обновили bridge, и вклад каждого изменения по отдельности не измеряли. ##### Что получилось | | Tuna | Проект в российском облаке | Зарубежный проект | | --------------------- | ------------------- | -------------------------- | ----------------- | | Модель | DeepSeek V4.1 Flash | DeepSeek V4.1 Flash | Claude Sonnet 5 | | Успешных разборов | 22 из 22 | 92,9 % | 15 из 15 | | Длительность, медиана | 2–3 минуты | 2–3 минуты | около минуты | | Цена разбора | около 10 центов | несколько рублей | 25–30 центов | Окно — 30 дней до 6 октября 2026 года; успешность считаем после стабилизации — смены модели и выхода bridge v0.11. Рублёвые суммы — оценка: цены модели в конфигурации у нас расходились с прайсом роутера. Счёт за месяц — единицы долларов на проект: около четырёх долларов в Tuna по биллингу провайдера, четыре-пять в зарубежном проекте на три кластера и меньше тысячи рублей на два кластера в российском облаке. В Tuna мы сверили оценку стоимости, которую bridge берёт из ответа Holmes, с биллингом ключа — сошлось до цента. ##### Почему хватает дешёвой быстрой модели Разбор алерта — это около миллиона токенов, из которых сама модель генерирует пару десятков тысяч. Всё остальное — накопленная история, которую агент пересылает на каждом ходу. Отсюда три свойства модели, которые важнее цены за миллион токенов по прайсу: * **Дешёвое чтение кэша.** По нашей оценке, из кэша читается около 90 % входных токенов. Это оценка обратным счётом, а не цифра из биллинга, но порядок понятен: экономика разбора держится на кэше. * **Большое окно контекста.** При окне в 200 тысяч токенов Holmes начинал сжимать историю уже около 126 тысяч, после сжатия заново запрашивал собранное — и разбор становился дольше и дороже. С окном в 400 тысяч сжатия прекратились. * **Надёжный вызов инструментов.** Модель, которая время от времени пишет вызов инструмента текстом или ломает JSON аргументов, обходится дороже любой «умной». Где стоит модель подороже: в зарубежном проекте с первого дня работает Claude Sonnet 5, подключённая напрямую у провайдера. Сравнения моделей там мы не устраивали. Алертов в этом проекте мало — большинство гаснет раньше, чем Alertmanager успевает их отправить, — поэтому в абсолютных цифрах дорогая модель обходится в те же несколько долларов в месяц. Два практических совета: * **Ставьте месячный лимит на ключ провайдера.** Троттлинг bridge защищает только путь от Alertmanager; ручные вопросы и другие клиенты агента идут мимо него. * **Сверяйте цены.** Если модель описана в `modelList` со своими `input_cost_per_token` и `output_cost_per_token`, стоимость в отчёте считается по ним. У нас эти числа расходились с прайсом роутера, и суммы в чате оказывались неверными. #### Данные и безопасность Сначала посмотрите, что лежит в ваших логах При внешнем API всё, что прочитает агент, уходит провайдеру модели: строки логов, манифесты, события, метки метрик. До внедрения проверьте свои приложения и логи на пароли, токены и персональные данные. Агент не отличает секрет от обычной строки: содержимое лога попадает в запрос к модели как есть. Что мы советуем сделать до первого алерта. **1. Аудит логов.** У агента есть доступ к логам Pod'ов всего кластера. Если приложение пишет в лог токен авторизации или адрес почты клиента, это надо чинить в приложении — и сделать это до подключения агента, а не после. **2. Zero Data Retention — в двух местах.** ZDR означает, что провайдер не хранит ваши запросы. В OpenRouter его стоит включать и настройкой аккаунта, и параметром запроса `provider.zdr: true` (в примере выше он уже есть). Настройку аккаунта не видно из конфигурации кластера, а параметр запроса зависит от того, донесла ли его цепочка библиотек, — вместе они страхуют друг друга. Проверяется это живым запросом: при включённом ZDR обращение к провайдеру вне ZDR-списка возвращает ошибку `ZDR violation`. **3. Роутер, у которого ZDR есть на деле.** Годится любой роутер с API, но лучше тот, чьи провайдеры действительно дают нулевое хранение. OpenRouter публикует [живой список](https://openrouter.ai/api/v1/endpoints/zdr) таких endpoint'ов, и на него стоит посмотреть до выбора модели: одна и та же модель у разных хостеров может быть как в списке, так и вне его. **4. Права только на чтение.** В чарте HolmesGPT по умолчанию включены наборы `bash` и `internet` — выключайте их явно. Secret'ы чарт агенту читать не даёт, но запрет на изменения должен обеспечивать RBAC, а не фраза в промпте. **5. Правило в skill'е — не техническое ограничение.** Мы пишем агенту «работай с агрегатами, не цитируй персональные идентификаторы», и он в целом слушается. Но это текст, а не барьер, и полагаться на него как на защиту нельзя. **6. Закройте API самого Holmes.** По умолчанию `/api/chat` доступен без аутентификации любому Pod'у кластера, а вместе с ним — права агента на чтение и ваш бюджет у провайдера. Варианты — NetworkPolicy (проверьте, что ваш CNI их исполняет) или ключ `HOLMES_API_KEY`. Теперь честно про нас. В Tuna стоит OpenRouter с ZDR, включённым в обоих местах, — проверено живыми запросами. В проекте в российском облаке запросы идут через ИИ-роутер Selectel: отдельной настройки ZDR там нет, и мы опираемся на заявленную провайдером политику обработки запросов. В зарубежном проекте модель подключена напрямую у её провайдера: политика хранения там — свойство договора и настроек организации, из конфигурации кластера её не видно, и это отдельный пункт в нашем чек-листе. #### VictoriaLogs Логи — главный источник данных для агента: на них приходится больше всего вызовов инструментов. Мы рекомендуем [VictoriaLogs](https://docs.victoriametrics.com/victorialogs/): она быстрая, а её HTTP API достаточно прост, чтобы им одинаково легко пользовались и скрипты, и агенты. В HolmesGPT для неё есть встроенный toolset. Мы специально переехали на VictoriaLogs — два проекта с Loki, один с Graylog — именно ради того, чтобы логи стали доступны программно: и нашим рабочим агентам, и Holmes. В итоге хранилище играет для агента сразу три роли: * источник логов приложений; * собственная память: skill ищет прошлые разборы в логах bridge; * адрес ссылки «полный разбор» под сообщением в чате. Вот запись, на которую ведёт ссылка «полный разбор» под сообщением из [кейса про очередь TCP](#tcp-listen-queue). Служебные поля коллектора убраны, текст разбора обрезан: ```json { "_time": "2026-10-03T10:44:06.793Z", "_msg": "investigation done", "cluster": "yucca", "alertname": "TCPListenQueueOverflow", "episode": "TCPListenQueueOverflow//2026-10-03T10:39:49Z", "starts_at": "2026-10-03T10:39:49Z", "duration": "4m7s", "cost": "0.0542736192", "cost_currency": "USD", "prompt_tokens": "1119866", "completion_tokens": "20957", "total_tokens": "1140823", "analysis": "I found a skill named **tuna-network-attacks** и использовал его для разбора…" } ``` Разборы лежат в логах обычными полями, поэтому бюджет считается одним запросом. Например, сколько стоил каждый алерт за месяц: ```text _time:30d {app="holmes-alert-bridge"} "investigation done" | stats by (alertname) count() n, sum(cost) total, avg(cost) avg | sort by (total) desc ``` Одной установки toolset'а мало — агенту нужно описать схему полей. Имена зависят от коллектора: у vector namespace лежит в `kubernetes.pod_namespace`, у fluent-bit — в `kubernetes.namespace_name`, и модель этого не угадает. Наши инструкции к toolset'у логов по смыслу такие: ```text Log fields (collector: vector): app, cluster, kubernetes.pod_namespace, kubernetes.pod_name, level, _msg A bare "phrase" is searched in _msg only. To filter by a field write field:="value". Pass `start` only. Never pass `end`, null or "now". One failed call does not mean the storage is down: fix the query and retry once. Do not name a root cause from a tail of 50 lines. Count first: ... | stats by (level, app) count() n ``` #### Промпты и skills Знание о проекте у нас разложено по четырём слоям. **Рамки расследования** задаёт системный промпт запроса — он встроен в bridge, есть на русском и английском. Смысл: ты расследуешь алерт без человека в диалоге; только чтение; держись namespace алерта; твой вывод — гипотеза; ответ уйдёт одним сообщением в чат — вердикт, наиболее вероятная причина, два-три шага проверки. **Паспорт кластера** — skill, который агент читает первым. Это самый полезный текст во всей настройке. Обезличенный пример по структуре наших: ```markdown --- name: prod-cluster description: How the production cluster is built, what is normal here and what is not. Read this FIRST for any investigation in this cluster. --- ## What this cluster is Managed Kubernetes, production of an online store. Node pools: `apps` (stateless services, autoscaled) and `infra` (monitoring, ingress, ArgoCD). ## Where the workloads live - `shop` — API and web frontend, the only namespace that serves customers. - `jobs` — CronJobs: exports, reports, cleanup. A single failed run is rarely urgent. - `monitoring`, `ingress`, `argocd` — infrastructure. ## Databases are outside the cluster PostgreSQL and Redis are managed services. You cannot kubectl into them: use their metrics and `tcp_check`. ## ArgoCD owns the infrastructure A manual change will be reverted. Never suggest `kubectl edit`. ## What you may read, and what you may not Application logs may contain customer data. Work with counts and aggregates, never quote e-mails, phone numbers or order contents. ## What is normal here - Nodes of the `apps` pool are replaced every night: short NotReady and evictions between 02:00 and 03:00 UTC are expected. - `jobs/report-*` retries up to three times. Only the third failure matters. ## How to fill tool parameters Time range: pass `start` only. Log fields: see the logs toolset instructions. ## Blaming an external provider is a claim you can check Before writing "the payment gateway is down", run `tcp_check` against it and compare the error rate with the previous day. ## What always deserves escalation Anything in `shop` that lasts longer than 10 minutes; any sign of data loss. ``` **Skills под типы алертов и сервисы.** Скелет один и тот же: ```markdown --- name: edge-triage description: Investigate EdgeDown and EdgeHighErrorRate. The edge proxies run on plain hosts OUTSIDE Kubernetes, so kubectl is useless here. --- ## What the edge is # слой → где живёт → systemd-unit → job метрик ## How the alert reaches you # выражение правила, что значат метки ## Workflow # 4–6 шагов с готовыми запросами LogsQL и PromQL ## Synthesize # что обязано быть в ответе, ссылки на дашборды ``` **Подсказка в самом правиле.** Аннотации алерта попадают в вопрос агенту целиком. Поэтому короткую инструкцию можно положить прямо в правило отдельной аннотацией, которую шаблон сообщения в чате не выводит: ```yaml - alert: KubernetesJobFailed annotations: summary: "Job {{ $labels.job_name }} failed" ai: >- Jobs in the `jobs` namespace are retried by the scheduler. Check whether the next run succeeded before calling it an incident. ``` Что мы поняли, пока это писали: * **Тексты skills — на английском, ответ — на русском.** Это сочетание у нас работает без нареканий. * **Инструмент, не названный в skill'е, почти не вызывается.** Мы подключили агенту ArgoCD, Grafana и TCP-проверки — и он ими практически не пользовался. Поэтому в паспорте кластера стоит держать раздел «инструменты, о которых ты забываешь», а в skills — называть нужный инструмент прямо в шагах. * **Правило надо класть туда, где модель его точно прочтёт.** Запрет передавать `end: "now"` стоял в инструкциях toolset'а логов, а модель всё равно его писала — десятки упавших вызовов. Помогло только общее правило в паспорте кластера; теперь оно встроено и в системный промпт bridge. * **Сломанные toolset'ы надо выключать явно.** Встроенные наборы в статусе `failed` всё равно попадают в системный промпт, и агент пытается ими пользоваться. * **«Виноват внешний сервис» — это проверяемое утверждение.** Пока у агента не было инструмента сетевой проверки и требования проверять самому, разборы недоступности партнёрского API заканчивались советом «сделайте curl». ##### Skill, который месяц ничего не находил Самая поучительная наша ошибка. У агента есть skill «не разбирали ли мы это уже»: перед расследованием он ищет в логах bridge прошлые разборы того же алерта. Идея хорошая, и в Tuna агент обращался к этому skill'у чаще, чем к любому другому. В двух контурах из трёх он месяц искал не по тому полю. Запрос в skill'е искал имя алерта голой фразой, а голая фраза в LogsQL ищется только в тексте сообщения — где лежит ровно `investigation done` и больше ничего: ```text {app="holmes-alert-bridge"} "investigation done" "KubernetesJobFailed" → 0 записей {app="holmes-alert-bridge"} "investigation done" alertname:="KubernetesJobFailed" → 73 записи ``` Агент выполнил сотни таких запросов и каждый раз честно писал «прошлых разборов нет» — в том числе про эпизод, который за месяц был разобран девятнадцать раз. Никакой ошибки при этом не возникало: пустой ответ — тоже ответ. В третьем контуре запрос был написан с фильтром по полю, и там память работала: агент ссылался на свои прошлые выводы и даже поправлял их. Исправление — одна строка. Мораль шире: **skill для агента надо тестировать как код**. Каждый запрос из него стоит хотя бы раз выполнить руками и убедиться, что он что-то находит. #### Кейсы ##### Очередь TCP переполнена, но sysctl тут ни при чём На одном из серверов Tuna сработал `TCPListenQueueOverflow`: ядро отбрасывает входящие соединения, потому что очередь слушающего сокета переполнена. В описании алерта зашит стандартный совет — поднять `net.core.somaxconn` или backlog в приложении. ![Telegram: алерт TCPListenQueueOverflow с советом поднять net.core.somaxconn и сообщение о том, что он погас](/blog/img/2026-10-07-holmesgpt-aiops/telegram-alert.png) Алерт в Telegram: сработал в 14:39 и через три минуты погас. ![Telegram: разбор Holmes по алерту TCPListenQueueOverflow — пять проверенных шагов, вердикт и что проверить](/blog/img/2026-10-07-holmesgpt-aiops/telegram-holmes-report.png) Разбор Holmes пришёл в 14:44 — в тот же чат, под алертом. Holmes за четыре минуты и пять центов выяснил другое: 1. Переполнение есть только на одном хосте, за предыдущие семь дней — ноль. Счётчик SYN cookies почти не вырос, значит, это не SYN-флуд. 2. Слушатель, который перестал принимать соединения, — `sshd`. В его журнале нашлись записи о начале `MaxStartups throttling` и об отброшенных соединениях — около двух тысяч за эпизод. 3. Источник — два адреса и порядка 180 попыток входа с несуществующими логинами за 15 минут. 4. Ресурсы хоста в норме, остальные сервисы на нём и соседние хосты не задеты. 5. К моменту разбора алерт уже погас, порты отвечают. Вердикт: кратковременная потеря TCP-соединений из-за флуда SSH-подключений. Очередь переполнилась, потому что `sshd` упёрся в собственное ограничение `MaxStartups`, а не потому, что хосту не хватило ресурсов; `net.core.somaxconn` здесь ни при чём. И отдельное наблюдение: fail2ban такой поток не отсекает, потому что соединения рвутся до этапа аутентификации. Совет из описания алерта увёл бы дежурного в сторону. А на скриншоте заодно видны две наши болячки из этой статьи: фраза «прошлых разборов этого алерта нет» — тот самый сломанный skill — и служебная преамбула агента в начале сообщения. ##### VirusTotal: шум или сигнал У нас есть [открытый инструмент](https://tuna.am/blog/vt-telegram-bot.md), который следит за тем, как наши IP-адреса, публикуемые домены и хэш-суммы сборок выглядят в базах антивирусов и спам-листах. Задача — отреагировать раньше, чем пользователь получит предупреждение «ваш софт вредоносный». Срабатывания у него бывают двух сортов. Чаще всего это шум: один-два малоизвестных движка пометили адрес туннельного сервера. Изредка — настоящий сигнал. Теперь каждое срабатывание дополняется вердиктом Holmes: отдельный skill объясняет ему, какие движки считать шумом и какие сочетания признаков — поводом звать человека. ![Сообщение о срабатывании VirusTotal с вердиктом Holmes](/blog/img/2026-10-07-holmesgpt-aiops/telegram-virustotal-mockup.png) Это пример сообщения В этом примере агент сначала признал, что срабатывание по адресу — шум движков малого охвата. Но заметил в отчёте новый файл с заметным числом детектов, трафик которого идёт на туннельный поддомен, — и эскалировал: через туннель, вероятно, раздаётся вредоносный файл, нужен человек. Заодно проверил, что прошлых вердиктов по этому файлу нет, и что туннель сейчас не используется, — то есть владельца надо искать по учётной записи. Этот путь идёт к Holmes напрямую, мимо bridge, — и это ещё одна причина держать лимит на ключе провайдера. ##### Ещё два коротких * **Агент разобрал собственное падение.** После обновления новый Pod Holmes ушёл в CrashLoop, и алерт об этом достался старому Pod'у. Тот нашёл отказ в доступе к новому пути в хранилище секретов, сравнил окружение двух ревизий и отметил, что сервис при этом не лежит, потому что старый Pod жив. Полторы минуты, десять центов. * **Один алерт — две разные причины.** В проекте в российском облаке агент связал нехватку памяти на прерываемом узле с плановой заменой соседнего узла и нашёл Pod, который потреблял заметно больше запрошенного. Через два дня на том же алерте он назвал другую причину — совпавшие расписания CronJob'ов — и явно написал, чем этот эпизод отличается от предыдущего. #### Грабли **Висящий алерт разбирается заново каждые сутки.** Окно дедупликации по умолчанию — 24 часа, и если алерт горит дольше, он честно разбирается ещё раз. В одном контуре на такие повторы уходила почти половина бюджета, причём половину разборов в проде давали несколько хронически падающих CronJob'ов. Лечится с двух сторон: увеличить окно (`dedupWindow`) до нескольких суток и наконец починить то, что горит неделями, — счёт за разборы очень мотивирует. **Служебные вставки агента в сообщениях.** Holmes оставляет в ответе заготовки под встраивание графиков в интерфейс Robusta: блоки вида `<< {"type": "promql", ...} >>` и картинки со схемой `tool-image://`. В чате это выглядит как мусор, и встречалось оно больше чем в половине разборов. Начиная с v0.11.1 bridge вырезает их перед отправкой. Преамбулу «I found a skill named…» в начале ответа убрать сложнее: это формат самого Holmes при работе со skills, правило в системном промпте на неё не действует. **Модель ломает аргументы инструментов.** Время от времени модель отдаёт аргументы вызова не объектом, а строкой с JSON внутри. Holmes на этом падает с ошибкой валидации, и разбор теряется целиком — в одном контуре это была самая частая причина неудачных разборов. Bridge в таких случаях повторяет разбор сразу, если позволяет бюджет, а с v0.11.1 пишет в лог, когда повтор не состоялся. В конце сентября эти падения прекратились сами, без изменений с нашей стороны. **Алерты на сам bridge.** Месяц у нас не было ни одного правила на метрики bridge: о затроттленных алертах и таймаутах можно было узнать только из логов. Минимум: ```yaml - alert: HolmesBridgeInvestigationsFailing expr: increase(holmes_bridge_investigations_total{status!="ok"}[1h]) > 0 - alert: HolmesBridgeThrottling expr: increase(holmes_bridge_alerts_throttled_total[1h]) > 0 ``` В allowlist самого bridge эти алерты добавлять не надо. **Цены в `modelList` ломают окно контекста.** Стоит вписать модели свои цены — и Holmes 0.41 перестаёт понимать размер её окна и падает на первом же вызове инструмента. Обходится переменной `OVERRIDE_MAX_CONTENT_SIZE`. В 0.42 падения уже нет, но окно по умолчанию — 200 тысяч, и для длинных разборов его всё равно стоит задать явно. **Инструменты падают по памяти.** `kubectl` на больших списках упирался не в лимит Pod'а, а в лимит памяти на один вызов инструмента. Он задаётся отдельно — `TOOL_MEMORY_LIMIT_MB`. **Парные правила дают два разбора.** Если в allowlist стоят и общее правило, и его специализированный двойник, один инцидент разбирается дважды с разницей в секунды. Оставляйте одно из пары. **«Успешный» разбор без единого запроса.** На старой модели дважды случилось так: агент прочитал пару skills, не сделал ни одного запроса к данным и уверенно написал, что у него нет доступа к метрикам. Формально разбор успешен, стоит он доли цента. Аномально дешёвый разбор — повод посмотреть на него глазами. И одна находка со знаком плюс: **`group_wait` — бесплатный фильтр**. В зарубежном проекте Alertmanager ждёт три минуты перед первой отправкой, и из десятков эпизодов в проде до агента доехали единицы — всё, что живёт минуту-две, гаснет раньше. #### Что дальше Чего мы пока не измерили — и не хотим делать вид, что измерили: * **качество гипотез** — 90–95 % остаются оценкой, пока мы не разметим выборку разборов против реальных причин инцидентов; * **эффект для людей** — насколько сократилось время разбора инцидента. Что хочется сделать в bridge: * метрику потраченной суммы, чтобы бюджет было видно в Grafana рядом с остальными счётчиками; * аккуратнее обходиться с висящими алертами — растущий интервал повторного разбора вместо фиксированного окна; * ключ API для запросов к Holmes; * ссылку на разбор не только в VictoriaLogs, но и в Loki, Elasticsearch и других хранилищах; * новые каналы доставки — Mattermost, Microsoft Teams, Discord. Чего в bridge не будет: параллельных расследований, правил маршрутизации (это работа Alertmanager) и автоматической починки. Код, чарт и документация — в [репозитории holmes-alert-bridge](https://gitlab.com/yuccastream/holmes-alert-bridge). Если попробуете у себя — расскажите, что получилось: issue и merge request'ы приветствуются. #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [aiops](https://tuna.am/blog/tags/aiops) * [kubernetes](https://tuna.am/blog/tags/kubernetes) * [open-source](https://tuna.am/blog/tags/open-source) --- ### Изменение настроек tuna при обновлении Immich 17 октября 2024 г. · 1 мин. чтения Изменение настроек по умолчанию в [Immich](https://immich.app/?utm_source=tuna.am), сервисе для самостоятельного хранения фотографий, аналог [Google Photos](https://www.google.com/photos/about/?utm_source=tuna.am). ![immich-login](/docs/img/examples/immich.png) В immich-server версии [**v1.118**](https://github.com/immich-app/immich/releases/tag/v1.118.0) изменился порт подключения по умолчанию с **3001** на **2283**, поэтому нужно поменять аргумент у tuna с `immich-server:3001` на `immich-server:2283`. Было ```yaml tuna: container_name: immich_tuna image: yuccastream/tuna:latest command: http immich-server:3001 --location=ru --subdomain=<ваш_поддомен> --inspect=false env_file: - .env restart: always depends_on: - immich-server ``` Стало ```yaml tuna: container_name: immich_tuna image: yuccastream/tuna:latest command: http immich-server:2283 --location=ru --subdomain=<ваш_поддомен> --inspect=false env_file: - .env restart: always depends_on: - immich-server ``` Этот код есть и в [примере](https://tuna.am/docs/tunnels/examples/immich.md). #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [cli](https://tuna.am/blog/tags/cli) * [tuna](https://tuna.am/blog/tags/tuna) * [immich](https://tuna.am/blog/tags/immich) --- ### Обновление клиента tuna 0.23.0 и инспектор 1.1.0 3 апреля 2025 г. · 1 мин. чтения В этом обновлении tuna 0.23.0 и инспектора 1.1.0 добавлено живое обновление списка запросов. [![inspector-live-updates](/assets/images/inspector-live-updates-b0bdc265f57916db1473f642f39ef087.webp)](https://tuna.am/docs/tunnels/http/inspect.md) #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) * [tuna](https://tuna.am/blog/tags/tuna) * [cli](https://tuna.am/blog/tags/cli) --- ### Обновления - оплата по счёту и новые функции клиента 22 августа 2024 г. · 3 мин. чтения Новые функций в этом выпуске! #### Оплата по счёту для организаций ![org_invoice](/assets/images/org_invoice-357a47311c2c3e7f9e7097c5dc18a18b.gif) Мы добавили возможность оплаты подписки за команду по счёту для организаций в России, а также блок с сравнением всех функций тарифов. Теперь вы можете создать команду, указать реквизиты организации и мы выставим счёт на оплату, который вы можете передать бухгалтеру. Счёт придёт на почту всем участникам команды с ролью **владелец**, а также в [настройках](https://my.tuna.am/team_settings) организации можно указать дополнительные контакты ответственных за оплату людей. #### Обновления в клиенте tuna 0.18.0 Было исправлено несколько ошибок, в частности утечка памяти при включённом инспекторе запросов в `tuna http --file-server`, а также добавлены новые команды и флаги, о них подробнее ниже. ##### tuna http --webdav ![webdav](/assets/images/webdav-45082cfdea1afcf6d5962db16fe2387c.png) В команде `tuna http` появился новый флаг `--webdav`. С помощью встроенного WebDAV сервера теперь вы можете предоставить доступ к каталогу на вашем компьютере, от куда можно не только скачать файлы, но и загрузить их к вам. Поддержка WebDAV есть стандартных проводниках всех современных операционных систем, поэтому для использования не нужно никакое дополнительно ПО. ##### tuna run Запуск туннеля при запуске команды. ![tuna_run](/assets/images/tuna_run-6efa86afeb5224d166817a19bbc239f1.gif) В этом режиме tuna выступает как обёртка (wrapper) для запуска вашего приложения. Можно одной командой запустить туннель и ваше приложение, tuna самостоятельно обнаружит порт который слушает приложение и запустит туннель, например: ```shell tuna run -- yarn start --host 0.0.0.0 ``` Мы сами используем к примеру редактируя эту документацию, в проекте с документацией есть `Makefile` в котором описан запуск проекта через `tuna run`, редактируя эту статью запускаем в консоли `make`, стартует проект с документацией в режиме разработки и к нему открывается туннель, который можно отправить коллегам на ревью этой статьи 🙂 Пример Makefile: ```shell .DEFAULT_GOAL := run .PHONY: run run: ## Запуск сервера через tuna враппер @tuna run -- yarn start --host 0.0.0.0 ``` ##### tuna detect Обнаружение портов и подготовка команд для tuna. ![tuna_detect](/assets/images/tuna_detect-35f718721bdbb52c4189c38be84b54a2.gif) В этом режиме tuna также выступает как обёртка (wrapper), но не стартует в последствии туннель, а просто выводит в консоль порты, что были обнаружены и предлагает команду для запуска. Это полезно если вы не знаете какой порт слушает приложение которое вам нужно запустить, пример: ```shell % tuna detect -- nc -l 1234 INFO[19:06:56] Waiting for available ports... INFO[19:06:56] 5 INFO[19:06:57] 4 INFO[19:06:57] Found port: 1234 INFO[19:06:58] 3 INFO[19:06:59] 2 INFO[19:07:00] 1 INFO[19:07:01] Here is your tunnel commands: INFO[19:07:01] 1. tuna tcp 127.0.0.1:1234 ``` #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) * [customer-portal](https://tuna.am/blog/tags/customer-portal) * [tuna](https://tuna.am/blog/tags/tuna) --- ### ☸️ Kubernetes-туннель — временный доступ к кластеру по одной ссылке 5 октября 2026 г. · 4 мин. чтения Знакомая ситуация: подрядчику нужно посмотреть логи в staging-кластере, коллеге из соседней команды — помочь с отладкой, а API-сервер кластера закрыт от интернета. Дальше обычно выбирают между «завести человеку VPN и учётку» и «скинуть свой kubeconfig» — и оба варианта плохие. В tuna-cli 0.36 появился новый тип туннеля — **Kubernetes**. Одна команда, и гость получает ссылку на готовый kubeconfig, с которым работает обычный `kubectl`: ```shell tuna kubernetes --context=staging --service-account=shop/debug --preset=debug --ttl=4h ``` #### Как это работает Клиент читает ваш локальный kubeconfig, поднимает к API-серверу reverse-proxy и публикует его через HTTP-туннель с валидным TLS-сертификатом. Гость получает одноразовую ссылку: ```shell curl -sfO https://<адрес туннеля>/tuna/<секрет>/kubeconfig.yaml KUBECONFIG=./kubeconfig.yaml kubectl get pods ``` В скачанном kubeconfig лежит **гостевой токен**, а не ваши учётные данные. Прокси проверяет этот токен и подставляет вместо него настоящие креды — они никогда не покидают вашу машину. Остановили туннель — доступ пропал, отзывать нечего. Через туннель работает всё, к чему привыкли пользователи `kubectl`: `get`, `list`, `watch`, `logs`, `exec` с stdin, `port-forward`, `pods/proxy` и запись — `scale`, `create`, `delete`. По сути, это такой auth-прокси к Kubernetes API, который поднимается одной командой и живёт ровно столько, сколько нужно. #### Права гостя — под вашим контролем Первый уровень защиты — **RBAC**. По умолчанию гость работает с вашими правами, и клиент честно об этом предупреждает. Правильнее создать для гостя сервисный аккаунт с минимальными правами и передать его во флаге `--service-account`: токен для него клиент выпустит сам через TokenRequest API и будет продлевать каждый час. Второй уровень — **ограничения самого туннеля**. Они работают поверх RBAC и могут только сужать права: | Флаг | Что делает | | ------------------------------------ | ----------------------------------------------------------------- | | `--namespace=shop` | Только один namespace, без кластерных ресурсов и `-A` | | `--read-only` | Только чтение: без `exec`, `attach` и `port-forward`, но с логами | | `--no-delete` | Всё, кроме удаления | | `--deny-resource=secrets,configmaps` | Запрет на конкретные ресурсы | | `--deny-subresource=exec,attach` | Запрет на субресурсы | Чтобы не собирать ограничения вручную, есть пресеты: | Пресет | Что разрешено | | ---------- | ------------------------------------------------------------------------ | | `view` | Только чтение, без `secrets`, `exec`, `attach`, `port-forward` и `proxy` | | `observer` | Только чтение подов и их логов | | `debug` | Всё, кроме удаления | | `open` | Без дополнительных ограничений | Пресеты и флаги суммируются и не ослабляют друг друга: `--preset=debug --read-only` даёт только чтение. #### Срок действия и одноразовые ссылки * `--ttl=4h` — через четыре часа `kubectl` гостя получит `this access has expired, ask for a new link`; * `--download-limit` — сколько раз можно скачать kubeconfig, по умолчанию **один**. Если гость при первой же попытке получил `410`, значит, конфиг до него забрал кто-то другой: остановите туннель и выдайте новую ссылку. Гостевые токены живут только в памяти процесса: после перезапуска клиента старые ссылки перестают работать. #### Всё под наблюдением Туннель запускается в новом [терминальном интерфейсе](https://tuna.am/docs/tunnels/tui.md): в шапке — сервисный аккаунт, namespace, ограничения и срок действия доступа, ниже — лента запросов гостя. Те же запросы видны в [инспекторе](https://tuna.am/docs/tunnels/http/inspect.md) как обычные HTTP-запросы, так что всегда понятно, что именно делал гость в кластере. #### Кому пригодится * **Подрядчикам и аутсорсу** — дать доступ к staging на время работ, без заведения учёток в облаке. * **Поддержке и дежурным** — быстро пустить коллегу посмотреть логи и поды, в режиме `observer`. * **Демо и обучению** — показать кластер на воркшопе с `--read-only` и коротким `--ttl`. * **Локальным кластерам** — kind, minikube или k3s на ноутбуке становятся доступны коллеге без проброса портов. Если нужен постоянный адрес, используйте зарезервированный поддомен (`--subdomain=k8s-staging`) или свой домен, а туннель можно запустить [как сервис](https://tuna.am/docs/tunnels/guides/service.md). Kubernetes-туннель доступен по [подписке](https://tuna.am/#pricing) начиная с **tuna-cli 0.36.0**, у команды есть короткий алиас `tuna k8s`. Все флаги и подробности — в [документации](https://tuna.am/docs/tunnels/kubernetes.md). #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) * [tuna](https://tuna.am/blog/tags/tuna) * [cli](https://tuna.am/blog/tags/cli) * [kubernetes](https://tuna.am/blog/tags/kubernetes) --- ### Дополнительные лицензии на увеличение лимитов 6 февраля 2025 г. · 1 мин. чтения Если вам недостаточно лимитов на активные туннели, поддомены, свои домены или статичные TCP порты, то теперь вы можете докупить дополнительную лицензию и увеличить эти лимиты. [![licenses](/assets/images/licenses-3bd87f31b597bffc40fefeb4a423b610.png)](https://my.tuna.am/subscription_update) Одна дополнительная лицензия увеличивает все лимиты в туннелях: * **+1** активный туннель * **+1** поддомен в зоне tuna.am * **+1** свой домен * **+1** статичный TCP порт По стоимости мы продолжаем придерживаться доступных и демократичных цен. В тарифе Профи 1 дополнительная лицензия: * **99** рублей в месячной подписке * **990** рублей в годовой подписке В тарифе Легенда 1 дополнительная лицензия на 1 участника: * **199** рублей в месячной подписке * **1990** рублей в годовой подписке Покупка дополнительных лицензий доступна на странице [редактирования подписки](https://my.tuna.am/subscription_update). #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [customer-portal](https://tuna.am/blog/tags/customer-portal) --- ### Плановые работы 14.04.2025 в регионе NL (Нидерланы) 11 апреля 2025 г. · 1 мин. чтения ⚠️ Внимание! Плановые работы 🛠️ **14.04.2025** запланированы в регионе **NL (Нидерланы)**, ожидается недоступность от 1 до 12 часов в течении дня. Будет произведена смена IP адресов и переезд к новому провайдеру. * `193.33.194.47` > `89.19.217.251` * `62.84.101.212` > `147.45.238.190` Старый IP на адресе `193.33.194.47` продолжит работать, для обратной совместимости с пользовательскими доменами, что используют в dns А запись. По завершении работ мы объявим о дате полного отключения старого адреса, а всех владельцев пользовательскими доменов дополнительно уведомим о необходимости изменить DNS запись после проведения работ. Работы необходимо провести в рамках модернизации инфраструктуры и повышения стабильности. #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [maintain](https://tuna.am/blog/tags/maintain) --- ### Плановые работы 16.04.2025 в регионе RU (Россия) 14 апреля 2025 г. · 1 мин. чтения ⚠️ Внимание! Плановые работы 🛠️ **16.04.2025** запланированы в регионе **RU (Россия)**, ожидается недоступность от 10 до 60 минут в промежутке с 11 до 13 часов МСК. Будет произведена смена IP адресов и переезд к новому провайдеру. * `178.20.41.29` > `37.252.22.27` * `178.20.43.146` > `37.252.21.90` Старый IP на адресе `178.20.41.29` продолжит работать, для обратной совместимости с пользовательскими доменами, что используют в dns А запись. По завершении работ мы объявим о дате полного отключения старого адреса, а всех владельцев пользовательскими доменов дополнительно уведомим о необходимости изменить DNS запись после проведения работ. Работы необходимо провести в рамках модернизации инфраструктуры и повышения стабильности. #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [maintain](https://tuna.am/blog/tags/maintain) --- ### 🆕 Мониторы - новый функционал 27 января 2026 г. · 4 мин. чтения Мы рады представить новый компонент платформы Tuna — **Мониторы**. Функционал для отслеживания работоспособности ваших сервисов, туннелей, задач и инфраструктуры с уведомлениями через различные каналы связи. [Перейти к разделу Мониторы в документации](https://tuna.am/docs/monitors.md) ![Главная страница мониторов](/docs/img/monitors/main.png) #### Что такое Tuna Мониторы? Мониторы позволяют контролировать работу ваших cron-задач, сервисов и инфраструктуры. При возникновении проблем вы сразу получите уведомление через настроенные каналы связи — email, Telegram, Slack и другие. **Мониторы** — это: * Отслеживание периодических задач (backup скриптов, cron задач) * Проверка доступности веб-сайтов и API, туннелей из нескольких регионов * Мониторинг сетевой инфраструктуры (TCP, DNS, ICMP) * Автоматические уведомления при сбоях и восстановлении * Интеграция с tuna CLI для удобной работы из терминала #### Для кого? 1. **DevOps-инженерам** — для мониторинга инфраструктуры и автоматизированных задач 2. **Разработчикам** — для отслеживания доступности API и сервисов 3. **Системным администраторам** — для контроля выполнения backup-скриптов и cron-задач 4. **Командам** — для централизованного мониторинга всех сервисов с общими уведомлениями #### 6 типов мониторов Tuna поддерживает 6 типов мониторов, разделённых на две категории: ##### Пользовательские мониторы Эти мониторы ожидают сигналы от ваших приложений и скриптов: | Тип | Описание | | ----------------- | ----------------------------------------------------------- | | **Задача (Job)** | Мониторинг выполнения периодических задач по расписанию | | **Heartbeat** | Мониторинг регулярных сигналов от сервисов в закрытых сетях | ##### Внешние мониторы Эти мониторы самостоятельно проверяют доступность ваших ресурсов из нескольких географических регионов: | Тип | Описание | | --------- | --------------------------------------------------------- | | **HTTP** | Проверка доступности веб-сайтов и API с валидацией ответа | | **TCP** | Проверка доступности TCP-сервисов (базы данных, почта) | | **DNS** | Проверка DNS-записей и их корректности | | **ICMP** | Проверка сетевой доступности (ping) | HTTP и TCP мониторы интегрированы с Туннелями. Если у вас есть активные туннели или зарезервированные домены/порты, то при создании монитора нужный ресурс будет в меню справа от адреса. ![Главная страница мониторов](/docs/img/monitors/http_tunnel.png) #### Ключевые возможности ##### Мониторинг cron-задач Отслеживайте выполнение backup-скриптов, синхронизаций и других периодических операций: ```bash # Простой backup с мониторингом tuna monitor exec MONITOR_ID -- pg_dump -U postgres mydb > /backups/dump.sql # В crontab 0 3 * * * tuna monitor exec MONITOR_ID -- /scripts/backup.sh ``` Система автоматически отправляет сигналы `start`, `finish` или `fail`, а также захватывает логи выполнения. ##### Heartbeat мониторинг Для сервисов в закрытых сетях, IoT устройств и фоновых процессов: ```bash # Отправка heartbeat каждые 5 минут */5 * * * * tuna monitor ping MONITOR_ID --host=my-server ``` ##### Проверка из нескольких регионов Внешние мониторы проверяют доступность ваших ресурсов из разных географических точек, что позволяет обнаружить проблемы с маршрутизацией или региональную недоступность. ##### SSL/TLS и Whois мониторинг HTTP мониторы автоматически проверяют SSL-сертификаты и отслеживают срок действия домена, чтобы вы не пропустили момент продления. ##### Интеграция с уведомлениями Мониторы интегрированы с системой [Контактов](https://tuna.am/docs/team/contacts.md) и [Интеграций](https://tuna.am/docs/team/integrations.md). Настройте уведомления в Telegram, Slack, по email или через webhook. #### CLI-интеграция Консольный клиент **tuna** полностью [интегрирован](https://tuna.am/docs/monitors/cli.md) с мониторами: * `tuna monitor ping` — отправка сигнала Heartbeat монитору * `tuna monitor exec` — выполнение команды с автоматическим отслеживанием * `tuna monitor status` — просмотр статуса мониторов Подробная информация о каждом типе мониторов, настройках и примерах использования доступна в [документации](https://tuna.am/docs/monitors.md). *** #### Уведомления и интеграции Уведомления и интеграции - это также большая часть нового функционала, которая интегрирована не только с [мониторами](https://tuna.am/docs/monitors.md), но и [отчётами](https://tuna.am/docs/reports.md). ![Виды интеграций](/docs/img/team/integrations_2.png) Поддерживаются популярные каналы связи: Telegram, Slack, Discord, VK Teams, Google Chat и произвольные Webhook. [Группы контактов](https://tuna.am/docs/team/contacts.md) позволяют гибко управлять получателями — объединяйте email-адреса и интеграции в именованные группы, используйте одну группу для нескольких мониторов и легко добавляйте или удаляйте получателей без изменения настроек самих мониторов. #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) * [tuna](https://tuna.am/blog/tags/tuna) * [cli](https://tuna.am/blog/tags/cli) --- ### 🔐 Менеджер паролей - зачем мы его сделали и как он устроен 20 февраля 2025 г. · 7 мин. чтения Когда вы доверяете свои пароли внешнему сервису, главный вопрос — можно ли ему доверять. Поэтому мы решили открыто рассказать, как изнутри устроен [Менеджер паролей](https://tuna.am/docs/passwords.md) Tuna: какими ключами и в каком порядке шифруются данные, что хранится у нас на сервере, а что — только у вас, и что произойдёт, если наша база данных утечёт. Цель простая — чтобы пользоваться менеджером было не страшно, потому что вы понимаете, как он работает. ![Tuna — менеджер паролей](/blog/img/2025-02-20-password-manager/00-cover.jpg) Коротко Все ключи шифрования создаются **на вашем устройстве** и никогда не покидают клиент в открытом виде. На сервер уходит только зашифрованный текст, а Мастер-ключ есть **только у вас**. Это модель нулевого знания (zero-knowledge): даже если наша инфраструктура будет скомпрометирована и утечёт вся база данных — расшифровать ваши пароли без Мастер-ключа невозможно. #### Нафига мы сделали менеджер паролей? Мы много работали по фрилансу в разных компаниях, поэтому есть насмотренность как люди меняются корпоративными паролями к сервисам, инфраструктуре и прочему. Ну так вот, если в компании нет купленного 1Password или чего-то подобного (что там Дудь рекламирует), то это просто аншлаг. * Нет единого хранилища, чаще всего это просто какой-то 1 ответственный человек, если он уйдёт, то всё... * Пароли передают в чатиках Tg или Slack * При увольнении сотрудника, если есть какая то общая учётка от внешнего сервиса, приходится почти рассылать новый пароль всем. Там ещё скоуп проблем, но это основное. В общем посмотрели мы на это всё и подумали, что у нас 99% пользователей это разработчики, наверняка у них та же самая проблема. Есть потребность хранить какие то инфраструктурные пароли, SSH ключи, офисный WI-FI и так далее. Но не всегда есть доступные инструменты для безопасного и удобного способа делиться ими с командой, заказчиками, аудиторами или просто друзьями. Так вот и решили, что надо — ну и сделали. #### Сколько стоит? Мы решили, что это будет **базовым бесплатным функционалом** в рамках нашей платформы. Безопасность — это базовая потребность (даже по пирамиде Маслоу), и мы хотим, чтобы даже самые маленькие стартапы на 5 человек могли себе позволить безопасно хранить и обмениваться паролями в компании или друзьями. Возможно позже мы введём какие то разумные ограничения или новые возможности которые будут доступны только с подпиской, но пока весь функционал доступен бесплатно всем. Вы можете зарегистрироваться, создать Команду, пригласить пользователей и завести общие каталоги с паролями без оформления подписки. #### Архитектура Что ж, ничего сложного, генерируем на клиенте какой-то ключ показываем его пользователю, нигде не сохраняем, этим ключом пользователь на клиенте шифрует пароли, в зашифрованном виде передаёт на сервер, мы храним. Когда пользователь хочет прочитать пароль, отдаём его, пользователь расшифровывает этот пароль своим ключом который есть только у него — профит. Кажется всё просто, но сложность начинается когда нам надо не только хранить пароли одного пользователя, а иметь какие то общие каталоги в командах и делиться паролями наружу одноразовой ссылкой. Тут то мы и начинаем замешивать симметричные и асимметричные ключи, шифровать одно другим и вообще становится не так всё просто. ##### Общие каталоги в команде Вообще в этом параграфе мы разберём почти полное устройство, так как будем распутывать клубок из конца в начало. Начнём с задачи — иметь общие каталоги с паролями в команде. Тут есть 2 пути: * Пароли должны быть зашифрованы 1 ключом который есть у всех. * При добавлении нового пользователя мы дублируем все пароли и шифруем его публичным ключом. Второй поход нам не подходит, так как пользователь 1 должен иметь возможность редактировать пароль, а пользователь 2 должен сразу это видеть и наоборот. Значит — пароли должны быть зашифрованы одним ключом который есть у всех. Как такое провернуть? А вот так: ![Пароли шифруются AES-ключом каталога, а сам AES-ключ — RSA-ключом пользователя](/blog/img/2025-02-20-password-manager/01-team-catalogs.jpg) В итоге пароли шифруются симметричным AES ключом, назовём его — AES-ключ каталога. Но не храним же мы его в открытом виде? Верно, этот AES-ключ каталога на самом деле зашифрован RSA-ключом пользователя. Распутываем клубок ... ![Приватный RSA-ключ шифруется Мастер-ключом, публичный хранится в открытом виде](/blog/img/2025-02-20-password-manager/02-rsa-keys.jpg) Когда вы инициируете менеджер паролей, для вашего пользователя генерируется ассиметричный RSA ключ, его приватная часть шифруется Мастер-ключом, а публичная сохраняетися в открытом виде. Итого, пользователь хранит: * свой Мастер-ключ Итого, мы храним: * публичный RSA-ключ * зашифрованный приватный RSA-ключ * зашифрованный AES-ключ каталога * зашифрованный пароли Давайте попробуем посмотреть картину в целом и собрать в кучу весь алгоритм что там вообще происходит? ![Полная схема алгоритма работы менеджера паролей](/blog/img/2025-02-20-password-manager/03-full-algorithm.jpg) Если коротко, то основная концепция в том, что на стороне сервера если что-то и хранится, то исключительно в зашифрованном виде, а на клиенте в открытом виде всё может существовать только в Runtime и перманентно тоже нигде не хранится. Чтобы проще это понять нужно пройтись по шагам: * Пользователь инициирует менеджер паролей * На клиенте (браузер) генерируется пара RSA-ключей приватный и публичный. * На клиенте генерируется Мастер-ключ, пользователь должен сохранить его себе * На клиенте приватный RSA-ключ шифруется Мастер-ключом * На сервер передаётся зашифрованный приватный RSA-ключ и публичный RSA-ключ * Пользователь создаёт новый каталог * На клиенте генерируется AES-ключ каталога * На клиенте AES-ключ каталога шифруется публичным RSA-ключом * На клиенте пароли шифруются AES-ключом каталога Когда нам надо сделать пароли общими, мы находим пользователя в команде, берём его публичный RSA-ключ, берём AES-ключ каталога расшифровываем его своим приватным RSA-ключом, шифруем публичным RSA-ключом нового пользователя и отправляем на сервер, на сервере у каталога появляется новый пользователь с AES-ключом каталога и новый пользователь теперь может расшифровать его своим приватным RSA-ключом, а затем и пароли зашифрованные AES-ключом каталога. В итоге получается примерно вот такая колбаса: ![Цепочка вложенного шифрования ключей и паролей](/blog/img/2025-02-20-password-manager/04-sausage.jpg) Фух ... ##### Делимся паролями наружу Если с пользователями внутри команды разобрались, то как делиться паролями наружу, ведь у незарегистрированных пользователей нет RSA-ключей и они вообще ничего не знают? ![Обмен паролем наружу по одноразовой ссылке](/blog/img/2025-02-20-password-manager/05-share-external.jpg) Тут мы приходим к тому нужно сделать копию пароля. Снова генерируем AES-ключ но в этот раз он будет только для 1 пароля. Зашифрованному паролю присваиваем UID и отправляем это на сервер. Что знает клиент: * UID пароля * AES-ключ которым он зашифрован Что знает сервер: * UID пароля * Зашифрованный пароль Далее клиент генерирует ссылку, где часть URI — это UID пароля, а другая AES-ключ: ```text https://my.tuna.am/password#{UID}#{AES-ключ} ``` Соответственно у себя в базе мы не храним AES-ключ и не можем расшифровать пароль, но пользователь, что перейдёт по ссылке без труда его расшифрует и посмотрит. Да, формально мы можем расшифровать пароль в момент 1-го же обращения, так как в запросе мы увидим полную ссылку, но делать этого мы конечно не будем. В целом есть идеи как улучшить этот момент, но пока всё на этапе обсуждения. Тем не менее именно в базе данных всё зашифровано. ![В базе данных всё хранится в зашифрованном виде](/blog/img/2025-02-20-password-manager/06-db-encrypted.jpg) Думаю тут можно завершить с архитектурой и перейти дальше. #### Какие планы? Мы уже получили обратную связь от CTO одного из наших клиентов, с просьбой добавить поддержку TOTP (Time-based one-time Password), думаю добавим в ближайшем релизе. Это актуально если в компании есть какой-то сервис с одним аккаунтом и вход там с подтверждением через TOTP. Думаем как сделать функционал Делимся паролями наружу более безопасным, но при этом таким же удобным. Также есть планы внедрить работу с паролями в консольную утилиту `tuna` чтобы можно было получать пароли в консоли. В целом продукт ещё в стадии Бета и мы активно собираем обратную связь. Пожалуй тут и закончим, с удовольствием отвечу на вопросы в комментариях 🤗. ![Tuna — менеджер паролей](/blog/img/2025-02-20-password-manager/07-closing.jpg) #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [security](https://tuna.am/blog/tags/security) * [passwords](https://tuna.am/blog/tags/passwords) * [tuna](https://tuna.am/blog/tags/tuna) --- ### 💳 Оплата международными картами — подключили PayPro Global 10 августа 2026 г. · 3 мин. чтения Пожалуй, самая долгожданная просьба в нашей поддержке наконец закрыта: подписку в Tuna теперь можно оплатить **международной картой**. Мы подключили платёжного провайдера **PayPro Global** и принимаем оплату в долларах картами Visa и Mastercard практически любой страны. ![Переключатель валюты оплаты в личном кабинете Tuna — рубли или доллары США](/blog/img/2026-08-10-paypro-global/currency.png) #### Что изменилось Раньше оплатить подписку можно было только российской картой через **ЮKassa** — и для многих наших пользователей это была стена. Аккаунт есть, тарифы понятны, а платить нечем: карта не проходит, и остаётся либо бесплатный тариф, либо просьба знакомым «оплати, я переведу». Теперь в [личном кабинете](https://my.tuna.am/subscription) появился переключатель **валюты оплаты**: * **RUB, российский рубль** — оплата картой российского банка через ЮKassa, как и раньше; * **USD, доллар США** — оплата через PayPro Global картой любой страны. Выбранная валюта определяет и провайдера, и цены — при переключении стоимость тарифов на странице сразу пересчитывается. Например, тариф **Профи** в долларах стоит 5 USD в месяц или 50 USD в год. #### Про PayPro Global [PayPro Global](https://payproglobal.com/) — международный платёжный провайдер, который больше пятнадцати лет специализируется на подписках для SaaS. Он выступает **merchant of record**, то есть берёт на себя приём платежа, конвертацию валют, налоги и всю сопутствующую отчётность в стране покупателя. Что это значит на практике: * принимаются карты **Visa и Mastercard** большинства стран мира; * оплата проходит на защищённой странице провайдера — данные карты не попадают на серверы Tuna; * подписка списывается автоматически, продлением и уведомлениями занимается провайдер; * чек и документы об оплате приходят на почту. #### Кого мы ждали больше всего В первую очередь — наших пользователей из **стран СНГ**. Многие из вас пишут нам не первый месяц: пользуемся Tuna каждый день, хотим тариф, но заплатить физически невозможно. Спасибо, что дождались и не ушли — теперь платформа доступна вам целиком, без оговорок и обходных путей. Это касается и всех остальных, кто живёт за пределами России: разработчиков в Европе, Азии, обеих Америках — процесс для вас теперь ровно такой же, как в любом привычном SaaS-сервисе. #### Что остаётся без изменений * Оплата российскими картами через ЮKassa работает как прежде. * Действующие подписки продолжают действовать, ничего переоформлять не нужно. * [Оплата по счёту](https://tuna.am/blog/invoices.md) для организаций в России никуда не делась. * Набор функций тарифов одинаковый независимо от валюты оплаты. #### Как оплатить Откройте [страницу подписки](https://my.tuna.am/subscription), выберите в блоке **«Валюта оплаты»** нужный вариант, проверьте цены и нажмите **«Оформить подписку»**. Дальше вас встретит платёжная страница выбранного провайдера. Если карта всё-таки не проходит или что-то идёт не так — [напишите нам](mailto:info@tuna.am), разберёмся. #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [customer-portal](https://tuna.am/blog/tags/customer-portal) * [tuna](https://tuna.am/blog/tags/tuna) --- ### Доменные зоны (wildcard), Менеджер паролей и tuna 0.21.2 23 января 2025 г. · 4 мин. чтения Доменные зоны, TLS сертификаты, Менеджер паролей и новые виды дистрибуции клиента tuna, улучшения безопасности и многое другие. #### Доменные зоны ##### Управление зонами В командах появилась возможность добавлять [доменные зоны](https://tuna.am/docs/team/domain_zones.md) и загружать свои [TLS сертификаты](https://tuna.am/docs/team/tls_certificates.md). ![domain_zones](/assets/images/domain_zones-561cf25dd9ba3a4321037fb19807bf2a.png) Владение доменной зоной уникально в рамках платформы Tuna. Если вы верифицировали владение зоной, к примеру, `tuna-dev.ru`, то с этого момента только участники вашей команды могут резервировать домены по маске `*.tuna-dev.ru`. Можно резервировать зоны второго и выше уровня, например, можно добавить отдельно `foo.tuna-dev.ru` и `bar.tuna-dev.ru`. ##### Использрование После успешного прохождения проверки владения пользователи смогут начать её использовать. На странице [управления доменами](https://my.tuna.am/domains), пользователь увидит все доступные зоны в команде привязанные к данному региону. ![domain-add](/assets/images/domain-add-0ed6d8a0d3b5fd9a224cc2d3175e6b6b.png) ##### TLS сертификат Если вы добавили и указали свой [TLS сертификат](https://tuna.am/docs/team/tls_certificates.md), то для всех поддоменов в этой зоне будет использоваться ваш сертификат и Let's encrypt не будет выпускаться. Это значительно ускоряет добавление новых поддоменов. А также даёт вам возможность использовать любые покупные сертификаты, самоподписанные или например от [Минцифры](https://www.gosuslugi.ru/tls). ![domain_zones-tls](/assets/images/domain_zones-tls-8cfa29c8835ad88220c78546050962ea.png) ##### Своя зона по умолчанию Также появляется возможность использовать свою зону как зону по умолчанию в данном регионе. Это значит, что все динамически созданные [HTTP туннели](https://tuna.am/docs/tunnels/http.md) будут иметь домен в вашей зоне. Например при запуске `tuna http -f .` вы сразу получите адрес `4l7mqf-212-49-103-2.your-domain.ru` вместо стандартного `4l7mqf-212-49-103-2.ru.tuna.am`, т.е. не нужно указывать флаг `--domain` и использовать какой-то статичный домен, вы получаете брендированный (white label) домен *из коробки*! ![self-domain-default](/assets/images/self-domain-default-5e1abf79dd1706f418f58a779ca6ca50.png) примечание Можно скрывать IP адреса пользователей в динамических доменах, подробнее в разделе [домены](https://tuna.am/docs/team/domains.md). #### Менеджер паролей Кардинально новый функционал не связанный с реверс-прокси туннелями, но тесно связанный с людьми которые пользуются реверс-прокси туннелями! ![passwords-main](/assets/images/main-dacca5895830a1cf52a5767b574b095a.png) Почему мы встроили **Менеджер паролей** в сервис для создания туннелей? Мы заметили, что во многих командах разработчиков и администраторов отсутствует культура безопасного хранения паролей и секретов. При этом у всех есть потребность хранить инфраструктурные пароли, SSH ключи, офисный WI-FI и так далее. Но не всегда есть доступные инструменты для безопасного и удобно способа делиться ими с командой, заказчиками, аудиторами или просто друзьями. Тогда люди начинают передавать пароли в открытом виде в чатах, письмах, записках. Наша цель это повысить культуру хранения секретов среди наших пользователей и обезопасить клиентов и от утечек, и несанкционированного доступа к их инфраструктуре. Поэтому Менеджер паролей является базовой и бесплатной функцией для всех. ![pwd-types](/assets/images/pwd-types-2d6a18327bbc102893246e45dd5e23fa.png) Создан для безопасного хранения и удобного обмена паролей и других видов секретов для разработчиков, администраторов их команд и не только. Мы не храним пароли в открытом виде, согласно модели [нулевого знания](https://en.wikipedia.org/wiki/Zero-knowledge_proof), **только** пользователь обладает ключами, которые могут расшифровать данные. к сведению В настоящий момент [Менеджер паролей](https://my.tuna.am/passwords) является бесплатной функцией и доступен всем пользователям и командам без ограничений. Вы можете хранить пароли, SSH-ключи, лицензии, заметки, реквизиты к базам данных и прочие типы секретов. Создавать общие каталоги с секретами внутри команды и делиться ими с любыми людьми вне платформы Tuna. Подробнее все возможности описаны в [отдельном разделе](https://tuna.am/docs/passwords.md). #### Выпуск tuna 0.21.2 В этом выпуске нет значительных улучшений или новых функций клиента. Но по просьбам наших пользователей мы добавили новые виды дистрибуции клиента tuna. ##### MSI пакеты для Windows Теперь для пользователей Windows помимо winget и ручной установки через powershell [доступны MSI пакеты](https://tuna.am/docs/guides/install/install-cli.md?os=windows). ##### AUR для Arch Linux Для Arch Linux пользователей мы подготовили [репозиторий в AUR](https://aur.archlinux.org/packages/tuna.am-bin), а также статические пакеты и добавили [раздел в инструкцию](https://tuna.am/docs/guides/install/install-cli.md?os=linux&subos=archlinux). ##### Исправления Устранена утечка памяти при включённом [инспекторе запросов](https://tuna.am/docs/tunnels/http/inspect.md) #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) * [tuna](https://tuna.am/blog/tags/tuna) * [cli](https://tuna.am/blog/tags/cli) --- ### Новый функционал - Команды 25 июля 2024 г. · 2 мин. чтения В этом обновлении мы добавили новый тариф для работы в командах! ![teams](/assets/images/teams1-27650c68c0b62decfc770ec87bbff0e1.png) Создание команд уже доступно всем пользователям, помимо возможности оплачивать подписку за всех членов команды, вы получаете расширенные лимиты относительно базового тарифа **Профи**. Сравнение лимитов: | Профи | Легенда | | ----------------------- | ---------------------------- | | 5 туннелей одновременно | **10** туннелей одновременно | | 10 статичных поддоменов | **20** статичных поддоменов | | 1 собственный домен | **10** собственных доменов | | 1 статичный TCP порт | **5** статичных TCP портов | Тариф рассчитан на использование в компаниях занимающихся разработкой сайтов и приложений. Также в скором времени мы добавим возможность оплаты по счёту. #### Кейсы применения ##### Подключение оплаты на сайте ![example1](/assets/images/example1-109056a20efb8309bb0faf4961ad6d5b.png) Если вам нужно тестировать оплату локально, то без обратных Webhooks это невозможно. Мы сами используем tuna для тестирования платежей с [ЮKassa](https://yookassa.ru/?utm_source=tuna.am&utm_medium=organic&utm_campaign=blog), но всё тоже самое будет верно и для других платёжных шлюзов ([CloudPayments](https://cloudpayments.ru/?utm_source=tuna.am&utm_medium=organic&utm_campaign=blog), [Stripe](https://stripe.com/?utm_source=tuna.am&utm_medium=organic&utm_campaign=blog), [2Checkout](https://www.2checkout.com/?utm_source=tuna.am&utm_medium=organic&utm_campaign=blog), и .т.д). C **tuna** вы можете создать тестовый магазин для каждого разработчика или тестировщика и внедрять и проверять работу оплаты в вашем проекте. ##### Ускорение командной разработки ![example2](/assets/images/example2-4ade121aee7ec540203cc4ed9b38dce4.png) При классической схеме, когда у вас есть команда backend и frontend разработчиков, порой сложно синхронизироваться при внедрении нового функционала, когда обе команды работают над 1 задачей. Backend делают бизнес-логику, frontend интерфейс сайта, а протестировать это можно или на отдельном стенде, когда UI c новой фичей смотрит в API с новой фичей. При этом все эти стенды и CI/CD пайплайны могут занимать много времени, так как на каждую итерацию запускаются тесты и прочие задачи. Намного проще, если backend-разработчик с помощью tuna публикует API со своего рабочего компьютера, в frontend-разработчик помощью tuna публикует UI. За несколько минут можно проверить, что всё работает как надо, сэкономить часы прогона тестов на CI/CD пайплайнах и выпустить в релиз новое приложение уже в среду, а не пятницу 🙂 #### Заключение Безусловно можно придумать ещё очень много примеров как и где **tuna** может улучшить или ускорить вашу разработку и мы обязательно расскажем о них в других постах нашего блога. #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) * [customer-portal](https://tuna.am/blog/tags/customer-portal) * [teams](https://tuna.am/blog/tags/teams) --- ### Выпуск tuna 0.16.1 24 июля 2024 г. · 1 мин. чтения В новой версии клиента есть несколько исправлений и улучшений, вот самые важные: * Исправлена работа инспектора с [Server-sent events](https://tuna.am/docs/tunnels/http.md#server-sent-events) Для обновления следуйте [инструкции](https://tuna.am/docs/guides/update.md). #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) * [tuna](https://tuna.am/blog/tags/tuna) --- ### Выпуск tuna 0.17.0 31 июля 2024 г. · 2 мин. чтения В этой версии клиента появились новые функции. #### Множественный запуск туннелей ![multi-tunnels](/assets/images/multi-tunnels-4cd333c20895595fcb5aae138d03ed59.gif) В проектах где нужно опубликовать несколько сервисов, может потребоваться запустить сразу несколько туннелей – UI, API, база данных или что-то ещё. Это может быть крайне удобно при командной разработке. Так вы можете создать файл `.tuna.yml` в корне репозитория и это сразу будет работать для всех разработчиков в команде, либо вы можете описать настройки в Readme проекта и тогда новые сотрудники легко разберутся как запустить и опубликовать проект. Подробнее о том как это настроить, описано [на отдельной странице](https://tuna.am/docs/tunnels/guides/multi-tunnels.md). #### Создание системных сервисов ![service](/assets/images/service-fc45e68f9c0ce148c0462f9ac3514c1d.gif) Создавать системные сервисы теперь стало проще. Мы добавили отдельную команду, с помощью которой вы легко можете создать фоновую службу для туннеля который должен работать всё время. Это работает для всех поддерживаемых операционных систем. Подробнее о том как это настроить, описано [на отдельной странице](https://tuna.am/docs/tunnels/guides/service.md). #### Флаг для CORS Для корректной работы сайта с API на стороннем домене необходимо настройки отдачу заголовков [Cross-Origin Resource Sharing](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) и корректно обрабатывать `OPTIONS` (preflight) запросы, поэтому мы добавили специальный флаг `--cors` для команды `tuna http`. Подробнее о том как c этим работать, описано [на отдельной странице](https://tuna.am/docs/tunnels/http.md#cors). #### Обновление Для обновления следуйте [инструкции](https://tuna.am/docs/guides/update.md). #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) * [tuna](https://tuna.am/blog/tags/tuna) --- ### Выпуск tuna 0.19.0 24 сентября 2024 г. · 2 мин. чтения Политики обработки трафика, QR-код и другие улучшения новой версии клиента tuna. #### Политики обработки трафика Функция позволяет описать правила и действия обработки трафика для входящих запросов и более гибко настроить взаимодействие с вашим приложением. К примеру вы можете включить базовую авторизацию только для определённого префикса, проверить наличие заголовков, отдельно обрабатывать `OPTIONS` запросы, запретить доступ к методу по подсети, ограничить доступ в определённые дни недели и многое другое. Настройка собственных фильтров с помощью мощного синтаксиса [expr-lang](https://expr-lang.org/) выведет вашу разработку на новый уровень. ![policy_debug](/docs/img/policy_debug.png) Мы постарались максимально подробно [задокументировать](https://tuna.am/docs/traffic-policy.md) работу с данной функцией. Сейчас это доступно только по [подписке](https://tuna.am/#pricing) в тарифе **Легенда**. #### Генерация QR кода с ссылкой Для команд `tuna http` и `tuna tcp` появился новый параметр `--qr` (переменная `TUNA_QR_CODE`). При включении этого для флага, для ссылки будет сгенерирован QR код и напечатан в консоли. Это может быть удобно если вы тестируете сайт на мобильном устройстве. ![](/docs/img/examples/qr.png) #### Адрес для инспектора запросов Ранее [инспектор HTTP запросов](https://tuna.am/docs/tunnels/http/inspect.md) всегда запускался на адресе `127.0.0.1`, как выяснилось это не очень удобно для тех, кто запускает **tuna** в Docker контейнере. Поэтому мы добавили возможность переопределить адрес и порт для инспектора запросов с помощью переменной окружения `TUNA_INSPECT_ADDR` или параметра `inspectAddr` в [конфигурационном файле](https://tuna.am/docs/guides/config-file.md). Пример для Docker Compose: ```yaml --- services: whoami: image: traefik/whoami restart: always tuna: image: yuccastream/tuna:latest command: http whoami:80 restart: always depends_on: - whoami environment: - TUNA_TOKEN=<ваш_токен> - TUNA_INSPECT_ADDR=0.0.0.0:4040 ports: - "4040:4040" ``` #### Обновление Для обновления следуйте [инструкции](https://tuna.am/docs/guides/update.md). #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) * [tuna](https://tuna.am/blog/tags/tuna) --- ### Выпуск tuna 0.20.0 1 ноября 2024 г. · 2 мин. чтения Авторизация по ключам в SSH туннелях, скрытие IP адреса в динамических HTTP туннелях, фильтры в аудит логах, улучшения безопасности и много другое в новой версии tuna. #### Авторизация по ключам в SSH туннелях Появилась возможность авторизации клиентов по SSH ключу. Теперь вы можете добавить свои [SSH ключи](https://tuna.am/docs/guides/ssh-keys.md) в [личном кабинете](https://my.tuna.am/public_keys) и использовать их для авторизации в [SSH туннелях](https://tuna.am/docs/tunnels/ssh.md). При этом в [Командах](https://my.tuna.am/team) вы можете также разрешить авторизоваться по ключу и другим участникам команды. ![](/docs/img/ssh-keys.png) #### Скрывать IP адрес в динамических HTTP туннелях В тарифе [Легенда](https://my.tuna.am/team) добавили функцию скрытия IP адреса пользователя в динамических HTTP туннелях. ![](/blog/img/2024-11-01/hide_ip.png) Вместо IP адреса будет использоваться имя команды приведённое к латинице. Минимальная длина сгенерированного имени - 8 символов, если название вашей команды короче, то оно будет дополнено случайными ascii символами. Ниже пример, как это работает. Поведение по умолчанию: ![](/blog/img/2024-11-01/no_hide_ip_terminal.png) Скрывать IP адрес: ![](/blog/img/2024-11-01/hide_ip_terminal.png) #### Фильтры в аудит логах В разделе с Аудит логами теперь есть фильтры, что позволит быстрее насти нужные действия совершаемые пользователями. #### Политика обновления клиента tuna Начиная с этой версии мы вводим политику обновления клиента. Мы стремимся, чтобы пользователи всегда имели доступ к актуальной версии tuna. Поэтому ограничиваем использование устаревших версий для пользователей без подписки. При выходе новой версии клиента, предыдущая продолжить работать на протяжении примерно 6 месяцев, точная дата прекращения работы будет отражена в таблице на странице [обновление](https://tuna.am/docs/guides/update.md#%D0%BF%D0%BE%D0%BB%D0%B8%D1%82%D0%B8%D0%BA%D0%B0-%D0%BE%D0%B1%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F-tuna). Пользователи с подпиской могут продолжать пользоваться любой версией без ограничений. #### Обновление Для обновления следуйте [инструкции](https://tuna.am/docs/guides/update.md). #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) * [tuna](https://tuna.am/blog/tags/tuna) * [cli](https://tuna.am/blog/tags/cli) --- ### Выпуск tuna 0.21.0 23 декабря 2024 г. · 3 мин. чтения Поддержка unicode доменов, подписанный и заверенный клиент для macOS, борьба с злоупотреблениями и взаимодействие с антивирусам, улучшения безопасности и многое другие в новой версии tuna. 🍾🎉🔥 Это последний релиз в 2024 году, хотим выразить благодарность всем нашим пользователям, желаем счастливого Рождества и Нового года! #### Поддержка unicode доменов Мы добавили полноценную поддержку unicode доменов. Теперь вы сможете подключить домен в зоне `.РФ` или [любой другой](https://www.reg.ru/web-tools/punycode) соответствующий [RFC3492](https://datatracker.ietf.org/doc/html/rfc3492). ![](/blog/img/2024-12-23/punicode.png) #### Подписанный и заверенный бинарный файл tuna для macOS Начиная с этой версии мы [подписываем и заверяем](https://developer.apple.com/documentation/security/notarizing-macos-software-before-distribution) в Apple клиент tuna для macOS. Это позволит больше не добавлять его в исключения при первом запуске. ![](/blog/img/2024-12-23/macos_notarize.png) Обратите внимание, что файл подписан и заверен на имя: ```yaml Developer ID Application: Lev Aminov (FW65BD237L) ``` Проверить локально можно с помощью команды: ```sh codesign -dv --verbose=4 $(which tuna) ``` #### Борьба с злоупотреблениями и взаимодействие с антивирусам В последние месяцы мы столкнулись с частыми злоупотреблениями. Некоторые пользователями распространяли вирусы для Android и Windows через платформу Tuna. В следствии чего наши туннельные ноды попали в чёрные списки VirusTotal, это негативно сказалось на работе других клиентов, в частности тех, кто использовал популярные антивирусы. По полученным данными от антивирусных компаний мы заблокировали несколько пользователей, которые распространяли вредоносное ПО, чем нарушали наши [условия использования](https://tuna.am/tos/). Далее последовало долгое взаимодействие со всеми антивирусными компаниями, чтобы нас исключили из чёрных списков, и вот по прошествии месяца мы снова чисты. Данная ситуация заставила нас иначе взглянуть на вопрос безопасности, в связи с чем мы внедрили несколько механизмов позволяющим минимизировать вредительство а так-же обработку входящих сообщений о злоупотреблениях. Теперь на бесплатных тарифах всем кто впервые открывает ссылку будет показываться предупреждение. ![](/blog/img/2024-12-23/html_warning.png) Также появилась отдельная страница в [документации](https://tuna.am/docs/abuse.md) описывающая правила работы и обработки входящих сообщений и жалоб. И несколько других доработок, улучшений и оптимизаций которые позволят сделать работу c Tuna безопасной и стабильной. #### Улучшения безопасности SSH туннелей Для SSH туннелей появился новый флаг `--password-auth` позволяющий выключить авторизацию по логин/пароль. Так теперь вы сможете подключиться к SSH серверу только с помощью [ключей](https://tuna.am/docs/guides/ssh-keys.md) добавленных в личном кабинете. Это значительно повышает безопасность доступа к вашей инфраструктуре и исключает возможности подбора пары логин/пароль с помощью перебора. Пример использования: ```sh tuna ssh --port=server-1 --password-auth=false ``` либо с конфигурацией через переменные окружения: ```sh export TUNA_TCP_PORT=server-1 export TUNA_SSH_PASSWORD_AUTH=false tuna ssh ``` #### Обновление Для обновления следуйте [инструкции](https://tuna.am/docs/guides/update.md). #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) * [tuna](https://tuna.am/blog/tags/tuna) * [cli](https://tuna.am/blog/tags/cli) --- ### IP фильтры в TCP, SSH, Postgres и Redis туннелях 13 июня 2025 г. · 3 мин. чтения В консольном клиенте **tuna** версии v0.25.0 мы добавили возможность ограничивать IP и подсети с которых можно подключаться. Это повышает уровень безопасности и особенно важно в приложениях без встроенной авторизации. #### Новые флаги В командах `tuna tcp`, `tuna ssh`, `tuna postgres` и `tuna redis` появились новые флаги и аналоги env: **Flags** ```shell --cidr-allow # Отклонять соединения, которые не соответствуют заданным CIDR --cidr-deny # Отклонить соединения, соответствующие заданным CIDR ``` **Envs** ```shell TUNA_CIDR_ALLOW # Отклонять соединения, которые не соответствуют заданным CIDR TUNA_CIDR_DENY # Отклонить соединения, соответствующие заданным CIDR ``` #### Примеры использования **TCP** Вы можете определить белый список [подсетей](https://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%B4%D1%81%D0%B5%D1%82%D1%8C) в CIDR-формате: ```shell tuna tcp 3389 --cidr-allow="10.0.0.1/32" ``` Либо запретить доступ из определенных подсетей: ```shell tuna tcp 3389 --cidr-deny="10.0.0.1/32" ``` Можно комбинировать, например указать широкую сеть и вычесть частные IP: ```shell tuna tcp 3389 --cidr-allow="10.0.0.1/24" --cidr-deny="10.0.0.33/32" ``` Также можно передавать списки через запятую: ```shell tuna tcp 3389 --cidr-allow="10.0.0.1/24,192.168.0.1/24" --cidr-deny="10.0.0.33/32,192.168.0.33/32" ``` **SSH** Вы можете определить белый список [подсетей](https://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%B4%D1%81%D0%B5%D1%82%D1%8C) в CIDR-формате: ```shell tuna ssh --cidr-allow="10.0.0.1/32" ``` Либо запретить доступ из определенных подсетей: ```shell tuna ssh --cidr-deny="10.0.0.1/32" ``` Можно комбинировать, например указать широкую сеть и вычесть частные IP: ```shell tuna ssh --cidr-allow="10.0.0.1/24" --cidr-deny="10.0.0.33/32" ``` Также можно передавать списки через запятую: ```shell tuna ssh --cidr-allow="10.0.0.1/24,192.168.0.1/24" --cidr-deny="10.0.0.33/32,192.168.0.33/32" ``` **Postgres** Вы можете определить белый список [подсетей](https://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%B4%D1%81%D0%B5%D1%82%D1%8C) в CIDR-формате: ```shell tuna postgres 5432 --cidr-allow="10.0.0.1/32" ``` Либо запретить доступ из определенных подсетей: ```shell tuna postgres 5432 --cidr-deny="10.0.0.1/32" ``` Можно комбинировать, например указать широкую сеть и вычесть частные IP: ```shell tuna postgres 5432 --cidr-allow="10.0.0.1/24" --cidr-deny="10.0.0.33/32" ``` Также можно передавать списки через запятую: ```shell tuna postgres 5432 --cidr-allow="10.0.0.1/24,192.168.0.1/24" --cidr-deny="10.0.0.33/32,192.168.0.33/32" ``` **Redis** Вы можете определить белый список [подсетей](https://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%B4%D1%81%D0%B5%D1%82%D1%8C) в CIDR-формате: ```shell tuna redis 6379 --cidr-allow="10.0.0.1/32" ``` Либо запретить доступ из определенных подсетей: ```shell tuna redis 6379 --cidr-deny="10.0.0.1/32" ``` Можно комбинировать, например указать широкую сеть и вычесть частные IP: ```shell tuna redis 6379 --cidr-allow="10.0.0.1/24" --cidr-deny="10.0.0.33/32" ``` Также можно передавать списки через запятую: ```shell tuna redis 6379 --cidr-allow="10.0.0.1/24,192.168.0.1/24" --cidr-deny="10.0.0.33/32,192.168.0.33/32" ``` #### IP политики в Легенде В [командах](https://tuna.am/docs/team.md), если указаны [IP политики](https://tuna.am/docs/team/ip_policies.md), то он будут работать в комплексе с этими флагами. #### Обновление Для обновления следуйте [инструкции](https://tuna.am/docs/guides/update.md). #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) * [tuna](https://tuna.am/blog/tags/tuna) * [cli](https://tuna.am/blog/tags/cli) --- ### Поддержка PROXY Protocol в TCP туннелях 28 января 2026 г. · 2 мин. чтения В [консольном клиенте](https://tuna.am/docs/guides/install/install-cli.md) **tuna** добавлена поддержка [PROXY Protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) для TCP туннелей. Теперь вы можете передавать оригинальный IP-адрес и порт клиента напрямую вашему приложению. ```shell $ tuna tcp 54321 --proxy-protocol=2 INFO[22:08:58] Welcome to Tuna INFO[22:09:00] Forwarding tcp://ru.tuna.am:22347 -> 127.0.0.1:54321 ``` [Перейти к документации](https://tuna.am/docs/tunnels/tcp.md#proxy-protocol) #### Зачем нужен PROXY Protocol? При использовании туннелей ваше приложение видит подключения от туннельного сервера, а не от реального клиента. PROXY Protocol решает эту проблему — он передаёт оригинальный IP и порт клиента в заголовке соединения, что позволяет: * Вести корректные логи подключений с реальными IP-адресами * Применять правила контроля доступа на уровне приложения * Собирать точную аналитику по географии пользователей #### Новый флаг В команде `tuna tcp` появился новый флаг `--proxy-protocol`, принимающий версию протокола: | Значение | Формат | Описание | | -------- | --------- | ----------------------------------------------- | | `1` | Текстовый | Человекочитаемый формат, легко отлаживать | | `2` | Бинарный | Более эффективный, рекомендуемый для продакшена | #### Примеры использования ##### Базовый пример ```shell tuna tcp 8443 --proxy-protocol=1 # или с переменной окружения TUNA_PROXY_PROTOCOL=1 tuna tcp 8443 ``` ##### Minecraft сервер Некоторые сборки игровых серверов, например [Velocity](https://docs.papermc.io/velocity/configuration/#advanced-section), поддерживают PROXY Protocol. Включите его в конфиге игры и в клиенте tuna: ```shell tuna tcp 45678 --proxy-protocol=2 ``` #### Совместимость PROXY Protocol широко поддерживается популярным серверным ПО: * **Haproxy** — поддерживает обе версии, определяет автоматически * **Nginx** — поддерживает обе версии, определяет автоматически * **Envoy** — поддерживает обе версии * Многие базы данных и приложения через прокси-слой подсказка Если вы не уверены какую версию выбрать — используйте версию `2`. Бинарный формат эффективнее и является рекомендуемым в большинстве случаев. #### Обновление Для обновления следуйте [инструкции](https://tuna.am/docs/guides/update.md). #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) * [tuna](https://tuna.am/blog/tags/tuna) * [cli](https://tuna.am/blog/tags/cli) --- ### 🆕 Отчёты - новый функционал 12 ноября 2025 г. · 2 мин. чтения Мы рады представить новый компонент платформы Tuna - **Отчёты**. Предназначенный для генерации отчётов об ошибках на вашем сайте. С помощью встраиваемого скрипта пользователи и QA-инженеры могут легко показать, где спрятался баг, а вы – получить отладочную информацию и сразу приступить к исправлению. [Перейти к разделу Отчёты в документации](https://tuna.am/docs/reports.md) ![Настройка](/docs/img/reports/setup.png) #### Как это работает? 1. Перейдите в личный кабинет и создайте проект в разделе [Отчёты](https://my.tuna.am/reports). 2. Добавьте на ваш сайт код перед закрытием тега ``: ```html ``` 3. Вызовите скрипт `CTRL + ALT + S` или `⌘ + ⌥ + S` и создайте отчёт. #### Как выглядит отчёт? Внутри отчёта будет скриншот или видео и вся отладочная информация из консоли, сетевые операции, действия пользователя и снимок DOM-дерева страницы. **Информация** На первой вкладке содержится общая сводная информация о клиенте, устройстве, браузере... ![](/docs/img/reports/info.png) **Инспектор** Снимок DOM-дерева страницы, с возможностью выбора элемента. *** примечание Эта вкладка доступна только для отчётов с скриншотом, в отчётах с видео невозможно захватить снимок DOM-дерева так как он может меняться по ходу. **Консоль** Список всех событий из консоли браузера. ![](/docs/img/reports/console.png) **Сеть** Список всех XHR запросов с возможностью заглянуть в детали. **Действия** Действия пользователя на странице. ![](/docs/img/reports/actions.png) **Комментарии** Также можно оставлять комментарии и реакции к комментариям. ![](/docs/img/reports/message.png) #### Видео обзор **YouTube** **VK Видео** *** #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) --- ### 🆕 Секреты - новый функционал 9 мая 2025 г. · 4 мин. чтения Мы рады представить новый компонент платформы Tuna - **Секреты**. Предназначенный для централизованного и безопасного управления конфиденциальными настройками и переменными окружения. Это мощная альтернатива `.env` файлам, переменным в GitLab/GitHub CI и прочим локальным хранилищам. [Перейти к разделу Секретов в документации](https://tuna.am/docs/secrets.md) #### 🔐 Что такое Tuna Секреты? Сервис секретов предназначен для хранения настроек к вашим приложениям, которые вы запускаете - локально, в CI/CD или в своих тестовых и продуктовых окружениях. Он является отличной альтернативой `.env` файлам и переменным окружениям в CI/CD системах. **Секреты** — это: * Единый источник конфигурации для локальной разработки, CI/CD, staging и production сред. * Удобный интерфейс управления — через веб, CLI и API. * Поддержка RBAC, комментариев, напоминаний и аудита изменений. * Гибкая работа с проектами, окружениями и конфигурациями. * Все секреты шифруются, ключи не хранятся в базе. Утечка БД не приведёт к раскрытию данных. #### 👥 Для кого? 1. **Разработчикам** — для упрощения настройки окружений и сокращения "магических" значений в коде. 2. **DevOps-инженерам** — для централизации и автоматизации конфигураций. 3. **Командам** — для безопасного и контролируемого совместного доступа к конфиденциальным данным. #### 🎯 Ключевые возможности Мы внедрили структуру, позволяющую эффективно управлять секретами.
В этом ролике вы увидите небольшой обзор возможностей: **VK Видео** **YouTube** *** Иерархия: проекты → окружения → конфигурации. Мы придерживаемся общепринятой структуры, поэтому хранение секретов разделяется по проектам, внутри проектов есть окружения, а внутри окружений конфигурации основные или дочерние. Внутри конфигураций сосредоточенно множество функций работы непосредственно с секретами и доступом к ним, аудит и прочее. При работе в [Команде](https://tuna.am/docs/team.md), в разделе с ролями появляется возможность гранулярно распределять доступ участников к нужным окружениям в проектах. Что ещё есть в секретах? * **Дублирование конфигураций** - создавайте уникальные конфигурации для каждого пользователя. * **Типы переменных** — можно указать тип bool, int и др. * **Генератор и комментарии** — удобное добавление и аннотация секретов. * **Напоминания** — email-уведомления о необходимости обновить секрет. * **Сравнение окружений** — находите различия между конфигурациями. * **Скрытие секретов** — исключите из сравнения уникальные прод-переменные. * **Сервисные ключи** — API-ключи на чтение/запись для конкретной конфигурации. * **Ограничение по IP** — контроль доступа по CIDR. * **История изменений** — полный аудит всех действий. #### ⚙️ CLI-интеграция Естественно консольный клиент **tuna** полностью [интегрирован](https://tuna.am/docs/secrets/cli.md): * `tuna secrets download` — Получение секретов с возможностью сохранения в файл (`json`, `yaml`, `env`) или вывода в *stdout*. * `tuna secrets setup` — Настройка каталога для конфигурации области действия. * `tuna secrets run` — Автоматическая конфигурация приложения с передачей переменных окружения непосредственно процессу. А с указанием флага `--watch`, перезапуск приложения будет автоматический, при изменении секрета в личном кабинете. **VK Видео** **YouTube** #### 🛡️ Управление доступом и безопасность * **RBAC в команде** — Предоставляйте доступ к окружениям точечно по пользователям. * **Сервисные ключи** — Выпускайте уникальные ключи для конкретных конфигураций с ограничением на *чтение* или *чтение и запись*. Идеально подходит для использования в CI/CD. * **Разрешенные IP адреса и подсети** — Ограничивайте доступ к секретам, указывая разрешенные IP адреса и подсети в формате CIDR. * **История изменений** — Полный аудит всех действий и изменений внутри конфигураций позволяет отслеживать, кто и когда изменил секреты. #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) * [tuna](https://tuna.am/blog/tags/tuna) * [cli](https://tuna.am/blog/tags/cli) --- ### 🗝️ Секреты целиком из консоли — большое обновление tuna secrets 24 сентября 2026 г. · 4 мин. чтения До недавнего времени [секреты](https://tuna.am/docs/secrets.md) в консоли умели немного: скачать конфигурацию, привязать каталог и запустить приложение с переменными окружения. Всё остальное — завести секрет, поправить значение, создать окружение — приходилось делать в личном кабинете. В **tuna-cli 0.35** `tuna secrets` стал полноценным инструментом: секретами, проектами, окружениями и сервисными ключами теперь можно управлять целиком из терминала, а вывод команд удобно разбирать в скриптах и CI. #### Работа с отдельными секретами Появились команды для чтения и записи секретов по одному: ```shell tuna secrets list # список, значения скрыты tuna secrets get API_TOKEN DB_URL # значения конкретных секретов tuna secrets set API_ENABLED=true --type boolean openssl rand -hex 32 | tuna secrets set API_TOKEN tuna secrets delete OLD_KEY tuna secrets upload .env # дополнить конфигурацию из файла ``` `set` принимает значение аргументом, из stdin или интерактивно — так в историю шелла не попадёт ничего лишнего. Можно задать тип значения, комментарий и видимость в веб-интерфейсе. `upload` дополняет конфигурацию из `.env` или `.json`, не трогая остальные секреты. #### Сравнить окружения, не раскрывая значений В таблицах вместо значения секрета теперь печатается его **отпечаток** — `hmac:cea41705`. Одинаковые значения дают одинаковый отпечаток, а восстановить значение из отпечатка нельзя. Так можно ответить на вопрос «а в stage и prod точно разные пароли к базе?», ничего не раскрывая, и спокойно печатать таблицы в логи CI: Настоящие значения показывают `list --values` и `get`. #### Новый разработчик — одна команда Положите в корень репозитория файл `tuna.yaml`: tuna.yaml ```yaml setup: - project: api-php config: dev ``` Теперь новому человеку в команде достаточно выполнить `tuna secrets setup` — и `tuna secrets run -- yarn start` запустит приложение с актуальными секретами. Для монорепозитория можно описать несколько привязок, каждую со своим каталогом. #### Секреты файлом, но без файла на диске Некоторые приложения читают конфигурацию только из файла. Раньше приходилось выгружать секреты через `download` и помнить, что файл потом надо удалить. Флаг `--mount` решает это иначе: клиент создаёт **именованный канал** (named pipe) и отдаёт через него секреты в нужном формате — `env`, `json`, `yaml` или по вашему шаблону. Значения живут только в памяти клиента, файла с секретами на диске не появляется, а после выхода процесса канал удаляется. ```shell tuna secrets run --mount ./secrets.json --mount-format json -- ./app --config ./secrets.json ``` С `--mount-max-reads 1` канал исчезает сразу после того, как приложение прочитало его при старте. #### Работа без сети `tuna secrets run` сохраняет последние полученные секреты в **зашифрованный** файл и использует его, если API недоступен, — приложение не встанет из-за проблем с сетью. Если же сервер ответил, что доступ отозван или конфигурации больше нет, копия удаляется: устаревшие секреты после отзыва доступа опаснее, чем остановка приложения. С `--offline` клиент вообще не обращается к API: #### Шаблоны конфигов `tuna secrets substitute` рендерит файл-шаблон со значениями секретов. Подходит для конфигов со своим форматом — `nginx.conf`, `application.yml`, `.ini` — и для манифестов Kubernetes: ```shell tuna secrets substitute config.tmpl --output config.ini tuna secrets substitute deployment.tmpl | kubectl apply -f - ``` Опечатка в имени секрета — ошибка с указанием места в шаблоне, а не молчаливая пустая строка в конфиге. #### Удобно в скриптах и CI Вывод всех команд `tuna secrets` переделан с расчётом на автоматизацию: * данные идут в stdout, статус и ошибки — в stderr, так что вывод можно смело перенаправлять в файл или пайп; * `-o json` и `-o yaml` есть у каждой подкоманды, включая команды записи, а ошибки в этом режиме тоже приходят JSON'ом; * `get --plain` печатает голое значение для подстановки: `docker login -p "$(tuna secrets get REGISTRY_PASSWORD --plain)"`; * `tuna secrets run` возвращает код выхода дочернего процесса, поэтому обёртку можно ставить прямо в CI-джобу. Готовые примеры для GitLab CI и GitHub Actions есть в [документации](https://tuna.am/docs/secrets/examples.md). #### Управление структурой Проекты, окружения, конфигурации и сервисные ключи теперь тоже создаются из консоли: ```shell tuna secrets projects create "API PHP" --slug api-php tuna secrets environments create Staging --slug stage --project api-php tuna secrets configs clone stage --name stage-feature-x --project api-php tuna secrets configs tokens create --description ci --access read --max-age 720h --project api-php --config stage ``` `tuna secrets open` открывает текущую конфигурацию в веб-интерфейсе — когда всё-таки нужен кабинет. #### Что проверить при обновлении * Удаление секретов, конфигураций, окружений, проектов и отзыв сервисных ключей с tuna-cli 0.36 спрашивают подтверждение. В CI и скриптах добавьте флаг `--yes`, иначе команда завершится ошибкой. * Если вы разбирали вывод `tuna secrets` в скриптах, проверьте их: строки лога вида `INFO[...]` заменены таблицами, а для машинного разбора теперь есть `-o json`. Полное описание команд и флагов — на странице [Работа в CLI](https://tuna.am/docs/secrets/cli.md). Обновить клиент можно по [инструкции](https://tuna.am/docs/guides/update.md). #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) * [tuna](https://tuna.am/blog/tags/tuna) * [cli](https://tuna.am/blog/tags/cli) * [secrets](https://tuna.am/blog/tags/secrets) --- ### 🔐 Безопасность Секретов и отличие от Паролей - мастер-ключ, шифрование и общая архитектура. 3 июня 2026 г. · 9 мин. чтения Когда вы отдаёте свои пароли, токены и ключи доступа во внешний сервис, главный вопрос — можно ли ему доверять. Поэтому мы решили показать, как устроена безопасность [Tuna Секретов](https://tuna.am/docs/secrets.md) изнутри: где хранится мастер-ключ, каким алгоритмом шифруются данные и — самое важное — что произойдёт, если нашу инфраструктуру взломают и утечёт вся база данных. Коротко Значения секретов шифруются **до** записи в базу алгоритмом **AES-256-GCM**. Ключ, которым их можно расшифровать, в базе **не лежит**. Утёкший дамп БД без мастер-ключа — это бесполезный набор зашифрованных данных. #### Пароли и секреты: две разные модели безопасности В Tuna есть два хранилища для чувствительных данных — [Менеджер паролей](https://tuna.am/docs/passwords.md) и [Секреты](https://tuna.am/docs/secrets.md). Они намеренно построены по-разному, потому что решают разные задачи. ![Сравнение моделей: пароли шифруются на клиенте, секреты — на сервере](/blog/img/2026-06-03-secrets-security/00-pwd-vs-secrets.png) **Менеджер паролей — модель нулевого знания (zero-knowledge).** Ключи шифрования создаются на вашем устройстве и никогда не покидают клиент — браузер или приложение. Шифрование и расшифровка происходят только на вашей стороне, а на сервер уходит уже зашифрованный текст. Принцип, заложенный в основу: *компрометация нашей инфраструктуры не должна приводить к компрометации ваших паролей* — расшифровать их можно лишь там, где есть мастер-ключ, а он есть только у вас. Обратная сторона — данные доступны только владельцу мастер-ключа: автоматически выдать пароль скрипту или пайплайну, не раскрывая его, в такой модели невозможно. **Секреты — серверное шифрование.** Здесь мастер-ключ находится на стороне платформы, и шифрование выполняет сервер. Это **осознанный компромисс**, и сделан он ради главного сценария секретов — автоматизации. Секрет должен сам, без участия человека, попадать в приложение при запуске, в CI/CD-пайплайн, в скрипт развёртывания. Запуск приложения с подгрузкой переменных, сервисные ключи для CI, автоматический перезапуск при изменении значения — всё это работает именно потому, что сервер способен выдать секрет по запросу авторизованного клиента, не требуя мастер-пароль каждый раз. Платой за удобство становится доверие к инфраструктуре платформы — технически сервер может расшифровать секрет. Поэтому всё, что описано дальше, — про то, как мы это доверие оправдываем. | | Пароли | Секреты | | ------------------------------ | ------------------------- | --------------------------------- | | Модель | Нулевое знание | Серверное шифрование | | Где находится ключ | Только у клиента | На стороне платформы | | Где идёт шифрование | На клиенте | На сервере | | Может ли Tuna прочитать данные | Нет | Да, для авторизованных операций | | Автоматизация (CI/CD, скрипты) | Ограничена | Полноценная | | Главный сценарий | Хранение и обмен паролями | Доставка конфигурации приложениям | #### Модель доверия секретов Раз сервер умеет расшифровывать секреты, главный принцип звучит так: **база данных не должна содержать ничего, чем можно расшифровать секреты**. Даже если у злоумышленника окажется полный дамп таблиц, в нём не должно быть достаточно материала, чтобы получить исходные значения. Достигается это классической схемой **конвертного шифрования** (envelope encryption) — двухуровневой иерархией ключей. #### Конвертное шифрование: два уровня ключей ![Иерархия ключей: мастер-ключ оборачивает ключ команды, ключ команды шифрует значения секретов](/blog/img/2026-06-03-secrets-security/01-key-hierarchy.png) В системе два уровня ключей: 1. **Мастер-ключ платформы (KEK, Key Encryption Key).** Хранится на стороне Tuna и в базу данных не попадает. Сам по себе он ничего пользовательского не шифрует — его единственная задача «оборачивать» (защищать) ключи команд. 2. **Ключ команды (DEK, Data Encryption Key).** Для каждой команды генерируется свой случайный ключ — криптографическим генератором случайных чисел. Именно им шифруются значения секретов этой команды. Ключ команды не хранится в открытом виде: он зашифрован мастер-ключом и в таком «обёрнутом» виде лежит в базе. Чтобы им воспользоваться, сервер сначала разворачивает его мастер-ключом в памяти. Получается цепочка зависимостей: **значение секрета** защищено **ключом команды**, а **ключ команды** защищён **мастер-ключом**. Разорвав любое звено, дальше пройти нельзя. Любопытно, что [менеджер паролей](https://tuna.am/blog/password-manager.md) построен на той же идее конвертного шифрования — с двумя принципиальными отличиями: «конверт» там запечатывается асимметрично, на паре открытого и закрытого ключей, а корневой ключ остаётся на стороне клиента, а не сервера. Схема одна и та же, по-разному распределено лишь доверие: секреты настроены на автоматизацию, пароли — на нулевое знание. #### Где и как хранится мастер-ключ Это основной для всей схемы вопрос, поэтому разберем каждое место хранения: * **Не в базе данных.** Мастер-ключ принципиально отделён от данных, которые он защищает. В дампе базы его нет. * **Не в коде и не в репозитории.** Он не зашит в исходники, а передаётся сервису извне — из защищённого хранилища конфигурации платформы. * **Только в памяти процесса.** Сервер держит ключ в оперативной памяти на время работы и не пишет его на диск в открытом виде. * **Полноценный 256-битный ключ.** Этого достаточно, чтобы перебор был вычислительно невозможен. Главный вывод: **доступ к базе данных и доступ к мастер-ключу — это два разных уровня доступа** с разными правами. Компрометация одного из них не означает автоматически компрометацию второго. #### Жизненный цикл секрета: запись и чтение Шифрование и расшифровка встроены в слой работы с данными и происходят прозрачно — приложение никогда не пишет открытое значение в базу и никогда не читает его оттуда напрямую. ![Последовательность сохранения и чтения секрета: шифрование перед записью, расшифровка после чтения](/blog/img/2026-06-03-secrets-security/02-lifecycle.png) **При сохранении** значение шифруется ключом команды ещё до записи. Для каждого значения берётся свой случайный одноразовый вектор (nonce) — поэтому даже два одинаковых секрета выглядят в базе по-разному. В хранилище попадает только зашифрованный текст. **При чтении** происходит обратный процесс: сервер достаёт шифр, разворачивает ключ команды и расшифровывает данные. Открытое значение существует только в памяти процесса ровно столько, сколько нужно, чтобы отдать его авторизованному клиенту. Мы используем режим **GCM** (Galois/Counter Mode) — это *аутентифицированное* шифрование. Помимо конфиденциальности оно гарантирует целостность: если кто-то изменит хотя бы один байт зашифрованных данных в базе, расшифровка не вернёт «мусор», а честно провалится с ошибкой проверки. Подделать или незаметно подменить значение в обход сервера не получится. В транзите всё дополнительно защищено TLS — между вашим клиентом и API данные идут по зашифрованному каналу. #### Что лежит в базе зашифровано, а что открыто Разбор того, какие данные и в каком виде реально хранятся в базе: | Зашифровано (AES-256-GCM) | В открытом виде | | ------------------------------- | ------------------------------------------- | | Значения секретов | Имена переменных | | Заметки к секретам | Типы значений | | Ключ команды (в обёрнутом виде) | Уровень видимости | | | Структура: проекты, окружения, конфигурации | | | Метки времени создания и изменения | Да, **метаданные — это тоже информация**. Даже не видя значений, по именам переменных можно судить о том, какими сервисами и технологиями вы пользуетесь. Сами секреты при этом остаются зашифрованными. Но это снова небольшой компромисс в угоду удобству и быстроте работы. #### Что будет, если утечёт база данных Это сценарий, ради предотвращения которого вся схема и строилась. Представим худшее: злоумышленник получил полный дамп нашей базы. ![Модель угроз при утечке базы: без мастер-ключа расшифровать значения невозможно](/blog/img/2026-06-03-secrets-security/03-db-leak.png) **Что у него на руках:** * Зашифрованные значения секретов — шифр AES-256-GCM, статистически неотличимый от случайного шума. * Ключ команды — но он сам зашифрован мастер-ключом. * Метаданные — имена, типы, структура проектов. **Чего у него нет:** * **Мастер-ключа.** Его нет в базе — он на стороне сервера, куда дамп базы доступа не даёт. Цепочка обрывается на первом же шаге. Чтобы расшифровать значение, нужен ключ команды. Чтобы развернуть ключ команды — нужен мастер-ключ. Мастер-ключа в дампе нет, а взломать AES-256 перебором невозможно. **Значения секретов остаются защищены.** Злоумышленник видит лишь каркас: имена и структуру, но не содержимое. ##### Границы защиты Никакая схема не защищает от всего, и важно понимать её рамки: * **Если утечёт И база, И мастер-ключ одновременно** — защита падает. Именно поэтому они хранятся раздельно, с разными правами доступа: чтобы одна уязвимость не вскрывала сразу оба уровня. * **Метаданные видны** при утечке базы — об этом сказано выше. * **Реакция на инцидент.** При подозрении на компрометацию правильный шаг — ротация: смена мастер-ключа, перевыпуск [сервисных ключей](https://tuna.am/docs/secrets.md) и обновление самих секретов в их первоисточниках. Сервисные ключи можно выпускать с ограниченным сроком жизни именно на такой случай. #### Дополнительные уровни защиты Шифрование — это фундамент, но не единственный слой. Доступ к секретам ограничен ещё на нескольких уровнях: * **Скрытые значения (Restricted).** Секрет с такой видимостью не отдаётся через API и не попадает в выгрузки — даже авторизованному пользователю показывается только факт его существования. * **Сервисные ключи с узким доступом.** Для CI/CD выпускаются ключи, привязанные к конкретной конфигурации, с правами только на чтение или на чтение и запись, и с опциональным сроком действия. Утечка такого ключа не открывает доступ ко всем секретам команды. * **Ограничение по IP (Trusted IP).** Доступ к конфигурации можно ограничить списком разрешённых адресов и подсетей в формате CIDR. * **Полный аудит.** Все изменения внутри конфигураций журналируются — видно, кто и когда менял каждый секрет. #### Что в планах Сейчас Tuna Секреты — это централизованное и зашифрованное хранилище. Логичный следующий шаг — сделать его **источником истины**, из которого секреты автоматически синхронизируются туда, где они нужны. ![Планы: синхронизация секретов из Tuna в Vault, Kubernetes Secrets, GitHub и GitLab CI/CD](/blog/img/2026-06-03-secrets-security/04-future-sync.png) В планах — интеграции для односторонней синхронизации: * **HashiCorp Vault** — отправка секретов в Vault, чтобы Tuna стала удобным интерфейсом управления, а приложения продолжали читать их привычным способом. * **Kubernetes Secrets** — синхронизация конфигурации напрямую в секреты нужного namespace кластера. * **GitHub Actions** — публикация в encrypted secrets репозитория или организации для использования в пайплайнах. * **GitLab CI/CD** — синхронизация в CI/CD variables проектов и групп. Идея в том, чтобы вы редактировали секрет в одном месте, а он автоматически и безопасно доходил до всех ваших окружений — без копирования значений между десятком панелей. #### Итог Безопасность Tuna Секретов держится на нескольких простых и проверенных принципах: * **Две модели под две задачи** — пароли шифруются на клиенте (мы их не видим), секреты — на сервере, ради автоматизации. * **AES-256-GCM** — аутентифицированное шифрование значений до записи в базу. * **Конвертное шифрование** — мастер-ключ защищает ключи команд, ключи команд защищают данные. * **Мастер-ключ отделён от данных** — его нет ни в базе, ни в коде, и утёкший дамп БД бесполезен. * **Слои доступа сверху** — видимость, сервисные ключи, ограничение по IP и аудит. Мы не делаем вид, что защита абсолютна, и открыто показываем её границы — потому что доверие строится на прозрачности, а не на маркетинговых обещаниях. #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [security](https://tuna.am/blog/tags/security) * [secrets](https://tuna.am/blog/tags/secrets) * [tuna](https://tuna.am/blog/tags/tuna) --- ### Обратный SSH туннель 6 сентября 2024 г. · 1 мин. чтения В этом выпуске мы исправили ошибки, улучшили стабильность платформы, а также добавили новую экспериментальную функцию. #### Обратный SSH туннель Внимание Функция на стадии BETA тестирования, в настоящий момент поддерживается создание только HTTP туннелей с динамическим поддоменом. Обратный SSH туннель `ssh -R` - это альтернативный механизм создания туннеля без установки и использования клиента **tuna**. Для создания туннеля используется стандартный SSH клиент, как правило, он присутствует во всех Unix подобных ОС. Может быть крайне полезным, когда вам нужно открыть доступ к какому либо ресурсу, но нет возможности установить полноценный клиент, или это избыточно. ```shell ssh -R 443:localhost:8080 ssh-ru.tuna.am http ``` ![](/docs/img/ssh-r.gif) #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) * [customer-portal](https://tuna.am/blog/tags/customer-portal) * [connect](https://tuna.am/blog/tags/connect) --- ### Новые названия тарифов 20 февраля 2026 г. · 1 мин. чтения Мы обновили названия тарифных планов. Функциональность и стоимость остались прежними — изменились только названия. #### Что изменилось? | Было | Стало | | ----------- | ----------- | | Хобби | **Новичок** | | Разработчик | **Профи** | | Команда | **Легенда** | Новые названия лучше отражают уровень возможностей каждого тарифа и путь роста пользователя на платформе. #### Почему переименовали? Старое название **Команда** вводило пользователей в заблуждение — многие думали, что тариф предназначен исключительно для командного использования. На самом деле никаких ограничений нет, и этим тарифом можно пользоваться в одиночку, получая расширенные лимиты и все возможности платформы. Новое название **Легенда** снимает это недоразумение. #### Смена тарифа с Профи на Легенду Раньше для перехода на тариф **Легенда** нужно было создавать отдельную [команду](https://tuna.am/docs/team.md) — теперь это не требуется. Вы можете перейти с **Профи** на **Легенду** прямо из [личного кабинета](https://my.tuna.am/subscription) без дополнительных шагов, сохранив все свои ресурсы и настройки. #### Что остаётся без изменений? * Стоимость подписок * Лимиты и функции каждого тарифа * Дополнительные лицензии * Все активные подписки продолжают работать Если у вас есть вопросы — [свяжитесь с нами](mailto:info@tuna.am). #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [customer-portal](https://tuna.am/blog/tags/customer-portal) --- ### Обзор возможностей работы в Легенде 11 октября 2024 г. · 4 мин. чтения В этой статье я подробно расскажу о фишках и преимуществах при работе с Tuna в команде: что вы получите, кейсы применения и чего ждать в будущем. ![team](/assets/images/Screenshot_20241010_135041-c84b39aa1b1dd6d30b303e89b384103f.png) #### Для кого тариф Легенда? ☝ Нет никаких ограничений в количестве участников в команде и вы можете иметь команду на себя одного, но в тарифе Легенда, вы получите увеличенные лимиты и расширенные возможности. | Новичок | Профи | Легенда | | ---------------------- | ----------------------- | ---------------------------------------------------------- | | 1 туннель одновременно | 5 туннелей одновременно | **10** туннелей одновременно | | 0 статичных поддоменов | 10 статичных поддоменов | **20** статичных поддоменов | | 0 собственных доменов | 1 собственный домен | **10** собственных доменов | | 0 статичных TCP портов | 1 статичный TCP порт | **5** статичных TCP портов | | - | - | [Политики трафика](https://tuna.am/docs/traffic-policy.md) | Поэтому, если вы уже пользуетесь Tuna на тарифе **Профи** и вам недостаточно, к примеру, 1-го статично TCP порта, а они используются не только для проброса [TCP трафика](https://tuna.am/docs/tunnels/tcp.md), но и для [SSH туннелей](https://tuna.am/docs/tunnels/ssh.md) и для [Trigger туннелей](https://tuna.am/docs/tunnels/trigger.md), то самое время перейти на тариф **Легенда**. #### Преимущества для компаний 🏢 ##### Оплата по счёту 🫰 Помимо возможности централизованной оплаты за всех участников, в Легенде доступна оплата банковским переводом, что часто является ключевым ограничением для закупок услуг компаниями или ИП. * Добавьте E-mail бухгалтера в [контакты команды](https://my.tuna.am/team_settings) * Укажите реквизиты [организации](https://my.tuna.am/team_organization) для выставления счёта * Дождитесь пока администратор подтвердит реквизиты (в рабочее время обычно не дольше 10-ти минут) * На странице управления [подпиской](https://my.tuna.am/subscription) укажите платёжное средство - **Банковский перевод** * Нажмите купить подписку (сформируется счёт и отправится всем контактам из 1-го пункта) * После поступления денег подписка автоматически активируется ![team_settings](/assets/images/Screenshot_20241010_154647-e0fbba0fd21219da1ef3e42ab1efb21b.png) ![team_organization](/assets/images/Screenshot_20241010_154821-eafa66a5ef8cf957f07dc5d15043fe04.png) ![subscription](/assets/images/Screenshot_20241010_151909-90d4a24d3b959f659100021690316fa1.png) ##### RBAC 🙄 *Ролевая модель распределения прав доступа* В компаниях всегда нужно разграничивать права доступа, поэтому RBAC, как правило, является фундаментальной. ![members](/assets/images/Screenshot_20241010_160215-9f7acb55125aa211fead1d2be999646b.png) Какие роли есть у нас: * **Основатель** - создатель команды. Имеет все привилегии, может приглашать/удалять членов команды, назначать роли всем кроме основателя, управлять подпиской, менять настройки команды, просматривать аудит логи, просматривать и управлять ресурсами членов команды (туннели/порты/домены), просматривать статистику. Участник с такой ролью может быть только 1, его роль нельзя изменить и его нельзя удалить. * **Владелец** - также имеет все привилегии в команде, но таких участников может быть много, может приглашать/удалять членов команды, назначать роли всем кроме основателя, управлять подпиской, менять настройки команды, просматривать аудит логи, просматривать и управлять ресурсами членов команды (туннели/порты/домены), просматривать статистику. * **Администратор** - может приглашать членов команды, удалять Участников и администраторов, назначать роли Участникам и Администраторам, просматривать и управлять ресурсами членов команды (туннели/порты/домены), просматривать статистику. * **Пользователь** - знает только название команды в которой он состоит и может использовать свой токен в этой команде. Помимо этого вы можете указать будет ли пользователь учитываться в подписке. Можно добавить пользователя, но отключить его, т.е. не платить за него. Когда это полезно? Например, руководитель создаёт команду и приглашает в нее разработчиков, покупает подписку на количество разработчиков, но не платит за себя, так как сам туннелями он не пользуется, при этом имеет полный контроль. ##### Статистика и управление ресурсами 📊 Вы можете просматривать статистику по тем ресурсам, что используют участники, сколько занято портов, доменов, сколько было создано туннелей и так далее. Мы также будем развивать и добавлять новые метрики, дополнять текущие. ![team_statistics](/assets/images/Screenshot_20241010_164530-4ff71fea993773f81d589779873d2f8d.png) Ещё можно посмотреть все запущенные сейчас туннели, ссылки и их авторов, а также удалить активный туннель любого участника. Можно видеть и удалять домены и порты. Вы всегда сможете проконтролировать кто и что публикует, на каком домене или порту. ![team_tunnels](/assets/images/Screenshot_20241010_164856-046be4fcd02c6d6e657683335166a1ef.png) ![team_domains](/assets/images/Screenshot_20241010_164902-9bfbeb970dc4b1f959b5c947d0fea138.png) ![team_tcp_ports](/assets/images/Screenshot_20241010_164908-e9b5a8f248fc87fd3550ccf2a3bebdeb.png) ##### Аудит логи 🧐 Помимо ресурсов, что используются в реальном времени можно посмотреть историю создания/удаления/изменения ресурсов, ролей и других событий в команде. ![team_audit_events](/assets/images/Screenshot_20241010_165029-bd62b21605209e084f5428c9f3ab9d09.png) Сейчас есть лишь базовые события, но функционал будет развиваться под потребности пользователей. #### Выводы * Тариф с командами полезен всем, не только компаниям * Компании могут оплачивать по счёту * Расширенные лимиты и функции * Командная разработка может ускориться и стать проще #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [review](https://tuna.am/blog/tags/review) * [team](https://tuna.am/blog/tags/team) --- ### Новый функционал - Дополнительные токены и управление командой 8 августа 2024 г. · 2 мин. чтения Новые функций в этом выпуске! #### Дополнительные токены ![temp-tokens](/assets/images/temp-tokens-75bbb4bde8675bcf5f03aaf1a23bb10b.png) Мы добавили возможность создавать [дополнительные токены](https://my.tuna.am/token) с различными ограничениями - по типу создаваемых туннелей HTTP/TCP, по времени действия, по количеству активных туннелей и количеству туннелей которые можно создать. Это очень удобно если вы хотите чтобы ваш друг/коллега/клиент запустил **tuna** у себя и предоставил вам доступ к ресурсу, но при этом вы не хотите после этого менять ваш основной токен, так как он настроен в вашем окружении. При создании токена мы сразу предложим несколько примеров использования, к примеру вот такой: ```shell bash <(curl -sSL https://get.tuna.am) && tuna ssh --token <временный_токен> ``` Ваш друг/коллега/клиент запускает 1 команду у себя, открывает вам доступ по SSH, вы оказываете поддержку, а дальше просто удаляете временный токен или он удалится сам по истечении времени жизни. #### Статистика и управление ресурсами команды ![team-stats](/assets/images/team-stats-44e346fcaa9ce2d033e8667c4fa68bf3.gif) В этом разделе улучшили отображение и управление ресурсами в команде. Приглашения и управление ролями участников, статистика используемых ресурсов, просмотр и управление туннелями, доменами и TCP портами. Всё это сделает работу с командой более прозрачной и комфортной. #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) * [customer-portal](https://tuna.am/blog/tags/customer-portal) * [temp-tokens](https://tuna.am/blog/tags/temp-tokens) * [team-stats](https://tuna.am/blog/tags/team-stats) --- ### 🧑‍💻 Terraform-провайдер для Tuna 1 октября 2026 г. · 3 мин. чтения Когда туннелей, доменов и шлюзов становится больше десятка, настраивать их кликами в личном кабинете уже неудобно: сложно повторить конфигурацию для второго окружения, непонятно, кто и когда что поменял. Поэтому мы выпустили **Terraform-провайдер** [`yuccastream/tuna`](https://registry.terraform.io/providers/yuccastream/tuna/latest/docs) — теперь инфраструктуру Tuna можно хранить в git рядом с остальным кодом, ревьюить в merge request'ах и применять через `terraform apply`. ```hcl terraform { required_providers { tuna = { source = "yuccastream/tuna" } } } resource "tuna_domain" "preview" { subdomain = "myapp-preview" location = "ru" } ``` #### Что можно описать | Ресурс | Что описывает | | --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | `tuna_domain` | [Зарезервированный домен](https://tuna.am/docs/team/domains.md): поддомен встроенной зоны, своей зоны или собственный домен | | `tuna_domain_zone` | [Доменная зона](https://tuna.am/docs/team/domain_zones.md) | | `tuna_tls_certificate` | [TLS-сертификат](https://tuna.am/docs/team/tls_certificates.md) для доменной зоны | | `tuna_gateway` | [Шлюз](https://tuna.am/docs/gateways.md) с политикой трафика | | `tuna_endpoint` | [TCP-порт](https://tuna.am/docs/team/tcp_ports.md) | | `tuna_ip_policy`, `tuna_ip_policy_rule` | [IP-политика](https://tuna.am/docs/team/ip_policies.md) и её правила | | `tuna_public_key` | [Публичный SSH-ключ](https://tuna.am/docs/team/ssh_public_keys.md) | | `tuna_temporal_token` | Временный токен для запуска туннелей | Источник данных `tuna_tunnels` возвращает список туннелей аккаунта. Существующие ресурсы из личного кабинета можно подтянуть в state через `terraform import`. Провайдер работает с Terraform 1.11+ и с OpenTofu. Приватный ключ TLS-сертификата передаётся через write-only атрибут и не попадает в state. #### Пример: временные туннели для CI Типичный сценарий — preview-окружения в CI. Terraform резервирует домен и выпускает временный токен с ограничениями, а CI-задача поднимает туннель с этим токеном. Основной API-ключ в CI при этом не попадает: ```hcl resource "tuna_temporal_token" "ci" { description = "CI preview" duration = "24h" allow_http = true allow_tcp = false limit_by_active_tunnels = 5 limit_by_created_tunnels = 100 } output "ci_tunnel_token" { value = tuna_temporal_token.ci.token sensitive = true } ``` ```bash terraform apply export TUNA_TOKEN="$(terraform output -raw ci_tunnel_token)" tuna http 8080 --subdomain=myapp-preview ``` #### Пример: шлюз с политикой из файла [Шлюз](https://tuna.am/docs/gateways.md) — это домен с политикой трафика, который работает без запущенного клиента. Политика лежит в соседнем файле и меняется так же, через ревью: ```hcl resource "tuna_domain" "api" { subdomain = "myapp-api" location = "ru" } resource "tuna_gateway" "api" { domain_id = tuna_domain.api.id policy = file("${path.module}/policy.yaml") } ``` Ещё несколько сценариев — своя доменная зона с wildcard-сертификатом, доступ по IP только из офиса — есть в [документации](https://tuna.am/docs/guides/terraform.md). #### API-ключи с правами по продуктам Провайдеру нужен API-ключ, и отдавать ему полный доступ к аккаунту незачем. Поэтому вместе с провайдером API-ключи получили **скоупы**: ключ можно ограничить туннелями, мониторингом, секретами, бастионом, отчётами или командой — на чтение или на запись. Для Terraform достаточно `tunnels:write`. Заодно мы закрыли для API-ключей всё, что может навредить аккаунту при утечке ключа: * выпуск новых API-ключей, приглашения в команду и смена ролей участников; * безопасность аккаунта: пароль, MFA, WebAuthn, токен туннелей, привязки провайдеров входа; * оплата и подписка: способ оплаты, смена тарифа, получатели счетов, удаление команды; * продление и завершение веб-сессий, [пароли](https://tuna.am/docs/passwords.md) и mesh. Всё это делается только из [личного кабинета](https://my.tuna.am/api_keys). Ключ, выпущенный без скоупов, получает доступ `read_api` — только на чтение. #### С чего начать 1. Выпустите в [личном кабинете](https://my.tuna.am/api_keys) API-ключ со скоупом `tunnels:write`. 2. Передайте его провайдеру через `export TUNA_API_KEY=...`. 3. Опишите первый ресурс и выполните `terraform init && terraform apply`. Справочник по всем ресурсам и атрибутам — в [Terraform Registry](https://registry.terraform.io/providers/yuccastream/tuna/latest/docs), обзор и сценарии — в [нашей документации](https://tuna.am/docs/guides/terraform.md). Это первая версия провайдера: если вам не хватает какого-то ресурса, [напишите нам](mailto:info@tuna.am) — расширим. #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) * [tuna](https://tuna.am/blog/tags/tuna) * [terraform](https://tuna.am/blog/tags/terraform) --- ### 🆕 Tuna Desktop - новое GUI приложение 26 мая 2025 г. · 2 мин. чтения Мы рады представить новый клиент для создания туннелей, теперь в виде приложения с интерфейсом для рабочего стола. ![desktop_main](/assets/images/main-3eefd7c74a66295ba24ca72f724f2433.png) #### 🤷‍♂️ Зачем? При локальной разработке часто бывает так, что есть какой-то туннель с статичным адресом, который должен быть доступен всегда. Например, когда мы тестируем наши платежи в [ЮКасса](https://tuna.am/docs/tunnels/examples/yookassa.md), у нас есть тестовый магазин для каждого разработчика, где прописан статичный адрес HTTP уведомления. Открывать каждый раз отдельный терминал и писать `tuna http -l ru -s test-yookassa-1 8080` становится утомительно, я каждый раз забываю сделать это заранее и приходится создавать несколько счетов или ждать когда платёжная система отправит повторное уведомление. Также мы знаем, что порой открыть доступ к локальному ресурсу нужно не только разработчикам или системным администраторам, а командная строка не самый дружелюбный интерфейс. Сложив несколько факторов мы решили сделать GUI приложение с максимально простым интерфейсом, чтобы пользоваться было комфортно даже бухгалтерке. #### 🎯 Ключевые возможности Сейчас на момент первого релиза приложение имеет минимум возможностей: * [HTTP туннели](https://tuna.am/docs/tunnels/http.md) * [TCP туннели](https://tuna.am/docs/tunnels/tcp.md) При этом даже этот функционал сильно ограничен относительно консольной версии, всё это сделано в угоду простоте. Но в будущем мы всё таки планируем расширить функционал, к примеру добавить файловый сервер и базовую авторизацию. ![desktop_list](/docs/img/desktop/list.png) ![desktop_icon](/docs/img/desktop/icon.png) ![desktop_setting](/docs/img/desktop/setting.png) #### 🧑‍💻 Поддерживаемые платформы Мы поддерживаем все популярные платформы Windows, macOS и Linux - [инструкция по установке](https://tuna.am/docs/guides/install/install-desktop.md). *** Для macOS и Windows позже планируем публикацию через официальные магазины приложений. примечание Если у вас есть предложения по улучшению, мы с удовольствием их обсудим в нашем [Telegram чате](https://telegram.me/+Kgbtt0_gJwI5ZmEy) или по [e-mail](mailto:info@tuna.am) #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) * [tuna](https://tuna.am/blog/tags/tuna) * [desktop](https://tuna.am/blog/tags/desktop) --- ### Не приходят webhooks от api.telegram.org в туннель в RU зоне 13 мая 2026 г. · 2 мин. чтения В последнее время многие пользователи сообщают об одной и той же проблеме: webhooks от `api.telegram.org` перестали приходить в туннели в регионе RU. В этом посте — как быстро обойти проблему, переключив туннель в другой регион. #### Проблема Симптомы следующие: * бот, зарегистрированный через `setWebhook`, перестал получать обновления; * запросы от `api.telegram.org` не доходят до туннеля в регионе RU — их не видно ни в логах клиента, ни в [инспекторе](https://my.tuna.am/tunnels); * при этом туннель работает: запросы из браузера и от других сервисов проходят штатно. Со стороны нашего сервиса и хостинг-провайдера в России никаких ограничений нет — туннель работает штатно, мы видим установленное соединение. Проблема где-то в магистрали между инфраструктурой Telegram и нашими RU-нодами; вероятнее всего, это ограничение со стороны РКН. Повлиять на это с нашей стороны мы не можем, но регион подключения у туннеля — это параметр клиента, и сменить его — дело пары секунд. #### Решение — сменить регион туннеля Самый быстрый способ — поднять туннель в другом регионе, например `nl` (Нидерланды). Полный список доступных регионов и все способы переопределения — в [документации](https://tuna.am/docs/tunnels/guides/locations.md). ##### Tuna Desktop При создании туннеля выберите регион в выпадающем списке **Регион**: ![Выбор региона в Tuna Desktop](/assets/images/td-0c10e1fdb48b465987307614651ad7fd.png) После сохранения туннель поднимется в выбранном регионе — webhooks от Telegram начнут приходить. ##### Командная строка Передайте регион аргументом `--location` (или коротким `-l`): ```shell tuna http 8080 --location=nl tuna http 8080 -l nl ``` Чтобы не указывать флаг каждый раз, регион можно задать по умолчанию одним из трёх способов. **Команда `tuna config save-location`** — сохранит значение в [конфигурационный файл](https://tuna.am/docs/guides/config-file.md): ```shell tuna config save-location nl ``` **Параметр в [конфигурационном файле](https://tuna.am/docs/guides/config-file.md)** напрямую: ```yaml location: nl ``` **[Переменная окружения](https://tuna.am/docs/guides/environment-variables.md)** `TUNA_LOCATION`: ```shell TUNA_LOCATION=nl ``` #### Что дальше После смены региона у туннеля изменится URL — не забудьте обновить адрес webhook'а в настройках вашего Telegram-бота (метод [`setWebhook`](https://core.telegram.org/bots/api#setwebhook) с новым URL). Если и после этого webhooks не приходят — напишите нам в [Telegram-сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) или на . #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [guides](https://tuna.am/blog/tags/guides) --- ### 🆕 Новые типы туннелей - Postgres и Redis 30 апреля 2025 г. · 2 мин. чтения Мы расширяем возможности [Туннелей](https://tuna.am/docs/tunnels.md) и добавили новые типы - [Postgres](https://tuna.am/docs/tunnels/postgres.md) и [Redis](https://tuna.am/docs/tunnels/redis.md), теперь с поддержкой инспекции запросов! Ранее для предоставления доступа к любым базам данных нужно было открывать доступ с помощью [TCP туннеля](https://tuna.am/docs/tunnels/tcp.md), но теперь для **Postgres** и **Redis** мы добавили возможность запускать специализированный тип туннеля. При этом появляется аудит и инспекция запросов которые вы отправляете в базу. #### \*\*Postgres [Postgres туннель](https://tuna.am/docs/tunnels/postgres.md) позволяет предоставить доступ к базе данных PostgreSQL и отслеживать выполняемые SQL запросы в инспекторе. *** Слева отображается список сессий, а справа вывод команд, которые были выполнены внутри сессий. ![web_postgres](/docs/img/inspect/web_postgres.webp) #### \*\*Redis [Redis туннель](https://tuna.am/docs/tunnels/redis.md) аналогично позволяет предоставить доступ к базе данных Redis и отслеживать выполняемые запросы в инспекторе. *** Слева отображается список сессий, а справа вывод команд, которые были выполнены внутри сессий. ![web_redis](/docs/img/inspect/web_redis.webp) *** #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) * [tuna](https://tuna.am/blog/tags/tuna) * [cli](https://tuna.am/blog/tags/cli) --- ### 🛠 Telegram бот для мониторинга VirusTotal 11 сентября 2025 г. · 2 мин. чтения Мы публикуем ещё один Open-Source инструмент который используем сами и хотим поделиться со всеми. На этот раз это - [Telegram бот для мониторинга доменов и IP адресов в базах VirusTotal](https://gitlab.com/yuccastream/vt-telegram-bot). #### Обзор Ещё на ранних этапах мы столкнулись с использованием нашей платформы мошенниками. Они раздают вредоносные программы, шлют спам, публикуют копии сайтов и занимаются прочим непотребством. Поэтому мы внедрили достаточно много инструментов для анализа и раннего обнаружения подобных нарушений. Но это не защищает на 100%, иногда туннельные ноды всё таки попадают в базы антивирусов, и тут наша задача как можно быстрее узнать об этом заблокировать нарушителя и оперативно связаться антивирусной компанией для удаления наших доменов, поддоменов и IP адресов из баз с карантином. К счастью, есть такой прекрасный ресурс как [VirusTotal](https://www.virustotal.com), по сути это агрегатор. В нём вы можете проверить ресурс (домен, ip, файл) на присутствие в базах каких либо - антивирусов. Всё очень просто и наглядно, выглядит примерно так: ![](/assets/images/vt-367db5466c61048a8e61b72928436bfe.png) VirusTotal имеет публичное API, ещё cli утилиту, готовые клиенты для некоторых языков и если зарегистрироваться и получить API Key, то можно всё неплохо автоматизировать, что позволит узнавать о присутствии в базах максимально оперативно. Что мы и сделали. Но стоит помнить, что на бесплатном тарифе есть некоторые ограничения по количеству запросов, но на дюжину доменов/ip вам точно хватит. ![](/assets/images/vt-quota-10b95ad6cd0ad82e502e8ef191c15f17.png) #### Как использовать? В [репозитории](https://gitlab.com/yuccastream/vt-telegram-bot) вы найдёте бинарные сборки и образы docker для запуска, а также инструкцию по конфигурации. Мы будем рады обратной связи и merge requests. #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) --- ### 🔐 Ключи доступа (passkeys) — вход в Tuna без пароля 15 июля 2026 г. · 4 мин. чтения Пароли всем надоели: их придумывают, забывают, пересылают в чат «на пару минут», а потом меняют после очередной утечки. В Tuna появился способ забыть о них насовсем — вход по **ключам доступа (passkeys)**. Приложили палец, взглянули в камеру или ввели PIN — и вы уже в аккаунте. Ни пароля, ни кода из приложения-аутентификатора. ![Кнопка «Войти с ключом доступа» на странице входа Tuna](/blog/img/2026-07-15-webauthn/login.png) #### Что такое ключ доступа Ключ доступа (passkey) — это пара криптографических ключей, которая приходит на смену паролю. Приватная половина никогда не покидает ваше устройство, менеджер паролей или аппаратный брелок, а на серверах Tuna оседает только **публичный** ключ. Красть на нашей стороне попросту нечего: сам по себе публичный ключ для входа бесполезен, в отличие от базы паролей. И ещё одна приятная деталь: каждый ключ намертво привязан к домену `tuna.am`. Подсунуть его на фишинговый сайт-двойник не выйдет — браузер даже не предложит ключ на чужом адресе. Пароль так не умеет: его можно выманить поддельной страницей или подобрать по утёкшей базе. #### Чем это удобнее пароля * **Нечего запоминать и вводить.** Логин — это один клик и касание пальцем, а не строчка из 16 символов со спецзнаками. * **Не выманить фишингом.** Ключ срабатывает только на настоящем домене Tuna — фальшивая страница уйдёт ни с чем. * **Один шаг вместо двух.** Passkey сам по себе сочетает два фактора: владение устройством плюс подтверждение личности (биометрия или PIN). Поэтому при входе по ключу Tuna **не спрашивает отдельный одноразовый код** — двухфакторность уже соблюдена. #### Где может жить ваш ключ WebAuthn — это открытый стандарт (FIDO2), а не проприетарная фишка одного вендора. Поэтому Tuna дружит практически с любым современным хранилищем ключей. А их, по большому счёту, два семейства. **Синхронизируемые passkeys** — ключ живёт в вашем менеджере паролей или облачной связке и сам подтягивается на все ваши устройства. Сменили телефон — ключи уже там. Сюда относятся: * **менеджеры паролей** — 1Password, Bitwarden, Dashlane, NordPass, Proton Pass, а для любителей держать всё локально — KeePassXC; * **встроенные хранилища ОС** — iCloud Keychain на Apple, Google Password Manager на Android и в Chrome, Windows Hello на Windows. **Аппаратные ключи (FIDO2)** — отдельный физический брелок, из которого приватный ключ не извлекается в принципе. Максимальная защита для тех, кому важно, чтобы секрет не покидал железку: * **YubiKey** от Yubico — де-факто отраслевой стандарт, версии под USB-A, USB-C и NFC (на скриншоте выше как раз добавлен такой — «Yubico 1»); * **Google Titan**, **Feitian**, **Nitrokey** (открытая прошивка), **Token2** и другие совместимые с FIDO2 ключи. Один брелок хранит десятки, а современные модели — и сотни ключей от разных сервисов, так что заводить отдельный «на Tuna» не нужно. #### Как добавить ключ Откройте [Профиль](https://my.tuna.am/profile) и найдите блок **«Ключи доступа (passkeys)»** рядом с настройками двухфакторной аутентификации. Нажмите **«Добавить ключ»**, а дальше всё сделает браузер: предложит сохранить passkey в менеджер, связку ключей или на аппаратный брелок и попросит подтвердить создание. ![Раздел «Ключи доступа (passkeys)» в профиле Tuna со списком ключей](/blog/img/2026-07-15-webauthn/settings.png) К одному аккаунту можно привязать до **10 ключей** — например, по одному на рабочий ноутбук, телефон и физический YubiKey в связке. Каждый ключ виден в списке с датой добавления и временем последнего входа, его легко переименовать или удалить. #### Как войти по ключу На странице входа под основной кнопкой появилась кнопка **«Войти с ключом доступа»**. Нажимаете её, выбираете ключ, подтверждаете биометрией или PIN — и вы внутри. Никаких почты, пароля и кода из приложения. А если в прошлый раз вы заходили именно так, рядом с кнопкой подсветится бейдж **«Последний вход»** — маленькая подсказка, чтобы не гадать, каким способом вы обычно пользуетесь. #### Безопасность * На серверах Tuna хранится только публичный ключ — приватная часть остаётся у вас. * Привязка к домену `tuna.am` защищает от фишинга. * Каждый вход требует подтверждения пользователя — биометрии или PIN. * Счётчик использований помогает выявить попытку клонирования ключа. При этом никто не заставляет бросать привычное: пароль и вход через Google, Yandex или Mail.ru работают как раньше. Ключи доступа их не отменяют, а дополняют — а каким способом входить, решаете вы. #### Попробуйте прямо сейчас Загляните в [Профиль](https://my.tuna.am/profile), откройте блок **«Ключи доступа (passkeys)»** и нажмите **«Добавить ключ»** — следующий вход в Tuna займёт одно касание. #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) * [security](https://tuna.am/blog/tags/security) * [tuna](https://tuna.am/blog/tags/tuna) --- ### 🆕 Вебхуки - новый функционал 27 августа 2025 г. · 1 мин. чтения В этом обновлении мы добавили новый функционал - [Вебхуки](https://my.tuna.am/webhooks) или Webhooks. Функционал позволяющий легко узнать, что находится в запросе который посылает какой либо сервис. В частности понять какая реально приходит информация в теле запроса, заголовки, IP источника и так далее. [Перейти в личный кабинет](https://my.tuna.am/webhooks) #### Обзор *** В личном кабинете появился новый раздел [Вебхуки](https://my.tuna.am/webhooks). Тут вы можете создавать ссылки для тестирования, отладки и создания заглушек(mocks). Это достаточно удобно когда вы хотите понять почему документация вебхука сервиса не соответствует реальности, просто укажите ссылку и всё сразу станет понятно. Вы увидите в удобном формате все заголовки и тело запроса. В [документации](https://tuna.am/docs/webhooks.md) к разделу вы найдёте более подробную информацию по управлению вебхуками и примеры. #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) --- ### 🆕 Вебхуки (SMTP, политики трафика, повтор в туннель), TOTP в паролях, улучшение дистрибуции клиентов 13 октября 2025 г. · 2 мин. чтения В этом обновлении - о новых функциях в Вебхуках. Небольшое, но важное обновление в Менеджере паролей. Улучшения и повышении безопасности в дистрибуции клиентов. #### Вебхуки ##### Политика трафика Помимо простого ответа теперь можно описать сложные правила обработки вебхука, имитируя например ответ API. Важно отметить что это будет работать даже на бесплатном тарифе и вы можете попробовать политики трафика бесплатно. ![Скриншот с политикой трафика в вебхуке](/docs/img/webhooks/reply_tp.png) ##### Пересылка запроса в туннель Если у вас есть запущенные туннели вы можете переслать в него принятый запрос. Нам показалось это может быть удобно и полезно при отладке чего-то на начальных этапах. ![Скриншот с пересылкой запроса в туннель](/docs/img/webhooks/resend_to_tunnel.png) #### TOTP в Менеджере паролей Появились долгожданные TOTP (Time-based one-time) пароли. Это значит, что если у вас есть 1 аккаунт от стороннего сервиса на команду, теперь вы можете спокойно включить 2FA. ![Гифка с TOTP](/docs/img/passwords/totp.webp) #### Улучшение дистрибуции клиентов ##### Безопасность Мы делаем упор на безопасности, поэтому рекомендуем проверять, что вы используете именно наши официальные сборки клиентов. Теперь все артефакты сборки, архивы, пакеты, инсталляторы, checksum файлы и docker образы подписываются нашей электронной подписью. * Публичный **GPG** ключ для верификации распространяется по ссылке - * Публичный [Cosign](https://docs.sigstore.dev/) ключ для верификации Docker images - ##### Дистрибуция для ALT Linux Добавили поддержку дистрибуции для российского ALT Linux, подробнее в [инструкции по установке](https://tuna.am/docs/guides/install.md). *** #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [release](https://tuna.am/blog/tags/release) --- ### Добро пожаловать в Tuna 16 июля 2024 г. · 1 мин. чтения Это первый пост в нашим блоге. Тут мы будем рассказывать о новшествах, а так же писать заметки о использовании сервиса, более подробно разбирать примеры из документации и много другое. ![base-usage](/assets/images/base-usage-6a21784aabebe0224f319ce91049c863.png) #### Оставьте отзыв Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1). ![](/blog/img/2024-08-22/feedback.gif) #### Новости Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить. #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) **Теги:** * [hello](https://tuna.am/blog/tags/hello) * [tuna](https://tuna.am/blog/tags/tuna) --- ## Changelog ### Журнал изменений #### [tuna-cli v0.37.0](https://tuna.am/changelog/cli-v0.37.0.md) 6 октября 2026 г. * \[FEATURE] Publish 1C:Enterprise infobases (cli) * \[ENHANCEMENT] Update Upgrade connection tests (cli) * \[BUGFIX] Fix brew upgrade command (cli) **Теги:** * [cli](https://tuna.am/changelog/tags/cli) --- ### tuna v0.25.0 13 июня 2025 г. * \[FEATURE] TCP allow and deny CIDRs (Добавлен функционал ограничения подключения к TCP туннелям по IP адресу) **Теги:** * [cli](https://tuna.am/changelog/tags/cli) --- ### tuna v0.26.0 27 августа 2025 г. * \[ENHANCEMENT] Рефакторинг **Теги:** * [cli](https://tuna.am/changelog/tags/cli) --- ### tuna v0.27.0 3 сентября 2025 г. * \[FEATURE] Prints additional json fields (cli) * \[FEATURE] Adds tunnel name to json logs (cli) **Теги:** * [cli](https://tuna.am/changelog/tags/cli) --- ### tuna v0.28.0 18 декабря 2025 г. * \[ENHANCEMENT] Преработан механизм переподключения при сетевых неполадках **Теги:** * [cli](https://tuna.am/changelog/tags/cli) --- ### tuna v0.30.0 28 января 2026 г. * \[Feature] Поддержка PROXY Protocol в TCP туннелях * \[BUGFIX] fix monitor User-Agent **Теги:** * [cli](https://tuna.am/changelog/tags/cli) --- ### tuna v0.31.0 9 февраля 2026 г. * \[FEATURE] Add support riscv64 arch (cli) * \[BUGFIX] skip HTTPS redirect for WebSocket upgrade requests (cli) * \[FEATURE] Reports in tunnels http --capture-key (cli) **Теги:** * [cli](https://tuna.am/changelog/tags/cli) --- ### tuna v0.32.0 23 марта 2026 г. * \[BUGFIX] Множество исправлений и улучшений * \[FEATURE] Asciinema format ssh sesions (cli) * \[FEATURE] Add support mips, mipsle, armv6, armv5 archs **Теги:** * [cli](https://tuna.am/changelog/tags/cli) --- ### tuna-cli v0.33.0 13 апреля 2026 г. * \[FEATURE] SSH session upload (cli) * \[BUGFIX] Fix tuna start args check (cli) **Теги:** * [cli](https://tuna.am/changelog/tags/cli) --- ### tuna-cli v0.34.0 27 мая 2026 г. * \[FEATURE] Adds Apps (node server ui) **Теги:** * [cli](https://tuna.am/changelog/tags/cli) --- ### tuna-cli v0.35.0 24 сентября 2026 г. * \[FEATURE] Secrets CLI: list, get, set, delete, upload, projects, environments, configs, service tokens, substitute, open (cli) * \[FEATURE] Secrets run --mount and offline mode, value fingerprints, -o json|yaml for all secrets commands (cli) * \[FEATURE] Adds whoami command (cli) * \[FEATURE] Unix socket upstreams for tcp and http tunnels (cli) * \[FEATURE] Adds compress_response policy action (cli) * \[FEATURE] Removes api-key create and session terminate commands, api-key del deletes a key (cli) * \[BUGFIX] (#222) Fix empty request body (cli) * \[BUGFIX] Sets correct record-session value (cli) **Теги:** * [cli](https://tuna.am/changelog/tags/cli) --- ### tuna-cli v0.35.1 24 сентября 2026 г. * \[BUGFIX] Fix package upgrade from the old repository (cli) * \[BUGFIX] Fix SSH hang after connection loss caused by golang.org/x/crypto v0.52.0 (cli) **Теги:** * [cli](https://tuna.am/changelog/tags/cli) --- ### tuna-cli v0.36.0 30 сентября 2026 г. * \[FEATURE] TUI Interface (cli) * \[FEATURE] Adds Kubernetes API tunnel (cli) * \[FEATURE] Free static subdomains (cli) * \[FEATURE] Passes request and message data to tuna trigger commands (cli) * \[FEATURE] Adds --policy-url flag for http tunnels (cli) * \[FEATURE] Highlight flags, commands, code examples (cli) * \[FEATURE] Confirmation prompts for delete commands, --yes to skip (cli) * \[ENHANCEMENT] Show the upgrade command for the detected install method (cli) * \[BUGFIX] Fixes GitHub and Sentry webhook signature verification (cli) * \[BUGFIX] Inspector records the real status of rejected upgrade requests (WebSocket, kubectl exec) (cli) **Теги:** * [cli](https://tuna.am/changelog/tags/cli) --- ### tuna-cli v0.36.1 30 сентября 2026 г. * \[BUGFIX] Fixes CLI build for FreeBSD (cli) **Теги:** * [cli](https://tuna.am/changelog/tags/cli) --- ### tuna-cli v0.37.0 6 октября 2026 г. * \[FEATURE] Publish 1C:Enterprise infobases (cli) * \[ENHANCEMENT] Update Upgrade connection tests (cli) * \[BUGFIX] Fix brew upgrade command (cli) **Теги:** * [cli](https://tuna.am/changelog/tags/cli) --- ### tuna-desktop v0.1.5 13 июня 2025 г. * \[BUGFIX] Fix client termination (исправлена проблема, когда приложение закрывается через 30 минут работы туннеля на бесплатном тарифе) **Теги:** * [desktop](https://tuna.am/changelog/tags/desktop) --- ### tuna-desktop v0.1.6 10 июля 2025 г. * \[FEATURE] Уведомление о наличии новой версии **Теги:** * [desktop](https://tuna.am/changelog/tags/desktop) --- ### tuna-desktop v0.2.0 18 декабря 2025 г. * \[ENHANCEMENT] Преработан механизм переподключения при сетевых неполадках **Теги:** * [desktop](https://tuna.am/changelog/tags/desktop) --- ## Docs ### Добро пожаловать 🐟 **Tuna** - это платформа для разработчиков и их команд, нацелена на ускорение разработки, упрощение командного взаимодействия и безопасность. #### Сеть ##### 🚇 Туннели Функционал позволяющий с помощью консольной утилиты *tuna* создавать обратные реверс-прокси [HTTP](https://tuna.am/docs/tunnels/http.md), [TCP](https://tuna.am/docs/tunnels/tcp.md) и [SSHd](https://tuna.am/docs/tunnels/ssh.md) туннели. Вы сможете получить прямой доступ из интернета к запущенным локально сайтам или приложениям. Просто запустите в консоли короткую команду, получаете в ответ ссылку, а ваш друг из любой точки мира перейдя по ней попадёт на сайт запущенный на вашем ПК в локальной сети, и всё это без VPN, требований в "белом" IP, без проброса портов на роутере. #### [\*\*HTTP](https://tuna.am/docs/tunnels/http.md) [Предоставить доступ к сайту, API, GraphQL, Websocket-серверу](https://tuna.am/docs/tunnels/http.md) #### [\*\*TCP](https://tuna.am/docs/tunnels/tcp.md) [Предоставить доступ к базе данных, SSH, RDP, игровому серверу](https://tuna.am/docs/tunnels/tcp.md) #### [\*\*SSHd](https://tuna.am/docs/tunnels/ssh.md) [Предоставить доступ по SSH без SSH сервера](https://tuna.am/docs/tunnels/ssh.md) #### [\*\*Trigger](https://tuna.am/docs/tunnels/trigger.md) [Выполнение действий по наступлению события](https://tuna.am/docs/tunnels/trigger.md) #### [\*\*Postgres](https://tuna.am/docs/tunnels/postgres.md) [Доступ в PostgreSQL с инспекцией SQL запросов](https://tuna.am/docs/tunnels/postgres.md) #### [\*\*Redis](https://tuna.am/docs/tunnels/redis.md) [Доступ в Redis с инспекцией запросов](https://tuna.am/docs/tunnels/redis.md) #### [\*\*Kubernetes](https://tuna.am/docs/tunnels/kubernetes.md) [Временный доступ к кластеру через kubectl без VPN](https://tuna.am/docs/tunnels/kubernetes.md) #### [📒 1С](https://tuna.am/docs/tunnels/1c.md) [Опубликовать базу 1С:Предприятие без настройки веб-сервера](https://tuna.am/docs/tunnels/1c.md) #### [📦 Установка](https://tuna.am/docs/guides/install.md) [Начните с установки и первичной настройки клиента - это займет не больше минуты](https://tuna.am/docs/guides/install.md) ##### 🪝 Вебхуки Функционал позволяющий легко узнать, что находится в запросе который посылает какой либо сервис. В частности понять какая реально приходит информация в теле запроса, заголовки, IP источника и так далее. #### [👀 Обзор продукта](https://tuna.am/docs/webhooks.md) [Отладка входящих HTTP запросов](https://tuna.am/docs/webhooks.md) ##### 🚦 Шлюзы Функция дополняющая туннели и предназначена для создания всегда доступного облачного балансировщика или WEB сервера с гибкими политиками обработки трафика. Туннели это хорошо, но бывает окружение состоит из нескольких сервисов часть из которых запущено у вас, у вашего коллеги и в тестовом контуре. Но благодаря гибким [политикам трафика](https://tuna.am/docs/traffic-policy.md) вы можете распределять запросы в нужные точки, управлять заголовками, авторизацией, временем работы и много другое. #### [👀 Обзор продукта](https://tuna.am/docs/gateways.md) [Всегда доступный облачный балансировщик с гибкими политиками обработки трафика](https://tuna.am/docs/gateways.md) ##### 📡 Мониторы Функционал для мониторинга работы CronJobs, Heartbeat, ICMP, DNS, HTTP и TCP приложений с поддержкой уведомлений через различные каналы связи. #### [👀 Обзор продукта](https://tuna.am/docs/monitors.md) [Мониторинг работы задач и сервисов](https://tuna.am/docs/monitors.md) #### Безопасность ##### 🔑 Пароли Менеджер паролей работает в WEB-интерфейсе личного кабинета, создан для безопасного хранения и удобного обмена паролями внутри рабочих команд и не только. Мы не храним пароли в открытом виде, согласно модели [нулевого знания (Zero-knowledge proof)](https://en.wikipedia.org/wiki/Zero-knowledge_proof), **только** пользователь обладает ключами, которые могут расшифровать данные. #### [👀 Обзор продукта](https://tuna.am/docs/passwords.md) [Безопасно храните и обменивайтесь с командой вашими паролями от инфраструктуры и сервисов.](https://tuna.am/docs/passwords.md) ##### 🔒 Секреты Сервис секретов предназначен для хранения настроек к вашим приложениям, которые вы запускаете - локально, в CI/CD или в своих тестовых и продуктовых окружениях. Он является отличной альтернативой `.env` файлам и переменным окружениям в CI/CD системах. #### [👀 Обзор продукта](https://tuna.am/docs/secrets.md) [Конфигурируйте приложения и окружения просто и безопасно](https://tuna.am/docs/secrets.md) ##### 🐡 Бастион SSH-сервер с ролевой мандатной моделью доступа, использующий принципы [нулевого доверия (Zero Trust)](https://en.wikipedia.org/wiki/Zero_trust_architecture). Предназначен для безопасного доступа к инфраструктуре, предоставляет централизованный контроль и аудит SSH-сессий. В отличие от классических SSH-серверов, бастион делает акцент на идентификацию пользователей, временные сертификаты и ролевую модель доступа, обеспечивая повышенную безопасность доступа к вашим серверам. [](https://tuna.am/docs/bastion.md) #### [👀 Обзор продукта](https://tuna.am/docs/bastion.md) [SSH-сервер с ролевой мандатной моделью доступа, использующий принципы ](https://tuna.am/docs/bastion.md)[нулевого доверия](https://en.wikipedia.org/wiki/Zero_trust_architecture). ##### 🛡️ Приложения Защищённый reverse proxy с авторизацией — контролируйте доступ к внутренним приложениям через tuna.am. Настройте политики доступа по ролям, странам и методам аутентификации, подключите корпоративный SSO и требуйте MFA для чувствительных операций. #### [👀 Обзор продукта](https://tuna.am/docs/apps.md) [Zero Trust доступ к вашим приложениям и сервисам](https://tuna.am/docs/apps.md) #### Совместная работа ##### 🪲 Отчёты Функционал для сбора ошибок и создания избыточных отчётов на вашем сайте. С помощью встраиваемого скрипта пользователи и QA-инженеры могут легко показать, где спрятался баг, а вы – получить отладочную информацию и сразу приступить к исправлению. #### [👀 Обзор продукта](https://tuna.am/docs/reports.md) [Сбор багов с сайта со скриншотами и отладочной информацией](https://tuna.am/docs/reports.md) ##### 🖌️ Доски Бесконечные доски для совместного планирования, документирования и штурмов. Стикеры, фигуры, стрелки, таймеры, комментарии и встроенные звонки помогают команде быстро накидывать идеи, проводить ретро и мозговые штурмы, не переключаясь между десятком сервисов. #### [👀 Обзор продукта](https://tuna.am/docs/boards.md) [Бесконечные доски с фигурами, стикерами и звонками для команды](https://tuna.am/docs/boards.md) ##### 🎥 Встречи Сервис онлайн-встреч прямо внутри Tuna. Созванивайтесь с командой, демонстрируйте экран и обсуждайте задачи в едином рабочем пространстве. #### [👀 Обзор продукта](https://tuna.am/docs/meet.md) [Онлайн-встречи и демонстрация экрана внутри платформы](https://tuna.am/docs/meet.md) #### Мы на сторонних площадках #### [🎣 Habr](https://habr.com/ru/companies/tuna/articles/) [Наш блог на habr.com](https://habr.com/ru/companies/tuna/articles/) #### [📣 Telegram](https://t.me/tuna_am) [Новости Tuna в Telegram-канале](https://t.me/tuna_am) #### [🪼 VC](https://vc.ru/u/525007-evgeniy-medvedev) [Наш блог на vc.ru](https://vc.ru/u/525007-evgeniy-medvedev) #### Помощь Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов: * [Электронная почта](mailto:info@tuna.am) * [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) --- ### Злоупотребления и жалобы #### Сообщения о нарушениях Если вы хотите сообщить о злоупотреблениях или незаконной деятельности, запрещенной нашими [Условиями использования](https://tuna.am/tos/), на сайте, размещенном через tuna, пожалуйста, отправьте письмо на с указанием проблемного URL и описанием типа нарушения, которое вы наблюдали, желательно подкрепить доказательства скриншотами, видео или другими доказательствами нарушения. Вы получите подтверждение по электронной почте о том, что ваш отчет принят и находится на рассмотрении. Перечень запрещённых действий и порядок применения мер описаны в [Правилах допустимого использования](https://tuna.am/aup.md). #### Борьба с злоупотреблениями в Интернете В tuna мы применяем многогранную стратегию для борьбы с недобросовестным использованием наших услуг. Мы инвестировали значительные ресурсы в автоматизированные системы, которые отмечают подозрительную, активности аккаунтов и сторонним отчетам в режиме реального времени. Эти меры мы дополняем модерацией вручную и инструментами, которые позволяют удалять вредоносный и незаконный контент с наших сервисов с минимальным риском его распространения в публичной сети. #### Предупреждение для браузеров Чтобы предотвратить фишинговые атаки через нашу платформу, tuna добавляет промежуточную страницу для бесплатных аккаунтов, получающих запросы из браузеров. Когда пользователь впервые посещает конечную точку, tuna отображает страницу с уведомлением о том, что контент предоставлен через tuna, и предупреждает, что не следует вводить конфиденциальную информацию, если отправителю ссылки нельзя доверять. Пользователи видят эту страницу только один раз для каждой конечной точки, а её отображение можно полностью обойти, добавив заголовок `tuna-skip-browser-warning` к вашему запросу. #### Анонимность Использование туннелирования через tuna позволяет сокрыть реальный IP-адрес источника. Однако эта анонимность может стимулировать использование tuna для размещения вредоносного контента. Чтобы устранить этот риск, tuna применяет следующие меры контроля: * Создание туннелей и публикация приложений доступно только после регистрации аккаунта. * IP-адреса источников для всех динамических HTTP туннелей включаются в сгенерированный URL. URL формируются следующим образом: `${random}-${origin-ip}.${location}.tuna.am`. Например, URL `4l7mqf-212-49-103-2.ru.tuna.am` имеет IP-адрес источника `212.49.103.2`. #### Интеграция через API Если вы являетесь представительством фирмы по предотвращению мошенничества, мы упростили и ускорили процесс подачи запросов на удаление контента, предоставив прямую интеграцию через [API](https://tuna.am/docs/guides/api.md). Если вы планируете отправлять значительное количество отчетов о нарушениях, свяжитесь с нами напрямую , чтобы запросить доступ для интеграции с нашим [API](https://tuna.am/docs/guides/api.md) для подачи отчетов о злоупотреблениях. --- ### Приложения Представьте: у вас есть внутренний сервис — админка, staging, Grafana, внутренний API — и вы хотите дать к нему доступ только нужным людям, из нужных стран, с подтверждением через корпоративный SSO. Приложения в Tuna решают именно эту задачу. Приложения — это защищённый reverse proxy, который проверяет каждый входящий запрос: кто пользователь, как он аутентифицировался, откуда пришёл и имеет ли право видеть запрашиваемый путь. ![apps-main](/assets/images/main-90152e8c052b1e7bdcedf49998a8c57c.png) Что можно сделать: * закрыть любой веб-сервис авторизацией за пару минут, без изменений в коде самого сервиса; * гранулярно разграничить доступ — например, `/admin/*` только для администраторов из России, а `/api/health` открыть без аутентификации; * подключить корпоративный SSO (Google, Yandex, GitHub, GitLab, VK, любой OIDC-совместимый провайдер); * требовать MFA или ручное одобрение администратора для чувствительных операций; * опубликовать сервис без публичного IP через туннель — достаточно запустить одну команду; * выдать машинный доступ через сервисные токены для CI/CD, мониторинга и автоматизации. #### Режимы работы При создании приложения нужно выбрать, как Tuna будет доставлять трафик до вашего сервиса. ##### Прокси Tuna нода обращается к upstream напрямую по URL. Этот режим подходит, когда сервис уже доступен по сети — запущен в Kubernetes, в облачной VM или просто в той же сети, что и нода. ![Создание приложения в режиме прокси](/docs/img/apps/new_proxy_filled.png) Можно указать несколько upstream-адресов — трафик будет распределяться по весам. Например, при весах 3 и 1 первый upstream получит 75% запросов, второй — 25%. ##### Туннель Бэкенд сам подключается к Tuna через клиент-агент. Идеальный вариант, когда сервис без публичного IP — за NAT, на dev-машине или в корпоративной сети. ![Создание приложения в режиме туннеля](/docs/img/apps/new_tunnel.png) После создания приложения в режиме туннеля на странице деталей появится готовая команда: ![Команда для запуска туннеля](/docs/img/apps/tunnel_command.png) ```shell tuna app <имя> --url=http://127.0.0.1:8080 ``` Запустите её на машине с сервисом — клиент установит исходящее соединение к ноде, и приложение станет доступно через защищённый домен. подсказка Для быстрой проверки без реального бэкенда добавьте флаг `--hello-world` — Tuna запустит встроенный тестовый сервер. #### Создание приложения подсказка Этот раздел доступен **Основателю**, **Владельцам** и **Администраторам**. Перейдите в раздел [Приложения](https://my.tuna.am/team_apps) и нажмите **+ Добавить приложение**. | Поле | Описание | | ------------- | ------------------------------------------------------------ | | **Имя** | Уникальное имя внутри команды, будет использоваться в CLI | | **Режим** | Прокси или Туннель | | **Upstreams** | Адреса бэкенда — только для режима Прокси | | **Домен** | Домен, через который приложение будет доступно пользователям | #### Основные параметры После создания откроется страница деталей приложения с основными настройками. ![Основные параметры приложения](/docs/img/apps/edit_params.png) * **Длительность сессии** — сколько живёт сессия после входа. По истечении пользователь проходит логин заново. По умолчанию — 24 часа. * **Таймаут неактивности** — сессия сгорает, если пользователь не делал запросов дольше указанного времени. По умолчанию отключено. #### Провайдеры Здесь выбираются способы входа в приложение. Можно комбинировать несколько вариантов — пользователь увидит их все на странице входа. ![Провайдеры авторизации](/docs/img/apps/providers_section.png) * **Email OTP** — пользователь вводит email и получает одноразовый код. Удобно для внешних подрядчиков и разовых доступов. * **Аккаунты tuna.am** — вход через личный аккаунт на tuna.am. * **Провайдеры команды** — внешние Identity Provider (Google, Yandex, GitHub, GitLab, VK, любой OIDC), настроенные на странице [Провайдеры](https://my.tuna.am/team_identity_providers). Снимите галочку «Все провайдеры команды», чтобы выбрать конкретные. ![Список провайдеров команды](/docs/img/apps/identity_providers.png) #### Обзор Блок **Обзор** на странице деталей наглядно визуализирует текущую конфигурацию: слева — кто может войти, в центре — через какие политики проходит запрос, справа — куда направляется трафик. ![Обзор приложения](/docs/img/apps/overview.png) Это удобный способ одним взглядом убедиться, что всё настроено как задумано. #### Страница входа Когда пользователь открывает защищённое приложение без активной сессии, он попадает на страницу входа. Набор кнопок формируется автоматически из подключённых провайдеров. ![Страница входа](/docs/img/apps/auth_page.png) Если в команде настроены внешние провайдеры, каждый из них отображается отдельной кнопкой «Войти через ...»: ![Страница входа с провайдерами](/docs/img/apps/auth_page_providers.png) к сведению Внешний вид страницы входа можно кастомизировать — добавить логотип через [настройки приложения](https://tuna.am/docs/apps/settings.md). #### Пользовательский каталог Участники команды видят все доступные им приложения в виде карточек на странице [Приложения](https://my.tuna.am/apps). Клик по карточке открывает приложение в новой вкладке. В боковом меню пользователю также доступны [Запросы доступа](https://tuna.am/docs/apps/access_requests.md) и [Сессии](https://tuna.am/docs/apps/sessions.md) — для управления собственными запросами и активными сессиями. #### Аудит Все действия с приложениями записываются в [аудит-лог](https://my.tuna.am/team_audit_events): создание и изменение приложений, входы пользователей, одобрения и отклонения запросов доступа, отзыв сессий. Каждое событие содержит детали — кто, когда, откуда и что именно произошло. ![Аудит-лог событий приложений](/docs/img/apps/audit_events.png) --- ### Запросы доступа Иногда доступ к ресурсу нужно выдавать не автоматически, а только после ручного подтверждения. Для этого в [политике](https://tuna.am/docs/apps/policies.md) есть опция **Требовать одобрение администратора** — пользователь не получит доступ, пока администратор не одобрит его запрос. #### Как это выглядит ##### 1. Пользователь объясняет причину После аутентификации, вместо доступа к приложению, пользователь видит форму, где нужно описать, зачем ему нужен доступ. Это помогает администратору принять обоснованное решение. ![Форма причины запроса](/docs/img/apps/approval_purpose.png) ##### 2. Ожидание решения После отправки запроса пользователь видит страницу ожидания. Вкладку можно оставить открытой — она обновится автоматически, когда администратор примет решение. ![Ожидание одобрения](/docs/img/apps/approval_pending.png) ##### 3. Администратор принимает решение Все запросы появляются в разделе [Запросы доступа](https://my.tuna.am/team_apps/access_requests). Можно фильтровать по статусу — только ожидающие, одобренные или отклонённые. ![Список запросов доступа](/docs/img/apps/access_requests.png) При клике на запрос открывается детальная карточка со всем контекстом: ![Детали запроса на доступ](/docs/img/apps/access_request_detail.png) Администратор видит, кто запрашивает доступ, откуда, к какому пути, какая политика сработала и какую причину указал пользователь. Остаётся выбрать **длительность доступа** (от 15 минут до бессрочного) и нажать **Одобрить** или **Отклонить**. к сведению Одобренный доступ действует ограниченное время. После истечения пользователю потребуется отправить новый запрос. #### Мои запросы Пользователи могут отслеживать статус своих запросов на странице [Приложения → Запросы доступа](https://my.tuna.am/apps/access_requests). --- ### Политики доступа подсказка Этот раздел доступен **Основателю**, **Владельцам** и **Администраторам**. Политики — это сердце системы контроля доступа в приложениях. Каждый входящий запрос проходит через цепочку политик, и первая политика, чей шаблон пути совпал, определяет судьбу запроса: пропустить, потребовать MFA, запросить одобрение или отказать. По умолчанию доступ запрещён — если ни одна политика не совпала, запрос будет отклонён. ![Список политик приложения](/docs/img/apps/policies_list.png) #### Как устроена политика Каждая политика задаётся тремя ключевыми параметрами: | Параметр | Описание | | ---------------- | --------------------------------------------------------------------- | | **Имя** | Понятное название — «Admin panel», «Public API», «Monitoring» | | **Паттерн пути** | Glob-шаблон URL-пути: `*` — все пути, `/admin/*` — всё внутри /admin/ | | **Действие** | Что произойдёт, если путь совпал | ##### Действия **Разрешить** — пользователь получит доступ, если пройдёт проверку правил. Самое частое действие. **Требовать MFA** — работает как «Разрешить», но дополнительно потребует подтверждение вторым фактором (TOTP-приложение или код на email). Используйте для чувствительных разделов — финансы, удаление данных, управление пользователями. ![Политика с действием Требовать MFA](/docs/img/apps/policy_edit.png) **Запретить** — безусловная блокировка. Правила даже не проверяются — запрос отклоняется сразу. Это полезно, когда нужно закрыть путь для всех, а затем создать allow-политику с более высоким приоритетом для избранных. ![Политика с действием Запретить](/docs/img/apps/policy_deny.png) **Пропустить** — путь доступен вообще без аутентификации. Страница входа не показывается. Типичные кандидаты: health check, webhook-эндпоинты, публичные API. ![Политика с действием Пропустить](/docs/img/apps/policy_bypass.png) ##### Дополнительные параметры * **Длительность сессии** — можно задать свой TTL сессии для конкретной политики, отличный от общего у приложения. * **Активна** — выключенная политика сохраняется, но пропускается при оценке. Удобно для временного отключения без удаления. * **Требовать одобрение администратора** — перед получением доступа пользователь заполнит форму с причиной запроса, а администратор вручную одобрит или отклонит. Подробнее — в разделе [Запросы доступа](https://tuna.am/docs/apps/access_requests.md). #### Правила Внутри каждой политики с действием «Разрешить» или «Требовать MFA» настраиваются правила — они определяют, *кто именно* получит доступ. ![Создание политики с правилами](/docs/img/apps/policy_new.png) ##### Режимы правил Правила группируются по режимам, и режимы комбинируются между собой: | Режим | Логика | Что значит | | -------------- | ------ | ------------------------------------------------ | | **Любое (or)** | OR | Достаточно совпадения хотя бы одного правила | | **Все (and)** | AND | Должны совпасть все правила одновременно | | **Исключить** | NOT | Если хоть одно правило совпало — доступ запрещён | Доступ предоставляется, когда: совпало хотя бы одно **Любое**, совпали все **Все**, и ни одно **Исключить** не сработало. ##### Типы правил | Тип | Описание | Пример значения | | ----------------- | ------------------------------------------------------------------------------------------- | -------------------- | | **Команда** | Все активные участники команды | — | | **Email** | Конкретный email-адрес | `alice@company.com` | | **Email RegExp** | Регулярное выражение по email | `.*@company\.com$` | | **Service Token** | Машинная аутентификация по [сервисному токену](https://tuna.am/docs/apps/service_tokens.md) | Client ID | | **IP / CIDR** | IP-адрес или подсеть | `10.0.0.0/8` | | **Способ входа** | Метод аутентификации | `oidc`, `otp`, `mfa` | | **Провайдер** | Конкретный Identity Provider | `google`, `*` | | **Страна** | ISO-код страны (определяется по GeoIP) | `RU`, `US`, `DE` | ##### Пример Допустим, вы хотите, чтобы к `/admin/*` имели доступ только участники команды, и только из России. Создайте политику: * **Имя**: admin * **Паттерн**: `/admin/*` * **Действие**: Разрешить * **Правила**: * Любое (or): Команда — все участники * Все (and): Страна — `RU` Результат: чтобы попасть в админку, нужно быть участником команды **и** заходить из России. #### Приоритет и порядок Политики оцениваются сверху вниз по номеру — чем меньше номер, тем выше приоритет. Как только путь запроса совпал с шаблоном политики, она применяется и остальные не проверяются. Порядок можно менять перетаскиванием в интерфейсе. warning При создании приложения автоматически создаётся политика **Default** с паттерном `*` и наименьшим приоритетом. Она отвечает за все пути, не покрытые другими политиками. Удалять её не рекомендуется — без неё все непокрытые пути будут молча отклоняться. #### Обзор Блок **Обзор** на странице деталей визуализирует полную картину: кто входит, через какие политики проходит и куда попадает. ![Обзор с провайдерами и MFA](/docs/img/apps/overview_providers.png) #### Тестирование политик Прежде чем применять конфигурацию, её можно проверить. Инструмент **Тест политик** позволяет смоделировать запрос с любыми параметрами — email, страна, IP, метод входа, статус MFA — и увидеть, какое решение примет система. ![Тестирование политик](/docs/img/apps/policy_test.png) Результат покажет, какая политика совпала, какие правила сработали и итоговое решение. Тестер не создаёт реальных сессий — это безопасный способ отладки. --- ### Сервисные токены подсказка Этот раздел доступен **Основателю**, **Владельцам** и **Администраторам**. Не все запросы к приложению приходят от людей. CI/CD пайплайны, мониторинг, скрипты автоматизации — им тоже нужен доступ, но логиниться через браузер они не могут. Для этого существуют сервисные токены — пара Client ID + Client Secret, которая позволяет машинам аутентифицироваться в защищённых приложениях. #### Создание токена Перейдите в раздел [Сервисные токены](https://my.tuna.am/team_apps_service_tokens) и нажмите **+ Добавить токен**. ![Создание сервисного токена](/docs/img/apps/service_tokens.png) Укажите: * **Имя** — понятное название, отражающее назначение: «CI/CD pipeline», «Prometheus», «Backup script». * **Срок действия** — от 1 дня до 1 года. После истечения токен перестанет работать. #### Использование После создания Tuna покажет Client ID и Client Secret. **Сохраните секрет** — он показывается только один раз и больше не доступен через интерфейс. ![Реквизиты созданного токена](/docs/img/apps/service_token_created.png) Для аутентификации передавайте оба значения в заголовках запроса: ```shell curl -H 'Tuna-Access-Client-Id: sat_...' \ -H 'Tuna-Access-Client-Secret: ...' \ https://your-app.example.com/ ``` #### Привязка к политикам Сам по себе токен не даёт доступа — он лишь идентифицирует клиента. Чтобы токен мог пройти через политику, добавьте правило с типом **Service Token** и укажите Client ID нужного токена. Типичный сценарий: создать отдельную политику (например, «Monitoring» на путь `/api/health`) с правилом Service Token — и мониторинг получит доступ только к нужному endpoint, без доступа к остальному приложению. #### Ротация Если секрет скомпрометирован или просто пришло время его обновить, токен можно ротировать. При ротации генерируется новый секрет, а старый продолжает работать в течение grace-периода (до 60 минут), чтобы вы могли обновить секрет во всех сервисах без простоя. --- ### Сессии Каждый раз, когда пользователь проходит аутентификацию в приложении, создаётся сессия. Она живёт до истечения срока или до момента, когда администратор её отзовёт. #### Мои сессии Каждый пользователь видит свои активные сессии на странице [Приложения → Сессии](https://my.tuna.am/apps/sessions). ![Список сессий пользователя](/docs/img/apps/sessions.png) Для каждой сессии отображается приложение, IP-адрес, страна (по GeoIP), время создания и истечения. Нажмите на корзину, чтобы завершить сессию — при следующем запросе потребуется повторная аутентификация. #### Сессии команды Администраторы видят сессии всех пользователей в разделе [Сессии](https://my.tuna.am/team_apps_sessions). При клике на строку открывается детальная карточка с полной информацией о сессии. ![Сессии команды с деталями](/docs/img/apps/sessions_admin.png) В карточке видно: | Поле | Описание | | ------------------------ | ----------------------------------------- | | **Приложение** | К какому приложению привязана сессия | | **Email** | Адрес пользователя | | **Тип** | Внутренний (участник команды) или внешний | | **IP** | IP-адрес, с которого была создана сессия | | **Страна** | Страна по GeoIP | | **Создана / Истекает** | Время жизни сессии | | **Последняя активность** | Когда был последний запрос | | **User-Agent** | Браузер и ОС клиента | Администратор может отозвать любую сессию, а кнопка **Закрыть все сессии** на странице деталей приложения завершает все активные сессии разом. --- ### Настройки подсказка Этот раздел доступен **Основателю**, **Владельцам** и **Администраторам**. На вкладке **Настройки приложения** собраны параметры, которые влияют на то, как прокси обрабатывает запросы к upstream — заголовки, пути, TLS, CORS и внешний вид страницы входа. ![Все настройки приложения](/docs/img/apps/settings_all.png) #### Видимость Определяет, видят ли участники команды это приложение в [пользовательском каталоге](https://my.tuna.am/apps). ![Настройка видимости](/docs/img/apps/settings_visibility.png) Если выключить — приложение исчезнет из каталога, но продолжит работать по своему адресу. Полезно для внутренних сервисов, к которым обращаются только через API или автоматизацию. #### Логотип и страница блокировки ![Логотип и страница блокировки](/docs/img/apps/settings_logo.png) * **Ссылка на логотип** — URL изображения, которое появится на странице входа вместо стандартного. Помогает пользователям сразу понять, куда они попали. * **Адрес страницы блокировки** — вместо стандартной страницы «доступ запрещён» пользователь будет перенаправлен по этому адресу. Например, на корпоративную страницу поддержки. #### Заголовок Host ![Настройка заголовка Host](/docs/img/apps/settings_host.png) * **Принудительно установить заголовок Host** — по умолчанию upstream получает Host из своего URL. Если ваш бэкенд ожидает конкретный Host (например, nginx с виртуальными хостами), укажите его здесь. * **Передать оригинальный Host из запроса клиента** — upstream увидит тот же Host, что ввёл пользователь в браузере. Перекрывает Host Override. #### Путь Управление URL-путём запроса перед проксированием. ![Настройка пути](/docs/img/apps/settings_path.png) * **Вырезать префикс** — удаляет указанный префикс из пути. Пример: при значении `/api/v1` запрос `/api/v1/users` пойдёт на upstream как `/users`. * **Добавить префикс** — приклеивает префикс к пути перед отправкой на upstream. Применяется после вырезания. к сведению Комбинация: вырезать `/api/v1` + добавить `/internal` → запрос `/api/v1/users` пойдёт на upstream как `/internal/users`. #### Лимит размера тела запроса ![Лимит размера тела запроса](/docs/img/apps/settings_body.png) Максимальный размер тела HTTP-запроса от клиента (upload) в байтах. По умолчанию — 32 МиБ (33554432 байт). Если ваш сервис принимает большие файлы, увеличьте значение. `0` — без ограничения. #### CORS Если ваш фронтенд живёт на другом домене и обращается к приложению через fetch/XMLHttpRequest — включите CORS. Preflight-запросы (OPTIONS) при этом проходят без авторизации. ![CORS выключен](/docs/img/apps/settings_cors.png) После включения появляются параметры: ![CORS включён](/docs/img/apps/settings_cors_enabled.png) | Параметр | Описание | | ------------------------- | --------------------------------------------------------------------------------------------- | | **Разрешённые источники** | Домены, с которых разрешены запросы. По одному на строку, `*` — все | | **Разрешённые методы** | HTTP-методы: GET, POST, PUT, DELETE и др. | | **Разрешённые заголовки** | Заголовки, которые клиент может отправлять | | **Разрешить Cookies** | Позволяет передавать cookies и заголовки авторизации. Нельзя комбинировать с `*` в источниках | | **Кэш Preflight** | Сколько секунд браузер может кэшировать ответ на OPTIONS | #### Заголовки запроса и ответа Добавьте пользовательские заголовки к запросам (при передаче на upstream) и ответам (перед отправкой клиенту). Типичные примеры: `X-Custom-Header` для идентификации источника, `Strict-Transport-Security` для HSTS. ![Пользовательские заголовки](/docs/img/apps/settings_headers.png) #### TLS до upstream Настройки TLS-соединения между прокси и вашим бэкендом. ![TLS до upstream](/docs/img/apps/settings_tls.png) * **Не проверять TLS сертификат upstream** — включайте только для тестовых окружений или бэкендов с самоподписанным сертификатом. ##### Клиентский сертификат (mTLS) Если ваш upstream требует взаимную аутентификацию (mTLS), прокси может предъявить клиентский сертификат. Это позволяет upstream убедиться, что запрос пришёл именно через Tuna, а не напрямую. * **Клиентский сертификат (PEM)** — сертификат, который прокси предъявляет upstream. * **Приватный ключ (PEM)** — ключ к сертификату. * **Корневой CA (PEM, опционально)** — корневой сертификат, если upstream использует собственный CA. --- ### Бастион SSH-сервер с ролевой мандатной моделью доступа, использующий принципы [нулевого доверия (Zero Trust)](https://en.wikipedia.org/wiki/Zero_trust_architecture). В отличие от классических SSH-серверов, бастион делает акцент на идентификацию пользователей, временные сертификаты и ролевую модель доступа, обеспечивая повышенную безопасность доступа к вашим серверам в купе с простой настройки. ![bastion-main](/assets/images/main-d010947b01a00aaabab74362acf8b84f.png) #### Обзор к сведению В настоящий момент функционал находится в стадии открытого тестирования. Это доступно всем пользователям с подпиской на тариф [Легенда](https://tuna.am/docs/team.md). В будущем формат и монетизация может существенно измениться. ##### Что такое бастион в контексте SSH-доступа? Вместо традиционного SSH-доступа `ssh user@host` на основе паролей или RSA ключей, пользователи аутентифицируются через наш [клиент tuna](https://tuna.am/docs/guides/install/install-cli.md) у нас на портале. Далее на бастион сервере работает аутентификация на основе сертификатов, это штатный функционал OpenSSH, но является самым безопасном из всех, но исторически был самым сложным в настройке. Всю сложность мы берём на себя, вам же остаётся только безопасность. После авторизации на портале, клиент генерирует RSA ключи и публичную часть передаёт в API, для доставки на бастион серверы. Клиент также генерирует временный PKI сертификат и он подписывается CA в портале Tuna. C RSA ключом и сертификатом вы подключаетесь к серверу, сервер проверяет, что сертификат действителен, подписан верным CA и у пользователя на которого выписан сертификат достаточно прав на доступ с учётом ролей и политик. Бастион серверы в свою очередь тоже имеют временные сертификаты пописанные CA и при установке соединения клиент также проверяют валидность в CA но сервера, так вы уверены, что ваш сервер, это ваш сервер, а не что-то подставное. В итоге мы ничего не знаем про приватные ключи серверов и клиентов, они генерируются и хранятся локально, а значит у нас нет возможности подключиться к вашей инфраструктуре, как и злоумышленникам в случае утечек у нас, но мы выступаем 3й стороной хранителем CA, что подписывает сертификаты и аутентифицирует пользователя. Основные принципы: * Мандатная (Role-Based Access Control, RBAC) модель — доступ к SSH-серверам управляется через роли и политики, а не вручную через файлы authorized_keys * Zero Trust — проверяет не только учетные данные пользователя, но и контекст - Кто запрашивает доступ? Какой сервер и с какой целью? Какие параметры у сессии (время, источник, политика MFA)? * Аутентификация без паролей (Passwordless) — вместо статических паролей, в дополнение к SSH-ключам используются PKI-сертификаты, которые автоматически истекают. * (скоро) Аудит и наблюдаемость — каждая SSH-сессия записывается, что позволяет просматривать действия пользователей в реальном времени. * (скоро) Интеграция с SSO (OAuth, OpenID, SAML, LDAP) — пользователи могут аутентифицироваться через корпоративные сервисы, такие как Google Workspace или Okta. ##### Как это выглядит на практике? ![main-scheme](/assets/images/scheme-aeeed643ed226b44f550ed63551bc21f.png) 1. Вы запускаете **tuna-bastion** на своём сервере и регистрируете его в API Tuna. Генерируется пара RSA ключей, и сертификат на 30 дней, который подписывает CA выделенный на команду в API Tuna. Приватный ключ хранится локально и никуда не передаётся, API Tuna его не знает, т.е. у нас нет доступа к вашим северам. 2. В панели управления [my.tuna.am](https://my.tuna.am/team) создаёте роль описывающую модель доступа и применяете к нужному пользователю. 3. Пользователь запускает у себя команду `tuna bastion login username`. Генерируется пара RSA ключей, и сертификат на 12 часов, который подписывает CA выделенный на команду в API Tuna, по аналогии с сервером. Но это происходит только если у пользователя достаточно прав на подключения с таким логином. 4. Пользователь запускает команду `tuna bastion ssh username@hostname` и если его сертификат валидный, сертификат сервера валидный, у пользователя достаточно прав и не наложено ограничений, то тогда сессия устанавливается. *** #### [🗃Инструкции](https://tuna.am/docs/bastion/guides.md) [3 элемента](https://tuna.am/docs/bastion/guides.md) #### [🗃Администратор](https://tuna.am/docs/bastion/admin.md) [5 элементов](https://tuna.am/docs/bastion/admin.md) #### [🗃Пользователь](https://tuna.am/docs/bastion/user.md) [3 элемента](https://tuna.am/docs/bastion/user.md) --- ### Администратор Описание функционала для администраторов бастиона. #### [📄️Серверы](https://tuna.am/docs/bastion/admin/servers.md) [В этом разделе происходит управление вашими бастион серверам](https://tuna.am/docs/bastion/admin/servers.md) #### [📄️Запросы доступа](https://tuna.am/docs/bastion/admin/access_requests.md) [Запросы доступа к серверам от пользователей](https://tuna.am/docs/bastion/admin/access_requests.md) #### [📄️Сессии](https://tuna.am/docs/bastion/admin/sessions.md) [Список активных сессий всех пользователей в команде](https://tuna.am/docs/bastion/admin/sessions.md) #### [📄️Блокировки](https://tuna.am/docs/bastion/admin/locks.md) [Блокировки для ограничения доступа пользователей к серверам](https://tuna.am/docs/bastion/admin/locks.md) #### [📄️Сертификаты](https://tuna.am/docs/bastion/admin/certificates.md) [Сертификаты CA, пользователей и серверов](https://tuna.am/docs/bastion/admin/certificates.md) --- ### Запросы доступа [В этом разделе](https://my.tuna.am/team_bastion_access_requests) отображаются запросы на доступ к серверам от пользователей команды. ![admin_access_request](/assets/images/admin_access_request-08b4eeff536b70961d844f024ee6a93a.png) Администратор увидит имя и почту пользователя, сервер к которому запрошен доступ, логин и причина которую указал пользователь. Как пользователь создаёт запрос, описано [тут](https://tuna.am/docs/bastion/user/access_requests.md). подсказка Этот раздел доступен **Основателю**, **Владельцам** и **Администраторам**. --- ### Сертификаты [В этом разделе](https://my.tuna.am/team_bastion_certificates) вы увидите отпечатки CA сертификатов, а также все подписанные сертификаты серверов и пользователей. ![admin_certificates](/assets/images/admin_certificates-d5b9974f3b3e56d0f0f9a603e5dc8bfb.png) Для серверов и пользователей используются отдельные CA. Так все серверы проверяют пользовательские сертификаты, что они подписаны CA для для пользователей, а пользователи наоборот, что сертификаты серверов подписаны CA для серверов. CA генерируется уникально для каждой команды при добавлении первого сервера. подсказка Этот раздел доступен **Основателю**, **Владельцам** и **Администраторам**. #### Ротация сертификатов #### CA warning Ротация CA сертификатов команды ещё недоступна, но планируется в ближайшем будущем. ##### Серверы к сведению По умолчанию выпускается на 30 дней Если бастион сервер активен при приближении даты истечения сертификат ротируется автоматически. ##### Клиенты к сведению По умолчанию выпускается на 12 часов Если сессия клиента активна и подключение работает через обёртку `tuna bastion ssh`, а не напрямую через нативный `ssh-client`, то при приближении даты истечения сертификат также ротируется автоматически. --- ### Блокировки [В этом разделе](https://my.tuna.am/team_bastion_certificates) вы можете создать блокировки для быстрого ограничения доступа пользователей к серверам. ![admin_locks](/assets/images/admin_locks-656695338bc34e8ddbc10bcf29da849d.png) Если вы хотите запретить доступ на сервер и группу серверов по метке, логину или конкретного пользователя. #### Когда это нужно? Можно придумать множество примеров, вот некоторые: * У вас есть уволенный сотрудник которому нужно срочно отозвать доступ ко всей инфраструктуре. * Вы хотите ограничить доступ к продуктовым серверам на время моратория новогодних каникул. * Профилактические работы на одном сервере и нужно закрыть к нему доступ всем пользователям. #### Пример Нельзя добавить блокировку без каких либо условий, нужно заполнить хотя бы одно условие: * Сервер * Роль * Пользователь * Логин В этом примере пользователю *Женя* будет запрещено логиниться на любые серверы, а все текущие сессии будут немедленно закрыты. ![admin_lock_add](/assets/images/admin_lock_add-c5240e11102893ce4e5b3d035ba4b57c.png) подсказка Этот раздел доступен **Основателю**, **Владельцам** и **Администраторам**. --- ### Серверы [В этом разделе](https://my.tuna.am/team_bastion_servers) происходит управление вашими бастион серверам: * Добавление * Удаление * Отображение списка с настройками и статусом ![bastion-main](/assets/images/main-d010947b01a00aaabab74362acf8b84f.png) #### Добавление сервера Нажмите кнопку **Добавить сервер**, вы увидите короткую инструкцию по установке бастион сервера на ваш хост с помощью скрипта, а также регистрацию и запуск сервера. примечание Установка и настройка `tuna-bastion` более подробно описана [тут](https://tuna.am/docs/bastion/guides/setup.md). ![](/docs/img/bastion/admin_server_add.png) подсказка Этот раздел доступен **Основателю**, **Владельцам** и **Администраторам**. --- ### Сессии [В этом разделе](https://my.tuna.am/team_bastion_sessions) отображается список всех активных сессий всех пользователей в команде. ![admin_sessions](/assets/images/admin_sessions-0721c0cbd6012b2adeae5561741f8599.png) подсказка Этот раздел доступен **Основателю**, **Владельцам** и **Администраторам**. --- ### Инструкции Инструкции по администрированию и использованию бастиона #### [📄️Установка](https://tuna.am/docs/bastion/guides/install.md) [Установка бастион сервера](https://tuna.am/docs/bastion/guides/install.md) #### [📄️Настройка](https://tuna.am/docs/bastion/guides/setup.md) [Настройка и запуск tuna-bastion сервера](https://tuna.am/docs/bastion/guides/setup.md) #### [📄️Использование](https://tuna.am/docs/bastion/guides/usage.md) [Запрос доступа, авторизация и подключение к бастион серверу](https://tuna.am/docs/bastion/guides/usage.md) --- ### Установка tuna-bastion #### C помощью скрипта Выполните команду в терминале: ```shell curl -sSLf https://releases.tuna.am/bastion/get.sh | sh ``` к сведению Скрипт автоматически обнаруживает дистрибутив и устанавливает `tuna-bastion` через пакетный менеджер. #### Через пакетный менеджер **Debian/Ubuntu** Debian и основанные на нём дистрибутивы (Ubuntu, Mint и другие), выполните в терминале следующие команды: ```shell sudo apt update sudo apt install -y ca-certificates curl gnupg curl -fsSL https://code.tuna.am/api/packages/tuna/debian/repository.key | sudo gpg --dearmor --batch --yes -o /usr/share/keyrings/tuna-forgejo.gpg echo 'deb [signed-by=/usr/share/keyrings/tuna-forgejo.gpg] https://code.tuna.am/api/packages/tuna/debian stable main' | sudo tee /etc/apt/sources.list.d/tuna-forgejo.list sudo apt update sudo apt install -y tuna-bastion ``` **SUSE/OpenSUSE** SUSE и OpenSUSE, выполните в терминале следующие команды: ```shell sudo zypper addrepo --repo https://code.tuna.am/api/packages/tuna/rpm/stable.repo sudo zypper install -y tuna-bastion ``` **RHEL/Fedora** RHEL и основанные на нём дистрибутивы (CentOS, Rocky, AlmaLinux и другие), а также Fedora, выполните в терминале следующие команды: ```shell sudo curl -fsSL https://code.tuna.am/api/packages/tuna/rpm/stable.repo -o /etc/yum.repos.d/tuna-forgejo.repo sudo dnf install -y tuna-bastion ``` --- ### Настройка #### Регистрация После [установки](https://tuna.am/docs/bastion/guides/install.md) нужно зарегистрировать сервер. В этот момент сервер генерирует локально SSH ключи и подписывает свои сертификаты в API Tuna. ```sh tuna-bastion enroll --key ``` примечание Как получить ключ для регистрации сервера, описано [тут](https://tuna.am/docs/bastion/admin/servers.md). Если все обязательные ключи не указаны, то вы увидите консольное меню: ```sh ? Enroll Key (--key) 3678287f-93ea-4ebe-8478-4d9e9f28d95d ? Data directory (--data-dir) /var/lib/tuna-bastion/data ? Listen SSH port (--ssh-port) 993 ? Advertise Address (--advertise-address) 1.2.3.4:993 ? Hostname (--hostname) server-1 ? Labels (--labels) env=testing,region=am,service=ssh Successfully enrolled node: 688fa3e2-035e-40fb-88e6-2869b6025014 ``` * **Enroll Key** - используется только при регистрации * **Data directory** - каталог где будут сохранены SSH ключи и сертификаты (по умолчанию `/var/lib/tuna-bastion/data`) * **Listen SSH port** - порт который будет локально слушать `tuna-bastion` сервер. По умолчанию мы предлагаем использовать порт `993` (IMAPs) ибо как правило он открыт в корпоративных фаерволах изначально. * **Advertise Address** - адрес который будет зарегистрирован в API и на него будет выписан сертификат. * **Hostname** - имя сервера, будет записано в API и сертификате, нельзя сменить. * **Labels** - метки сервера, пометками можно настраивать роли доступа, их в случае необходимости можно будет переопределить в конфиг файле `/etc/tuna-bastion/config.yaml`. #### Запуск Запустите сервер ```sh systemctl enable --now --no-block tuna-bastion.service ``` Если всё в порядке вы увидите, что сервер теперь доступен на [этой странице](https://my.tuna.am/team_bastion_servers). В случае неполадок смотрите логи сервера. ```sh journalctl -o short -n 100 -f -u tuna-bastion.service ``` --- ### Использование После [запуска](https://tuna.am/docs/bastion/guides/setup.md) бастион серверов, вы можете подключаться к ним с помощью клиента [tuna](https://tuna.am/docs/guides/install/install-cli.md). #### Авторизация Прежде чем приступить, выберете нужный сервер к которому вам нужен доступ, посмотреть список серверов можно [тут](https://tuna.am/docs/bastion/user/servers.md). Если у вас нет доступа, запросите его у администраторов команды. Далее нужно авторизоваться указав Login конечного пользователя на сервере, в нашем примере это `root`, хотя мы рекомендуем использовать выделенного пользователя. ```sh $ tuna bastion login root INFO[12:01:27] Open in your browser: https://my.tuna.am/bastion_login/c95e812f-e1ef-4f32-a8e3-4fec7ddb7406 INFO[12:01:27] Waiting for approval... ``` В этот момент нужно будет подтвердить, что вы это вы перейдя по ссылке и авторизоваться на портале Tuna. Это и есть часть принципа [нулевого доверия (Zero Trust)](https://tuna.am/docs/bastion.md). ![](/docs/img/bastion/user_auth.png) Если всё в порядке для вашего пользователя будет подписан сертификат на 12 часов, с этим сертификатом пользователь сможет подключаться к бастион серверам к которым ему предоставили доступ с помощью [ролей](https://tuna.am/docs/team/roles.md). Все ключи и сертификат будут сохранены локально. ```sh INFO[12:03:03] Keys directory: /home/jidckii/.tuna/bastion/keys ``` #### Подключение С действующим сертификатом вы сможете посмотреть список доступных серверов и в консоли: ```sh $ tuna bastion ls INFO[12:58:24] t480s (env=testing, region=am, service=ssh) ``` Либо сразу подключиться: ```sh tuna bastion ssh root@t480s ``` к сведению Login `root` указан для примера, у вас может быть свой пользователь. Если прав достаточно и нет блокировок то появится активная сессия как у [пользователя](https://tuna.am/docs/bastion/user/sessions.md) так и в [администраторском](https://tuna.am/docs/bastion/admin/sessions.md) разделе. также можно сгенерировать ssh_config и использовать его для подключения через нативный `ssh-client`, например: ```sh $ tuna bastion ssh_config root@t480s Host t480s Hostname 127.0.0.1 Port 1234 User root CertificateFile /home/example/.tuna/bastion/keys/root-cert.pub UserKnownHostsFile /home/example/.tuna/bastion/keys/known_hosts IdentityFile /home/example/.tuna/bastion/keys/id_rsa ``` сохраните в локальный файл и используйте его для подключения ```sh tuna bastion ssh_config root@t480s > t480s.ssh_config ``` ```sh ssh -F t480s.ssh_config t480s ``` Важно По истечении сертификата нужно будет снова авторизоваться `tuna bastion login` и выпустить новый сертификат. Но если сессия клиента активна и подключение работает через обёртку `tuna bastion ssh`, а не напрямую через нативный `ssh-client`, то при приближении даты истечения сертификат также ротируется автоматически. --- ### Пользователь Описание функционала для пользователей бастиона #### [📄️Серверы](https://tuna.am/docs/bastion/user/servers.md) [Бастион серверы в вашей команде](https://tuna.am/docs/bastion/user/servers.md) #### [📄️Запросы доступа](https://tuna.am/docs/bastion/user/access_requests.md) [Запросы доступа к серверам в команде](https://tuna.am/docs/bastion/user/access_requests.md) #### [📄️Сессии](https://tuna.am/docs/bastion/user/sessions.md) [Ваши сессии к бастион серверам](https://tuna.am/docs/bastion/user/sessions.md) --- ### Запросы доступа [В этом разделе](https://my.tuna.am/bastion_access_requests) вы можете увидеть все ваши запросы доступа и их статус. ![user_access_request](/assets/images/user_access_request-c4d4df9857e284efa1dce04f24a607e5.png) Создать запрос можно на странице с [серверами](https://tuna.am/docs/bastion/user/servers.md). --- ### Серверы [В этом разделе](https://my.tuna.am/bastion_servers) вы можете увидеть все доступные бастион серверы в вашей команде и запросить доступ к серверу у администратора, если нет разрешающей роли. ![user_servers](/assets/images/user_servers-ce39643ed9351764cd22f2ca71f26973.png) Также в этом разделе вы можете запросить доступ к серверу: ![user_server_req_access](/assets/images/user_server_req_access-2a38a340696cd3527c3e530caccde969.png) Нужно будет указать Login пользователя на сервере и причину которую увидит администратор команды: ![user_server_req_access_2](/assets/images/user_server_req_access_2-ce2523b5db38d86ffa55174bb0fb6fb3.png) Или посмотреть команду подключения: ![user_server_cmd_view](/assets/images/user_server_cmd_view-f9a71b3eb72f216352b6d983c09f15f4.png) ![user_server_cmd_view_2](/assets/images/user_server_cmd_view_2-efbaef7431070d17a91fc3375fae9edb.png) --- ### Сессии [В этом разделе](https://my.tuna.am/bastion_sessions) отображается список всех активных сессий всех пользователей в команде. ![user_sessions](/assets/images/user_sessions-fc16c879c45d817b2fabac6d1a46d84a.png) --- ### Доски [Перейти в личный кабинет](https://my.tuna.am/boards) Онлайн-доски для команды: штурмите идеи, рисуйте архитектуру и созванивайтесь — всё в одном месте. *** #### Обзор **Доски** — это бесконечный холст, на котором можно рисовать схемы, собирать стикеры, оставлять комментарии, созваниваться и работать одновременно всей командой. Что можно делать на досках * Проектировать и документировать архитектуру и инфраструктуру * Проводить брейнштормы, ретро и планирование задач * Созваниваться голосом прямо в окне доски * Оставлять комментарии и обсуждать решения * Презентовать результаты команде * Экспортировать итоги в PNG, JPG, PDF или SVG #### Структура сервиса Внутри сервиса **Доски** находятся отдельные **доски**, каждая из которых представляет собой независимый бесконечный холст. Доски доступны всем участникам вашей команды в Tuna — все изменения синхронизируются в реальном времени. #### Создание первой доски 1. Перейдите в раздел [Доски](https://my.tuna.am/boards) в личном кабинете. 2. Нажмите кнопку **+ Создать новую**. 3. Задайте название доски — оно поможет отличать её от других. 4. Откройте доску и пригласите коллег — им достаточно зайти в тот же раздел. *** #### Инструменты доски ##### Фигуры и схемы Используйте фигуры, линии и стрелки, чтобы рисовать архитектуру, флоу и любые диаграммы. В библиотеке доступны как базовые геометрические формы, так и готовые наборы иконок (например, **Agentic Workflows**, **Yandex Cloud** и другие) — удобно для описания инфраструктуры. ![Библиотека фигур и иконок на доске](/docs/img/boards/figurs.png) ##### Стикеры Классический инструмент для брейнштормов и ретро. Стикеры можно перемещать, группировать, менять размеры и цвета, добавлять текст внутри. ![Стикеры разных цветов и размеров](/docs/img/boards/sticker.png) ##### Текст и шрифты Добавляйте текстовые блоки на холст, выбирайте шрифт, начертание (жирный, курсив, подчёркнутый, зачёркнутый), цвет текста и цвет выделения. ![Варианты шрифтов и форматирования текста](/docs/img/boards/fonts.png) ##### Изображения и медиа На доску можно добавлять картинки и видео — например, скриншоты экрана, фотографии или короткие записи. Это удобно, чтобы сослаться на конкретный экран или показать, как воспроизводится баг. ![Изображения и видео на доске](/docs/img/boards/pic.png) ##### Эмодзи Любой объект на доске можно дополнить эмодзи — быстрый способ обозначить статус, настроение или приоритет. ![Добавление эмодзи на доску](/docs/img/boards/emoji.png) *** #### Совместная работа ##### Вся команда на доске Несколько человек могут работать на одной доске одновременно. Курсоры участников видны в реальном времени — как будто вы сидите рядом. Все изменения появляются мгновенно. ##### Комментарии Оставляйте комментарии прямо на элементах доски — вопрос точно не потеряется, а обсуждение будет привязано к конкретному объекту. К комментариям можно отвечать тредом и закрывать их после решения. ![Комментарии на элементе доски](/docs/img/boards/comments.png) ##### Активность и треды В панели **Активность** собраны все обсуждения с доски — удобно посмотреть, что нового написали коллеги, и быстро перейти к нужному треду. ![Панель активности с тредами](/docs/img/boards/activity.png) ##### Реакции Быстрая обратная связь без слов: ставьте реакции — лайк, сердце, огонь и другие — на элементы доски или сообщения коллег. ![Реакции на доске](/docs/img/boards/reactions.png) ##### Голосовой чат Нажмите одну кнопку — и вы уже в общей голосовой комнате с командой. Не нужно отдельно поднимать Zoom, Google Meet или Telegram-звонок: обсуждение идёт прямо в окне доски. ![Голосовой чат на доске](/docs/img/boards/voice-chat.png) ##### Таймер Запустите общий таймер для брейншторма или ретро — все участники видят обратный отсчёт одновременно. Можно поставить на паузу или быстро добавить +1 / +5 минут. ![Таймер для участников доски](/docs/img/boards/timer.png) ##### Режим демонстрации Переключитесь в режим презентации, чтобы провести команду по нужным частям доски без лишнего скроллинга и масштабирования. Доска превращается в слайд-шоу с заранее выбранными областями. *** #### Экспорт доски Сохраните результат сессии в одном из форматов: * **PNG** — для публикаций и переписок * **JPG** — для лёгких изображений * **PDF** — для отчётов и печати * **SVG** — для дальнейшего редактирования в векторных редакторах Поделитесь файлом с теми, кого не было на сессии, или приложите его к задаче. *** #### Тарифы Доски включены в подписку Tuna и не требуют отдельной оплаты. Функционал доступен на тарифах **Разработчик** и **Легенда** — подробности смотрите на странице [тарифов](https://tuna.am/#pricing). --- ### Шлюзы Шлюз - это всегда доступный облачный балансировщик или WEB сервер с гибкими политиками обработки трафика. ![gateways-main](/assets/images/main-19b8b7724c36ce8fe4c771d5447f65ea.png) #### Обзор Вы можете зарезервировать свой или использовать домен в зоне tuna.am и создать для этого домена шлюз. В описании шлюзов используются [политики трафика](https://tuna.am/docs/traffic-policy.md). После сохранения настройки применятся и запросы начнут обрабатываться нодой за которой закреплён домен и соответственно шлюз. #### Когда это полезно? Туннели это хорошо, но бывает окружение состоит из нескольких сервисов часть из которых запущено у вас, у вашего коллеги и в тестовом контуре. Но благодаря гибким [политикам трафика](https://tuna.am/docs/traffic-policy.md) вы можете распределять запросы в нужные точки, управлять заголовками, авторизацией, временем работы и много другое. #### Как создать Шлюз? 1. Зарезервируйте домен в разделе с [доменами](https://my.tuna.am/domains) который вы планируете использовать, для примера в этой статье это будет `demo.stage.tuna.am` 2. Перейдите в раздел [Шлюзы](https://my.tuna.am/gateways) и нажмите **Добавить шлюз** , выберете зарезервированный ранее домен. 3. Опишите политику используя синтаксис [политик трафика](https://tuna.am/docs/traffic-policy.md) и нажмите **Создать**. Если синтаксис корректен, шлюз сразу будет доступен и вы можете работать. #### Пример Представим демо стенд доступный только в будни, основная часть которого в тестовом контуре, а 2 микросервиса за туннелями разработчиков. ```yaml rules: - expressions: - now().Weekday().String() in ["Saturday", "Sunday"] actions: - type: custom_response config: statusCode: 200 content: В выходные не работаем! headers: content-type: "text/plain; charset=utf-8" - expressions: - hasPrefix(req.URL.Path, "/admin") actions: - type: reverse_proxy config: url: "https://valera-dev.run.tuna.am" - expressions: - hasPrefix(req.URL.Path, "/checkout") actions: - type: reverse_proxy config: url: "https://alena-dev.run.tuna.am" - actions: - type: reverse_proxy config: url: "https://testing.example.com" ``` И так по выходным вы будете получать сообщение `В выходные не работаем!`, а в будни все основные запросы отправятся в тестовый контур на `https://testing.example.com`, всё за `/admin` уйдёт на туннель `https://valera-dev.run.tuna.am` , а `/checkout` к `https://alena-dev.run.tuna.am`. --- ### Инструкции Здесь собраны полезные заметки и рецепты, которые помогут в трудную минуту. Есть о чем рассказать? Напишите нам на . #### [🗃Установка](https://tuna.am/docs/guides/install.md) [2 элемента](https://tuna.am/docs/guides/install.md) #### [📄️Обновление](https://tuna.am/docs/guides/update.md) [Обновление клиента до актуальной версии](https://tuna.am/docs/guides/update.md) #### [📄️API](https://tuna.am/docs/guides/api.md) [Обзор и доступ к API](https://tuna.am/docs/guides/api.md) #### [📄️Автодополнение](https://tuna.am/docs/guides/completion.md) [Автодополнение команд нажатием TAB](https://tuna.am/docs/guides/completion.md) #### [📄️Конфигурационный файл](https://tuna.am/docs/guides/config-file.md) [Настройка через конфигурационный файл](https://tuna.am/docs/guides/config-file.md) #### [📄️Очерёдность конфигурации](https://tuna.am/docs/guides/config-ordering.md) [Правила переопределения настроек](https://tuna.am/docs/guides/config-ordering.md) #### [📄️Работа tuna в корпоративной сети](https://tuna.am/docs/guides/corporate-network.md) [Обнаружение проблем подключения](https://tuna.am/docs/guides/corporate-network.md) #### [📄️Переменные окружения](https://tuna.am/docs/guides/environment-variables.md) [Перечень используемых переменных окружения для работы с tuna](https://tuna.am/docs/guides/environment-variables.md) #### [📄️Удаление](https://tuna.am/docs/guides/remove.md) [Удаление клиента](https://tuna.am/docs/guides/remove.md) #### [📄️SSH ключи](https://tuna.am/docs/guides/ssh-keys.md) [Страница управления SSH ключами](https://tuna.am/docs/guides/ssh-keys.md) #### [📄️Terraform](https://tuna.am/docs/guides/terraform.md) [Управление доменами, шлюзами, токенами и политиками tuna через Terraform и OpenTofu](https://tuna.am/docs/guides/terraform.md) #### [📄️Устранение неполадок](https://tuna.am/docs/guides/troubleshooting.md) [Диагностика и устранение неполадок при работе с tuna](https://tuna.am/docs/guides/troubleshooting.md) --- ### API #### Обзор Мы предоставляем программный интерфейс ко всем ресурсам, доступным пользователю. API доступен по адресу `https://api.tuna.am` для всех зарегистрированных пользователей. Все ресурсы собраны на [отдельной странице](https://my.tuna.am/swagger/), там же можно проверить работу интересующего метода указав свой API-ключ в SwaggerUI. #### Быстрый старт Перед началом работы нужно создать API ключ, сделать это можно на [отдельной странице](https://my.tuna.am/api_keys). Для прохождения аутентификации ключ нужно передавать в HTTP заголовке `Authorization: Bearer {API-ключ}` примечание Устаревший вариант `Authentication: Bearer {API-ключ}` поддерживается, но может быть удален в будущем, пожалуйста, используйте актуальный заголовок. ##### Пример с cURL Чтобы получить описание пользователя выполните запрос с помощью curl: ```bash curl -H "Authorization: Bearer {API-ключ}" https://api.tuna.am/v1/user ``` ##### Пример с tuna ```bash tuna config save-api-key "{API-ключ}" tuna domain list ``` #### Ошибки ##### HTTP статус коды Ошибки обычно возвращают `4xx` код ответа. Реже вы можете получать ошибки `5xx` - это означает, что ошибка связана с tuna API, а не с вашим кодом. ##### Формат ошибки Все ошибки возвращаемые tuna имеют следующий формат: ```json { "code": "BadRequest", "error": "Incorrect identifier: strconv.ParseInt: parsing \"foobar\": invalid syntax", "request_id": "785f3f7e174cc6dc2c2d359bed4d921d" } ``` Ошибки всегда содержат поле `code` и опционально текст в поле `error`. --- ### Автодополнение Автодополнение - это удобный функционал командной строки, для вывода подсказок по нажатию на кнопку TAB. **PowerShell** ```powershell tuna completion powershell | Out-String | Invoke-Expression ``` Для проверки наберите `tuna` и нажмите кнопку TAB несколько раз. Чтобы сохранить настройки для будущих сессий, выполните следующие шаги: 1. Откройте PowerShell от имени **Администратора** и выполните команду, что бы разрешить выполнять пользовательские сценарии в оболочке: ```powershell Set-ExecutionPolicy RemoteSigned ``` На вопрос отвечаем: A (Да для всех). 2. Откройте новое окно PowerShell уже от своего пользователя и выполните команды по очереди: ```powershell if (!(Test-Path -Path $PROFILE.CurrentUserAllHosts)) { New-Item -ItemType File -Path $PROFILE.CurrentUserAllHosts -Force } Add-Content $PROFILE.CurrentUserAllHosts "tuna completion powershell | Out-String | Invoke-Expression" ``` Либо можете отредактировать файл через текстовый редактор: ```shell notepad $PROFILE.CurrentUserAllHosts ``` Добавив строку: ```powershell tuna completion powershell | Out-String | Invoke-Expression ``` **Zsh** ```shell source <(tuna completion zsh) ``` Чтобы сохранить настройки для будущих сессий, добавьте в файл `~/.zshrc`: ```shell if command -v tuna &>/dev/null; then eval "$(tuna completion zsh)" fi ``` **Bash** ```shell source <(tuna completion bash) ``` Чтобы сохранить настройки для будущих сессий, добавьте в файл `~/.bashrc`: ```shell if command -v tuna &>/dev/null; then eval "$(tuna completion bash)" fi ``` **Fish** ```shell tuna completion fish | source ``` Чтобы сохранить настройки для будущих сессий, добавьте в файл `~/.config/fish/completions/tuna.fish`: ```shell tuna completion fish ``` --- ### Конфигурационный файл Часть основных настроек можно задать через конфигурационный файл в yaml формате. #### Путь по умолчанию В Windows обычно файл хранится по пути - `$env:USERPROFILE\AppData\Local\tuna\tuna.yml`,
в Unix-подобных операционных системах (macOS, Linux, FreeBSD) - `${HOME}/.config/tuna/tuna.yml`. #### Сохранение основных настроек Часть настроек можно определить специальными командами: Сохранить токен: ```shell tuna config save-token <ваш_токен> ``` Задать [регион](https://tuna.am/docs/tunnels/guides/locations.md): ```shell tuna config save-location nl ``` Задать [API-ключ](https://tuna.am/docs/guides/api.md): ```shell tuna config save-api-key <ваш_api_key> ``` #### Пример файла Пример основных настроек: ```yaml --- version: "1" token: tt_*** apiKey: tak_*** location: nl inspectAddr: "0.0.0.0" ``` #### Использование иного пути к файлу Можно явно указывать путь к файлу с помощью флага `--config`: ```shell tuna --config /tmp/tuna.yml http 8080 ``` Или через переменную окружения `TUNA_CONFIG`: ```shell export TUNA_CONFIG=/tmp/tuna.yml tuna http 8080 ``` #### Множественный запуск туннелей В файле может хранится описание для [множественного запуска](https://tuna.am/docs/tunnels/guides/multi-tunnels.md) туннелей, пример: ```yaml --- tunnels: web: tags: [frontend, ui] commandLine: tuna http localhost:5173 --subdomain=web php: tags: [backend, php, api] commandLine: tuna http 8080 --subdomain=api python: tags: [backend, python, api] commandLine: tuna http 9000 --subdomain=new-api postgres: tags: db commandLine: tuna tcp 5432 --port=postgres mysql: tags: db commandLine: tuna tcp 3306 --port=mysql ``` #### Политики трафика В файле может хранится описание правил для [политик трафика](https://tuna.am/docs/traffic-policy.md), пример: ```yaml --- rules: - name: robots.txt expressions: - hasPrefix(req.URL.Path, "/robots.txt") actions: - name: шаг 1 type: custom_response config: statusCode: 200 content: | User-agent: * Disallow: / headers: content-type: "text/plain" - name: Мок для банков expressions: - hasPrefix(req.URL.Path, "/banks") actions: - type: custom_response config: statusCode: 403 content: | Запрещено headers: content-type: "text/plain; charset=utf-8" - expressions: - hasPrefix(req.URL.Path, "/v1") actions: - type: reverse_proxy config: url: "http://127.0.0.1:7070" ``` #### Проверка корректности синтаксиса ```shell tuna config check ``` --- ### Очерёдность конфигурации Настройка может осуществляться через конфигурационный файл, переменные окружения и аргументы командной. Приоритет при чтении конфигурации: 1. [Конфигурационный файл](https://tuna.am/docs/guides/config-file.md) 2. [Переменные окружения](https://tuna.am/docs/guides/environment-variables.md) 3. Аргументы командной строки --- ### Работа tuna в корпоративной сети Чаще всего с этим не должно быть проблем, так как корпоративные фаерволы разрешают исходящие соединения, однако могут быть ограничения по портам подключения, которые могут помешать работе tuna. Если у вас появляются ошибки при создании туннеля, выполните команду `tuna diagnose` для получения диагностической информации, отчет поможет лучше понять, где именно проблема. ```shell Please wait, testing connectivity... TLS connectivity: Google.com: ok [1.46189625s] Yandex.ru: ok [1.246520375s] tuna API: ok [1.484186875s] tuna NL location: ok [739.467083ms] tuna RU location: ok [597.777167ms] TCP connectivity: tuna NL location: ok [75.757708ms] tuna RU location: ok [34.079541ms] ``` Как правило, tuna использует порт `443` для подключения к нодам при создании туннеля. Если проверки `TCP connectivity` не проходят, обратитесь к своим сетевым администраторам для решения проблемы. --- ### Переменные окружения Список поддерживаемых [переменных среды](https://ru.wikipedia.org/wiki/%D0%9F%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F_%D1%81%D1%80%D0%B5%D0%B4%D1%8B) клиентом **tuna**. #### Глобальные | Имя | Описание | | --------------- | ---------------------------------------------------------------------------------------------------------------------------- | | TUNA_CONFIG | Путь к [конфигурационному файлу](https://tuna.am/docs/guides/config-file.md) | | TUNA_LOG | Путь к файлу журнала: /file/to/file.log, stdout, stderr" (умолчание "stdout") | | TUNA_LOG_LEVEL | Уровень логирования: debug, info, warn, error, fatal (умолчание "info") | | TUNA_LOG_FORMAT | Формат логирования: text, json (умолчание "text") | | TUNA_TUI | Включить (`1`) или выключить (`0`) [интерфейс в терминале](https://tuna.am/docs/tunnels/tui.md) | | TUNA_NO_PROMPT | Не задавать вопросов, например подтверждения удаления: команда без `--yes` завершится ошибкой, как при запуске без терминала | #### Общие | Имя | Описание | | ------------- | -------------------------------------------------------------------------------------- | | TUNA_PORT | Порт или адрес назначения (например, `8080` или `10.0.0.10:5432`) | | TUNA_TOKEN | Токен для создания туннеля | | TUNA_LOCATION | [Регион](https://tuna.am/docs/tunnels/guides/locations.md) подключения (`nl` или `ru`) | | TUNA_API_KEY | [API-ключ](https://tuna.am/docs/guides/api.md) | #### Для HTTP туннелей | Имя | Описание | | -------------------------- | ---------------------------------------------------------------------------------------------------------------------- | | TUNA_BASIC_AUTH | Добавить базовую аутентификацию (например, user:pass) | | TUNA_CIDR_ALLOW | Отклонять соединения, которые не соответствуют заданным CIDR | | TUNA_CIDR_DENY | Отклонить соединения, соответствующие заданным CIDR | | TUNA_CORS | Включить добавление CORS заголовков и автоматическую обработку OPTIONS запросов | | TUNA_DOMAIN | Зарезервированный домен | | TUNA_FILE_SERVER | Путь к каталогу для публикации файлов по http | | TUNA_FILE_SERVER_SPA | Путь к каталогу для публикации SPA сайта | | TUNA_HTTPS_REDIRECT | Перенаправлять запросы на https (`true` или `false`) | | TUNA_INSPECT | Включить или отключить [инспектор запросов](https://tuna.am/docs/tunnels/http/inspect.md) (`true` или `false`) | | TUNA_INSPECT_ADDR | Задать адрес для инспектора запросов | | TUNA_KEY_AUTH | Добавить ключ аутентификации, переданный в заголовке `X-Token` | | TUNA_POLICY_FILE | Путь файлу конфигурации с правилами (по умолчанию `.tuna.yml`) | | TUNA_POLICY_URL | [Ссылка](https://tuna.am/docs/traffic-policy.md#policy-url) на файл с правилами в формате YAML или JSON (только https) | | TUNA_QR_CODE | Сгенерировать и показать QR-код | | TUNA_RATE_LIMIT | Ограничьте количество запросов к вашему приложению (например, 20 для 20 запросов/сек) | | TUNA_REQUEST_HEADER | Добавление заголовков для передачи локальному сервису (например, `host:tuna.am`) | | TUNA_RESPONSE_HEADER | Добавление заголовков для передачи клиенту (например, `env:test`) | | TUNA_SUBDOMAIN | Зарезервированный поддомен | | TUNA_TLS_SKIP_VERIFY | Игнорировать проверку TLS | | TUNA_VERIFY_WEBHOOK | Проверить, подписаны ли вебхуки этим поставщиком (например, gitlab) | | TUNA_VERIFY_WEBHOOK_SECRET | Секрет, используемый провайдером для подписи вебхуков, если таковые имеются | | TUNA_WEBDAV | Путь к каталогу для публикации файлов по WebDAV | #### Для TCP туннелей | Имя | Описание | | ------------------- | ------------------------------------------------------------ | | TUNA_TCP_PORT | Номер зарезервированного порта или алиас | | TUNA_QR_CODE | Сгенерировать и показать QR-код | | TUNA_CIDR_ALLOW | Отклонять соединения, которые не соответствуют заданным CIDR | | TUNA_CIDR_DENY | Отклонить соединения, соответствующие заданным CIDR | | TUNA_PROXY_PROTOCOL | Включить PROXY Protocol (`1` или `2`) | #### Для SSH туннелей | Имя | Описание | | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | TUNA_TCP_PORT | Номер зарезервированного порта или алиас | | TUNA_SSH_AUTH | Задать [статические username/password](https://tuna.am/docs/tunnels/ssh.md#%D1%81%D1%82%D0%B0%D1%82%D0%B8%D1%87%D0%BD%D1%8B%D0%B9-%D0%BF%D0%B0%D1%80%D0%BE%D0%BB%D1%8C) | | TUNA_SSH_PASSWORD_AUTH | Включить или выключить аутентификацию с помощью логин/пароль | | TUNA_RECORD_SESSION | [Запись SSH сессий](https://tuna.am/docs/tunnels/ssh.md#%D0%B7%D0%B0%D0%BF%D0%B8%D1%81%D1%8C-ssh-%D1%81%D0%B5%D1%81%D1%81%D0%B8%D0%B9) | | TUNA_CIDR_ALLOW | Отклонять соединения, которые не соответствуют заданным CIDR | | TUNA_CIDR_DENY | Отклонить соединения, соответствующие заданным CIDR | #### Для TRIGGER туннелей | Имя | Описание | | -------------------------------- | --------------------------------------------------------------------------- | | TUNA_TCP_PORT | Номер зарезервированного порта или алиас | | TUNA_TRIGGER_SMTP_USERNAME | Имя пользователя для подключения по SMTP | | TUNA_TRIGGER_SMTP_PASSWORD | Пароль пользователя для подключения по SMTP | | TUNA_TRIGGER_SMTP_LISTEN_ADDRESS | Локальный адрес SMTP-сервера триггера (умолчание "127.0.0.1:1025") | | TUNA_TRIGGER_WEBHOOK_SECRET | Секрет, который будет проверяться со значением заголовка `X-Webhook-Secret` | #### Для Postgres/Redis туннелей | Имя | Описание | | ----------------- | -------------------------------------------------------------------------------------------------------------- | | TUNA_TCP_PORT | Номер зарезервированного порта или алиас | | TUNA_QR_CODE | Сгенерировать и показать QR-код | | TUNA_INSPECT | Включить или отключить [инспектор запросов](https://tuna.am/docs/tunnels/http/inspect.md) (`true` или `false`) | | TUNA_INSPECT_ADDR | Задать адрес для инспектора запросов | | TUNA_CIDR_ALLOW | Отклонять соединения, которые не соответствуют заданным CIDR | | TUNA_CIDR_DENY | Отклонить соединения, соответствующие заданным CIDR | #### Для Kubernetes туннелей | Имя | Описание | | ------------------------- | ------------------------------------------------------------------------ | | KUBECONFIG | Путь к kubeconfig (один файл) | | TUNA_K8S_CONTEXT | Контекст kubeconfig (по умолчанию `current-context`) | | TUNA_K8S_SERVICE_ACCOUNT | Сервисный аккаунт для гостя (`[namespace/]name`) | | TUNA_K8S_NAMESPACE | Ограничить доступ одним namespace | | TUNA_K8S_PRESET | Пресет ограничений: `view`, `observer`, `debug`, `open` | | TUNA_K8S_READ_ONLY | Разрешить только чтение | | TUNA_K8S_NO_DELETE | Запретить удаление ресурсов | | TUNA_K8S_DENY_RESOURCE | Запрещённые ресурсы (например, `secrets,configmaps`) | | TUNA_K8S_DENY_SUBRESOURCE | Запрещённые субресурсы (`exec`, `attach`, `portforward`, `log`, `proxy`) | | TUNA_K8S_TTL | Срок действия доступа (например, `4h`, `0` — бессрочно) | | TUNA_K8S_DOWNLOAD_LIMIT | Сколько раз можно скачать kubeconfig (`0` — без лимита) | #### Для публикации 1С Работают также переменные [HTTP туннелей](#%D0%B4%D0%BB%D1%8F-http-%D1%82%D1%83%D0%BD%D0%BD%D0%B5%D0%BB%D0%B5%D0%B9): доступ, адрес, инспектор. | Имя | Описание | | ------------------- | ------------------------------------------------------------------------------ | | TUNA_1C_HOME | Каталог установки 1С:Предприятие | | TUNA_1C_PLATFORM | Разрядность платформы 1С: `x64` или `x86` | | TUNA_1C_PORT | Локальный порт веб-сервера (по умолчанию случайный свободный) | | TUNA_1C_PUBLISH_DIR | Каталог с файлами [публикации](https://tuna.am/docs/tunnels/1c.md#publish-dir) | #### Создание и управление сервисами | Имя | Описание | | ----------------------------- | ----------------------------------------------------------- | | TUNA_SERVICE_NAME | Имя сервиса | | TUNA_SERVICE_INSTALL_USER | Пользователь от под имени которого будет запускаться сервис | | TUNA_SERVICE_INSTALL_PASSWORD | Пароль при указании иного пользователя (только Windows) | #### Множественный запуск туннелей | Имя | Описание | | ----------------------- | -------------------------------------------------------------- | | TUNA_START_TUNNELS_FILE | Путь файлу конфигурации с туннелями (по умолчанию `.tuna.yml`) | | TUNA_START | Имя туннеля для запуска | | TUNA_START_TAGS | Теги туннелей для запуска | | TUNA_START_ALL | Запуск всех туннелей | #### Обнаружение портов | Имя | Описание | | ------------------- | -------------------------------------------------- | | TUNA_DETECT_SECONDS | Промежуток времени выделенный на обнаружение порта | #### Секреты | Имя | Описание | | -------------------------------- | ---------------------------------------------------------------------------------------------------------- | | TUNA_SECRETS_SCOPE | Конфигурация каталога для области действия (по умолчанию `.`) | | TUNA_SECRETS_PROJECT | Алиас проекта | | TUNA_SECRETS_CONFIG | Алиас конфигурации | | TUNA_SECRETS_FORMAT | Формат вывода (json, yaml, env, env-no-quotes или docker) (по умолчанию `json`) | | TUNA_SECRETS_NO_FILE | Печатать на stdout (по умолчанию `false`) | | TUNA_SECRETS_WATCH | Автоматически перезапускать процесс при изменении секретов (по умолчанию `false`) | | TUNA_SECRETS_NO_INTERACTIVE | Не спрашивать проект и конфигурацию в `tuna secrets setup`, а завершаться ошибкой (по умолчанию `false`) | | TUNA_SECRETS_FALLBACK_PASSPHRASE | Парольная фраза для файла офлайн-режима `tuna secrets run` | | TUNA_SECRETS_MOUNT_PATH | Путь к секретам при `tuna secrets run --mount`. Переменную устанавливает сам клиент для дочернего процесса | #### Работа с direnv [direnv](https://direnv.net) — это менеджер переменных среды для терминала, он позволяет автоматически загружать и выгружать переменные среды в зависимости от текущего каталога – это позволяет иметь переменные среды, специфичные для каждого проекта, над которым вы работаете. Перед каждым приглашением direnv проверяет наличие файла `.envrc` в текущем и родительском каталогах и если файл существует, он загружается в подшаблон bash, и все экспортированные переменные затем захватываются direnv, а затем становятся доступными для оболочки. Перед началом использования direnv, его необходимо установить, инструкция по установке доступна в [официальной документации](https://direnv.net/#getting-started), после этого в каталоге проекта нужно создать файл `.envrc` с настройками tuna, например: ```shell export TUNA_PORT=8080 export TUNA_SUBDOMAIN=my-project ``` При переходе в каталог проекта и вызове команды `tuna http` у вас будет создаваться туннель с учетом настроек из файла `.envrc`: ```shell % tuna http INFO[13:00:00] Welcome to Tuna INFO[13:00:00] Account: test (Paid till 05.04.2024) INFO[13:00:00] Web Interface: http://127.0.0.1:4040 INFO[13:00:00] Forwarding https://my-project.ru.tuna.am -> 127.0.0.1:8080 ``` --- ### Установка Мы стараемся сделать так, чтобы работать с Tuna было комфортно всем, и опытным и новичкам, по этому поддерживаем 2 клиента: 1. Консольная утилита **tuna-cli** - имеет полный набор функций и интеграций с платформой. Швейцарский нож в руках опытного разработчика. 2. Приложение для рабочего стола **Tuna Desktop** - базовый функционал для создания туннелей. Максимально простая установка, настройка и запуск. Справится даже ваша бухгалтерка. [![Изображение консоли c запущенной tuna cli](/docs/img/getting-started/cli.png "Я хардкорный синьор, emacs - мой дом")](https://tuna.am/docs/guides/install/install-cli.md)[![Изображение c запущенной Tuna Desktop](/docs/img/getting-started/desktop.png "Я вайбкодер, клик-клик")](https://tuna.am/docs/guides/install/install-desktop.md) 🖌 Безопасность и проверка подлинности Все сборки, файлы подписей, публичные ключи доступны по ссылке - Мы делаем упор на безопасности, поэтому рекомендуем проверять, что вы используете именно наши официальные сборки клиентов. Начиная с версии tuna-cli **0.27.4** и Tuna Desktop **v0.1.11** все артефакты сборки, архивы, пакеты, инсталляторы, checksum файлы и docker образы подписываются нашей электронной подписью. * Публичный **GPG** ключ для верификации распространяется по ссылке - * Публичный [Cosign](https://docs.sigstore.dev/) ключ для верификации Docker images - Все артефакты tuna cli пописаны **GPG** ключом, docker образы помощью **cosign**. Артефакты Tuna Desktop для Linux пописаны также **GPG** ключом, для Windows и macOS помощью **cosign** и содержат `.bundle` файл для удобства проверки. warning Мы настоятельно рекомендуем проверять, что вы используете оригинальные артефакты сборки и именно наши репозитории. --- ### tuna-cli #### Установка **Windows** ##### Установка с помощью winget Откройте PowerShell и выполните команду: ```shell winget install --id yuccastream.tuna ; powershell ``` ##### Установка MSI пакета Скачайте последнюю версию tuna по [ссылке](https://releases.tuna.am/tuna/latest/tuna_x64.msi) и запустите установку дважды кликнув на файл. [![Установщик для Windows x64 (требует прав администратора)](/docs/img/getting-started/badge-msi-installer.svg "Установщик для Windows x64 (требует прав администратора)")](https://releases.tuna.am/tuna/latest/tuna_x64.msi) 🖌 Проверка подлинности Начиная с версии **0.27.4** все артефакты подписаны при помощи [cosign](https://docs.sigstore.dev/). Для проверки оригинальности архива [установите клиент cosign](https://docs.sigstore.dev/cosign/system_config/installation/), скачайте публичный ключ и выполните проверку. ```shell winget install GnuPG.Gpg4win Invoke-WebRequest -Uri "https://releases.tuna.am/tuna/latest/tuna_x64.msi" -OutFile "tuna_x64.msi" Invoke-WebRequest -Uri "https://releases.tuna.am/tuna/latest/tuna_x64.msi.sig" -OutFile "tuna_x64.msi.sig" Invoke-WebRequest -Uri "https://releases.tuna.am/tuna.asc" -OutFile "tuna.asc" gpg --import tuna.asc gpg --verify tuna_x64.msi.sig tuna_x64.msi ``` ##### Установка вручную Откройте PowerShell и выполните команды по очереди: **AMD64** ```powershell winget install GnuPG.Gpg4win cd $env:TEMP Invoke-WebRequest -Uri "https://releases.tuna.am/tuna/latest/tuna_windows_amd64.zip" -OutFile "$env:TEMP\tuna_windows_amd64.zip" Invoke-WebRequest -Uri "https://releases.tuna.am/tuna/latest/tuna_windows_amd64.zip.sig" -OutFile "$env:TEMP\tuna_windows_amd64.zip.sig" Invoke-WebRequest -Uri "https://releases.tuna.am/tuna.asc" -OutFile "$env:TEMP\tuna.asc" gpg --import tuna.asc gpg --verify tuna_windows_amd64.zip.sig tuna_windows_amd64.zip Expand-Archive -Path "$env:TEMP\tuna_windows_amd64.zip" -DestinationPath "$env:TEMP\tuna" -Force Copy-Item -Path "$env:TEMP\tuna\tuna.exe" -Destination "$env:USERPROFILE\AppData\Local\Microsoft\WindowsApps" -Force ``` **ARM64** ```powershell winget install GnuPG.Gpg4win cd $env:TEMP Invoke-WebRequest -Uri "https://releases.tuna.am/tuna/latest/tuna_windows_arm64.zip" -OutFile "$env:TEMP\tuna_windows_arm64.zip" Invoke-WebRequest -Uri "https://releases.tuna.am/tuna/latest/tuna_windows_arm64.zip.sig" -OutFile "$env:TEMP\tuna_windows_arm64.zip.sig" Invoke-WebRequest -Uri "https://releases.tuna.am/tuna.asc" -OutFile "$env:TEMP\tuna.asc" gpg --import tuna.asc gpg --verify tuna_windows_arm64.zip.sig tuna_windows_arm64.zip Expand-Archive -Path "$env:TEMP\tuna_windows_arm64.zip" -DestinationPath "$env:TEMP\tuna" -Force Copy-Item -Path "$env:TEMP\tuna\tuna.exe" -Destination "$env:USERPROFILE\AppData\Local\Microsoft\WindowsApps" -Force ``` ##### Проверка работы Чтобы убедиться, что установка прошла корректно, выполните команду: ```bash tuna help ``` **macOS** ##### Установка с помощью brew Для установки brew, следуйте [инструкции](https://brew.sh/), затем выполните команду в терминале: ```bash brew install yuccastream/tap/tuna ``` Если ранее вы установили **tuna** *вручную* или с помощью *скрипта*, удалите предыдущую версию: ```bash sudo rm -f /usr/local/bin/tuna ``` ##### Установка с помощью скрипта Выполните команду в терминале: **curl** ```shell sh -c "$(curl -sSLf https://releases.tuna.am/tuna/get.sh)" ``` **wget** ```shell sh -c "$(wget -qO- https://releases.tuna.am/tuna/get.sh)" ``` ##### Установка вручную Откройте терминал, выполните следующие команды: **ARM64** ```shell cd $(mktemp -d) curl -sfSL "https://releases.tuna.am/tuna/latest/tuna_darwin_arm64.tar.gz" | tar -f - -xz chmod +x tuna sudo mv -f tuna /usr/local/bin/tuna ``` **AMD64** ```shell cd $(mktemp -d) curl -sfSL "https://releases.tuna.am/tuna/latest/tuna_darwin_amd64.tar.gz" | tar -f - -xz chmod +x tuna sudo mv -f tuna /usr/local/bin/tuna ``` *** к сведению Бинарный файл [подписан и заверен](https://developer.apple.com/documentation/security/notarizing-macos-software-before-distribution) в Apple на имя: `Developer ID Application: Lev Aminov (FW65BD237L)` Проверить локально можно с помощью команды: ```sh codesign -dv --verbose=4 $(which tuna) ``` ##### Проверка работы Чтобы убедиться, что установка прошла корректно, выполните команду: ```bash tuna help ``` **Linux** Поддерживаемые архитектуры | Архитектура | Описание | | ------------------- | ------------------------------------------------------------------------------------ | | **AMD64** (x86_64) | Стандартные ПК и серверы | | **ARM64** (aarch64) | Raspberry Pi 3/4/5, Apple Silicon (в Linux VM), серверы на ARM | | **ARMv7** | Raspberry Pi 2, большинство 32-битных ARM SBC | | **ARMv6** | Raspberry Pi 1, Pi Zero / Zero W | | **ARMv5** | Старые встраиваемые устройства | | **MIPS** | Роутеры и встраиваемые устройства (big-endian) | | **MIPS LE** | Роутеры и встраиваемые устройства (little-endian) | | **RISC-V 64** | RISC-V платы (например, [NanoKVM](https://tuna.am/docs/tunnels/examples/nanokvm.md)) | ##### Установка с помощью скрипта Выполните команду в терминале: **curl** ```shell sh -c "$(curl -sSLf https://releases.tuna.am/tuna/get.sh)" ``` **wget** ```shell sh -c "$(wget -qO- https://releases.tuna.am/tuna/get.sh)" ``` подсказка Скрипт определит дистрибутив, подключит репозиторий и установит пакет, если это возможно. Иначе скачает бинарный файл и установит в исполняемый PATH. ##### Установка вручную **Debian/Ubuntu** Debian и основанные на нём дистрибутивы (Ubuntu, Mint и другие), выполните в терминале следующие команды: ```shell sudo apt update sudo apt install -y ca-certificates curl gnupg curl -fsSL https://code.tuna.am/api/packages/tuna/debian/repository.key | sudo gpg --dearmor --batch --yes -o /usr/share/keyrings/tuna-forgejo.gpg echo 'deb [signed-by=/usr/share/keyrings/tuna-forgejo.gpg] https://code.tuna.am/api/packages/tuna/debian stable main' | sudo tee /etc/apt/sources.list.d/tuna-forgejo.list sudo apt update sudo apt install -y tuna-cli ``` **SUSE/OpenSUSE** SUSE и OpenSUSE, выполните в терминале следующие команды: ```shell sudo zypper addrepo --repo https://code.tuna.am/api/packages/tuna/rpm/stable.repo sudo zypper install -y tuna-cli ``` **RHEL/Fedora** RHEL и основанные на нём дистрибутивы (CentOS, Rocky Linux, AlmaLinux, а также Fedora), выполните в терминале следующие команды: ```shell sudo curl -fsSL https://code.tuna.am/api/packages/tuna/rpm/stable.repo -o /etc/yum.repos.d/tuna-forgejo.repo sudo dnf install -y tuna-cli ``` **ALT Linux** [ALT Linux](https://www.basealt.ru/alt-workstation-k?utm_source=tuna.am&utm_medium=organic&utm_campaign=docs), выполните в терминале следующие команды: ```shell sudo apt-get update sudo apt-get install -y curl apt-repo sudo rpm --import https://releases.tuna.am/tuna.asc sudo apt-repo add rpm https://code.tuna.am/api/packages/tuna/alt/stable.repo $(arch) classic sudo apt-repo add rpm https://code.tuna.am/api/packages/tuna/alt/stable.repo noarch classic sudo apt-get update sudo apt-get install -y tuna-cli ``` **Arch Linux** Arch Linux, выполните в терминале следующие команды: ```shell yay -Syu --noconfirm tuna.am-bin ``` **Linux** Для установки в любых Linux-системах (NixOS, Alpine Linux и другие), выполните в терминале следующие команды: **AMD64** ```shell cd $(mktemp -d) curl -sfSL -O "https://releases.tuna.am/tuna/latest/tuna_linux_amd64.tar.gz" -O "https://releases.tuna.am/tuna/latest/tuna_linux_amd64.tar.gz.sig" curl -sfSL -O https://releases.tuna.am/tuna.asc gpg --import tuna.asc gpg --verify tuna_linux_amd64.tar.gz.sig tuna_linux_amd64.tar.gz tar -xzf tuna_linux_amd64.tar.gz chmod +x tuna sudo mv -f tuna /usr/local/bin/tuna ``` **ARM64** ```shell cd $(mktemp -d) curl -sfSL -O "https://releases.tuna.am/tuna/latest/tuna_linux_arm64.tar.gz" -O "https://releases.tuna.am/tuna/latest/tuna_linux_arm64.tar.gz.sig" curl -sfSL -O https://releases.tuna.am/tuna.asc gpg --import tuna.asc gpg --verify tuna_linux_arm64.tar.gz.sig tuna_linux_arm64.tar.gz tar -xzf tuna_linux_arm64.tar.gz chmod +x tuna sudo mv -f tuna /usr/local/bin/tuna ``` **ARMv7** ```shell cd $(mktemp -d) curl -sfSL -O "https://releases.tuna.am/tuna/latest/tuna_linux_armv7.tar.gz" -O "https://releases.tuna.am/tuna/latest/tuna_linux_armv7.tar.gz.sig" curl -sfSL -O https://releases.tuna.am/tuna.asc gpg --import tuna.asc gpg --verify tuna_linux_armv7.tar.gz.sig tuna_linux_armv7.tar.gz tar -xzf tuna_linux_armv7.tar.gz chmod +x tuna sudo mv -f tuna /usr/local/bin/tuna ``` **ARMv6** ```shell cd $(mktemp -d) curl -sfSL -O "https://releases.tuna.am/tuna/latest/tuna_linux_armv6.tar.gz" -O "https://releases.tuna.am/tuna/latest/tuna_linux_armv6.tar.gz.sig" curl -sfSL -O https://releases.tuna.am/tuna.asc gpg --import tuna.asc gpg --verify tuna_linux_armv6.tar.gz.sig tuna_linux_armv6.tar.gz tar -xzf tuna_linux_armv6.tar.gz chmod +x tuna sudo mv -f tuna /usr/local/bin/tuna ``` **ARMv5** ```shell cd $(mktemp -d) curl -sfSL -O "https://releases.tuna.am/tuna/latest/tuna_linux_armv5.tar.gz" -O "https://releases.tuna.am/tuna/latest/tuna_linux_armv5.tar.gz.sig" curl -sfSL -O https://releases.tuna.am/tuna.asc gpg --import tuna.asc gpg --verify tuna_linux_armv5.tar.gz.sig tuna_linux_armv5.tar.gz tar -xzf tuna_linux_armv5.tar.gz chmod +x tuna sudo mv -f tuna /usr/local/bin/tuna ``` **MIPS** ```shell cd $(mktemp -d) curl -sfSL -O "https://releases.tuna.am/tuna/latest/tuna_linux_mips.tar.gz" -O "https://releases.tuna.am/tuna/latest/tuna_linux_mips.tar.gz.sig" curl -sfSL -O https://releases.tuna.am/tuna.asc gpg --import tuna.asc gpg --verify tuna_linux_mips.tar.gz.sig tuna_linux_mips.tar.gz tar -xzf tuna_linux_mips.tar.gz chmod +x tuna sudo mv -f tuna /usr/local/bin/tuna ``` **MIPS LE** ```shell cd $(mktemp -d) curl -sfSL -O "https://releases.tuna.am/tuna/latest/tuna_linux_mipsle.tar.gz" -O "https://releases.tuna.am/tuna/latest/tuna_linux_mipsle.tar.gz.sig" curl -sfSL -O https://releases.tuna.am/tuna.asc gpg --import tuna.asc gpg --verify tuna_linux_mipsle.tar.gz.sig tuna_linux_mipsle.tar.gz tar -xzf tuna_linux_mipsle.tar.gz chmod +x tuna sudo mv -f tuna /usr/local/bin/tuna ``` **RISC-V 64** ```shell cd $(mktemp -d) curl -sfSL -O "https://releases.tuna.am/tuna/latest/tuna_linux_riscv64.tar.gz" -O "https://releases.tuna.am/tuna/latest/tuna_linux_riscv64.tar.gz.sig" curl -sfSL -O https://releases.tuna.am/tuna.asc gpg --import tuna.asc gpg --verify tuna_linux_riscv64.tar.gz.sig tuna_linux_riscv64.tar.gz tar -xzf tuna_linux_riscv64.tar.gz chmod +x tuna sudo mv -f tuna /usr/local/bin/tuna ``` ##### Проверка работы Чтобы убедиться, что установка прошла корректно, выполните команду: ```bash tuna help ``` **FreeBSD** ##### Установка с помощью скрипта Выполните команду в терминале: **curl** ```shell sh -c "$(curl -sSLf https://releases.tuna.am/tuna/get.sh)" ``` **wget** ```shell sh -c "$(wget -qO- https://releases.tuna.am/tuna/get.sh)" ``` ##### Установка вручную **AMD64** ```shell cd $(mktemp -d) curl -sfSL -O "https://releases.tuna.am/tuna/latest/tuna_freebsd_amd64.tar.gz" -O "https://releases.tuna.am/tuna/latest/tuna_freebsd_amd64.tar.gz.sig" curl -sfSL -O https://releases.tuna.am/tuna.asc gpg --import tuna.asc gpg --verify tuna_freebsd_amd64.tar.gz.sig tuna_freebsd_amd64.tar.gz tar -xzf tuna_freebsd_amd64.tar.gz chmod +x tuna sudo mv -f tuna /usr/local/bin/tuna ``` **ARM64** ```shell cd $(mktemp -d) curl -sfSL -O "https://releases.tuna.am/tuna/latest/tuna_freebsd_arm64.tar.gz" -O "https://releases.tuna.am/tuna/latest/tuna_freebsd_arm64.tar.gz.sig" curl -sfSL -O https://releases.tuna.am/tuna.asc gpg --import tuna.asc gpg --verify tuna_freebsd_arm64.tar.gz.sig tuna_freebsd_arm64.tar.gz tar -xzf tuna_freebsd_arm64.tar.gz chmod +x tuna sudo mv -f tuna /usr/local/bin/tuna ``` **ARMv7** ```shell cd $(mktemp -d) curl -sfSL -O "https://releases.tuna.am/tuna/latest/tuna_freebsd_armv7.tar.gz" -O "https://releases.tuna.am/tuna/latest/tuna_freebsd_armv7.tar.gz.sig" curl -sfSL -O https://releases.tuna.am/tuna.asc gpg --import tuna.asc gpg --verify tuna_freebsd_armv7.tar.gz.sig tuna_freebsd_armv7.tar.gz tar -xzf tuna_freebsd_armv7.tar.gz chmod +x tuna sudo mv -f tuna /usr/local/bin/tuna ``` ##### Проверка работы Чтобы убедиться, что установка прошла корректно, выполните команду: ```bash tuna help ``` **Docker** Чтобы получить последнюю версию Docker-образа, выполните команду: ```shell docker pull yuccastream/tuna:latest ``` 🖌 Проверка подлинности Начиная с версии **0.27.4** все образы подписаны при помощи [cosign](https://docs.sigstore.dev/). Для проверки оригинальности образа [установите клиент cosign](https://docs.sigstore.dev/cosign/system_config/installation/), скачайте публичный ключ и выполните проверку. ```shell curl -sSLfO https://releases.tuna.am/tuna-cosign.asc cosign verify --key tuna-cosign.asc docker.io/yuccastream/tuna:0.27.4 ``` ##### Пример Docker Compose сервиса ```yaml --- services: whoami: image: traefik/whoami restart: always tuna: image: yuccastream/tuna:latest command: http whoami:80 --inspect=false restart: always depends_on: - whoami environment: - TUNA_TOKEN=<ваш_токен> ``` Пример с использованием в [Kubernetes](https://tuna.am/docs/tunnels/examples/kubernetes.md). *** #### Авторизация Для работы клиента необходим Токен, зарегистрируйтесь [по ссылке](https://my.tuna.am/), и авторизуйте приложение. Токен будет сохранён в [конфиг файл](https://tuna.am/docs/guides/config-file.md), либо можно скопировать на [отдельной странице](https://my.tuna.am/token) и указать вручную. ```bash tuna login ``` Указать токен вручную ```bash tuna config save-token <ТОКЕН> ``` #### Пользуйтесь Все готово, чтобы приступить к работе. Запустите tuna с передачей порта и делитесь ссылкой с коллегами: ```bash tuna http 8080 ``` Постоянный адрес При каждом запуске туннель получает новый адрес. Чтобы адрес не менялся, используйте свой [бесплатный постоянный поддомен](https://tuna.am/docs/tunnels/http.md#free-subdomain): `tuna http 8080 --subdomain=<ваш-поддомен>`. Поддомен привязан к аккаунту и работает только с вашим токеном из шага [Авторизация](#%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F). ##### Что дальше? * Изучите примеры настроек [HTTP туннеля](https://tuna.am/docs/tunnels/http.md) * Нужен доступ к сервису, не использующему HTTP? Узнайте подробнее в разделе по [TCP туннелю](https://tuna.am/docs/tunnels/tcp.md) --- ### Tuna Desktop ![](/docs/img/desktop/main.png) ![](/docs/img/desktop/list.png) Подробный обзор на приложение есть в [блоге](https://tuna.am/blog/tuna-desktop-first.md). #### Установка **Windows** Скачайте и установите полную или портативную версию. [![Установщик для Windows x64 (требует прав администратора)](/docs/img/getting-started/badge-exe-installer.svg "Установщик для Windows x64 (требует прав администратора)")](https://releases.tuna.am/desktop/latest/tuna-desktop_windows-amd64_installer_latest.zip)[![Портативная версия для Windows x64](/docs/img/getting-started/badge-exe-portable.svg "Портативная версия для Windows x64")](https://releases.tuna.am/desktop/latest/tuna-desktop_windows-amd64_portable_latest.zip) 🖌 Проверка подлинности Начиная с версии **v0.1.11** все артефакты подписаны при помощи [cosign](https://docs.sigstore.dev/). Для проверки оригинальности архива [установите клиент cosign](https://docs.sigstore.dev/cosign/system_config/installation/), скачайте публичный ключ и выполните проверку. ```shell winget install sigstore.cosign # installer Invoke-WebRequest -Uri "https://releases.tuna.am/desktop/latest/tuna-desktop_windows-amd64_installer_latest.zip" -OutFile "tuna-desktop_windows-amd64_installer_latest.zip" Invoke-WebRequest -Uri "https://releases.tuna.am/desktop/latest/tuna-desktop_windows-amd64_installer_latest.zip.bundle" -OutFile "tuna-desktop_windows-amd64_installer_latest.zip.bundle" cosign.exe verify-blob --bundle=tuna-desktop_windows-amd64_installer_latest.zip.bundle tuna-desktop_windows-amd64_installer_latest.zip # portable Invoke-WebRequest -Uri "https://releases.tuna.am/desktop/latest/tuna-desktop_windows-amd64_portable_latest.zip" -OutFile "tuna-desktop_windows-amd64_portable_latest.zip" Invoke-WebRequest -Uri "https://releases.tuna.am/desktop/latest/tuna-desktop_windows-amd64_portable_latest.zip.bundle" -OutFile "tuna-desktop_windows-amd64_portable_latest.zip.bundle" cosign.exe verify-blob --bundle=tuna-desktop_windows-amd64_portable_latest.zip.bundle tuna-desktop_windows-amd64_portable_latest.zip ``` **macOS** Скачайте и установите версию для macOS. [![Скачать DMG для macOS](/docs/img/getting-started/badge-dmg.svg "Универсальная версия для всех архитектур")](https://releases.tuna.am/desktop/latest/tuna-desktop_darwin-universal_latest.dmg) 🖌 Проверка подлинности Начиная с версии **v0.1.11** все артефакты подписаны при помощи [cosign](https://docs.sigstore.dev/). Для проверки оригинальности архива [установите клиент cosign](https://docs.sigstore.dev/cosign/system_config/installation/), скачайте публичный ключ и выполните проверку. ```shell brew install cosign curl -sSLf -O https://releases.tuna.am/desktop/latest/tuna-desktop_darwin-universal_latest.dmg.bundle -O https://releases.tuna.am/desktop/latest/tuna-desktop_darwin-universal_latest.dmg cosign verify-blob --bundle=tuna-desktop_darwin-universal_latest.dmg.bundle tuna-desktop_darwin-universal_latest.dmg ``` **Linux** ##### Установка с помощью скрипта Выполните команду в терминале: **curl** ```shell sh -c "$(curl -sSLf https://releases.tuna.am/desktop/get.sh)" ``` **wget** ```shell sh -c "$(wget -qO- https://releases.tuna.am/desktop/get.sh)" ``` подсказка Скрипт определит дистрибутив, подключит репозиторий и установит пакет. ##### Установите из репозитория или скачайте пакет. **Debian/Ubuntu** Debian и основанные на нём дистрибутивы (Ubuntu, Mint и другие), выполните в терминале следующие команды: ```shell sudo apt update sudo apt install -y ca-certificates curl gnupg curl -fsSL https://code.tuna.am/api/packages/tuna/debian/repository.key | sudo gpg --dearmor --batch --yes -o /usr/share/keyrings/tuna-forgejo.gpg echo 'deb [signed-by=/usr/share/keyrings/tuna-forgejo.gpg] https://code.tuna.am/api/packages/tuna/debian stable main' | sudo tee /etc/apt/sources.list.d/tuna-forgejo.list sudo apt update sudo apt install -y tuna-desktop ``` подсказка В репозитории сборка для Debian 12+ / Ubuntu 22.04+ *** [![Скачать DEB x86_64 (для Debian 12+ / Ubuntu 22.04+)](/docs/img/getting-started/badge-deb-amd64.svg "Скачать DEB x86_64 (для Debian 12+ / Ubuntu 22.04+)")](https://releases.tuna.am/desktop/latest/current/tuna-desktop_latest-1_amd64.deb) [![Скачать DEB aarch64 (для Debian 12+ / Ubuntu 22.04+)](/docs/img/getting-started/badge-deb-arm64.svg "Скачать DEB aarch64 (для Debian 12+ / Ubuntu 22.04+)")](https://releases.tuna.am/desktop/latest/current/tuna-desktop_latest-1_arm64.deb) Для старых OS (Debian 11- / Ubuntu 20.04-) В старых версиях в зависимостях `libwebkit2gtk-4.0-37`, в новых уже `libwebkit2gtk-4.1-0`. [![Скачать DEB x86_64 (для Debian 11- / Ubuntu 20.04-)](/docs/img/getting-started/badge-deb-amd64.svg "Скачать DEB x86_64 (для Debian 11- / Ubuntu 20.04-)")](https://releases.tuna.am/desktop/latest/old/tuna-desktop_latest-1_amd64.deb)[![Скачать DEB aarch64 (для Debian 12+ / Ubuntu 22.04+)](/docs/img/getting-started/badge-deb-arm64.svg "Скачать DEB aarch64 (для Debian 12+ / Ubuntu 22.04+)")](https://releases.tuna.am/desktop/latest/old/tuna-desktop_latest-1_arm64.deb) **SUSE/OpenSUSE** SUSE и OpenSUSE, выполните в терминале следующие команды: ```shell sudo zypper addrepo --repo https://code.tuna.am/api/packages/tuna/rpm/stable.repo sudo zypper install -y tuna-desktop ``` подсказка В репозитории сборка для SUSE/Leap 15.5+ и Tumbleweed *** [![Скачать RPM x86_64 (для SUSE 15.5+ / RHEL based 10+ / Fedora / ALT Linux p11+ )](/docs/img/getting-started/badge-rpm-amd64.svg "Скачать RPM x86_64 (для SUSE 15.5+ / RHEL based 10+ / Fedora / ALT Linux p11+)")](https://releases.tuna.am/desktop/latest/current/tuna-desktop-latest-1.x86_64.rpm) [![Скачать RPM aarch64 (для SUSE 15.5+ / RHEL based 10+ / Fedora / ALT Linux p11+ )](/docs/img/getting-started/badge-rpm-arm64.svg "Скачать RPM aarch64 (для SUSE 15.5+ / RHEL based 10+ / Fedora / ALT Linux p11+)")](https://releases.tuna.am/desktop/latest/current/tuna-desktop-latest-1.aarch64.rpm) Для старых OS (SUSE 15.4- / RHEL based 9- / ALT Linux p10- ) В старых версиях в зависимостях `libwebkit2gtk-4.0-37`, в новых уже `libwebkit2gtk-4.1-0`. [![Скачать RPM x86_64 (для SUSE 15.4- / RHEL based 9- / ALT Linux p10-)](/docs/img/getting-started/badge-rpm-amd64.svg "Скачать RPM x86_64 (для SUSE 15.4- / RHEL based 9- / ALT Linux p10-)")](https://releases.tuna.am/desktop/latest/old/tuna-desktop-latest-1.x86_64.rpm)[![Скачать RPM aarch64 (для SUSE 15.4- / RHEL based 9- / ALT Linux p10-)](/docs/img/getting-started/badge-rpm-arm64.svg "Скачать RPM aarch64 (для SUSE 15.4- / RHEL based 9- / ALT Linux p10-)")](https://releases.tuna.am/desktop/latest/old/tuna-desktop-latest-1.aarch64.rpm) **RHEL/Fedora** RHEL и основанные на нём дистрибутивы (CentOS, Rocky Linux, AlmaLinux, а также Fedora), выполните в терминале следующие команды: ```shell sudo curl -fsSL https://code.tuna.am/api/packages/tuna/rpm/stable.repo -o /etc/yum.repos.d/tuna-forgejo.repo sudo dnf install -y tuna-desktop ``` подсказка В репозитории сборка для RHEL/CentOS/AlmaLinux/Rocky Linux 10+ *** [![Скачать RPM x86_64 (для SUSE 15.5+ / RHEL based 10+ / Fedora / ALT Linux p11+ )](/docs/img/getting-started/badge-rpm-amd64.svg "Скачать RPM x86_64 (для SUSE 15.5+ / RHEL based 10+ / Fedora / ALT Linux p11+)")](https://releases.tuna.am/desktop/latest/current/tuna-desktop-latest-1.x86_64.rpm) [![Скачать RPM aarch64 (для SUSE 15.5+ / RHEL based 10+ / Fedora / ALT Linux p11+ )](/docs/img/getting-started/badge-rpm-arm64.svg "Скачать RPM aarch64 (для SUSE 15.5+ / RHEL based 10+ / Fedora / ALT Linux p11+)")](https://releases.tuna.am/desktop/latest/current/tuna-desktop-latest-1.aarch64.rpm) Для старых OS (SUSE 15.4- / RHEL based 9- / ALT Linux p10- ) В старых версиях в зависимостях `libwebkit2gtk-4.0-37`, в новых уже `libwebkit2gtk-4.1-0`. [![Скачать RPM x86_64 (для SUSE 15.4- / RHEL based 9- / ALT Linux p10-)](/docs/img/getting-started/badge-rpm-amd64.svg "Скачать RPM x86_64 (для SUSE 15.4- / RHEL based 9- / ALT Linux p10-)")](https://releases.tuna.am/desktop/latest/old/tuna-desktop-latest-1.x86_64.rpm)[![Скачать RPM aarch64 (для SUSE 15.4- / RHEL based 9- / ALT Linux p10-)](/docs/img/getting-started/badge-rpm-arm64.svg "Скачать RPM aarch64 (для SUSE 15.4- / RHEL based 9- / ALT Linux p10-)")](https://releases.tuna.am/desktop/latest/old/tuna-desktop-latest-1.aarch64.rpm) **ALT Linux** [ALT Linux](https://www.basealt.ru/alt-workstation-k?utm_source=tuna.am&utm_medium=organic&utm_campaign=docs), выполните в терминале следующие команды: ```shell sudo apt-get update sudo apt-get install -y curl apt-repo sudo rpm --import https://releases.tuna.am/tuna.asc sudo apt-repo add rpm https://code.tuna.am/api/packages/tuna/alt/stable.repo $(arch) classic sudo apt-get update sudo apt-get install tuna-desktop ``` подсказка В репозитории сборка для ALT Linux p11+ и Sisyphus Репозиторий для ALT Linux p10- В старых версиях в зависимостях `libwebkit2gtk-4.0-37`, в новых уже `libwebkit2gtk-4.1-0`. ```shell sudo apt-get update sudo apt-get install -y curl apt-repo sudo rpm --import https://releases.tuna.am/tuna.asc sudo apt-repo add rpm https://code.tuna.am/api/packages/tuna/alt/old.repo $(arch) classic sudo apt-get update sudo apt-get install tuna-desktop ``` *** [![Скачать RPM x86_64 (для SUSE 15.5+ / RHEL based 10+ / Fedora / ALT Linux p11+ )](/docs/img/getting-started/badge-rpm-amd64.svg "Скачать RPM x86_64 (для SUSE 15.5+ / RHEL based 10+ / Fedora / ALT Linux p11+)")](https://releases.tuna.am/desktop/latest/current/tuna-desktop-latest-1.x86_64.rpm) [![Скачать RPM aarch64 (для SUSE 15.5+ / RHEL based 10+ / Fedora / ALT Linux p11+ )](/docs/img/getting-started/badge-rpm-arm64.svg "Скачать RPM aarch64 (для SUSE 15.5+ / RHEL based 10+ / Fedora / ALT Linux p11+)")](https://releases.tuna.am/desktop/latest/current/tuna-desktop-latest-1.aarch64.rpm) Для старых OS (SUSE 15.4- / RHEL based 9- / ALT Linux p10- ) В старых версиях в зависимостях `libwebkit2gtk-4.0-37`, в новых уже `libwebkit2gtk-4.1-0`. [![Скачать RPM x86_64 (для SUSE 15.4- / RHEL based 9- / ALT Linux p10-)](/docs/img/getting-started/badge-rpm-amd64.svg "Скачать RPM x86_64 (для SUSE 15.4- / RHEL based 9- / ALT Linux p10-)")](https://releases.tuna.am/desktop/latest/old/tuna-desktop-latest-1.x86_64.rpm)[![Скачать RPM aarch64 (для SUSE 15.4- / RHEL based 9- / ALT Linux p10-)](/docs/img/getting-started/badge-rpm-arm64.svg "Скачать RPM aarch64 (для SUSE 15.4- / RHEL based 9- / ALT Linux p10-)")](https://releases.tuna.am/desktop/latest/old/tuna-desktop-latest-1.aarch64.rpm) **Arch Linux** Arch Linux, выполните в терминале следующие команды: ```shell ( ARCH=$(uname -m) URL="https://releases.tuna.am" cd $(mktemp -d) curl -sSLfO "${URL}/tuna.asc" curl -sSLfO "${URL}/desktop/latest/tuna-desktop_latest_checksums_linux-pkgs.txt" curl -sSLfO "${URL}/desktop/latest/current/tuna-desktop-latest-1-${ARCH}.pkg.tar.zst" curl -sSLf "${URL}/desktop/latest/current/tuna-desktop-latest-1-${ARCH}.pkg.tar.zst.sig" -o tuna-desktop_latest.sig sha256sum -c --ignore-missing tuna-desktop_latest_checksums_linux-pkgs.txt gpg --batch --import tuna.asc gpg --batch --verify tuna-desktop_latest.sig tuna-desktop-latest-1-${ARCH}.pkg.tar.zst pacman -Sy pacman -U tuna-desktop-latest-1-${ARCH}.pkg.tar.zst ) ``` *** [![Скачать PKG x86_64 (для Arch Linux)](/docs/img/getting-started/badge-pkg-amd64.svg "Скачать pkg x86_64 (для Arch Linux)")](https://releases.tuna.am/desktop/latest/current/tuna-desktop-latest-1-x86_64.pkg.tar.zst) [![Скачать pkg aarch64 (для Arch Linux)](/docs/img/getting-started/badge-pkg-arm64.svg "Скачать pkg aarch64 (для Arch Linux)")](https://releases.tuna.am/desktop/latest/current/tuna-desktop-latest-1-aarch64.pkg.tar.zst) Для старых OS В старых версиях в зависимостях `libwebkit2gtk-4.0-37`, в новых уже `libwebkit2gtk-4.1-0`. [![Скачать pkg x86_64 (для Arch Linux)](/docs/img/getting-started/badge-pkg-amd64.svg "Скачать pkg x86_64 (для Arch Linux)")](https://releases.tuna.am/desktop/latest/old/tuna-desktop-latest-1-x86_64.pkg.tar.zst)[![Скачать pkg aarch64 (для Arch Linux)](/docs/img/getting-started/badge-pkg-arm64.svg "Скачать pkg aarch64 (для Arch Linux)")](https://releases.tuna.am/desktop/latest/old/tuna-desktop-latest-1-aarch64.pkg.tar.zst) *** #### Обновление На Windows и macOS скачайте свежую версию по ссылкам выше и установите её. На Linux обновите пакет `tuna-desktop` пакетным менеджером (`apt`, `zypper`, `dnf`, `apt-get`) или ещё раз выполните скрипт установки. На Arch Linux повторите команды установки: они скачивают последнюю версию. #### Авторизация Для работы клиента необходим Токен, зарегистрируйтесь [по ссылке](https://my.tuna.am/), и авторизуйте приложение. Токен будет сохранён в [конфиг файл](https://tuna.am/docs/guides/config-file.md), либо можно скопировать на [отдельной странице](https://my.tuna.am/token) и указать вручную. Нажмите **Войти в приложение** ![Войти в приложен�ие](/docs/img/getting-started/desktop-login.png) В браузере откроется ссылка с предложение подтвердить вход, нажмите **Войти** ![Вход в приложение tuna](/docs/img/getting-started/desktop-login-browser.png) Указать токен вручную Под кнопкой *Войти в приложение*, нажмите на ссылку **использовать токен для входа** и введите токен с [страницы](https://my.tuna.am/token): ![Вход в приложение tuna](/docs/img/getting-started/desktop-set-token.png) #### Пользуйтесь Все готово, чтобы приступить к работе. Создайте один или несколько туннелей и запустите их. ![Нажмите - добавить туннель](/docs/img/getting-started/desktop-use.png) #### Что дальше? * Изучите примеры настроек [HTTP туннеля](https://tuna.am/docs/tunnels/http.md) * Нужен доступ к сервису, не использующему HTTP? Узнайте подробнее в разделе по [TCP туннелю](https://tuna.am/docs/tunnels/tcp.md) --- ### Удаление **Windows** #### Удаление при установке с помощью winget Откройте PowerShell и выполните команду: ```shell winget uninstall --id yuccastream.tuna ; powershell ``` #### Удаление при установке MSI пакета Удалите программу через панель управления программами. #### Удаление при установке вручную Откройте PowerShell и выполните команду: ```powershell Remove-Item "$env:USERPROFILE\AppData\Local\Microsoft\WindowsApps\tuna.exe" -Force ``` **macOS** #### Удаление при установке с помощью brew Выполните команду в терминале: ```bash brew uninstall yuccastream/tap/tuna ``` #### Удаление при установке вручную или с помощью скрипта Выполните команду в терминале: ```bash sudo rm -f /usr/local/bin/tuna ``` **Linux** #### Удаление при установке через пакетный менеджер **Ubuntu/Debian** Debian и основанные на нём дистрибутивы (Ubuntu, Mint и другие), выполните в терминале следующие команды: ```shell sudo apt purge tuna.am tuna-cli tunad ``` **SUSE/OpenSUSE** SUSE и OpenSUSE, выполните в терминале следующие команды: ```shell sudo zypper remove tuna.am tuna-cli tunad ``` **RHEL/Fedora** RHEL и основанные на нём дистрибутивы (CentOS, Rocky, AlmaLinux и другие), а также Fedora, выполните в терминале следующие команды: ```shell sudo dnf remove tuna.am tuna-cli tunad ``` **Arch Linux** Arch Linux, выполните в терминале следующие команды: ```shell sudo pacman -R tuna.am-bin ``` #### Удаление при установке вручную Выполните команду в терминале: ```bash sudo rm -f /usr/local/bin/tuna ``` **FreeBSD** Выполните команду в терминале: ```shell sudo rm -f /usr/local/bin/tuna ``` --- ### SSH ключи На странице [SSH ключей](https://my.tuna.am/public_keys) вы можете добавить свои публичные ключи и использовать их для авторизации в [SSHd туннелях](https://tuna.am/docs/tunnels/ssh.md) или создания [HTTP туннель с SSH клиентом](https://tuna.am/docs/tunnels/guides/ssh-reverse.md). ![](/docs/img/ssh-keys.gif) Чтобы разрешить подключения в SSH туннелях с помощью своих SSH ключей, нужно включить соответствующие настройки, в случае команды можно дополнительно разрешить использовать ваш ключ участникам команды. ![](/docs/img/ssh-keys.png) --- ### Terraform-провайдер Провайдер `yuccastream/tuna` описывает ресурсы tuna кодом: домены и доменные зоны, шлюзы, эндпоинты, IP-политики, TLS-сертификаты, SSH-ключи и временные токены. Работает с Terraform и OpenTofu. Провайдер в Terraform Registry Документация по всем ресурсам и атрибутам — на странице [yuccastream/tuna](https://registry.terraform.io/providers/yuccastream/tuna/latest/docs) в Terraform Registry. #### Установка Нужен Terraform 1.11 или новее: в более старых версиях не работают write-only атрибуты, а через них передаётся приватный ключ TLS-сертификата. ```hcl terraform { required_version = ">= 1.11" required_providers { tuna = { source = "yuccastream/tuna" } } } provider "tuna" {} ``` ```bash terraform init ``` В OpenTofu Registry провайдера пока нет. Для OpenTofu укажите реестр явно: `source = "registry.terraform.io/yuccastream/tuna"`. #### Аутентификация Провайдеру нужен API-ключ. Выпустите его в [личном кабинете](https://my.tuna.am/api_keys) со скоупом `tunnels:write`: этого достаточно для всех ресурсов провайдера, полный доступ `api` не нужен. Ключ со скоупом по умолчанию `read_api` подходит только для чтения, `apply` с ним завершится ошибкой. API-ключ нельзя выпустить через API, поэтому провайдер не управляет ключами: их создают только в личном кабинете. Ключ передаётся переменной окружения (рекомендуется) или в блоке `provider`: ```bash export TUNA_API_KEY="" ``` ```hcl provider "tuna" { api_key = var.tuna_api_key } ``` | Параметр | Переменная окружения | Описание | | --------- | -------------------- | --------------------------------------------- | | `api_key` | `TUNA_API_KEY` | API-ключ | | `api_url` | `TUNA_API_URL` | Адрес API, по умолчанию `https://api.tuna.am` | #### Ресурсы | Ресурс | Что описывает | | ---------------------- | --------------------------------------------------------------------------------------------------------------------------- | | `tuna_domain` | [Зарезервированный домен](https://tuna.am/docs/team/domains.md): поддомен встроенной зоны, своей зоны или собственный домен | | `tuna_domain_zone` | [Доменная зона](https://tuna.am/docs/team/domain_zones.md) | | `tuna_tls_certificate` | [TLS-сертификат](https://tuna.am/docs/team/tls_certificates.md) для доменной зоны | | `tuna_gateway` | [Шлюз](https://tuna.am/docs/gateways.md) на зарезервированном домене | | `tuna_endpoint` | [TCP-порт](https://tuna.am/docs/team/tcp_ports.md) | | `tuna_ip_policy` | [IP-политика](https://tuna.am/docs/team/ip_policies.md) | | `tuna_ip_policy_rule` | Правило IP-политики | | `tuna_public_key` | [Публичный SSH-ключ](https://tuna.am/docs/team/ssh_public_keys.md) | | `tuna_temporal_token` | Временный токен для запуска туннелей | Источник данных `tuna_tunnels` возвращает список туннелей аккаунта. Параметр `location` у доменов, зон и эндпоинтов принимает значения `ru` или `nl`. Полный справочник по атрибутам — в [Terraform Registry](https://registry.terraform.io/providers/yuccastream/tuna/latest/docs). #### Сценарий: временные туннели для CI Terraform резервирует домен и выпускает временный токен с ограничениями, а CI-задача поднимает туннель с этим токеном. Основной API-ключ в CI не попадает. ```hcl resource "tuna_domain" "preview" { subdomain = "myapp-preview" location = "ru" } resource "tuna_temporal_token" "ci" { description = "CI preview" duration = "24h" allow_http = true allow_tcp = false limit_by_active_tunnels = 5 limit_by_created_tunnels = 100 } output "ci_tunnel_token" { value = tuna_temporal_token.ci.token sensitive = true } ``` Токен помечен как `sensitive`, поэтому забирайте его явно: ```bash terraform apply export TUNA_TOKEN="$(terraform output -raw ci_tunnel_token)" tuna http 8080 --subdomain=myapp-preview ``` Проверить, что туннель поднялся, можно через источник данных: ```hcl data "tuna_tunnels" "all" {} output "active_tunnels" { value = [for t in data.tuna_tunnels.all.tunnels : t.public_url if t.active] } ``` #### Сценарий: своя зона с сертификатом и доступом по IP ```hcl resource "tuna_tls_certificate" "wildcard" { description = "wildcard for tunnels.example.com" certificate_pem = file("${path.module}/cert.pem") private_key_pem = file("${path.module}/key.pem") } resource "tuna_domain_zone" "example" { domain = "tunnels.example.com" location = "ru" tls_certificate_id = tuna_tls_certificate.wildcard.id } resource "tuna_domain" "app" { subdomain = "app" location = "ru" domain_zone_id = tuna_domain_zone.example.id } resource "tuna_ip_policy" "office" { name = "office-only" active = true } resource "tuna_ip_policy_rule" "office_allow" { ip_policy_id = tuna_ip_policy.office.id name = "office" cidr = "203.0.113.0/24" action = "allow" } ``` `private_key_pem` — write-only атрибут: провайдер передаёт ключ в API, но не сохраняет его в state. #### Шлюз ```hcl resource "tuna_domain" "api" { subdomain = "myapp-api" location = "ru" } resource "tuna_gateway" "api" { domain_id = tuna_domain.api.id policy = file("${path.module}/policy.yaml") } ``` В `policy.yaml` лежит [политика трафика](https://tuna.am/docs/traffic-policy.md). Домен со шлюзом занят шлюзом: туннель на нём не запустится, сервер ответит `Domain already reserved by gateway`. Для туннеля резервируйте отдельный домен. #### Изменение ресурсов В API нет редактирования эндпоинтов, доменов, доменных зон и временных токенов, поэтому любое изменение их атрибутов (включая `alias` или `description`) пересоздаёт ресурс. У временного токена при этом меняется значение: туннели со старым токеном придётся перезапустить. Шлюзы, IP-политики и их правила обновляются на месте. Правило пересоздаётся только при смене `ip_policy_id`. #### Импорт Существующие ресурсы импортируются по числовому ID из личного кабинета или API: ```bash terraform import tuna_domain.app 123 terraform import tuna_gateway.api 123 ``` У правила IP-политики составной ID `/`: ```bash terraform import tuna_ip_policy_rule.office_allow 123/456 ``` API не возвращает приватный ключ сертификата, поэтому после импорта `tuna_tls_certificate` задайте `private_key_pem` в конфигурации. --- ### Устранение неполадок Здесь мы постарались собрать все возможные неполадки с которыми встречались наши пользователи и описать их решение. Большая часть проблем связана с сетевыми проблемами или пользовательским окружением. подсказка Многие ошибки и проблемы могут быть уже решены в последней версии клиента, поэтому прежде чем проводить диагностику или обращаться за помощью к [нам](mailto:info@tuna.am) или [сообществу](https://telegram.me/+Kgbtt0_gJwI5ZmEy), убедитесь, что у вас установлена последняя версия клиента. Инструкция по обновлению есть [тут](https://tuna.am/docs/guides/update.md). #### Самостоятельная диагностика сетевой доступности Если у вас появляются ошибки при создании туннеля, выполните команду `tuna diagnose` для получения диагностической информации, отчет поможет лучше понять, где именно проблема. ```shell Please wait, testing connectivity... TLS connectivity: Google.com: ok [1.46189625s] Yandex.ru: ok [1.246520375s] tuna API: ok [1.484186875s] tuna NL location: ok [739.467083ms] tuna RU location: ok [597.777167ms] TCP connectivity: tuna NL location: ok [75.757708ms] tuna RU location: ok [34.079541ms] ``` Как правило, tuna использует порт `443` для подключения к нодам при создании туннеля. Если проверки `TCP connectivity` не проходят, проверьте нет ли фаервола который может ограничивать подключения. #### Распространённые ошибки ##### Tunnel already active ```shell ERRO[09:01:09] Failed to get connection settings: Tunnel already active Code: BadRequest Request ID: 2008cc71bdf725853748bb91d69c4669, retrying in 1s ERRO[09:01:10] Failed to get connection settings: Tunnel already active Code: BadRequest Request ID: 0118213a8f8d341f002ec30ee1499768, retrying in 2s ERRO[09:01:12] Failed to get connection settings: Tunnel already active Code: BadRequest Request ID: 608d043eb16376a619b671eb0d33dc0b, retrying in 4s ``` Данная ошибка `Tunnel already active` означают, что туннель уже существует, возможно он завис, или запущен у вас где-то в фоне. Самый простой способ решить проблему, это удалить зависший туннель в [панели управления туннелями](https://my.tuna.am/tunnels). Проблема может возникать в случаях когда произошёл обрыв соединения и наш сервер не смог корректно это отследить. Мы работаем над тем, что бы в будущем такое поведение не проявлялось. ##### Tunnel limit reached Если вы видите ошибку `Tunnel limit reached` (Исчерпан лимит по туннелям), хотя вы знаете, что на самом деле это не так, это может также означать, что есть зависший активный туннель. Как и в прошлой ошибке способ решить проблему можно удалив зависший туннель в [панели управления туннелями](https://my.tuna.am/tunnels). ##### VPN Много странного поведения проявляется при работе через VPN или если вы часто подключаетесь/отключаетесь к нему. К сожалению тут нет универсального решения, так как всё зависит от конкретной операционной системы или VPN клиента. Мы можем рекомендовать исключить маршрутизацию к ресурсам Tuna через VPN, если это позволяет сделать ваш клиент. Исключите обращения к IP `api.tuna.am` и [нодам](https://tuna.am/docs/tunnels/guides/locations.md). --- ### Обновление Если при запуске tuna вы увидели сообщение `New version available`, значит самое время обновиться. Обновление позволяет своевременно получать исправления ошибок, а так же новый функционал. Процедура обновления не сложнее установки: **Windows** Выполните команду в PowerShell или [обновите вручную](https://tuna.am/docs/guides/install/install-cli.md?os=windows): ```bash winget upgrade --id yuccastream.tuna ; powershell ``` **macOS** Выполните команды в терминале или [обновите вручную](https://tuna.am/docs/guides/install/install-cli.md?os=macos): ```bash brew update brew upgrade yuccastream/tap/tuna ``` **Linux** ##### Обновление через пакетный менеджер **Ubuntu/Debian** Debian и основанные на нём дистрибутивы (Ubuntu, Mint и другие), выполните в терминале следующие команды: ```shell sudo apt update sudo apt install tuna-cli ``` **SUSE/OpenSUSE** SUSE и OpenSUSE, выполните в терминале следующие команды: Если tuna установлена до версии 0.35.0, один раз переключите репозиторий: ```shell sudo zypper removerepo tuna sudo zypper addrepo --repo https://code.tuna.am/api/packages/tuna/rpm/stable.repo ``` Обновите пакет: ```shell sudo zypper refresh sudo zypper install -y tuna-cli ``` **RHEL/Fedora** RHEL и основанные на нём дистрибутивы (CentOS, Rocky, AlmaLinux и другие), а также Fedora, выполните в терминале следующие команды: Если tuna установлена до версии 0.35.0, один раз переключите репозиторий: ```shell sudo curl -fsSL https://code.tuna.am/api/packages/tuna/rpm/stable.repo -o /etc/yum.repos.d/tuna-forgejo.repo sudo rm -f /etc/yum.repos.d/tuna-rpm.repo /etc/yum.repos.d/tuna.repo ``` Обновите пакет: ```shell sudo dnf install -y --refresh tuna-cli ``` **ALT Linux** ALT Linux, выполните в терминале команду: ```shell sudo apt-get update && sudo apt-get install tuna-cli ``` **Arch Linux** Arch Linux, обновите пакет `tuna.am-bin` из AUR: ```shell yay -S tuna.am-bin ``` Без yay подойдёт скрипт ниже: он сам поставит пакет через yay или pacman. ##### Обновление с помощью скрипта Скрипт подходит для любого дистрибутива: где есть пакет tuna, он обновит пакет, в остальных (Alpine, NixOS и другие) заменит бинарный файл. Выполните команду в терминале или [обновите вручную](https://tuna.am/docs/guides/install/install-cli.md?os=linux): **curl** ```shell sh -c "$(curl -sSLf https://releases.tuna.am/tuna/get.sh)" ``` **wget** ```shell sh -c "$(wget -qO- https://releases.tuna.am/tuna/get.sh)" ``` **FreeBSD** Выполните команду в терминале или [обновите вручную](https://tuna.am/docs/guides/install/install-cli.md?os=freebsd): **curl** ```shell sh -c "$(curl -sSLf https://releases.tuna.am/tuna/get.sh)" ``` **wget** ```shell sh -c "$(wget -qO- https://releases.tuna.am/tuna/get.sh)" ``` **Docker** Выполните команду: ```bash docker pull yuccastream/tuna:latest ``` Чтобы убедиться, что обновление прошло корректно, выполните `tuna version`. #### Политика обновления tuna Мы стремимся, чтобы пользователи всегда имели доступ к актуальной версии tuna. Поэтому мы ограничиваем использование устаревших версий для пользователей без подписки. При выходе новой версии клиента, предыдущая продолжит работать на протяжении примерно 6 месяцев, точная дата прекращения работы будет отражена в таблице ниже. Пользователи с подпиской могут продолжать пользоваться любой версией без ограничений. | Версия tuna | Дата окончания поддержки | | ------------- | ------------------------ | | старше 0.14.x | 1 ноября 2024 г. | | 0.14.x | 1 декабря 2024 г. | | 0.15.x | 1 января 2025 г. | | 0.16.x | 1 февраля 2025 г. | | 0.17.x | 1 марта 2025 г. | | 0.18.x | 1 апреля 2025 г. | | 0.19.x | 1 мая 2025 г. | | 0.20.x | 1 июня 2025 г. | | 0.21.x | 1 октября 2025 г. | | 0.22.x | 1 октября 2025 г. | | 0.23.x | 1 ноября 2025 г. | | 0.24.x | 1 ноября 2025 г. | | 0.25.x | 1 декабря 2025 г. | | 0.26.x | 1 февраля 2026 г. | | 0.27.x | 1 марта 2026 г. | | 0.28.x | 1 мая 2026 г. | | 0.29.x | 1 июля 2026 г. | | 0.30.x | 1 августа 2026 г. | | 0.31.x | 1 сентября 2026 г. | | 0.32.x | 1 октября 2026 г. | | 0.33.x | 1 ноября 2026 г. | | 0.34.x | 1 декабря 2026 г. | | 0.35.x | 1 января 2027 г. | --- ### Встречи [Перейти в личный кабинет](https://my.tuna.am/meet) Видеозвонки для команды: звоните, общайтесь, решайте проблемы быстро — всё на нашей платформе. ![Видеовстреча в Tuna](/docs/img/meet/main.png) *** #### Обзор **Встречи** — это видеозвонки прямо внутри Tuna. Простой и привычный интерфейс, похожий на Google Meet. Что можно делать на встречах * Созваниваться в постоянных каналах команды * Создавать разовые встречи и делиться ссылкой * Настраивать микрофон, камеру и фон до подключения * Демонстрировать экран * Общаться в чате во время звонка * Поднимать руку, ставить реакции * Подключаться с телефона #### Структура сервиса Сервис **Встречи** состоит из двух типов комнат: * **Приватные каналы** — постоянные комнаты вашей команды (например, *Общее*, *Болталка*, *Инцидент*). Доступны только участникам организации. * **Разовые встречи** — создаются по кнопке **Новая встреча**, делятся по ссылке или коду. ![Главный экран встреч с кнопкой Новая встреча и списком приватных каналов](/docs/img/meet/start.png) #### Создание первой встречи 1. Перейдите в раздел [Встречи](https://my.tuna.am/meet) в личном кабинете. 2. Нажмите **Новая встреча**, чтобы создать разовую комнату, или выберите один из приватных каналов команды. 3. Скопируйте ссылку или код и отправьте коллегам — для приватных каналов достаточно зайти в тот же раздел. Чтобы присоединиться к чужой встрече, вставьте ссылку или код в поле **Вставьте ссылку или код встречи** и нажмите **Войти**. *** #### Возможности встреч ##### Окно настроек перед звонком Перед подключением проверьте микрофон и камеру, выберите нужное устройство из подключённых или временно отключите их. Так вы заходите в комнату уже готовым — без неловких «меня слышно?». ![Окно настройки микрофона и камеры перед подключением](/docs/img/meet/precall.png) ##### Фоны и эффекты Замените фон на один из готовых (офис, пляж Майами, парковка) или включите размытие — удобно, если вокруг бардак или вы созваниваетесь из непрофильного места. ##### Окно участников Список активных участников отображается рядом с видео. Каждый может **поднять руку**, чтобы взять слово — ведущий сразу увидит, кто хочет высказаться. ![Список участников встречи](/docs/img/meet/participants.png) ##### Реакции Быстрая обратная связь без перебивания: ставьте лайк, сердце, огонь и другие реакции — они появляются у всех участников. ![Панель реакций во встрече](/docs/img/meet/reactions.png) ##### Демонстрация экрана Покажите коллегам свой экран без долгой настройки — одна кнопка, и презентация уже идёт. Подходит для демо, дебага и обзора макетов. ##### Чат Во время звонка можно переписываться в чате — например, скинуть ссылку, не прерывая выступающего. Чат сохраняется на время встречи. ![Чат во время встречи](/docs/img/meet/chat.png) ##### Встречи с телефона Подключайтесь к встречам с мобильного устройства — видео, аудио, чат и демонстрация экрана работают так же, как в десктопной версии. ![Встреча на мобильном устройстве](/docs/img/meet/mobile.png) *** #### Тарифы Встречи включены в подписку Tuna и не требуют отдельной оплаты. Функционал доступен на тарифах **Разработчик** и **Легенда** — подробности смотрите на странице [тарифов](https://tuna.am/#pricing). --- ### Мониторы [Перейти в личный кабинет](https://my.tuna.am/monitors) Функционал для мониторинга работы CronJobs, Heartbeat, ICMP, DNS, HTTP и TCP приложений с поддержкой уведомлений через различные каналы связи. ![Главная страница мониторов](/docs/img/monitors/main.png) *** #### Обзор Мониторы позволяют отслеживать работоспособность ваших сервисов, задач и инфраструктуры. При возникновении проблем вы получите уведомления через настроенные каналы связи. *** #### Типы мониторов ![Типы мониторов](/docs/img/monitors/types.png) Tuna поддерживает 6 типов мониторов, разделённых на две категории: ##### Пользовательские мониторы Эти мониторы ожидают сигналы от ваших приложений и скриптов: | Тип | Описание | Применение | | -------------- | ------------------------------------------ | ---------------------------------------------------------- | | **Задача** | Мониторинг выполнения периодических задач | Backup скрипты, cron задачи, периодические операции | | **Heartbeat** | Мониторинг регулярных сигналов от сервисов | Сервисы в закрытых сетях, IoT устройства, фоновые процессы | ##### Внешние мониторы Эти мониторы самостоятельно проверяют доступность ваших ресурсов из нескольких регионов: | Тип | Описание | Применение | | --------- | ------------------------------------- | ---------------------------------------------- | | **HTTP** | Проверка доступности веб-сайтов и API | Сайты, REST API, webhooks | | **TCP** | Проверка доступности TCP-сервисов | Базы данных, почтовые серверы, игровые серверы | | **DNS** | Проверка DNS-записей | Домены, MX записи, TXT записи | | **ICMP** | Проверка сетевой доступности (ping) | Серверы, сетевое оборудование | *** #### Статусы мониторов Каждый монитор может находиться в одном из следующих состояний: | Статус | Описание | | -------------- | -------------------------------- | | ⚪ **New** | Новый монитор, ещё не проверялся | | 🟢 **Up** | Работает нормально | | 🔵 **Running** | Выполняется (для Job/Heartbeat) | | 🔴 **Down** | Неисправен/недоступен | ![скриншот с разными статусами мониторов](/docs/img/monitors/statuses.png) *** #### Создание монитора 1. Перейдите на страницу [Мониторы](https://my.tuna.am/monitors) 2. Нажмите кнопку **Создать монитор** 3. Выберите тип монитора 4. Заполните параметры монитора 5. Настройте уведомления (опционально) 6. Сохраните монитор Для всех типов мониторов есть общие настройки **Описание** и **Уведомления**. А вот **Детали** и **Проверки** отличаются в зависимости от типа монитора. Подробнее про каждый тип есть отдельная [страница](https://tuna.am/docs/monitors/types.md). *** #### Уведомления Мониторы интегрированы с системой уведомлений через [Контакты](https://tuna.am/docs/team/contacts.md) и [Интеграции](https://tuna.am/docs/team/integrations.md). Если никакие конкретные группы контактов не указаны, то уведомления будут приходить на почтовый ящик пользователя. Также можно отключить уведомления от монитора. *** #### Просмотр монитора На странице детальной информации монитора доступно множество информации. Данные могут отличаться в зависимости от типа монитора. ![скриншот с статусом и всей информацией о мониторе](/docs/img/monitors/status.png) ##### Управление * **Включение/Отключение** уведомлений по монитору * **Редактирование** - изменить параметры монитора * **Удаление** - удалить монитор ![уведомления отключены](/docs/img/monitors/alert_disable.png) *** #### Регионы и интервал проверки Внешние мониторы (HTTP, TCP, DNS, ICMP) могут проверяются из нескольких географических регионов. При создании внешнего монитора вы можете выбрать один или несколько регионов проверки. Также здесь вы указываете как часто нужно выполнять проверку доступности ресурса - интервал. ![скриншот с выбором региона](/docs/img/monitors/region.png) *** #### Работа в CLI Для [Job](https://tuna.am/docs/monitors/types/job.md) и [Heartbeat](https://tuna.am/docs/monitors/types/heartbeat.md) мониторов доступна работа через консольный клиент [tuna](https://tuna.am/docs/guides/install/install-cli.md). Подробнее: [Работа с мониторами в CLI](https://tuna.am/docs/monitors/cli.md) *** #### [🗃Типы мониторов](https://tuna.am/docs/monitors/types.md) [6 элементов](https://tuna.am/docs/monitors/types.md) #### [📄️Статус-страницы](https://tuna.am/docs/monitors/status_pages.md) [Публичные страницы со статусом ваших сервисов на основе мониторов Tuna](https://tuna.am/docs/monitors/status_pages.md) #### [📄️Работа в CLI](https://tuna.am/docs/monitors/cli.md) [Управление мониторами через консольный клиент tuna](https://tuna.am/docs/monitors/cli.md) #### [🗃Примеры](https://tuna.am/docs/monitors/examples.md) [2 элемента](https://tuna.am/docs/monitors/examples.md) --- ### Работа в CLI #### Обзор Консольный клиент [tuna](https://tuna.am/docs/guides/install/install-cli.md) позволяет взаимодействовать с [Job](https://tuna.am/docs/monitors/types/job.md) и [Heartbeat](https://tuna.am/docs/monitors/types/heartbeat.md) мониторами напрямую из терминала или скриптов. Основные команды: * `tuna monitor ping` — отправка сигнала Heartbeat монитору * `tuna monitor exec` — выполнение команды с отслеживанием Job монитора * `tuna monitor status` — просмотр статуса мониторов *** #### Авторизация Для просмотра статуса монитора необходим [API-ключ](https://tuna.am/docs/guides/api.md). Его можно передать несколькими способами: **Переменная окружения** ```bash export TUNA_API_KEY=your-api-key tuna monitor ping YOUR_MONITOR_ID ``` **Флаг** ```bash tuna monitor ping YOUR_MONITOR_ID --api-key=your-api-key ``` **Конфиг файл** ```bash # Сохранить ключ в конфиг tuna config save-api-key your-api-key # Теперь можно использовать без явного указания ключа tuna monitor ping YOUR_MONITOR_KEY ``` *** #### monitor ping Отправляет сигнал для Heartbeat монитора. ##### Синтаксис ```bash tuna monitor ping MONITOR_ID [флаги] ``` ##### Параметры | Параметр | Описание | По умолчанию | | ------------ | -------------------------------------------- | ------------ | | `MONITOR_ID` | Ключ монитора (обязательный) | — | | `--state` | Состояние: `ping`, `start`, `finish`, `fail` | `ping` | | `--message` | Дополнительное сообщение | — | | `--host` | Имя хоста отправителя | hostname | ##### Примеры ###### Простой ping ```bash tuna monitor ping MONITOR_ID ``` ###### С указанием хоста ```bash tuna monitor ping MONITOR_ID --host=server-01 ``` ###### С сообщением ```bash tuna monitor ping MONITOR_ID --message="All systems operational" ``` ###### Разные состояния ```bash # Начало работы tuna monitor ping MONITOR_ID --state=start # Успешное завершение tuna monitor ping MONITOR_ID --state=finish # Ошибка tuna monitor ping MONITOR_ID --state=fail ``` ##### Использование в crontab ```bash # Heartbeat каждые 5 минут */5 * * * * /usr/local/bin/tuna monitor ping MONITOR_ID --host=gitlab-runner ``` ##### Использование в systemd ```ini # /etc/systemd/system/heartbeat.service [Unit] Description=Send heartbeat to Tuna [Service] Type=oneshot ExecStart=/usr/local/bin/tuna monitor ping MONITOR_ID ``` ```ini # /etc/systemd/system/heartbeat.timer [Unit] Description=Heartbeat timer [Timer] OnBootSec=1min OnUnitActiveSec=5min [Install] WantedBy=timers.target ``` *** #### monitor exec Выполняет команду и автоматически отслеживает Job монитор. При запуске отправляется сигнал `start`, при успешном завершении — `finish`, при ошибке — `fail`. ##### Синтаксис ```bash tuna monitor exec MONITOR_ID [флаги] -- COMMAND [ARGS...] ``` ##### Параметры | Параметр | Описание | По умолчанию | | ------------- | ----------------------------- | ------------ | | `MONITOR_ID` | Ключ монитора (обязательный) | — | | `--host` | Имя хоста выполнения | hostname | | `--no-stdout` | Не отправлять вывод на сервер | false | ##### Примеры ###### Простой запуск ```bash tuna monitor exec MONITOR_ID -- ./backup.sh ``` ###### С указанием хоста ```bash tuna monitor exec MONITOR_ID --host=backup-server -- ./backup.sh ``` ###### Без отправки логов ```bash tuna monitor exec MONITOR_ID --no-stdout -- ./backup.sh ``` ###### Команда с аргументами ```bash tuna monitor exec MONITOR_ID -- pg_dump -U postgres -d mydb -f /backups/dump.sql ``` ###### Команда с пайпом ```bash tuna monitor exec MONITOR_ID -- bash -c 'pg_dump mydb | gzip > /backups/dump.sql.gz' ``` ##### Использование в crontab ```bash # Backup каждую ночь в 3:00 0 3 * * * /usr/local/bin/tuna monitor exec MONITOR_ID -- /scripts/backup.sh # Очистка логов каждый час 0 * * * * /usr/local/bin/tuna monitor exec MONITOR_ID -- /scripts/cleanup.sh ``` ##### Логирование При использовании `monitor exec` система захватывает stdout и stderr выполняемой команды. Логи можно просмотреть в веб-интерфейсе в истории событий монитора. ![скриншот с сообщением в message](/docs/img/monitors/event.png) Для отключения отправки логов используйте флаг `--no-stdout`: ```bash tuna monitor exec MONITOR_ID --no-stdout -- ./command.sh ``` ##### Обработка сигналов `monitor exec` корректно обрабатывает сигналы Unix: * При получении SIGINT, SIGTERM, SIGHUP — сигнал передаётся дочернему процессу * При завершении дочернего процесса с ненулевым кодом — отправляется `fail` * При корректном завершении (exit code 0) — отправляется `finish` *** #### monitor status Показывает статус мониторов команды. Для просмотра статуса необходим [API-ключ](https://tuna.am/docs/guides/api.md). ##### Синтаксис ```bash tuna monitor status [MONITOR_ID] [флаги] ``` ##### Параметры | Параметр | Описание | По умолчанию | | ----------- | --------------------------------------- | --------------- | | `KEY` | Ключ конкретного монитора (опционально) | — | | `--api-key` | API ключ для авторизации | `$TUNA_API_KEY` | ##### Примеры ###### Статус всех мониторов ```bash tuna monitor status ``` ###### Статус конкретного монитора ```bash tuna monitor status MONITOR_ID ``` *** #### Практические примеры ##### Backup PostgreSQL с мониторингом ```bash #!/bin/bash # /scripts/backup-postgres.sh BACKUP_DIR="/backups/postgres" DATE=$(date +%Y%m%d_%H%M%S) DB_NAME="production" tuna monitor exec MONITOR_ID --host=pg-prod-replica-1 -- bash -c " pg_dump -U postgres $DB_NAME | gzip > $BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz # Удаление старых бэкапов (старше 7 дней) find $BACKUP_DIR -name '*.sql.gz' -mtime +7 -delete " ``` ##### Синхронизация файлов ```bash #!/bin/bash # /scripts/sync-files.sh tuna monitor exec MONITOR_ID -- rsync -avz --delete /data/ backup-server:/backups/data/ ``` ##### Мониторинг сервиса в Docker ```bash #!/bin/bash # healthcheck.sh внутри контейнера # Проверка здоровья приложения if curl -sf http://localhost:8080/health > /dev/null; then tuna monitor ping MONITOR_ID --message="healthy" else tuna monitor ping MONITOR_ID --state=fail --message="unhealthy" fi ``` ##### Мониторинг GitLab Runner ```bash # В crontab на машине с GitLab Runner */5 * * * * /usr/local/bin/tuna monitor ping MONITOR_ID --host=raspberry-pi --message="Runner active" ``` --- ### Примеры Примеры и пошаговые инструкции по настройке мониторов для различных устройств и сценариев. #### [📄️JetKVM](https://tuna.am/docs/monitors/examples/jetkvm.md) [Мониторинг доступности JetKVM с помощью Tuna Heartbeat monitor](https://tuna.am/docs/monitors/examples/jetkvm.md) #### [📄️NanoKVM (Sipeed)](https://tuna.am/docs/monitors/examples/nanokvm.md) [Мониторинг доступности NanoKVM с помощью Tuna Heartbeat monitor](https://tuna.am/docs/monitors/examples/nanokvm.md) --- ### Мониторинг доступности JetKVM [JetKVM](https://jetkvm.com/) — это компактное IP-KVM устройство на базе Rockchip RV1106 (ARM Cortex-A7). Для embedded устройств, таких как JetKVM, критически важно отслеживать их работоспособность. Heartbeat-мониторинг позволяет получать уведомления, если устройство потеряло связь с интернетом или перестало отвечать. к сведению Эта инструкция объясняет, как настроить мониторинг доступности JetKVM. Если вам также нужен удалённый доступ к устройству через интернет, см. [инструкцию по настройке туннелей](https://tuna.am/docs/tunnels/examples/jetkvm.md). *** #### Подготовка ##### Что потребуется * JetKVM с системной версией **v0.2.7 или новее** * **Developer Mode** включен и SSH-доступ настроен (см. [инструкцию по туннелям](https://tuna.am/docs/tunnels/examples/jetkvm.md#%D0%BF%D0%BE%D0%B4%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BF%D0%BE-ssh)) * Аккаунт на [tuna.am](https://my.tuna.am/) ##### Установка tuna на JetKVM (опционально) Heartbeat уведомления можно отправлять и при помощи wget, установка tuna cli не обязательна, но если вы также используете туннели для удалённого доступа, то логично будет использовать этот же клиент и для Heartbeat уведомлений. Подключитесь к JetKVM по SSH: ```bash ssh root@ ``` Установите tuna с помощью скрипта, указав `/userdata/tuna` в качестве директории установки: ```bash mkdir -p /userdata/tuna INSECURE=true INSTALL_DIR=/userdata/tuna sh -c "$(wget -qO- http://releases.tuna.am/tuna/get.sh)" ``` подсказка Раздел `/userdata` сохраняется при OTA-обновлениях, поэтому tuna не придётся переустанавливать. *** #### Создание Heartbeat монитора 1. Перейдите в [личный кабинет → Мониторы](https://my.tuna.am/monitors) 2. Нажмите "Создать монитор" 3. Выберите тип **Heartbeat** 4. Задайте параметры: * **Описание**: JetKVM availability * **Интервал**: 5 минут (на бесплатном тарифе минимальный 30 минут) * **Grace Period**: 1 минута (время ожидания перед алертом) 5. Настройте каналы уведомлений 6. Сохраните монитор и скопируйте **MONITOR_ID** Подробнее о Heartbeat мониторах: [Документация Heartbeat](https://tuna.am/docs/monitors/types/heartbeat.md) *** #### Создание init-скрипта мониторинга Рекомендуется tuna CLI Начиная с версии **0.31**, клиент tuna содержит встроенные CA-сертификаты и не зависит от системных. На JetKVM отсутствуют корневые CA-сертификаты, поэтому wget может работать только с `--no-check-certificate`, а API `monitor.tuna.am` может быть недоступен по HTTP. Рекомендуем использовать tuna CLI для мониторинга — он гарантированно работает по HTTPS. Создайте init-скрипт `/userdata/init.d/S97tuna-heartbeat`: **tuna CLI (рекомендуется)** ```bash cat << 'INITEOF' > /userdata/init.d/S97tuna-heartbeat #!/bin/sh PIDFILE=/tmp/tuna-heartbeat.pid wait_network() { i=0 while ! ip route | grep -q default; do sleep 1 i=$((i + 1)) if [ "$i" -ge 60 ]; then return 1 fi done return 0 } start() { ( wait_network || exit 1 while true; do /userdata/tuna/tuna monitor ping --host=jetkvm YOUR_MONITOR_ID # Интервал между пингами (30 минут = 1800 секунд) sleep 1800 done ) & echo $! > "$PIDFILE" } stop() { if [ -f "$PIDFILE" ]; then kill "$(cat "$PIDFILE")" 2>/dev/null rm -f "$PIDFILE" fi } case "$1" in start) start ;; stop) stop ;; restart) stop; sleep 1; start ;; *) echo "Usage: $0 {start|stop|restart}" ;; esac INITEOF chmod +x /userdata/init.d/S97tuna-heartbeat ``` **wget** ```bash cat << 'INITEOF' > /userdata/init.d/S97tuna-heartbeat #!/bin/sh PIDFILE=/tmp/tuna-heartbeat.pid wait_network() { i=0 while ! ip route | grep -q default; do sleep 1 i=$((i + 1)) if [ "$i" -ge 60 ]; then return 1 fi done return 0 } start() { ( wait_network || exit 1 while true; do wget -q -T 5 --no-check-certificate -O /dev/null "https://monitor.tuna.am/YOUR_MONITOR_ID/jetkvm" # Интервал между пингами (30 минут = 1800 секунд) sleep 1800 done ) & echo $! > "$PIDFILE" } stop() { if [ -f "$PIDFILE" ]; then kill "$(cat "$PIDFILE")" 2>/dev/null rm -f "$PIDFILE" fi } case "$1" in start) start ;; stop) stop ;; restart) stop; sleep 1; start ;; *) echo "Usage: $0 {start|stop|restart}" ;; esac INITEOF chmod +x /userdata/init.d/S97tuna-heartbeat ``` Важно Замените `YOUR_MONITOR_ID` на реальный ID монитора из личного кабинета. **Пояснение параметров:** | Параметр | Описание | | ----------------- | ------------------------------------------------------------------------------- | | `YOUR_MONITOR_ID` | ID монитора из личного кабинета (обязательно) | | `--host=jetkvm` | Идентификатор устройства в логах мониторинга (опционально) | | `sleep 1800` | Интервал между сигналами в секундах (должен соответствовать настройке монитора) | Формат init-скрипта Скрипт использует тот же формат, что и скрипты для туннелей: `#!/bin/sh`, обработка аргументов `start`/`stop`, фоновый запуск. Подробнее о требованиях к init-скриптам см. [инструкцию по туннелям](https://tuna.am/docs/tunnels/examples/jetkvm.md#%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B0-%D0%B0%D0%B2%D1%82%D0%BE%D0%B7%D0%B0%D0%BF%D1%83%D1%81%D0%BA%D0%B0-jetkvm). *** #### Проверка работы Запустите скрипт вручную: ```bash /userdata/init.d/S97tuna-heartbeat start ``` Убедитесь, что процесс запущен: ```bash ps | grep heartbeat ``` Проверьте статус монитора в [личном кабинете](https://my.tuna.am/monitors) — через 1-2 минуты статус должен измениться с "New" на "Up". *** #### Управление мониторингом **Остановка мониторинга:** ```bash /userdata/init.d/S97tuna-heartbeat stop ``` **Запуск мониторинга:** ```bash /userdata/init.d/S97tuna-heartbeat start ``` **Полное отключение автозапуска:** ```bash mv /userdata/init.d/S97tuna-heartbeat /userdata/init.d/disabled-tuna-heartbeat ``` **Включить обратно:** ```bash mv /userdata/init.d/disabled-tuna-heartbeat /userdata/init.d/S97tuna-heartbeat ``` *** #### Восстановление после OTA-обновления Скрипт и бинарник хранятся в `/userdata/`, который сохраняется при OTA-обновлениях. После обновления прошивки мониторинг продолжит работать без дополнительных действий. При полной перепрошивке (когда `/userdata` был очищен) потребуется заново установить бинарник и создать init-скрипт. *** #### Диагностика неполадок ##### Процесс heartbeat не запускается Проверьте, что процесс присутствует в списке: ```bash ps | grep heartbeat ``` Если процесса нет — проверьте, что скрипт существует и исполняем: ```bash ls -la /userdata/init.d/S97*heartbeat* ``` Запустите скрипт вручную для диагностики: ```bash /userdata/init.d/S97tuna-heartbeat start ``` ##### Монитор показывает "Down" **Причины:** * Неверный MONITOR_ID * Отсутствует интернет-соединение * Интервал в скрипте не соответствует настройкам монитора **Проверка:** ```bash # Проверить наличие IP-адреса ip addr # Проверить маршрут по умолчанию ip route # Проверить доступ в интернет ping -c 3 8.8.8.8 ``` ##### После обновления прошивки heartbeat перестал работать Проверьте, что скрипт на месте: ```bash ls -la /userdata/init.d/S97*heartbeat* ``` Если скрипт отсутствует — он мог быть удалён при полной перепрошивке. Пересоздайте его по инструкции выше. --- ### Мониторинг доступности NanoKVM [NanoKVM](https://wiki.sipeed.com/hardware/en/kvm/NanoKVM/introduction.html) — это компактное IP-KVM устройство от Sipeed на базе RISC-V (Cube/PCIe) или ARM64 (Pro) или ARMv7 (GxxKVM/JxxKVM). Для embedded устройств, таких как NanoKVM, критически важно отслеживать их работоспособность. Heartbeat-мониторинг позволяет получать уведомления, если устройство потеряло связь с интернетом или перестало отвечать. к сведению Эта инструкция объясняет, как настроить мониторинг доступности NanoKVM. Если вам также нужен удалённый доступ к устройству через интернет, см. [инструкцию по настройке туннелей](https://tuna.am/docs/tunnels/examples/nanokvm.md). *** #### Подготовка ##### Что потребуется * NanoKVM, подключённый к локальной сети и доступный по SSH или терминал в веб интерфейсе * Аккаунт на [tuna.am](https://my.tuna.am/) ##### Установка tuna на NanoKVM (опционально) Heartbeat уведомления можно отправлять и при помощи curl, установка tuna cli не обязательна, но если вы также используете туннели для удалённого доступа, то логично будет использовать этот же клиент и для Heartbeat уведомлений. Подключитесь к NanoKVM по SSH: ```bash ssh root@ ``` Или откройте терминал в веб интерфейсе: ![NanoKVM terminal](/docs/img/tunnels/guides/terminal.png) Установите tuna с помощью скрипта, указав `/data/tuna` в качестве директории установки: **curl** ```bash mkdir -p /data/tuna INSTALL_DIR=/data/tuna sh -c "$(curl -sSLf https://releases.tuna.am/tuna/get.sh)" ``` **wget** ```bash mkdir -p /data/tuna INSTALL_DIR=/data/tuna sh -c "$(wget -qO- https://releases.tuna.am/tuna/get.sh)" ``` подсказка Раздел `/data` смонтирован как exFAT с `fmask=0022`, файлы автоматически получают права `0755` — бинарник можно запускать сразу после копирования. Кроме того, `/data` сохраняется при обновлениях, поэтому tuna не придётся переустанавливать. *** #### Создание Heartbeat монитора 1. Перейдите в [личный кабинет → Мониторы](https://my.tuna.am/monitors) 2. Нажмите "Создать монитор" 3. Выберите тип **Heartbeat** 4. Задайте параметры: * **Описание**: NanoKVM availability * **Интервал**: 5 минут (на бесплатном тарифе минимальный 30 минут) * **Grace Period**: 1 минута (время ожидания перед алертом) 5. Настройте каналы уведомлений 6. Сохраните монитор и скопируйте **MONITOR_ID** Подробнее о Heartbeat мониторах: [Документация Heartbeat](https://tuna.am/docs/monitors/types/heartbeat.md) *** #### Создание скрипта мониторинга Создайте скрипт `/data/tuna/tuna-heartbeat.sh`: ```bash cat << 'EOF' > /data/tuna/tuna-heartbeat.sh #!/bin/sh # Ждём сеть while ! ip route | grep -q default; do sleep 1 done # Бесконечный цикл отправки heartbeat while true; do /data/tuna/tuna monitor ping --host=nanokvm YOUR_MONITOR_ID # Интервал между пингами (30 минут = 1800 секунд) sleep 1800 done EOF chmod +x /data/tuna/tuna-heartbeat.sh ``` Если используете curl то вместо строки: `/data/tuna/tuna monitor ping --host=nanokvm YOUR_MONITOR_ID` укажите вызов curl и ссылку из личного кабинета: `curl -sSLf -m 5 https://monitor.tuna.am/YOUR_MONITOR_ID/nanokvm` Важно Замените `YOUR_MONITOR_ID` на реальный ID монитора из личного кабинета. **Пояснение параметров:** | Параметр | Описание | | ----------------- | ------------------------------------------------------------------------------- | | `YOUR_MONITOR_ID` | ID монитора из личного кабинета (обязательно) | | `--host=nanokvm` | Идентификатор устройства в логах мониторинга (опционально) | | `sleep 300` | Интервал между сигналами в секундах (должен соответствовать настройке монитора) | *** #### Настройка автозапуска Добавьте строку в `/etc/inittab` для автоматического запуска и перезапуска мониторинга: ```bash cat << 'EOF' >> /etc/inittab # Tuna Heartbeat monitor (respawn = auto-restart) thb::respawn:/data/tuna/tuna-heartbeat.sh EOF ``` Применить без перезагрузки: ```bash kill -HUP 1 ``` *** #### Проверка работы Убедитесь, что процесс мониторинга запущен: ```bash ps -ef | grep heartbeat ``` В выводе должна быть строка с `/data/tuna/tuna-heartbeat.sh`. Если процесса нет — проверьте `/etc/inittab`: ```bash grep heartbeat /etc/inittab ``` Строка должна начинаться с `thb::respawn`, а не с `#`. Проверьте статус монитора в [личном кабинете](https://my.tuna.am/monitors) — через 1-2 минуты статус должен измениться с "New" на "Up". *** #### Управление мониторингом **Остановка мониторинга:** ```bash sed -i 's/^thb:/#thb:/' /etc/inittab && kill -HUP 1 ``` **Запуск мониторинга:** ```bash sed -i 's/^#thb:/thb:/' /etc/inittab && kill -HUP 1 ``` *** #### Восстановление после перепрошивки Бинарник и скрипты в `/data/tuna/` сохраняются при обновлении приложения через веб-интерфейс и при remote rsync. После полной перепрошивки (Etcher) потребуется заново скопировать бинарник и создать скрипты. При remote rsync нужно восстановить только строки в `/etc/inittab`: ```bash cat << 'EOF' >> /etc/inittab # Tuna Heartbeat monitor (respawn = auto-restart) thb::respawn:/data/tuna/tuna-heartbeat.sh EOF kill -HUP 1 ``` *** #### Почему не cron? В NanoKVM существует [известная проблема с cron](https://github.com/sipeed/NanoKVM/issues/211): * Crontabs не существуют по умолчанию * Созданные crontabs не переживают перезагрузку * Нет системного `/etc/crontab` Поэтому для периодических задач на NanoKVM рекомендуется использовать `inittab` с бесконечным циклом — этот подход надёжен и соответствует архитектуре системы. Альтернатива для других систем На обычных Linux-системах (Debian, Ubuntu) для heartbeat мониторинга предпочтительнее использовать cron или systemd timers. См. [примеры в документации Heartbeat](https://tuna.am/docs/monitors/types/heartbeat.md). *** #### Диагностика неполадок ##### Процесс heartbeat не запускается Проверьте, что процесс присутствует в списке: ```bash ps -ef | grep heartbeat ``` Если в выводе нет строк с `/data/tuna/tuna-heartbeat.sh` — убедитесь, что запись в `/etc/inittab` не закомментирована: ```bash grep heartbeat /etc/inittab ``` Строка должна начинаться с `thb::respawn`, а не с `#`. Если она закомментирована — раскомментируйте и перечитайте конфигурацию: ```bash kill -HUP 1 ``` ##### Монитор показывает "Down" **Причины:** * Неверный MONITOR_ID * Отсутствует интернет-соединение * Интервал в скрипте не соответствует настройкам монитора **Проверка:** ```bash # Проверить наличие IP-адреса ip addr # Проверить маршрут по умолчанию ip route # Проверить доступ в интернет ping -c 3 8.8.8.8 ``` ##### После обновления прошивки heartbeat перестал работать Проверьте, не обновлялась ли прошивка — после remote rsync нужно восстановить записи в `/etc/inittab` (см. [Восстановление после перепрошивки](#%D0%B2%D0%BE%D1%81%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BF%D0%BE%D1%81%D0%BB%D0%B5-%D0%BF%D0%B5%D1%80%D0%B5%D0%BF%D1%80%D0%BE%D1%88%D0%B8%D0%B2%D0%BA%D0%B8)) *** --- ### Статус-страницы [Перейти в личный кабинет](https://my.tuna.am/monitors/status-pages) Публичные страницы для информирования пользователей о состоянии ваших сервисов. ![Пример статус-страницы со статусом сервисов](/docs/img/monitors/status_pages/main.png) *** #### Обзор **Статус-страница** собирает выбранные мониторы в одну публичную страницу с историей доступности и текущим статусом каждого сервиса. Удобно показывать клиентам и команде, что работает, что временно недоступно и какой uptime у инфраструктуры. Зачем нужны статус-страницы * Информировать клиентов о работоспособности сервиса * Показывать историю доступности (uptime) с понятной шкалой * Группировать мониторы по логике (Личный кабинет, API, Базы данных и т.д.) * Закрывать страницу паролем для внутреннего использования * Брендировать страницу под свой проект — логотип, фавикон, ссылки * Размещать на собственном поддомене `*.tuna-status.am` #### Список статус-страниц Все ваши страницы доступны в разделе [Статус-страницы](https://my.tuna.am/monitors/status-pages). Здесь видно название, алиас (поддомен) и количество подключённых мониторов. ![Список статус-страниц в личном кабинете](/docs/img/monitors/status_pages/list.png) #### Создание статус-страницы 1. Перейдите в раздел [Статус-страницы](https://my.tuna.am/monitors/status-pages). 2. Нажмите **+ Создать статус-страницу**. 3. Заполните основные настройки и выберите мониторы — подробнее ниже. 4. Сохраните страницу — она сразу будет доступна по адресу `<алиас>.tuna-status.am`. *** #### Настройки ##### Основное * **Название** — отображается в шапке страницы и в заголовке вкладки браузера. * **Алиас** — определяет адрес страницы в формате `<алиас>.tuna-status.am`. * **Описание** — короткий текст под заголовком (необязательно). ![Основные настройки статус-страницы: название, алиас, описание, доступ, ссылки](/docs/img/monitors/status_pages/settings_1.png) ##### Доступ * **Установить пароль** — закрывает страницу авторизацией. Удобно для внутренних дашбордов или приватных клиентов. * **Скрыть от поисковых систем** — добавляет блокировку для поисковых ботов, чтобы страница не индексировалась. ##### Ссылки * **URL сайта** — ссылка на основной сайт сервиса. Отображается на статус-странице. * **URL поддержки** — ссылка на форму или портал поддержки, куда пользователь может обратиться при инциденте. ##### Брендирование Подстройте внешний вид страницы под фирменный стиль: * **Логотип** — изображение в шапке (PNG, JPG или SVG). * **Ссылка на логотипе** — куда переходит пользователь по клику на лого (обычно главная сайта). * **Фавикон** — иконка вкладки браузера (PNG, ICO или SVG). ![Настройки брендирования: логотип, ссылка на логотипе, фавикон, период истории, цветовая тема](/docs/img/monitors/status_pages/settings_2.png) ##### Отображение * **Период истории** — за какой промежуток показывать историю доступности (например, 7 дней). * **Цветовая тема** — `Авто` (подстраивается под систему пользователя), светлая или тёмная. ##### Мониторы Добавляйте мониторы и группируйте их по разделам — каждая группа получит свой заголовок на странице. Внутри группы мониторы можно переименовать (то, что увидит пользователь, может отличаться от внутреннего названия в Tuna). ![Группы мониторов на статус-странице: Личный кабинет, Туннели, Встречи](/docs/img/monitors/status_pages/settings_3.png) подсказка Группы и мониторы внутри них можно перетаскивать — порядок на статус-странице совпадает с порядком в настройках. *** #### Как выглядит страница Здесь вы можете посмотреть пример брендированной статус-страницы в светлой и темной темах. ##### Светлая тема ![Брендированная статус-страница в светлой теме](/docs/img/monitors/status_pages/branding_d.png) ##### Тёмная тема ![Брендированная статус-страница в тёмной теме](/docs/img/monitors/status_pages/branding_n.png) В правом нижнем углу пользователь может вручную переключить тему и язык интерфейса. --- ### Типы мониторов Tuna поддерживает 6 типов мониторов для разных сценариев использования. *** #### Пользовательские мониторы Эти мониторы ожидают сигналы от ваших приложений и скриптов: * [**Job (CronJob)**](https://tuna.am/docs/monitors/types/job.md) — мониторинг выполнения периодических задач * [**Heartbeat**](https://tuna.am/docs/monitors/types/heartbeat.md) — мониторинг регулярных сигналов от сервисов *** #### Внешние мониторы Эти мониторы самостоятельно проверяют доступность ваших ресурсов: * [**HTTP**](https://tuna.am/docs/monitors/types/http.md) — проверка доступности веб-сайтов и API * [**TCP**](https://tuna.am/docs/monitors/types/tcp.md) — проверка доступности TCP-сервисов * [**DNS**](https://tuna.am/docs/monitors/types/dns.md) — проверка DNS-записей * [**ICMP (Ping)**](https://tuna.am/docs/monitors/types/icmp.md) — проверка сетевой доступности *** #### [📄️Задача (Job)](https://tuna.am/docs/monitors/types/job.md) [Мониторинг выполнения периодических задач по расписанию](https://tuna.am/docs/monitors/types/job.md) #### [📄️Heartbeat](https://tuna.am/docs/monitors/types/heartbeat.md) [Мониторинг регулярных сигналов от сервисов и приложений](https://tuna.am/docs/monitors/types/heartbeat.md) #### [📄️HTTP](https://tuna.am/docs/monitors/types/http.md) [Мониторинг доступности веб-сайтов и API](https://tuna.am/docs/monitors/types/http.md) #### [📄️TCP](https://tuna.am/docs/monitors/types/tcp.md) [Мониторинг доступности TCP сервисов и портов](https://tuna.am/docs/monitors/types/tcp.md) #### [📄️DNS](https://tuna.am/docs/monitors/types/dns.md) [Мониторинг DNS записей и резолва доменов](https://tuna.am/docs/monitors/types/dns.md) #### [📄️ICMP (Ping)](https://tuna.am/docs/monitors/types/icmp.md) [Мониторинг сетевой доступности хостов через ICMP](https://tuna.am/docs/monitors/types/icmp.md) --- ### DNS [Перейти в личный кабинет](https://my.tuna.am/monitors) DNS монитор проверяет корректность DNS записей и резолва доменов. *** #### Принцип работы 1. Система выполняет DNS запрос для указанного домена 2. Проверяет наличие и значение DNS записей 3. При несоответствии условиям — отправляется уведомление *** #### Параметры ##### Описание | Параметр | Описание | Обязательный | | ------------ | ------------------------------ | ------------ | | **Название** | Уникальное имя монитора | Да | | **Описание** | Примечание о назначении задачи | Нет | ![скриншот с описанием монитора](/docs/img/monitors/description.png) ##### Детали | Параметр | Описание | По умолчанию | | ----------- | --------------------------------------- | ------------ | | **Домен** | IP адрес или домен | - | | **Таймаут** | Максимальное время ожидания ответа | 10 секунд | | **Повторы** | Количество повторных попыток при ошибке | 3 | ![скриншот с деталями DNS монитора](/docs/img/monitors/details_dns.png) ##### Проверки DNS монитор поддерживает различные проверки ответа: ![скриншот с параметрами проверок DNS монитора](/docs/img/monitors/check_dns.png) подсказка Для **MX** записей метрика указывается через двоеточие, как на скриншоте выше. ##### Регионы Выберите один или несколько регионов для проверки. Монитор будет отправлять запросы из каждого выбранного региона с заданным интервалом. | Параметр | Описание | По умолчанию | | ------------ | ---------------- | ------------ | | **Интервал** | Частота проверок | 5 минут | ![скриншот с регионом монитора](/docs/img/monitors/region.png) ##### Уведомления Здесь можно указать группы контактов для уведомлений, если не указывать, то используется Email пользователя. Также задаётся период ожидания - **Grace Period**. Добавляется к ожидаемому времени следующего сигнала. Например, если интервал 5 минут и Grace Period 2 минуты, то алерт будет отправлен через 7 минут после последнего сигнала. Повтор уведомлений напоминает о проблеме, можно задать интервал этих напоминаний и их количество. ![скриншот с деталями job монитора](/docs/img/monitors/notify.png) *** #### Типы DNS записей DNS монитор поддерживает проверку следующих типов записей: | Тип | Описание | Пример значения | | --------- | ------------------------------------- | ------------------------------------- | | **A** | IPv4 адрес | `93.184.216.34` | | **AAAA** | IPv6 адрес | `2606:2800:220:1:248:1893:25c8:1946` | | **CNAME** | Каноническое имя (alias) | `www.example.com` | | **MX** | Почтовый сервер | `mail.example.com.:10` | | **TXT** | Текстовая запись | `v=spf1 include:_spf.google.com ~all` | | **NS** | Name server | `ns1.example.com` | | **SOA** | Start of Authority | — | | **PTR** | Pointer (reverse DNS) | `example.com` | | **SRV** | Service record | `0 5 5269 xmpp.example.com` | | **CAA** | Certification Authority Authorization | `0 issue "letsencrypt.org"` | --- ### Heartbeat [Перейти в личный кабинет](https://my.tuna.am/monitors) Heartbeat - монитор предназначен для отслеживания регулярных сигналов от сервисов, работающих в закрытых сетях, IoT устройств или фоновых процессов. *** #### Принцип работы 1. Вы создаёте Heartbeat монитор и задаёте ожидаемый интервал сигналов 2. Ваше приложение периодически отправляет сигнал `ping` 3. Если сигнал не приходит в течение заданного времени — отправляется уведомление *** #### Параметры ##### Описание | Параметр | Описание | Обязательный | | ------------ | ------------------------------ | ------------ | | **Название** | Уникальное имя монитора | Да | | **Описание** | Примечание о назначении задачи | Нет | ![скриншот с описанием монитора](/docs/img/monitors/description.png) ##### Детали Указываем ожидаемый интервал между задачами и опционально максимальное время выполнения. ![скриншот с деталями heartbeat монитора](/docs/img/monitors/details_heartbeat.png) ![скриншот с деталями heartbeat монитора](/docs/img/monitors/cron_heartbeat.png) ###### Интервал Поддерживается два типа расписания: **Интервал** Ожидаемый интервал между сигналами: | Значение | Описание | | -------- | -------------------------------- | | 1 минута | Сигнал ожидается каждую минуту | | 5 минут | Сигнал ожидается каждые 5 минут | | 15 минут | Сигнал ожидается каждые 15 минут | | 30 минут | Сигнал ожидается каждые 30 минут | | 60 минут | Сигнал ожидается каждый час | **Cron выражение** Для нерегулярных расписаний используйте [Cron-выражение](https://ru.wikipedia.org/wiki/Cron): ```shell ┌───────────── минута (0 - 59) │ ┌───────────── час (0 - 23) │ │ ┌───────────── день месяца (1 - 31) │ │ │ ┌───────────── месяц (1 - 12) │ │ │ │ ┌───────────── день недели (0 - 6) │ │ │ │ │ * * * * * ``` **Примеры:** | Выражение | Описание | | ---------------- | ------------------------------ | | `*/5 * * * *` | Каждые 5 минут | | `0 * * * *` | Каждый час | | `0 9-18 * * 1-5` | Каждый час с 9 до 18 по будням | ##### Уведомления Задача монитор отправляет уведомления в следующих случаях: | Причина | Описание | | --------------- | -------------------------------------------- | | **Not Running** | Задача не запустилась в течение Grace Period | | **Recovery** | Задача восстановилась после ошибки | Здесь можно указать группы контактов для уведомлений, если не указывать, то используется Email пользователя. Также задаётся период ожидания - **Grace Period**. Добавляется к ожидаемому времени следующего сигнала. Например, если интервал 5 минут и Grace Period 2 минуты, то алерт будет отправлен через 7 минут после последнего сигнала. Повтор уведомлений напоминает о проблеме, можно задать интервал этих напоминаний и их количество. ![скриншот с деталями job монитора](/docs/img/monitors/notify.png) *** #### Использование ##### Через CLI ```bash # Простой ping tuna monitor ping MONITOR_ID # С указанием хоста (полезно для идентификации источника) tuna monitor ping MONITOR_ID --host=server-01 # С сообщением tuna monitor ping MONITOR_ID --message="All systems operational" ``` ##### Через HTTP Помимо tuna cli, можно отправлять сигналы напрямую через HTTP запросы. Это полезно когда CLI недоступен или вы используете другие языки программирования. **Формат URL:** ```shell https://monitor.tuna.am/{MONITOR_ID}/{slug-name} ``` подсказка `{slug-name}` - опционален и нужен скорее для простой идентификации монитора в коде. **curl** ```bash # Простой ping curl -s "https://monitor.tuna.am/MONITOR_ID/test" # С указанием статуса curl -s "https://monitor.tuna.am/MONITOR_ID/test?state=ping" curl -s "https://monitor.tuna.am/MONITOR_ID/test?state=start" curl -s "https://monitor.tuna.am/MONITOR_ID/test?state=finish" curl -s "https://monitor.tuna.am/MONITOR_ID/test?state=fail" # С сообщением (корректная кодировка UTF-8) curl -G "https://monitor.tuna.am/MONITOR_ID/test" \ --data-urlencode "message=Backup completed successfully" # С указанием хоста и сообщением curl -G "https://monitor.tuna.am/MONITOR_ID/test?host=server-01" \ --data-urlencode "message=Все системы работают" ``` **wget** ```bash # Простой ping wget -qO- "https://monitor.tuna.am/MONITOR_ID/test" # С параметрами wget -qO- "https://monitor.tuna.am/MONITOR_ID/test?state=ping&host=server-01" ``` **Python** ```python import requests from urllib.parse import urlencode MONITOR_ID = "your_monitor_id" BASE_URL = f"https://monitor.tuna.am/{ENDPOINT_TOKEN}" # Простой ping requests.get(BASE_URL) # С параметрами params = { "state": "ping", "host": "server-01", "message": "Задача выполнена успешно" } requests.get(BASE_URL, params=params) ``` **PowerShell** ```powershell # Простой ping Invoke-WebRequest -Uri "https://monitor.tuna.am/MONITOR_ID/test" -Method GET # С параметрами $params = @{ state = "ping" host = "server-01" message = "Backup completed" } $uri = "https://monitor.tuna.am/MONITOR_ID/test" Invoke-WebRequest -Uri $uri -Method GET -Body $params ``` ###### Параметры запроса | Параметр | Описание | | --------- | ------------------------------------------------------- | | `state` | Статус сигнала: `ping`, `start`, `finish`, `fail` | | `host` | Идентификатор хоста (полезно при нескольких источниках) | | `message` | Произвольное сообщение | ##### В systemd сервисе ```ini # /etc/systemd/system/my-heartbeat.service [Unit] Description=Heartbeat ping to Tuna After=network.target [Service] Type=oneshot ExecStart=/usr/local/bin/tuna monitor ping MONITOR_ID [Install] WantedBy=multi-user.target ``` ```ini # /etc/systemd/system/my-heartbeat.timer [Unit] Description=Run heartbeat every 5 minutes [Timer] OnBootSec=1min OnUnitActiveSec=5min [Install] WantedBy=timers.target ``` ```bash systemctl enable --now my-heartbeat.timer ``` ##### В crontab ```bash # Heartbeat каждые 5 минут */5 * * * * /usr/local/bin/tuna monitor ping MONITOR_ID ``` *** #### Статусы | Статус | Описание | | -------- | --------------------------------------- | | **New** | Монитор создан, ожидается первый сигнал | | **Up** | Сигналы приходят регулярно | | **Down** | Сигнал не пришёл в ожидаемое время | *** #### Примеры использования ##### Мониторинг GitLab Runner в офисе ```bash # На машине с GitLab Runner */5 * * * * /usr/local/bin/tuna monitor ping MONITOR_ID --host=gitLab-runner-0 ``` ##### Мониторинг VPN соединения ```bash #!/bin/bash # Проверяем VPN канал и отправляем heartbeat только если соединение активно ping -c 1 192.168.14.88 && tuna monitor ping MONITOR_ID --message="VPN is up" ``` --- ### HTTP [Перейти в личный кабинет](https://my.tuna.am/monitors) HTTP монитор проверяет доступность веб-сайтов и API, отправляя HTTP запросы из нескольких географических регионов. *** #### Принцип работы 1. Система отправляет HTTP запрос на указанный URL из выбранных регионов 2. Можно задавать метод и проверять код ответа, заголовки и тело ответа 3. При несоответствии условиям — отправляется уведомление *** #### Параметры ##### Описание | Параметр | Описание | Обязательный | | ------------ | ------------------------------ | ------------ | | **Название** | Уникальное имя монитора | Да | | **Описание** | Примечание о назначении задачи | Нет | ![скриншот с описанием монитора](/docs/img/monitors/description.png) ##### Детали | Параметр | Описание | По умолчанию | | ------------------------------ | --------------------------------------- | ------------ | | **Метод** | HTTP метод запроса | GET | | **Адрес** | URL проверяемого ресурса | - | | **Заголовки** | Дополнительные HTTP заголовки | — | | **Таймаут** | Максимальное время ожидания ответа | 10 секунд | | **Повторы** | Количество повторных попыток при ошибке | 3 | | **Следовать перенаправлениям** | Следовать ли перенаправлениям (3xx) | Да | **Поддерживаемые методы:** * GET * POST * PUT * PATCH * DELETE * HEAD * OPTIONS * TRACE ![скриншот с деталями HTTP монитора](/docs/img/monitors/details_http.png) ##### Проверки HTTP монитор поддерживает различные проверки ответа: ![скриншот с параметрами проверок HTTP монитора](/docs/img/monitors/check_http.png) ##### Регионы Выберите один или несколько регионов для проверки. Монитор будет отправлять запросы из каждого выбранного региона с заданным интервалом. | Параметр | Описание | По умолчанию | | ------------ | ---------------- | ------------ | | **Интервал** | Частота проверок | 5 минут | ![скриншот с регионом монитора](/docs/img/monitors/region.png) ##### Уведомления Здесь можно указать группы контактов для уведомлений, если не указывать, то используется Email пользователя. Также задаётся период ожидания - **Grace Period**. Добавляется к ожидаемому времени следующего сигнала. Например, если интервал 5 минут и Grace Period 2 минуты, то алерт будет отправлен через 7 минут после последнего сигнала. Повтор уведомлений напоминает о проблеме, можно задать интервал этих напоминаний и их количество. ![скриншот с деталями job монитора](/docs/img/monitors/notify.png) *** #### SSL/TLS и Whois мониторинг HTTP монитор автоматически проверяет SSL сертификаты для HTTPS адресов и выводит информацию о нём. А также регистратора домена и срок истечения. ![скриншот с SSL сертификатом HTTP монитора](/docs/img/monitors/tls.png) --- ### ICMP (Ping) [Перейти в личный кабинет](https://my.tuna.am/monitors) ICMP монитор проверяет сетевую доступность хостов с помощью ICMP Echo Request (ping). *** #### Принцип работы 1. Система отправляет ICMP Echo Request на указанный хост 2. Ожидает ICMP Echo Reply 3. При отсутствии ответа — отправляется уведомление *** #### Параметры ##### Описание | Параметр | Описание | Обязательный | | ------------ | ------------------------------ | ------------ | | **Название** | Уникальное имя монитора | Да | | **Описание** | Примечание о назначении задачи | Нет | ![скриншот с описанием монитора](/docs/img/monitors/description.png) ##### Детали | Параметр | Описание | По умолчанию | | ----------- | --------------------------------------- | ------------ | | **Хост** | IP адрес или домен | - | | **Таймаут** | Максимальное время ожидания ответа | 10 секунд | | **Повторы** | Количество повторных попыток при ошибке | 3 | ![скриншот с деталями ICMP монитора](/docs/img/monitors/details_icmp.png) ##### Регионы Выберите один или несколько регионов для проверки. Монитор будет отправлять запросы из каждого выбранного региона с заданным интервалом. | Параметр | Описание | По умолчанию | | ------------ | ---------------- | ------------ | | **Интервал** | Частота проверок | 5 минут | ![скриншот с регионом монитора](/docs/img/monitors/region.png) ##### Уведомления Здесь можно указать группы контактов для уведомлений, если не указывать, то используется Email пользователя. Также задаётся период ожидания - **Grace Period**. Добавляется к ожидаемому времени следующего сигнала. Например, если интервал 5 минут и Grace Period 2 минуты, то алерт будет отправлен через 7 минут после последнего сигнала. Повтор уведомлений напоминает о проблеме, можно задать интервал этих напоминаний и их количество. ![скриншот с деталями job монитора](/docs/img/monitors/notify.png) *** #### Ограничения * Некоторые хосты блокируют ICMP трафик на firewall уровне * ICMP не проверяет работоспособность сервисов, только сетевую доступность * Для проверки конкретных сервисов используйте [TCP](https://tuna.am/docs/monitors/types/tcp.md) или [HTTP](https://tuna.am/docs/monitors/types/http.md) мониторы *** --- ### Задача (Job) [Перейти в личный кабинет](https://my.tuna.am/monitors) Задача/Job - монитор предназначен для отслеживания выполнения периодических задач: backup скриптов, cron задач и других операций по расписанию. *** #### Принцип работы 1. Вы создаёте Job монитор и задаёте расписание выполнения 2. При запуске задачи отправляется сигнал `start` 3. При успешном завершении отправляется сигнал `finish` 4. При ошибке отправляется сигнал `fail` 5. Система отслеживает своевременность запуска и время выполнения *** #### Параметры ##### Описание | Параметр | Описание | Обязательный | | ------------ | ------------------------------ | ------------ | | **Название** | Уникальное имя монитора | Да | | **Описание** | Примечание о назначении задачи | Нет | ![скриншот с описанием монитора](/docs/img/monitors/description.png) ##### Детали Указываем ожидаемый интервал между задачами и опционально максимальное время выполнения. ![скриншот с деталями job монитора](/docs/img/monitors/details_job.png) ![скриншот с деталями job монитора](/docs/img/monitors/cron_job.png) ###### Интервал Поддерживается два типа расписания: **Интервал** Ожидаемый интервал между сигналами: | Значение | Описание | | -------- | -------------------------------- | | 1 минута | Сигнал ожидается каждую минуту | | 5 минут | Сигнал ожидается каждые 5 минут | | 15 минут | Сигнал ожидается каждые 15 минут | | 30 минут | Сигнал ожидается каждые 30 минут | | 60 минут | Сигнал ожидается каждый час | **Cron выражение** Для нерегулярных расписаний используйте [Cron-выражение](https://ru.wikipedia.org/wiki/Cron): ```shell ┌───────────── минута (0 - 59) │ ┌───────────── час (0 - 23) │ │ ┌───────────── день месяца (1 - 31) │ │ │ ┌───────────── месяц (1 - 12) │ │ │ │ ┌───────────── день недели (0 - 6) │ │ │ │ │ * * * * * ``` **Примеры:** | Выражение | Описание | | ---------------- | ------------------------------ | | `*/5 * * * *` | Каждые 5 минут | | `0 * * * *` | Каждый час | | `0 9-18 * * 1-5` | Каждый час с 9 до 18 по будням | ###### Время выполнения Максимальная длительность задачи **Running Time** - если задача выполняется дольше указанного времени, отправляется уведомление. ##### Уведомления Задача монитор отправляет уведомления в следующих случаях: | Причина | Описание | | ---------------- | --------------------------------------------------------------- | | **Fail** | Задача завершилась с ошибкой (сигнал `fail` или exit code != 0) | | **Not Running** | Задача не запустилась в течение Grace Period | | **Long Running** | Задача выполняется дольше Running Time | | **Recovery** | Задача восстановилась после ошибки | Здесь можно указать группы контактов для уведомлений, если не указывать, то используется Email пользователя. Также задаётся период ожидания - **Grace Period**. Добавляется к ожидаемому времени следующего сигнала. Например, если интервал 5 минут и Grace Period 2 минуты, то алерт будет отправлен через 7 минут после последнего сигнала. Повтор уведомлений напоминает о проблеме, можно задать интервал этих напоминаний и их количество. ![скриншот с деталями job монитора](/docs/img/monitors/notify.png) *** #### Использование ##### Через CLI (рекомендуется) Команда `tuna monitor exec` автоматически отправляет сигналы `start`, `finish` или `fail`: ```bash tuna monitor exec MONITOR_ID -- ./backup.sh ``` Если вы хотите контролировать сигналы вручную: ```bash # Начало выполнения tuna monitor ping MONITOR_ID --state=start # Выполнение вашей задачи ./your-task.sh # Успешное завершение tuna monitor ping MONITOR_ID --state=finish # Или ошибка tuna monitor ping MONITOR_ID --state=fail ``` ##### Через HTTP Помимо tuna cli, можно отправлять сигналы напрямую через HTTP запросы. Это полезно когда CLI недоступен или вы используете другие языки программирования. **Формат URL:** ```shell https://monitor.tuna.am/{MONITOR_ID}/{slug-name} ``` подсказка `{slug-name}` - опционален и нужен скорее для простой идентификации монитора в коде. **curl** ```bash # Простой ping curl -s "https://monitor.tuna.am/MONITOR_ID/test" # С указанием статуса curl -s "https://monitor.tuna.am/MONITOR_ID/test?state=ping" curl -s "https://monitor.tuna.am/MONITOR_ID/test?state=start" curl -s "https://monitor.tuna.am/MONITOR_ID/test?state=finish" curl -s "https://monitor.tuna.am/MONITOR_ID/test?state=fail" # С сообщением (корректная кодировка UTF-8) curl -G "https://monitor.tuna.am/MONITOR_ID/test" \ --data-urlencode "message=Backup completed successfully" # С указанием хоста и сообщением curl -G "https://monitor.tuna.am/MONITOR_ID/test?host=server-01" \ --data-urlencode "message=Все системы работают" ``` **wget** ```bash # Простой ping wget -qO- "https://monitor.tuna.am/MONITOR_ID/test" # С параметрами wget -qO- "https://monitor.tuna.am/MONITOR_ID/test?state=ping&host=server-01" ``` **Python** ```python import requests from urllib.parse import urlencode MONITOR_ID = "your_monitor_id" BASE_URL = f"https://monitor.tuna.am/{ENDPOINT_TOKEN}" # Простой ping requests.get(BASE_URL) # С параметрами params = { "state": "ping", "host": "server-01", "message": "Задача выполнена успешно" } requests.get(BASE_URL, params=params) ``` **PowerShell** ```powershell # Простой ping Invoke-WebRequest -Uri "https://monitor.tuna.am/MONITOR_ID/test" -Method GET # С параметрами $params = @{ state = "ping" host = "server-01" message = "Backup completed" } $uri = "https://monitor.tuna.am/MONITOR_ID/test" Invoke-WebRequest -Uri $uri -Method GET -Body $params ``` ###### Параметры запроса | Параметр | Описание | | --------- | ------------------------------------------------------- | | `state` | Статус сигнала: `ping`, `start`, `finish`, `fail` | | `host` | Идентификатор хоста (полезно при нескольких источниках) | | `message` | Произвольное сообщение | Подробнее: [Работа с мониторами в CLI](https://tuna.am/docs/monitors/cli.md) *** #### Статусы | Статус | Описание | | ----------- | ------------------------------------------------------- | | **New** | Монитор создан, ожидается первый запуск | | **Running** | Задача выполняется (получен сигнал `start`) | | **Up** | Задача успешно завершена (получен сигнал `finish`) | | **Down** | Задача завершилась с ошибкой или не запустилась вовремя | *** #### Логирование При использовании `tuna monitor exec` система автоматически захватывает stdout и stderr вашей задачи. Логи можно просмотреть в интерфейсе в истории событий монитора. ![скриншот с сообщением в message](/docs/img/monitors/event.png) Для отключения отправки логов используйте флаг `--no-stdout`: ```bash tuna monitor exec MONITOR_ID --no-stdout -- ./task.sh ``` *** #### Примеры использования ##### Backup PostgreSQL ```bash #!/bin/bash # /scripts/backup-postgres.sh tuna monitor exec MONITOR_ID -- pg_dump -U postgres mydb > /backups/mydb_$(date +%Y%m%d).sql ``` ##### Синхронизация данных ```bash #!/bin/bash # /scripts/sync-data.sh tuna monitor exec MONITOR_ID -- rsync -avz /data/ remote:/backup/data/ ``` ##### Crontab ```bash # Backup базы данных каждую ночь в 3:00 0 3 * * * tuna monitor exec MONITOR_ID -- /scripts/backup-db.sh # Очистка логов каждый час 0 * * * * tuna monitor exec MONITOR_ID -- /scripts/cleanup-logs.sh ``` --- ### TCP [Перейти в личный кабинет](https://my.tuna.am/monitors) TCP монитор проверяет доступность сервисов через TCP соединение: базы данных, почтовые серверы, игровые серверы и другие TCP-приложения. *** #### Принцип работы 1. Система устанавливает TCP соединение с указанным хостом и портом 2. Если соединение успешно установлено — сервис считается доступным 3. При ошибке соединения — отправляется уведомление *** #### Параметры ##### Описание | Параметр | Описание | Обязательный | | ------------ | ------------------------------ | ------------ | | **Название** | Уникальное имя монитора | Да | | **Описание** | Примечание о назначении задачи | Нет | ![скриншот с описанием монитора](/docs/img/monitors/description.png) ##### Детали | Параметр | Описание | По умолчанию | | ----------- | --------------------------------------- | ------------ | | **Ресурс** | `host:port` | - | | **Таймаут** | Максимальное время ожидания соединения | 10 секунд | | **Повторы** | Количество повторных попыток при ошибке | 3 | ![скриншот с деталями TCP монитора](/docs/img/monitors/details_tcp.png) ##### Регионы Выберите один или несколько регионов для проверки. Монитор будет отправлять запросы из каждого выбранного региона с заданным интервалом. | Параметр | Описание | По умолчанию | | ------------ | ---------------- | ------------ | | **Интервал** | Частота проверок | 5 минут | ![скриншот с регионом монитора](/docs/img/monitors/region.png) ##### Уведомления Здесь можно указать группы контактов для уведомлений, если не указывать, то используется Email пользователя. Также задаётся период ожидания - **Grace Period**. Добавляется к ожидаемому времени следующего сигнала. Например, если интервал 5 минут и Grace Period 2 минуты, то алерт будет отправлен через 7 минут после последнего сигнала. Повтор уведомлений напоминает о проблеме, можно задать интервал этих напоминаний и их количество. ![скриншот с деталями job монитора](/docs/img/monitors/notify.png) *** --- ### Менеджер паролей В этом разделе описаны возможности и функции [Менеджера паролей](https://my.tuna.am/passwords). ![passwords-main](/assets/images/main-dacca5895830a1cf52a5767b574b095a.png) #### Обзор Менеджер паролей Tuna создан для безопасного хранения и удобного обмена паролей и других видов секретов для разработчиков, администраторов их команд и не только. Мы не храним пароли в открытом виде, согласно модели [нулевого знания](https://en.wikipedia.org/wiki/Zero-knowledge_proof), **только** пользователь обладает ключами, которые могут расшифровать данные. к сведению В настоящий момент [Менеджер паролей](https://my.tuna.am/passwords) является бесплатной функцией и доступен всем пользователям и командам без ограничений. Вы можете хранить пароли, SSH-ключи, лицензии, заметки, реквизиты к базам данных и прочие типы секретов. Создавать общие каталоги с секретами внутри команды и делиться ими с любыми людьми вне платформы Tuna. Подробнее все возможности описаны в [отдельном разделе](https://tuna.am/docs/passwords/usage.md). #### Мотивация Почему мы встроили **Менеджер паролей** в Tuna? Мы заметили, что во многих командах разработчиков и администраторов отсутствует культура безопасного хранения паролей и секретов. При этом у всех есть потребность хранить какие то инфраструктурные пароли, SSH ключи, офисный WI-FI и так далее. Но не всегда есть доступные инструменты для безопасного и удобно способа делиться ими с командой, заказчиками, аудиторами или просто друзьями. Тогда люди начинают передавать пароли в открытом виде в чатах, письмах, записках. Наша цель это повысить культуру хранения секретов среди наших пользователей и обезопасить клиентов и от утечек, и несанкционированного доступа к их инфраструктуре. Поэтому **Менеджер паролей** является базовой и бесплатной функцией для всех. #### Архитектура При создании хранилища браузер генерирует **Приватный (Private key)** и **Публичный (Public key)** RSA ключи, а также **Мастер-ключ** (Passphrase в терминологии openssl) которым зашифрован **Приватный ключ**. **Мастер-ключ** есть только у пользователя, рекомендуем хранить его в надёжном месте (желательно записать на бумаге) и не передавать никому и ни при каких обстоятельствах. Если вы потеряете свой **Мастер-ключ** восстановить доступ к паролям будет невозможно. **Приватный** и **Публичный (Public key)** ключи хранятся на стороне Tuna в зашифрованном виде. Сами пароли шифруются **Приватным ключом**. ![schema](/assets/images/schema-464332b4967897a522780f7dd4631521.png) Алгоритм чтения зашифрованной записи выглядит следующим образом: 1. Пользователь авторизуется в личном кабинете [my.tuna.am](https://my.tuna.am/) 2. Переходит на вкладку [Менеджер паролей](https://my.tuna.am/passwords) 3. Пользователь получает запрос ПИН-кода и свой зашифрованный приватный ключ 4. Пользователь вводит ПИН-код, после чего происходит расшифровка и верификация мастер ключа, затем расшифровка и верификация приватного ключа 5. Пользователь получает список каталогов и список записей 6. Пользователь переходит в запись, в этот момент запись расшифровывается с помощью приватного ключа При редактировании или создании новой записи данные сначала шифруются с помощью приватного ключа в браузере, после чего отправляются на сервер - это гарантирует, что мы не можем расшифровать хранящиеся на серверах Tuna записи и не сможем восстановить доступ к ним в случае утраты мастер-ключа. Внимание Доступ к своему хранилищу паролей имеет **ТОЛЬКО** его владелец. Если пользователь потерял свой **Мастер-ключ** восстановить доступ к паролям **невозможно**! Вы видите **Мастер-ключ** лишь 1 раз при создании **Мастер-ключа** и хранилища. Рекомендуем хранить **Мастер-ключ** в надёжном месте (желательно записать на бумаге) и не передавать никому и ни при каких обстоятельствах. #### Навигация #### [📄️Создание хранилища](https://tuna.am/docs/passwords/init.md) [Инициализация хранилища паролей и Мастер-ключа](https://tuna.am/docs/passwords/init.md) #### [📄️Обзор возможностей](https://tuna.am/docs/passwords/usage.md) [Обзор возможности и функции](https://tuna.am/docs/passwords/usage.md) #### [📄️Восстановление доступа](https://tuna.am/docs/passwords/restore.md) [Восстановление доступа при утере Мастер-ключа](https://tuna.am/docs/passwords/restore.md) --- ### Создание хранилища Нажмите **Создать мастер-ключ**, после чего скопируйте его и сохраните в надёжном месте (желательно записать на бумаге) и не передавать никому и ни при каких обстоятельствах. осторожно При утере **Мастер-ключа** восстановить доступ к паролям будет невозможно. ![init](/assets/images/init-a7974ec60b970a223370ec231a2ce0c9.png) Для удобства работы с хранилищем в текущей сессии браузера введите короткий ПИН-код, любая строка от 4х символов. ПИН-код уникален только в рамках сессии, в разных браузерах или на разных устройствах вы можете использовать разные ПИН-коды. Мастер-ключ будет зашифрован этим ПИН-ом + уникальная [соль](https://ru.wikipedia.org/wiki/%D0%A1%D0%BE%D0%BB%D1%8C_\(%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%BE%D0%B3%D1%80%D0%B0%D1%84%D0%B8%D1%8F\)) текущей сессии. Зашифрованный таким образом Мастер-ключ будет сохранён в [localStorage](https://www.w3schools.com/html/html5_webstorage.asp) браузера и вам не потребуется каждый раз вводить Мастер-ключ во время всего периода жизни сессии. ![unlock](/assets/images/unlock-b9592161c0cbb8f02402245b60cff0ef.png) Доступ к паролям будет автоматически блокироваться через 5 секунд при переходе на в любой другой раздел сайта Tuna, другую вкладку браузера или окно программы. При возвращении в раздел Менеджер паролей, потребуется ввести введенный ранее ПИН. Если вы забыли ПИН - то его можно сбросить, заново ввести Мастер-ключ и новый ПИН. При выходе из аккаунта (закрытии сессии) все данные из localStorage удаляются. ![list](/assets/images/list-031871c5856889fe788459d8d9e183c8.png) После инициализации **Мастер-ключ** будет сохранён и внутри хранилища в виде пароля каталоге **Мои пароли**. Этот каталог отличается от других тем, что им нельзя делиться, с другими членами команды. --- ### Восстановление доступа осторожно При утере **Мастер-ключа** восстановить доступ к паролям будет невозможно. Если пользователь всё таки потерял свой **Мастер-ключ**: * В случае если у вас было открыто несколько сессий в разных браузерах или устройствах и вы помните ПИН хотя бы от одной сессии, то вы можете открыть **Менеджер паролей** на авторизованном устройстве и посмотреть **Мастер-ключ** сохранённый в каталоге **Мои пароли**. Список активных сессий вы можете посмотреть в [профиле](https://my.tuna.am/profile) пользователя. Нажмите **Закрыть все сессии** чтобы увидеть все активные сессии. **Не нажимайте** *Закрыть сессии*, только посмотрите какие ещё есть авторизованные устройства. ![session-close](/assets/images/session-close-98c7f1430587e089fdece50587990e80.png) ![session-show](/assets/images/session-show-e30f44a233001f6263c1d0d3f2506618.png) * В [команде](https://tuna.am/docs/team/passwords.md) вы можете самостоятельно удалить хранилище со всеми паролями (это доступно **Основателю** и **Владельцам**) и пользователь сможет создать его заново. * В случае персонального аккаунта, необходимо обратиться в поддержку с зарегистрированного почтового ящика, администраторы удалят ваше хранилище со всеми паролями и можно было создать его заново. --- ### Обзор возможностей #### Типы секретов Вы можете создавать несколько разных типов секретов. ![pwd-types](/assets/images/pwd-types-2d6a18327bbc102893246e45dd5e23fa.png) * Пароль * Заметка * Электронная почта * SSH ключ * API ключ * База данных * Лицензия * WiFi роутер #### Каталоги и обмен в команде Можно создавать каталоги и группировать пароли по смыслу или уровню доступа. Например вы можете создать отдельный каталог с доступами к Production и Testing инфраструктуре с SSH и API ключами и доступами к Базам данных. Или отдельные каталоги для отделов DevOps, Backend, Frontend и добавить в каталоги соответствующих людей. Внутри [команды](https://tuna.am/docs/team.md) вы можете делиться этими каталогами с другими участниками. Они смогут просматривать, редактировать и добавлять новые пароли в этом каталоге. ![dir-share](/assets/images/dir-share-5876f952a07bb0b4177f9ef7c4a87891.png) #### Поделиться наружу Чтобы поделиться паролем с любым человеком вне команды, выберете нужный пароль и внизу справа нажмите на значок **поделиться**. Далее вы увидите меню с настройками ограничений сколько будет работать ссылка, также можно ограничить на одноразовый просмотр пароля. осторожно Никогда публикуйте пароль с **Мастер-ключом** ![](/docs/img/passwords/pwd-share-external-1.png) ![dir-share](/assets/images/pwd-share-external-2-8a82b021cd907354192a247d682d3030.png) ![dir-share](/assets/images/pwd-share-external-4-bb36935af49d4a82a33de92ac2dee3bf.png) --- ### Отчёты [Перейти в личный кабинет](https://my.tuna.am/reports) Функционал для сбора ошибок и создания избыточных отчётов на вашем сайте. ![Изображение с примером отчёта](/docs/img/reports/main.png) *** #### Обзор С помощью встраиваемого скрипта пользователи и QA-инженеры могут легко показать, где спрятался баг, а вы – получить отладочную информацию и сразу приступить к исправлению. ![Настройка](/docs/img/reports/setup.png) Для этого создайте проект и подключите скрипт на ваш сайт. #### Структура сервиса Внутри сервиса **Отчёты** находятся **Проекты**, предполагается, что вы создаёте отдельный проект под каждый свой сайт. Проекты разделяются по уникальному ключу `captureKey`. Внутри проектов уже будут появляться создаваемые вами отчёты с скриншотами и видео записями. #### Установка Разместите код на HTML странице перед закрытием тега ``: ```html ``` Замените **YOUR_CAPTURE_KEY** вашим из нужного проекта. #### Параметры скрипта Параметры задаются в объекте `window.reportOptions` до подключения скрипта. | Параметр | Тип | По умолчанию | Описание | | -------------------- | ---------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `captureKey` | `string` | — | Ключ проекта. Обязательный. | | `video` | `boolean` | `true` | Запись видео. Подробнее — [ниже](#video). | | `sensitiveUrlParams` | `string[]` | `[]` | Дополнительные параметры URL, значения которых маскируются. См. [Приватность данных](https://tuna.am/docs/reports/privacyOptions.md#%D0%B4%D0%BE%D0%B1%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D1%81%D0%B2%D0%BE%D0%B8%D1%85-%D0%BF%D0%B0%D1%80%D0%B0%D0%BC%D0%B5%D1%82%D1%80%D0%BE%D0%B2-sensitiveurlparams). | | `sensitiveHeaders` | `string[]` | `[]` | Дополнительные HTTP-заголовки, значения которых маскируются. См. [Приватность данных](https://tuna.am/docs/reports/privacyOptions.md#%D0%B4%D0%BE%D0%B1%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D1%81%D0%B2%D0%BE%D0%B8%D1%85-%D0%B7%D0%B0%D0%B3%D0%BE%D0%BB%D0%BE%D0%B2%D0%BA%D0%BE%D0%B2-sensitiveheaders). | ##### Запись видео По умолчанию пользователь выбирает, что приложить к отчёту: скриншот или запись экрана. Запись видео хранится в памяти страницы, поэтому на многостраничных сайтах она обрывается при переходе на другую страницу. Для таких сайтов видео можно выключить: ```html ``` Видео выключает только явное `video: false`. Без параметра или с любым другим значением запись остаётся включённой. При `video: false` окно «Выберите тип захвата» не показывается: по [кнопке](#%D0%BD%D0%B0%D0%B6%D0%B0%D1%82%D0%B8%D0%B5-%D0%BD%D0%B0-%D0%BA%D0%BD%D0%BE%D0%BF%D0%BA%D1%83), [горячей клавише](#%D0%B3%D0%BE%D1%80%D1%8F%D1%87%D0%B8%D0%B5-%D0%BA%D0%BB%D0%B0%D0%B2%D0%B8%D1%88%D0%B8) или вызову `showCaptureModal()` из обработчика клика сразу снимается скриншот. Исключение — ссылка с `?report=true` По [ссылке с аргументом](#%D0%B0%D1%80%D0%B3%D1%83%D0%BC%D0%B5%D0%BD%D1%82-%D0%B2-url) окно открывается без действия пользователя, а без него браузер не запустит захват экрана. Поэтому в этом случае показывается окно с одной карточкой «Скриншот». В личном кабинете на странице подключения проекта есть флажок **Запись видео** — он меняет значение `video` в сниппете, который вы копируете на сайт. #### Вызов cкрипта для создания отчёта Есть несколько способов создать отчёт: * Горячие клавиши * Кнопка (data аттребут) * Вызов из кода (JS) * Аргумент в URL ##### Горячие клавиши **Windows** Используйте сочетание клавиш `CTRL` + `ALT` + `S` **macOS** Используйте сочетание клавиш `⌘ command` + `⌥ option` + `S` **Linux** Используйте сочетание клавиш `CTRL` + `ALT` + `S` ##### Нажатие на кнопку Вызывайте форму создания отчета, добавив кнопку с data-аттрибутом: ```html ``` ##### Вызов из кода Вызывайте форму создания отчета из своего кода, добавив команду: ```js if (typeof window.autoCapture !== 'undefined' && window.autoCapture.showCaptureModal) { window.autoCapture.showCaptureModal(); } ``` ##### Аргумент в URL Вызывайте форму создания отчета, добавив к URL в адресной строке аргумент `report=true`. ```url https://example.com/dashboard?report=true ``` #### Идентификация пользователя Если пользователь авторизован на вашем сайте, передайте его данные в скрипт — отчёт будет привязан к этому пользователю. Данные попадают в отчёт как репортер и видны в блоке **Контекст** на странице отчёта. ```js if (window.autoCapture && window.autoCapture.capture) { window.autoCapture.capture.identify({ identifier: "user-42", name: "Иван Иванов", email: "ivan@example.com", avatarUrl: "https://example.com/avatar.png" }); } ``` Все поля необязательные. | Поле | Описание | | ------------ | ---------------------------------------------------------------------------------------------------------- | | `identifier` | Идентификатор пользователя в вашей системе | | `name` | Имя | | `email` | Адрес почты. На него оформляется подписка на уведомления по отчёту, см. [Email репортера](#reporter-email) | | `avatarUrl` | Ссылка на аватар | Чтобы сбросить данные, например при выходе из аккаунта, передайте `null`: ```js window.autoCapture.capture.identify(null); ``` Вызывайте после инициализации скрипта Скрипт подключается с атрибутом `async`, и `window.autoCapture.capture` равен `null`, пока он не инициализировался. Поэтому проверяйте его перед вызовом, как в примере выше, иначе получите ошибку. #### Email репортера В форме «Сообщить о проблеме» есть необязательное поле для адреса почты. На указанный адрес: * приходит письмо «Ваш отчёт получен» со ссылкой на отчёт; * оформляется подписка на новые комментарии к отчёту, в письме есть ссылка для отписки; * выдаётся доступ к отчёту. Публичный отчёт открывается по ссылке из письма сразу. Чтобы открыть приватный, нажмите **Запросить ссылку** — на почту придёт одноразовая ссылка для входа. Поле всегда открывается пустым. Если вы передаёте адрес через [`identify()`](#identify): * заполненное поле важнее — используется адрес из него; * при пустом поле используется адрес из `identify()`. Адрес репортера видят только участники команды проекта. По публичной ссылке на отчёт он не показывается. Некорректный адрес, переданный через `identify()`, не мешает отправке: отчёт будет принят, но письма и подписки не будет. #### Запроса на создание отчёта с записью экрана Если вы хотите чтобы пользователь записал для вас отчёт не с сайта, а продемонстрировал проблему на своей рабочей станции, тогда можно создать ссылку с запросом на запись экрана. ![](/docs/img/reports/external_1.png) ![](/docs/img/reports/external_2.png) *** Перейдя по ссылке пользователь сможет записать для вас видео и рассказать о проблеме. ![](/docs/img/reports/external_3.png) #### Как выглядит отчёт? Внутри отчёта будет скриншот или видео и вся отладочная информация из консоли, сетевые операции, действия пользователя и снимок DOM-дерева страницы. **Информация** На первой вкладке содержится общая сводная информация о клиенте, устройстве, браузере... ![](/docs/img/reports/info.png) **Инспектор** Снимок DOM-дерева страницы, с возможностью выбора элемента. *** примечание Эта вкладка доступна только для отчётов с скриншотом, в отчётах с видео невозможно захватить снимок DOM-дерева так как он может меняться по ходу. **Консоль** Список всех событий из консоли браузера. ![](/docs/img/reports/console.png) **Сеть** Список всех XHR запросов с возможностью заглянуть в детали. **Действия** Действия пользователя на странице. ![](/docs/img/reports/actions.png) **Комментарии** Также можно оставлять комментарии и реакции к комментариям. ![](/docs/img/reports/message.png) #### Видимость отчёта По умолчанию отчёт создаётся с видимостью - **Только для участников команды**, но вы можете сделать его публичным. Например для ведения диалога с клиентом создавшим отчёт. ![](/docs/img/reports/share.png) --- ### Приватность данных По умолчанию Отчёт собирает данные о взаимодействии пользователей и сетевых запросах для отладки проблем. В зависимости от вашего приложения, некоторые из этих данных могут содержать конфиденциальную информацию, которую вы не хотите регистрировать. Некоторые типы данных никогда не собираются: * Токены аутентификации и cookie-файлы в сетевых запросах * Информация, введенная в формы Обратите внимание, что информация на этой странице относится только к зафиксированным событиям и журналам. Визуальная информация на скриншотах и записях экрана не удаляется автоматически. *** #### Обзор При создании автоматически захватываются пользовательские взаимодействия, сетевые запросы и состояние страницы. Однако некоторые данные требуют особой защиты: * Пароли и данные аутентификации * Персональные данные (email, телефон, ИНН) * Платёжная информация (номера карт, CVV) * API-ключи и токены * Другая конфиденциальная информация Tuna Отчёты предоставляет несколько уровней защиты данных, которые вы можете комбинировать в зависимости от требований безопасности вашего приложения. *** #### Автоматическая защита По умолчанию автоматически маскируются следующие данные: ##### Поля ввода Автоматически маскируются значения полей: * ``, ``, `` — по типу * Поля с атрибутом `name` или `id`, содержащим ключевые слова: * **Аутентификация:** `password`, `passwd`, `pwd`, `secret`, `pin`, `otp` * **Контактные данные:** `email`, `phone`, `tel`, `mobile` * **Идентификация:** `ssn`, `passport`, `license`, `national_id`, `tax_id`, `inn`, `snils` * **Платёжные данные:** `card`, `credit`, `debit`, `payment`, `billing`, `visa`, `mastercard`, `amex`, `discover`, `maestro`, `mir` * **Реквизиты карт:** `cvv`, `cvc`, `cvn`, `expir` * **Банковские реквизиты:** `iban`, `swift`, `bic`, `routing`, `account` * **Токены и ключи:** `token`, `apikey`, `api_key`, `auth`, `private` * Поля с классами: `password`, `passwd`, `email`, `phone`, `ssn`, `credit`, `card`, `payment`, `sensitive`, `private`, `secret`, `masked`, `hidden`, `secure`, `confidential` Поиск по подстроке Поиск ключевых слов работает по подстроке. Например, `card` покроет `cardnumber`, `card_number`, `creditcard`. А `expir` покроет `expiry`, `expiration`. ```html ``` ##### URL-параметры Автоматически маскируются query-параметры в URL, содержащие: * **Аутентификация:** `password`, `passwd`, `pwd` * **Токены и ключи:** `token`, `key`, `secret`, `apikey`, `api_key` * **Сессии:** `auth`, `credential`, `session`, `access` * **OAuth/OIDC:** `code`, `nonce` ```text До: https://example.com/api?token=abc123&user=john После: https://example.com/api?token=***&user=john ``` ###### Добавление своих параметров (sensitiveUrlParams) Вы можете расширить список маскируемых URL-параметров через опцию `sensitiveUrlParams`: ```javascript window.reportOptions = { captureKey: 'YOUR_CAPTURE_KEY', sensitiveUrlParams: ['my_secret_param', 'internal_id', 'ref_code'] }; ``` Эти параметры будут добавлены к стандартному списку, а не заменят его. ##### HTTP-заголовки Автоматически маскируются HTTP-заголовки в сетевых запросах: * **Стандартные:** `authorization`, `www-authenticate`, `cookie` * **Токены и ключи:** `token`, `secret`, `apikey`, `api-key`, `api_key` * **Сессии и подписи:** `signature`, `credential`, `session` * **Служебные:** `idempotency-key`, `idempotence-key` * **Облачные провайдеры:** `x-amz-*` (AWS), `x-goog-*` (Google Cloud), `x-ms-*` (Azure), `cf-access-*` (Cloudflare), `ocp-apim-*` (Azure API Management) Также маскируются заголовки со значениями, начинающимися с `Bearer `или `Basic `. ###### Добавление своих заголовков (sensitiveHeaders) Вы можете расширить список маскируемых HTTP-заголовков через опцию `sensitiveHeaders`: ```javascript window.reportOptions = { captureKey: 'YOUR_CAPTURE_KEY', sensitiveHeaders: ['x-my-custom-header', 'x-internal-token'] }; ``` Эти заголовки будут добавлены к стандартному списку, а не заменят его. *** #### HTML-атрибуты для маскировки Вы можете явно указать элементы, которые нужно замаскировать или скрыть, используя data-атрибуты. ##### data-capture-mask Маскирует содержимое элемента, заменяя текст на `***`. ```html Секретный текст

Конфиденциальная информация

Номер договора: 12345

``` Наследование Вместо добавления атрибута на каждый элемент можно добавить его на родительский контейнер: ```html
``` ##### data-capture-hide Полностью скрывает элемент из отчёта. ```html

Эта информация не будет захвачена

``` ##### Разница между mask и hide | Атрибут | Результат | Когда использовать | | ------------------- | ------------------------------------------- | ----------------------------------------- | | `data-capture-mask` | Элемент виден, содержимое заменено на `***` | Когда важно показать наличие данных | | `data-capture-hide` | Элемент полностью отсутствует | Когда элемент не должен быть виден вообще | *** #### Примеры использования ##### Пример 1: Форма авторизации ```html
``` ##### Пример 2: Платёжная форма ```html

Платёжные данные

Платёжные данные

``` ##### Пример 3: Профиль пользователя ```html ``` *** #### Рекомендации по безопасности 1. **Используйте принцип минимальных привилегий** — маскируйте всё, что может быть чувствительным, даже если вы не уверены. 2. **Тестируйте в dev-окружении** — перед деплоем проверьте, что все чувствительные данные действительно маскируются. 3. **Комбинируйте методы** — используйте как автоматическую защиту, так и явные data-атрибуты. 4. **Регулярно проверяйте отчёты** — убедитесь, что в отчётах нет утечек конфиденциальных данных. 5. **Документируйте для команды** — создайте внутренние гайдлайны по использованию data-атрибутов маскировки. *** #### Совместимость Функции приватности работают во всех поддерживаемых браузерах: * Chrome 80+ * Firefox 75+ * Safari 14+ * Edge 80+ *** --- ### Ограничения #### Туннели Мы накладываем ограничение в **100 RPS** (запросов в секунду) на Host (домен) в [HTTP туннелях](https://tuna.am/docs/tunnels/http.md), других ограничений, к примеру по объёму передаваемого трафика в месяц, в настоящий момент нет, но может появиться в ближайшем будущем. Мы делаем ограничения демократичными, они призваны обеспечить комфортную работу для всех пользователей в разделяемых ресурсах. --- ### Секреты В этом разделе описаны возможности и функции [Секретов](https://my.tuna.am/secrets). #### Обзор **Секреты** — это компонент платформы Tuna, созданный для безопасного хранения конфиденциальных и не только данных, удобного управления конфигурациями приложений в любых средах: локально, CI/CD, тестовые и продуктивные окружения. Является отличной альтернативой `.env` файлам в компании с [direnv](https://direnv.net/) или переменным окружения в [GitLab CI/CD](https://tuna.am/docs/secrets/examples.md#-gitlab-ci) / [GitHub Actions](https://tuna.am/docs/secrets/examples.md#-github-actions). **VK Видео** **YouTube** #### Для кого? * *Разработчики* — чтобы упростить настройку окружений и сократить количество "магических" значений в коде. * *DevOps-инженеры* — для централизации и автоматизации конфигураций. * *Команды* — для безопасного и контролируемого совместного доступа к конфиденциальным данным. #### Основные возможности Мы придерживаемся общепринятой структуры, поэтому хранение секретов разделяется по проектам, внутри проектов есть окружения, а внутри окружений конфигурации основные или дочерние. Внутри конфигураций сосредоточенно множество функций работы непосредственно с секретами и доступом к ним, аудит и прочее. При работе в [Команде](https://tuna.am/docs/team.md), в разделе с ролями появляется возможность гранулярно распределять доступ участников к нужным окружениям в проектах. Доступ к секретам осуществляется через веб интерфейс личного кабинета, с помощью консольного клиента [tuna](https://tuna.am/docs/guides/install/install-cli.md) или через [API](https://tuna.am/docs/guides/api.md). Все секреты хранятся в нашей базе данных в зашифрованном виде, при этом ключ шифрования в самой базе не хранится, так что в случае утечки базы, ваши секреты останутся анонимными. Но всё таки **Секреты** это не [Пароли](https://tuna.am/docs/passwords.md), здесь мы **не** применяем подход [нулевого знания](https://en.wikipedia.org/wiki/Zero-knowledge_proof), в угоду удобству. Секреты позволяют удобно управлять чувствительными настройками приложений, вроде токенов интеграций с внешними сервисами, URL подключения к базе данных и прочих настроек. ##### Проекты Вы можете создавать несколько проектов, под проектом предполагается одно приложение, например API или сервер авторизации. Каждый проект имеет Имя и Алиас. Имя - это название отображаемое в интерфейсе удобное для восприятия, может иметь пробелы и т.д., а Алиас - нужен для обращения к проекту через CLI tuna или через API. ![](/docs/img/secrets/projects.webp) Количество создаваемых проектов лимитировано и зависит от тарифа. ##### Окружения Каждый проект содержит окружения, по умолчанию 3 (Development, Staging, Production), их можно переименовывать менять порядок, а также добавлять или убавлять под свои нужды. ![](/docs/img/secrets/envs.webp) Как и проекты окружения имеют Имя и Алиас: ![](/docs/img/secrets/env_rename.webp) ##### Конфигурации Каждое окружение имеет основную конфигурацию, ещё нельзя удалить. Относительно основной конфигурации в окружении можно создавать её копии, т.е. дочерние конфигурации. ![](/docs/img/secrets/configs.webp) Так, например, у вас есть Development окружение - это `master` ветка в git с которой равёрнут стенд. Относительно основной конфигурации каждый разработчик может создать свою уникальную конфигурацию. ##### Секреты Сами секреты представляют пару Ключ = Значение. Ключ это всегда строка [формата](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html), имени переменной окружения. Значение может быть любым. Для больше безопасности мы добавляем возможность задать тип для каждой переменной, например вы точно знаете, что `API_ENABLED` это **bool**, и вы можете определить это, тогда вы гарантированно не ошибётесь и не запишите туда строку или число. ![](/docs/img/secrets/secret_type.webp) Наведя курсор на значение и кликнув можно его отобразить, сверху также появятся дополнительные кнопки управления значением. ![](/docs/img/secrets/secret_value.webp) К примеру, вот так выглядит генератор секретов: ![](/docs/img/secrets/secret_generator.webp) ###### Комментарии К каждому секрету можно оставить комментарий: ![](/docs/img/secrets/secret_comment.webp) 1. Отобразить комментарий конкретного секрета 2. Отобразить комментарии всех секретов ###### Напоминания Ещё к каждому секрету можно оставить напоминания, и вам будут приходить уведомления на email: ![](/docs/img/secrets/secret_reminder_1.webp) ![](/docs/img/secrets/secret_reminder_2.webp) ##### Синхронизация секретов в окружениях Добавляя новые переменные в основную конфигурацию какого-либо окружения вы увидите индикацию у других окружений, что какие-то переменные осутствуют: ![](/docs/img/secrets/skiped_1.webp) ![](/docs/img/secrets/skiped_2.webp) Вам будет предложено заполнить пропущенные секреты или скрыть их: ![](/docs/img/secrets/skiped_3.webp) ##### Сравнение значения секрета в разных окружениях Вы всегда можете провести инвентаризацию и сравнить значение секрета во всех окружениях и убедиться, например, что подключение к Production базе не скопировано по ошибке в Staging или Development. ![](/docs/img/secrets/secret_compare_1.webp) ![](/docs/img/secrets/secret_compare_2.webp) ##### Скрытые секреты Безусловно, могут быть переменные которые есть только в одном окружении, например в Production, и чтобы не видеть постоянно уведомление о пропущенных секретах, вы можете скрыть их, но они будут отображаться в настройках конфигурации. ![](/docs/img/secrets/secret_hide_1.webp) ![](/docs/img/secrets/secret_hide_2.webp) ##### Доступ к сведению Доступно только по [подписке](https://tuna.am/#pricing). ###### Сервисные ключи Вы можете выпустить уникальный для данной конфигурации *Сервисный ключ*, это аналог пользовательского [API-ключа](https://tuna.am/docs/guides/api.md), но ограниченный только на данную конфигурацию. Сервисный ключ может быть ограничен как только на *чтение* так и на *чтение и запись*. Это полезно например для CI/CD. ![](/docs/img/secrets/access_key.webp) Сервисный ключ можно узнать по префиксу - `tst_`, тогда как API-ключ имеет префикс - `tak_`, а [токен](https://my.tuna.am/token) для создания туннелей - `tt_`. ###### Разрешенные IP адреса и подсети Доступ также можно ограничивать по IP адресам и подсетям в CIDR формате. По умолчанию разрешено всем. ![](/docs/img/secrets/access_ip.webp) В комплексе, например вы можете выпустить *Сервисный ключ* для prod окружения и ограничить получение секретов для IP адресов с gitlab-runners и ваших Production серверов. ##### История изменений Также ведётся полный аудит всех действий и изменений внутри конфигурации. Если кто-то изменил пароль подключения к безе данных, вы сможете узнать об этом. ![](/docs/img/secrets/audit.webp) #### Навигация #### [📄️Работа в CLI](https://tuna.am/docs/secrets/cli.md) [Управление секретами, запуск приложений и администрирование проектов через консольный клиент tuna](https://tuna.am/docs/secrets/cli.md) #### [📄️Примеры](https://tuna.am/docs/secrets/examples.md) [Примеры работы с tuna secrets](https://tuna.am/docs/secrets/examples.md) #### [🗃Инструкции](https://tuna.am/docs/secrets/guides.md) [1 элемент](https://tuna.am/docs/secrets/guides.md) --- ### Работа в CLI #### Обзор С помощью консольного клиента [tuna](https://tuna.am/docs/guides/install/install-cli.md) можно получать секреты, автоматически конфигурировать текущую среду или передавать конфигурацию в [env](https://ru.wikipedia.org/wiki/%D0%9F%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F_%D1%81%D1%80%D0%B5%D0%B4%D1%8B) нужного приложения. Кроме того, из консоли доступно управление самой структурой — проектами, окружениями, конфигурациями и сервисными ключами. | Команды | Для чего | | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | | [`list`](#list), [`get`](#get), [`set`](#set), [`delete`](#delete), [`upload`](#upload) | Чтение и изменение секретов в конфигурации | | [`run`](#%D0%B7%D0%B0%D0%BF%D1%83%D1%81%D0%BA-%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B9) | Запуск приложения с секретами в переменных окружения | | [`download`](#download), [`substitute`](#substitute) | Выгрузка секретов в файл или шаблон | | [`setup`](#setup), [`open`](#open) | Привязка каталога к конфигурации, открытие в браузере | | [`projects`](#%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D1%8B), [`environments`](#%D0%BE%D0%BA%D1%80%D1%83%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F), [`configs`](#%D0%BA%D0%BE%D0%BD%D1%84%D0%B8%D0%B3%D1%83%D1%80%D0%B0%D1%86%D0%B8%D0%B8) | Управление структурой и сервисными ключами | Для получения секретов через консольное приложение tuna или [API](https://tuna.am/docs/guides/api.md) необходим [API-ключ](https://my.tuna.am/api_keys) пользователя или [Сервисный ключ конфигурации](https://tuna.am/docs/secrets.md#%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BD%D1%8B%D0%B5-%D0%BA%D0%BB%D1%8E%D1%87%D0%B8). При локальной разработке удобнее использовать глобальные API-ключи пользователя, но для работы в CI/CD, Production и других общих средах мы **настоятельно рекомендуем** использовать Сервисный ключ конфигурации. #### Почему tuna secrets лучше direnv при локальной разработке? [direnv](https://direnv.net) - прекрасная утилита для локальной конфигурации, но она всё таки заставляет следить за локальным файлом `.env` и если на Production появились новые переменные, вы можете не сразу узнать об этом и потратить часы на бессмысленную отладку. В tuna secrets предусмотрена [автоматическая синхронизация секретов](https://tuna.am/docs/secrets.md#%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F-%D1%81%D0%B5%D0%BA%D1%80%D0%B5%D1%82%D0%BE%D0%B2-%D0%B2-%D0%BE%D0%BA%D1%80%D1%83%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F%D1%85), что значительно упрощает этот процесс. #### Почему tuna secrets лучше Gitlab/Github/Bitbucket Variables? На самом деле причина тут та же, что и с direnv. Например, у вас есть специальный проект предназначенный для сборки и публикации приложения с помощью [goreleaser](https://goreleaser.com/) и он может требовать множество ключей и токенов для разных внешних интеграций, при этом для разных окружений и использовать для этого Gitlab/Github/Bitbucket Variables неудобно, а ещё неудобнее следить за этим, плюс сложность в разграничении прав. В tuna secrets доступ к окружениям регулируется RBAC и вы можете точечно распределять доступ только нужным людям/роботам/скриптам. А обновив секрет или добавив новый, он сразу начнёт работать в CI. #### Авторизация Для доступа к секретам понадобится [Сервисный ключ](https://tuna.am/docs/secrets.md#%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BD%D1%8B%D0%B5-%D0%BA%D0%BB%D1%8E%D1%87%D0%B8) определённой конфигурации или пользовательский [API-ключ](https://my.tuna.am/api_keys). Его можно передать через флаг `--api-key`, переменную окружения `TUNA_API_KEY` или сохранить в конфиг файл `tuna config save-api-key ` Ключи различаются не только областью действия, но и набором доступных команд: | Ключ | Что можно | | ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- | | Сервисный ключ конфигурации (`tst_`) | Читать секреты своей конфигурации: `run`, `download`, `list`, `get`. С доступом `write` — ещё `set`, `delete` и `upload` в ту же конфигурацию | | Пользовательский API-ключ (`tak_`) | Всё то же плюс управление структурой: `projects`, `environments`, `configs` и выпуск сервисных ключей | Обращение сервисным ключом к чужой конфигурации возвращает `403`, а к командам управления структурой — `401`. Поэтому в CI/CD держите сервисный ключ конфигурации, а проекты и конфигурации заводите пользовательским ключом. #### Проект и конфигурация Почти каждая команда работает в контексте проекта и конфигурации. Их можно задать тремя способами, в порядке приоритета: 1. флагами `--project` (`-p`) и `--config` (`-c`); 2. переменными окружения `TUNA_SECRETS_PROJECT` и `TUNA_SECRETS_CONFIG`; 3. привязкой каталога к конфигурации — командой [`setup`](#setup). Флаг `--scope` (по умолчанию `.`) указывает, для какого каталога брать привязку. Подробнее — в разделе про [`setup`](#setup). ```shell tuna secrets list --project api-php --config stage tuna secrets list -p api-php -c stage tuna secrets list # проект и конфигурация из привязки каталога ``` #### Формат вывода Клиент разделяет данные и служебные сообщения: * данные идут в `stdout`; * статусные сообщения, предупреждения и ошибки — в `stderr`. Поэтому вывод любой команды можно перенаправлять в файл и передавать по конвейеру, не боясь поймать в него лишние строки: ```shell tuna secrets list --only-names > names.txt tuna secrets list | grep API_ ``` ##### Таблицы Человеку команды печатают таблицу без рамок: заголовки капсом, пустая ячейка — `-`, даты в формате RFC3339 в вашей локальной временной зоне. Такую таблицу удобно резать `awk` и она не разъезжается в узком терминале. ```shell $ tuna secrets list NAME VALUE TYPE NOTE UPDATED JKLNRFEDUILNNIF hmac:cea41705 string - 2026-09-17T11:56:51+04:00 ``` ##### Отпечатки значений В колонке `VALUE` по умолчанию печатается не значение секрета, а его отпечаток вида `hmac:cea41705` — HMAC-SHA256 от значения на ключе команды. Одинаковые значения дают одинаковый отпечаток, а из отпечатка нельзя восстановить значение. Поэтому отпечатки можно сравнивать между конфигурациями («в stage и prod действительно разные пароли к базе?») и печатать в логи CI, не раскрывая секрет. Так выглядит сравнение двух окружений: `API_TOKEN` и `API_ENABLED` в dev и prod совпадают, `API_DB` и `LOG_LEVEL` различаются — и всё это видно, не раскрывая ни одного значения. *** Настоящие значения показывают [`list --values`](#list) и [`get`](#get): ```shell $ tuna secrets list --values NAME VALUE TYPE NOTE UPDATED JKLNRFEDUILNNIF vcTpFuptQLtJ0beoTQA13rHNeAaGNtjs string - 2026-09-17T11:56:51+04:00 ``` ##### JSON и YAML Флаг `-o` (`--output`) со значением `json` или `yaml` есть у всех подкоманд `tuna secrets`, включая команды записи: `set`, `delete`, `upload`, `create`, `rename`, `lock` и остальные печатают в машинном виде то, что получилось в результате. ```shell $ tuna secrets set FOO=bar2 -o json { "FOO": { "id": 42, "name": "FOO", "value": "bar2", "fingerprint": "hmac:b274b135", "value_type": "string", "visibility": "masked", "override": false, "note": "", "can_be_converged": false, "can_be_promoted": false, "reminder": null, "created_at": "2026-09-18T06:43:10Z", "updated_at": "2026-09-18T06:43:10Z" } } ``` В машинном выводе секрет приходит со всеми полями и **с настоящим значением** — в отличие от таблицы, где по умолчанию стоит отпечаток. Помните об этом, перенаправляя такой вывод в файл или в лог. Исключение — секрет с видимостью `restricted`: сервер не отдаёт ни значение, ни отпечаток, поэтому оба поля приходят пустыми. Пустой результат — это всегда валидный `[]` или `{}`, а не пустой вывод, так что парсер в скрипте не придётся защищать отдельной проверкой. ##### Сырые значения для скриптов Флаг `--plain` у команд [`get`](#get) и [`configs tokens create`](#%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BD%D1%8B%D0%B5-%D0%BA%D0%BB%D1%8E%D1%87%D0%B8) печатает только само значение, **без перевода строки в конце**. Это удобно для подстановки в другую команду: ```shell $ docker login -u robot -p "$(tuna secrets get REGISTRY_PASSWORD --plain)" registry.example.com ``` ##### Ошибки Ошибки печатаются в `stderr`, код возврата в этом случае — `1`: ```shell $ tuna secrets list -p test -c nonexistent Error: Failed to list secrets in test/nonexistent: Config does not exist Code: NotFound Request ID: 83d3961b1452ab3c7174965acbfbd711 ``` С `-o json` ошибка тоже становится JSON — его можно разобрать и, например, приложить `request_id` к обращению в поддержку: ```json {"code":"NotFound","error":"Failed to list secrets in test/nonexistent: Config does not exist","request_id":"83d3961b1452ab3c7174965acbfbd711"} ``` #### Работа с секретами ##### List Список секретов конфигурации. Алиас — `ls`. | Флаг | Описание | | -------------- | ------------------------------------- | | `--values` | Показывать значения вместо отпечатков | | `--only-names` | Только имена, одной колонкой | ```shell $ tuna secrets list NAME VALUE TYPE NOTE UPDATED JKLNRFEDUILNNIF hmac:cea41705 string - 2026-09-17T11:56:51+04:00 ``` В записи видно, как отпечаток `LOG_LEVEL` меняется вместе со значением, а `list --values` показывает уже само значение: *** ##### Get Значения одного или нескольких секретов. В отличие от `list`, `get` показывает значения сразу. | Флаг | Описание | | --------- | ---------------------------------------------------------- | | `--plain` | Только значения, без таблицы и без перевода строки в конце | ```shell $ tuna secrets get API_TOKEN API_DB NAME VALUE TYPE NOTE UPDATED API_DB postgres://postgres@db:5432/api string - 2026-09-17T11:56:51+04:00 API_TOKEN PwZayIp9NpNntNYd2jkAAQgViM6dXdIm string - 2026-09-17T11:56:51+04:00 ``` Если запрошенного секрета в конфигурации нет, команда завершится ошибкой и не напечатает ничего — так опечатка в имени не превратится в пустую переменную. ##### Set Запись одного или нескольких секретов. | Флаг | Описание | | ------------------ | ------------------------------------------------------------------------------------------------------------------ | | `--type` | Тип значения: `string`, `json`, `boolean`, `integer`, `decimal`, `email`, `url`, `yaml`, `xml`, `date`, `datetime` | | `--note` | Комментарий к секрету | | `--visibility` | Видимость значения в веб-интерфейсе: `masked` или `unmasked` | | `--no-interactive` | Не спрашивать значение интерактивно, а завершиться ошибкой | Значение можно передать четырьмя способами: ```shell $ tuna secrets set API_TOKEN=PwZayIp9NpNntNYd2jkAAQgViM6dXdIm # inline $ tuna secrets set API_TOKEN PwZayIp9NpNntNYd2jkAAQgViM6dXdIm # отдельным аргументом $ openssl rand -hex 32 | tuna secrets set API_TOKEN # из stdin $ tuna secrets set API_TOKEN # интерактивно ``` Интерактивный ввод включается только для одного имени без `=`, когда в stdin ничего не пришло; с `--no-interactive` вместо него будет ошибка. Ввести можно и многострочное значение, например приватный ключ: ввод заканчивается пустой строкой, а следом строкой с одной точкой. За один вызов можно записать несколько секретов, флаги `--type`, `--note` и `--visibility` применяются ко всем сразу: ```shell $ tuna secrets set API_ENABLED=true API_DEBUG=false --type boolean ``` В ответ команда печатает записанные секреты: ```shell $ tuna secrets set FOO=bar NAME VALUE TYPE NOTE UPDATED FOO hmac:bd154f88 string - 2026-09-18T10:43:10+04:00 ``` Не используйте видимость restricted Флаг `--visibility` принимает и значение `restricted`, но пользоваться им сейчас не стоит: сервер перестаёт отдавать значение такого секрета вообще всем — в том числе `tuna secrets run`, — а `tuna secrets download` для всей конфигурации начинает отвечать `403`. Вернуть значение после этого нельзя. Если кто-то изменил тот же секрет между чтением и записью, команда сообщит об этом и завершится ошибкой, не затирая чужое изменение. В этом случае достаточно повторить вызов. ##### Delete Удаление одного или нескольких секретов. Алиас — `rm`. ```shell $ tuna secrets delete FOO NAME VALUE TYPE NOTE UPDATED API_TOKEN hmac:3e96898b string - 2026-09-18T10:43:09+04:00 DB_HOST hmac:829a119e string - 2026-09-18T10:43:09+04:00 DB_PORT hmac:620ef1fa string - 2026-09-18T10:43:09+04:00 ``` Команда печатает конфигурацию в том виде, в каком она осталась после удаления. Если хотя бы одного из перечисленных секретов в конфигурации нет, не удаляется ничего. Подтверждение удаления Начиная с версии **0.36.0** команды удаления переспрашивают перед выполнением: `delete`, `projects delete`, `environments delete`, `configs delete` и `configs tokens revoke`. Флаг `--yes` (`-y`) пропускает вопрос. Без терминала — в CI, cron, скриптах — вопрос задать нельзя, поэтому без `--yes` команда сразу завершится ошибкой `--yes is required when not running interactively`. ##### Upload Загрузка секретов из файла `.env` или `.json`. ```shell $ tuna secrets upload .env NAME VALUE TYPE NOTE UPDATED API_TOKEN hmac:1ea77bae string - 2026-09-18T10:43:11+04:00 DB_HOST hmac:829a119e string - 2026-09-18T10:43:09+04:00 DB_PORT hmac:620ef1fa string - 2026-09-18T10:43:09+04:00 REDIS_URL hmac:3df78001 string - 2026-09-18T10:43:11+04:00 ``` Как и `delete`, команда печатает конфигурацию целиком — уже после слияния. Содержимое файла **дополняет** конфигурацию: секреты с совпадающими именами перезаписываются, остальные остаются на месте. Полной заменой конфигурации `upload` не является. #### Запуск приложений Команда `run` запускает ваше приложение, передавая ему секреты в переменных окружения. Сами секреты при этом не попадают ни в файл, ни в историю команд. ```shell tuna secrets run -- yarn start ``` *** ##### Что передаётся процессу | Флаг | Описание | | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | | `--command` | Выполнить строку через оболочку: `--command "echo $HOME && env"` | | `--only-secrets` | Передать только секреты и минимум системных переменных (`PATH`, `HOME`, `PS1`, `USER`, `SHELL`, `TMPDIR`) | | `--preserve-env` | Список имён через запятую, для которых приоритет у уже существующего значения в окружении; без значения флаг означает `true` — сохранить все | | `--name-transformer` | Преобразовать имена: `upper-camel`, `camel`, `lower-snake`, `lower-kebab`, `tf-var`, `dotnet-env` | | `--forward-signals` | Пробрасывать сигналы дочернему процессу; по умолчанию включено, когда `stdout` не терминал | `tuna` возвращает код выхода дочернего процесса, поэтому обёртку можно ставить в CI-джобу, не ломая её логику. ```shell $ tuna secrets run --project api-php --config stage -- yarn start $ tuna secrets run --scope /home/user/src/api -- yarn start $ tuna secrets run --only-secrets -- env ``` ##### Автоматический перезапуск при изменении секрета Если передать флаг `--watch`, клиент подписывается на изменения конфигурации и перезапускает процесс с новыми значениями. ```shell tuna secrets run --watch -- yarn start ``` Перезапуск происходит не мгновенно: сервер сверяет конфигурацию раз в 30 секунд и только после этого присылает событие. Столько же может пройти между изменением секрета и рестартом приложения — если пару десятков секунд ничего не происходит, это нормальная работа, а не сломанный `--watch`. Момент перезапуска видно в `stderr`: ```shell Secrets changed; restarting process ``` В записи приложение печатает значение раз в пять секунд: сначала идёт старое, затем строка о перезапуске, затем новое. *** Лучше всего работу продемонстрирует данное видео: **VK Видео** **YouTube** В видео мы запускаем вот такую команду: ```shell tuna secrets run --watch -- bash -c 'while true; do echo -n "$(date -Is) [pid: $$] ==> " ; echo ${API_TOKEN} ; sleep 1; done' ``` ##### Секреты файлом вместо переменных окружения Некоторые приложения читают конфигурацию только из файла. Флаг `--mount` создаёт временный именованный канал (named pipe), кладёт в него секреты и передаёт путь дочернему процессу в переменной `TUNA_SECRETS_MOUNT_PATH`. В переменные окружения секреты в этом режиме не попадают. Канал создаётся по указанному пути с правами `0600`, но значения живут только в памяти клиента: каждое открытие файла на чтение получает полный снимок и EOF, записанного файла с секретами на диске не появляется. После выхода процесса канал удаляется. ```shell $ tuna secrets run --mount ./secrets.json --mount-format json -- ./app --config "$TUNA_SECRETS_MOUNT_PATH" ``` | Флаг | Описание | | ------------------- | ----------------------------------------------------------------------------------- | | `--mount` | Путь к создаваемому каналу | | `--mount-format` | Формат содержимого: `env` (по умолчанию), `env-no-quotes`, `json`, `yaml`, `docker` | | `--mount-template` | Файл-шаблон, который рендерится в канал вместо фиксированного формата | | `--mount-max-reads` | Сколько раз файл можно прочитать, `0` — без ограничения | *** Флаг `--mount-max-reads N` удаляет канал после N чтений — удобно, когда секреты читает ровно один процесс при старте. к сведению Именованные каналы не поддерживаются в Windows, там `--mount` работать не будет. Если клиент убить сигналом `SIGKILL`, канал останется на диске и следующий запуск откажется стартовать: `mount path already exists`. Такой файл нужно удалить вручную. ##### Офлайн-режим `run` умеет хранить последние успешно полученные секреты в зашифрованном файле и использовать их, когда API недоступен — приложение не встанет из-за проблем с сетью. | Флаг | Описание | | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------- | | `--fallback` | Путь к файлу; по умолчанию вычисляется из адреса API, ключа, проекта и конфигурации | | `--fallback-only`, `--offline` | Читать только файл, не обращаясь к API | | `--fallback-readonly` | Использовать файл, но не обновлять его | | `--no-fallback` | Не читать и не писать файл | | `--fallback-passphrase` | Парольная фраза; по умолчанию вычисляется из ключа, проекта и конфигурации. Также читается из `TUNA_SECRETS_FALLBACK_PASSPHRASE` | Если API ответил, что доступ запрещён или конфигурация не найдена (`401`, `403`, `404`), файл удаляется: устаревшая копия секретов после отзыва доступа опаснее, чем остановка приложения. При сетевых ошибках и `5xx` клиент, наоборот, читает файл и печатает предупреждение. Парольная фраза по умолчанию выводится из API-ключа, проекта и конфигурации — значит, после ротации ключа старый файл расшифровать уже нельзя. Если файл должен пережить ротацию, задайте фразу явно: флаг `--fallback-passphrase` имеет приоритет над переменной `TUNA_SECRETS_FALLBACK_PASSPHRASE`. Старые файлы можно убрать командой `run clean`: ```shell $ tuna secrets run clean --dry-run Would delete 0 fallback file(s) $ tuna secrets run clean --max-age 720h $ tuna secrets run clean --all ``` По умолчанию удаляются файлы старше 14 дней (`--max-age 336h`). Первый запуск ходит в API и попутно пишет файл, второй с `--offline` обходится без сети: *** #### Выгрузка секретов ##### Download Получение секретов конфигурации в файл или на стандартный вывод. ```shell tuna secrets download ``` *** | Флаг | Описание | | -------------------- | ----------------------------------------------------------------------------------------------------------- | | `--format` | `json` (по умолчанию), `yaml`, `env`, `env-no-quotes`, `docker` | | `--no-file` | Печатать на стандартный вывод вместо записи в файл | | `--name-transformer` | Преобразовать имена: `upper-camel`, `camel`, `lower-snake`, `lower-kebab`, `tf-var`, `dotnet`, `dotnet-env` | | `--scope` | Каталог, привязку которого использовать | Настройки можно задать и [переменными окружения](https://tuna.am/docs/guides/environment-variables.md#%D1%81%D0%B5%D0%BA%D1%80%D0%B5%D1%82%D1%8B). ###### Передача проекта и конфигурации Флаги `--project` и `--config` принимают на вход имя (алиас) проекта и конфигурации. По умолчанию конфигурация сохранится в файл `tuna.json` в текущем каталоге. ```shell $ tuna secrets download --project api-php --config stage Downloaded secrets to tuna.json $ cat tuna.json { "API_DB": "postgres://postgres:postgres@localhost:5432/postgres", "API_TOKEN": "PwZayIp9NpNntNYd2jkAAQgViM6dXdIm" } ``` ###### Передача формата Можно указать, в каком формате вам нужен файл. **json** ```shell $ tuna secrets download --project api-php --config stage --format json Downloaded secrets to tuna.json $ cat tuna.json { "API_DB": "postgres://postgres:postgres@localhost:5432/postgres", "API_TOKEN": "PwZayIp9NpNntNYd2jkAAQgViM6dXdIm" } ``` **yaml** ```shell $ tuna secrets download --project api-php --config stage --format yaml Downloaded secrets to tuna.yaml $ cat tuna.yaml API_DB: postgres://postgres:postgres@localhost:5432/postgres API_TOKEN: PwZayIp9NpNntNYd2jkAAQgViM6dXdIm ``` **env** ```shell $ tuna secrets download --project api-php --config stage --format env Downloaded secrets to tuna.env $ cat tuna.env API_DB="postgres://postgres:postgres@localhost:5432/postgres" API_TOKEN="PwZayIp9NpNntNYd2jkAAQgViM6dXdIm" ``` Неизвестный формат — ошибка, а не молчаливая выгрузка «чего-нибудь». ###### Формат docker Формат `docker` печатает пары `KEY=value` без кавычек — то же, что `env-no-quotes`. Такой файл подходит для `docker run --env-file`, где кавычки стали бы частью значения: ```shell $ tuna secrets download --format docker --no-file API_TOKEN=s3cr3t-token-value DB_HOST=db.internal DB_PORT=5432 $ tuna secrets download --format docker tuna.env $ docker run --env-file tuna.env myapp ``` ###### Преобразование имён Флаг `--name-transformer` меняет стиль имён — полезно, когда потребитель секретов ждёт не `SCREAMING_SNAKE_CASE`: ```shell $ tuna secrets download --no-file --format json --name-transformer camel { "apiDb": "postgres://postgres:postgres@localhost:5432/postgres", "apiToken": "PwZayIp9NpNntNYd2jkAAQgViM6dXdIm" } ``` Трансформер `dotnet` есть только у `download`: он даёт имена вида `Section:Key`, а двоеточие в имени переменной окружения недопустимо. Поэтому у `tuna secrets run` его нет — для .NET там `dotnet-env` с двойным подчёркиванием. ###### Свой файл В команде можно передать путь и определить свой файл. ```shell $ tuna secrets download --project api-php --config stage foo-bar.json Downloaded secrets to foo-bar.json ``` ###### Вывод в stdout Флаг `--no-file` отключает запись в файл и печатает конфигурацию на стандартный вывод. ```shell $ tuna secrets download --project api-php --config stage --no-file --format env API_TOKEN="PwZayIp9NpNntNYd2jkAAQgViM6dXdIm" API_DB="postgres://postgres:postgres@localhost:5432/postgres" ``` ##### Substitute Рендер файла-шаблона со значениями секретов. Подходит для конфигов, у которых свой формат: `nginx.conf`, `application.yml`, `.ini` и подобных. Шаблон — это [text/template](https://pkg.go.dev/text/template) Go, данными служит набор пар имя-значение: config.tmpl ```gotemplate database_url = {{ .DB_URL }} api_key = {{ index . "API-KEY" }} extra = {{ index . "FEATURES" | fromjson | tojson }} ``` ```shell $ tuna secrets substitute config.tmpl --output config.ini $ tuna secrets substitute config.tmpl | kubectl apply -f - ``` *** Без `--output` результат печатается на стандартный вывод. С `--output` файл пишется атомарно и с правами `0600`. Обращение вида `{{ index . "DB-NAME" }}` нужно для имён, которые не являются идентификаторами Go. Кроме стандартных функций доступны `tojson` и `fromjson`. Если в шаблоне упомянут секрет, которого нет в конфигурации, команда не подставляет пустое значение, а завершается с кодом `1`. В сообщении видно и позицию в шаблоне, и само имя: ```shell $ tuna secrets substitute app.conf.tpl Error: Failed to render template: template: secrets:2:11: executing "secrets" at <.API_TOKN>: map has no entry for key "API_TOKN" ``` По той же причине условие `{{ if .DEBUG }}` для необязательного секрета тоже будет ошибкой. Пишите его через `index` — на отсутствующем ключе он возвращает пустую строку: ```gotemplate {{ if index . "DEBUG" }}debug{{ else }}quiet{{ end }} ``` Так же строго рендерится шаблон в `tuna secrets run --mount-template` — движок там общий. #### Настройка окружения ##### Setup Привязка каталога к проекту и конфигурации — после неё `--project` и `--config` можно не передавать. Привязки хранятся в [конфиг файле](https://tuna.am/docs/guides/config-file.md) клиента. ```shell tuna secrets setup ``` Без флагов команда предложит выбрать проект и конфигурацию из списка. ###### Настройка без меню Как и в случае с `download`, в `setup` можно передать `--project` и `--config`: ```shell $ tuna secrets setup --project api-php --config stage SCOPE PROJECT CONFIG /home/user/src/api api-php stage ``` *** Флаг `--no-interactive` (или переменная `TUNA_SECRETS_NO_INTERACTIVE`) запрещает спрашивать недостающие значения — команда завершится ошибкой. Это то, что нужно в CI и в скриптах установки. ###### Настройка каталога, отличного от текущего Если вы хотите настроить не текущий каталог, передайте нужный путь во флаг `--scope`: ```shell tuna secrets setup --project api-php --config stage --scope /home/user/src/api ``` ###### Файл tuna.yaml в репозитории Чтобы новому разработчику хватило одной команды `tuna secrets setup`, положите в корень репозитория файл `tuna.yaml`: tuna.yaml ```yaml setup: - project: api-php config: dev ``` Для монорепозитория можно описать несколько привязок, у каждой записи свой `path` относительно корня: tuna.yaml ```yaml setup: - project: api-php config: dev path: backend - project: ui config: dev path: frontend ``` Файл читается только тогда, когда проект и конфигурация не заданы флагами или переменными окружения, и только в каталоге `--scope` — вверх по дереву клиент не поднимается. ###### Как выглядит привязка Результат `setup` попадает в конфиг файл клиента: ```shell $ cat ~/.config/tuna/tuna.yml secrets: scoped: /home/user/src/api: project: api-php config: stage ``` Находясь в `/home/user/src/api`, проект и конфигурацию передавать не нужно. Из другого каталога — либо передайте их явно, либо укажите `--scope`: ```shell $ pwd /home/user/src/worker $ tuna secrets download --format env --no-file --scope /home/user/src/api API_TOKEN="PwZayIp9NpNntNYd2jkAAQgViM6dXdIm" API_DB="postgres://postgres:postgres@localhost:5432/postgres" ``` ##### Open Открыть текущую конфигурацию в веб-интерфейсе: ```shell tuna secrets open ``` Если браузер открыть не удалось, команда напечатает ссылку. С `-o json` она печатает только адрес. #### Управление структурой Проекты, окружения и конфигурации можно создавать и менять прямо из консоли — те же действия, что и в [веб-интерфейсе](https://my.tuna.am/secrets). ##### Проекты ```shell $ tuna secrets projects SLUG NAME DESCRIPTION CONFIGS SECRETS CREATED test test - 5 12 2026-09-17T11:20:40+04:00 ``` | Команда | Описание | | --------------------------- | -------------------------------------------------- | | `projects` | Список проектов | | `projects get [project]` | Информация о проекте | | `projects create [name]` | Создать проект: `--slug`, `--description` | | `projects update [project]` | Изменить: `--name`, `--slug`, `--description` | | `projects delete [project]` | Удалить; без аргумента предложит выбрать из списка | ```shell $ tuna secrets projects create "API PHP" --slug api-php --description "Основное API" ``` ##### Окружения ```shell $ tuna secrets environments --project api-php SLUG NAME PERSONAL CONFIGS CREATED dev Development yes 2026-09-18T10:43:08+04:00 stage Staging no 2026-09-18T10:43:09+04:00 prod Production no 2026-09-18T10:43:09+04:00 ``` | Команда | Описание | | --------------------------------- | --------------------------------------- | | `environments` | Список окружений проекта | | `environments get ENVIRONMENT` | Информация об окружении | | `environments create NAME` | Создать: `--slug`, `--personal-configs` | | `environments rename ENVIRONMENT` | Переименовать: `--name`, `--slug` | | `environments delete ENVIRONMENT` | Удалить окружение | Алиасы команды — `envs` и `environment`. ##### Конфигурации ```shell $ tuna secrets configs --project api-php SLUG ENVIRONMENT TYPE LOCKED CREATED LAST FETCH dev dev original yes 2026-09-17T11:20:40+04:00 2026-09-17T16:20:35+04:00 prod/fghd prod duplicate no 2026-09-17T11:55:14+04:00 2026-09-17T16:17:42+04:00 ``` Колонка `TYPE` различает основную конфигурацию окружения (`original`) и её копию (`duplicate`), `LAST FETCH` показывает, когда секреты забирали в последний раз — по ней видно, пользуется ли кто-нибудь конфигурацией. | Команда | Описание | | ------------------------- | ----------------------------------------------------- | | `configs` | Список конфигураций проекта, фильтр — `--environment` | | `configs get [config]` | Информация о конфигурации | | `configs create [name]` | Создать в окружении: `--environment`, `--locked` | | `configs clone [config]` | Скопировать внутри окружения: `--name` | | `configs rename [config]` | Переименовать: `--name` | | `configs lock [config]` | Запретить изменения | | `configs unlock [config]` | Снять запрет | | `configs delete [config]` | Удалить конфигурацию | | `configs logs` | История изменений: `--page`, `--page-size` | ###### История изменений ```shell $ tuna secrets configs logs TIME ACTOR ACTION SECRET 2026-09-17T16:20:37+04:00 Женя secret_delete CLAUDE_ML ``` к сведению Срок хранения истории изменений зависит от [тарифа](https://tuna.am/#pricing): на бесплатном — 3 дня, на Профи — 90 дней, на Легенде — 180 дней. Более старые записи удаляются автоматически. ###### Сервисные ключи [Сервисный ключ](https://tuna.am/docs/secrets.md#%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BD%D1%8B%D0%B5-%D0%BA%D0%BB%D1%8E%D1%87%D0%B8) ограничен одной конфигурацией — это то, что стоит использовать в CI/CD вместо пользовательского API-ключа. | Команда | Описание | | -------------------------- | ------------------------------------------------------------------- | | `configs tokens` | Список ключей конфигурации | | `configs tokens create` | Выпустить ключ: `--description`, `--access`, `--max-age`, `--plain` | | `configs tokens revoke ID` | Отозвать ключ по идентификатору | | Флаг `create` | Описание | | --------------- | ------------------------------------------------------------------------------- | | `--access` | `read` (по умолчанию) или `write` | | `--max-age` | Срок жизни в формате Go-длительности, например `720h`; без него ключ бессрочный | | `--description` | Описание, по которому ключ потом можно узнать в списке | | `--plain` | Напечатать только сам ключ, без таблицы и без перевода строки | Значение ключа показывается один раз — при создании: ```shell $ tuna secrets configs tokens create --description ci --access read --max-age 720h Save this token - it will not be shown again ID DESCRIPTION ACCESS EXPIRES CREATED TOKEN 5 ci read 2026-10-18T10:43:31+04:00 2026-09-18T10:43:31+04:00 tst_... $ tuna secrets configs tokens ID DESCRIPTION ACCESS EXPIRES CREATED 6 ci-plain read 2026-10-18T10:43:31+04:00 2026-09-18T10:43:31+04:00 5 ci read 2026-10-18T10:43:31+04:00 2026-09-18T10:43:31+04:00 ``` Предупреждение «Save this token» идёт в `stderr`, поэтому в скрипте ключ можно забрать прямо в переменную: ```shell $ TUNA_API_KEY=$(tuna secrets configs tokens create --description "gitlab ci" --access read --max-age 720h --plain) ``` --- ### Примеры к сведению Названия всех команд лишь для примера у вас вероятнее всего будет свой вариант. #### Локальная разработка ##### 🍪 JavaScript (Vue, React, Angular и др.) Практически любой web проект содержит `package.json` и в нём есть scripts, где описаны разные команды, для сборки, для запуска и отладки локально. Выглядит примерно так: ```json ... "scripts": { "serve": "vite", ... ``` 1. Перейдите в каталог с проектом `cd ~/path/to/your/project`. 2. Установите конфигурацию для проекта `tuna secrets setup`. 3. Отредактируйте `package.json` и добавите обёртку `tuna secrets run`, должно получиться примерно так: ```json ... "scripts": { "serve": "tuna secrets run --watch -- vite", ... ``` 4. Запустите приложение как обычно `yarn serve` или `npm run serve` *** ##### 🐹 Go (Golang) Go-проекты обычно запускаются через `go run` или `make`: 1. Перейдите в каталог с проектом `cd ~/path/to/your/project`. 2. Выполните `tuna secrets setup`. 3. Запустите приложение с обёрткой: ```shell tuna secrets run --watch -- go run ./cmd/server ``` Пример Makefile: ```yaml .DEFAULT_GOAL := run .PHONY: run run: ### Запуск @tuna secrets run --watch -- go run ./cmd/server ``` ##### 🦀 Rust (Rocket, Actix и др.) Rust-проекты чаще всего используют cargo: 1. Перейдите в каталог с проектом `cd ~/path/to/your/project`. 2. Выполните `tuna secrets setup`. 3. Запустите приложение с обёрткой: ```shell tuna secrets run --watch -- cargo run ``` Пример Makefile: ```yaml .DEFAULT_GOAL := run .PHONY: run run: ### Запуск @tuna secrets run --watch -- cargo run ``` *** ##### 🥠 Node.js серверный проект (Express, Fastify и др.) Node.js backend обычно также использует `package.json`, например: ```json ... "scripts": { "dev": "node server.js", ... ``` 1. Перейдите в каталог с проектом `cd ~/path/to/your/project`. 2. Установите конфигурацию для проекта `tuna secrets setup`. 3. Отредактируйте `package.json`, добавив обёртку: ```json ... "scripts": { "dev": "tuna secrets run --watch -- node server.js", ... ``` 4. Запустите приложение `yarn dev` или `npm run dev`. *** ##### 🐍 Python (Flask, Django и др.) Python-проекты часто запускаются через `python`, `manage.py` или `Makefile`. 1. Перейдите в каталог с проектом `cd ~/path/to/your/project`. 2. Установите конфигурацию для проекта добавив обёртку `tuna secrets setup`. 3. Оберните команду запуска: ```bash tuna secrets run --watch -- python app.py ``` Если у вас Django: ```bash tuna secrets run --watch -- python manage.py runserver ``` Если у вас Makefile: ```yaml .DEFAULT_GOAL := run .PHONY: run run: ### Запуск @tuna secrets run --watch -- python manage.py runserver ``` 4. Запустите приложение этой командой. *** ##### 🐘 PHP (Laravel, Symfony и др.) Обычно используется встроенный веб-сервер PHP: ```shell php -S localhost:8000 -t public ``` 1. Перейдите в каталог с проектом `cd ~/path/to/your/project`. 2. Установите конфигурацию для проекта `tuna secrets setup`. 3. Запустите сервер через обёртку `tuna secrets run`: ```bash tuna secrets run --watch -- php -S localhost:8000 -t public ``` Если у вас Laravel: ```bash tuna secrets run --watch -- php artisan serve ``` Пример Makefile: ```yaml .DEFAULT_GOAL := run .PHONY: run run: ### Запуск @tuna secrets run --watch -- php artisan serve ``` *** ##### ☕ Java/Kotlin (Spring Boot, Micronaut и др.) Такие проекты часто используют Gradle или Maven: 1. Перейдите в каталог с проектом `cd ~/path/to/your/project`. 2. Установите конфигурацию для проекта `tuna secrets setup`. 3. Оберните команду запуска: Для Gradle: ```bash tuna secrets run --watch -- ./gradlew bootRun ``` Для Maven: ```bash tuna secrets run --watch -- mvn spring-boot:run ``` Пример Makefile: ```yaml .DEFAULT_GOAL := run .PHONY: run run: ### Запуск @tuna secrets run --watch -- mvn spring-boot:run ``` 4. Запустите приложение как обычно. *** ##### 🪟 C#/.NET (ASP.NET Core и др.) Проекты на .NET запускаются через `dotnet run`: 1. Перейдите в каталог с проектом `cd ~/path/to/your/project`. 2. Выполните `tuna secrets setup`. 3. Запустите приложение с обёрткой: ```shell tuna secrets run --watch -- dotnet run ``` Пример Makefile (на Linux/macOS): ```yaml .DEFAULT_GOAL := run .PHONY: run run: ### Запуск @tuna secrets run --watch -- dotnet run ``` *** #### CI/CD ##### 🦊 Gitlab CI Создайте [сервисные ключи](https://tuna.am/docs/secrets.md#%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BD%D1%8B%D0%B5-%D0%BA%D0%BB%D1%8E%D1%87%D0%B8) для нужных конфигураций и сохраните ключ в [Gitlab ci variables](https://docs.gitlab.com/ci/variables/). Предположим, у вас есть проект `myproj` в нём есть окружение `prod`, создайте сервисный ключ и сохраните его в переменную `TUNA_API_KEY_MYPROJ_PROD` в Gitlab variables. Ниже пример того как это может выглядеть в Job: **Переменные окружения** ```yaml production: extends: [.base] environment: name: prod variables: TUNA_API_KEY: $TUNA_API_KEY_MYPROJ_PROD TUNA_SECRETS_PROJECT: $CI_PROJECT_NAME TUNA_SECRETS_CONFIG: $CI_ENVIRONMENT_NAME TUNA_SECRETS_FORMAT: env TUNA_SECRETS_NO_FILE: true before_script: - source <(tuna secrets download) script: - goreleaser release ``` **Флаги** ```yaml production: extends: [.base] environment: name: prod before_script: - source <(tuna --api-key=${TUNA_API_KEY_MYPROJ_PROD} secrets download --project=${CI_PROJECT_NAME} --config=${CI_ENVIRONMENT_NAME} --format=env --no-file) script: - goreleaser release ``` **Обёртка run** ```yaml production: extends: [.base] environment: name: prod variables: TUNA_API_KEY: $TUNA_API_KEY_MYPROJ_PROD TUNA_SECRETS_PROJECT: $CI_PROJECT_NAME TUNA_SECRETS_CONFIG: $CI_ENVIRONMENT_NAME script: - tuna secrets run -- goreleaser release ``` Секреты попадают только в окружение процесса: ни файла в рабочем каталоге, ни `source` в истории джобы. Код выхода `goreleaser` становится кодом выхода джобы. Заметьте, что **project** и **config** мы получаем прямо из окружения, это возможно, если имя проекта в Gitlab и Tuna Secrets совпадают, а также environment.name в Gitlab Job соответствует алиасу конфигурации. *** ##### 🐱 GitHub Actions Создайте [сервисные ключи](https://tuna.am/docs/secrets.md#%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BD%D1%8B%D0%B5-%D0%BA%D0%BB%D1%8E%D1%87%D0%B8) для нужных конфигураций и сохраните ключ в [GitHub Secrets](https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions). Предположим, у вас есть проект `myproj` в нём есть окружение `prod`, создайте сервисный ключ и сохраните его в переменную `TUNA_API_KEY_MYPROJ_PROD` в GitHub Secrets. Ниже пример того как это может выглядеть в Job: **Переменные окружения** ```yaml name: Release on: push: tags: - "v*" jobs: production: runs-on: ubuntu-latest env: TUNA_API_KEY: ${{ secrets.TUNA_API_KEY_MYPROJ_PROD }} TUNA_SECRETS_PROJECT: ${{ github.event.repository.name }} TUNA_SECRETS_CONFIG: prod TUNA_SECRETS_FORMAT: env TUNA_SECRETS_NO_FILE: true steps: - uses: actions/checkout@v4 - run: | source <(tuna secrets download) goreleaser release ``` **Флаги** ```yaml name: Release on: push: tags: - "v*" jobs: production: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: | source <(tuna --api-key=${{ secrets.TUNA_API_KEY_MYPROJ_PROD }} secrets download --project=${{ github.event.repository.name }} --config=prod --format=env --no-file) goreleaser release ``` **Обёртка run** ```yaml name: Release on: push: tags: - "v*" jobs: production: runs-on: ubuntu-latest env: TUNA_API_KEY: ${{ secrets.TUNA_API_KEY_MYPROJ_PROD }} TUNA_SECRETS_PROJECT: ${{ github.event.repository.name }} TUNA_SECRETS_CONFIG: prod steps: - uses: actions/checkout@v4 - run: tuna secrets run -- goreleaser release ``` Заметьте, что `project = github.event.repository.name` мы получаем прямо из окружения, это возможно, если имя проекта в GitHub и Tuna Secrets совпадают, **config** - задаётся явно. *** ##### 🧰 Отдельные секреты в скриптах Когда джобе нужен один секрет, выгружать всю конфигурацию незачем. Флаг `--plain` печатает значение без перевода строки в конце, поэтому его удобно подставлять прямо в команду: ```yaml publish: script: - docker login -u "$CI_REGISTRY_USER" -p "$(tuna secrets get REGISTRY_PASSWORD --plain)" "$CI_REGISTRY" ``` Флаг `-o json` есть у всех команд, включая запись, — это то, что нужно скриптам: ```yaml rotate-token: script: - openssl rand -hex 32 | tuna secrets set API_TOKEN - tuna secrets get API_TOKEN -o json | jq -r '.API_TOKEN.updated_at' ``` Ротация требует сервисного ключа с доступом `write`. А вот проверка, что в stage и prod не оказалось одинаковых паролей. Она работает с [отпечатками](https://tuna.am/docs/secrets/cli.md#%D0%BE%D1%82%D0%BF%D0%B5%D1%87%D0%B0%D1%82%D0%BA%D0%B8-%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B9), а не со значениями, поэтому результат не страшно оставить в логе джобы: ```yaml check-secrets: script: - tuna secrets list -c stage -o json | jq -r 'to_entries[] | "\(.key) \(.value.fingerprint)"' > stage.txt - tuna secrets list -c prod -o json | jq -r 'to_entries[] | "\(.key) \(.value.fingerprint)"' > prod.txt - comm -12 stage.txt prod.txt ``` *** ##### 🧵 Bitbucket Pipelines Создайте [сервисные ключи](https://tuna.am/docs/secrets.md#%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BD%D1%8B%D0%B5-%D0%BA%D0%BB%D1%8E%D1%87%D0%B8) для нужных конфигураций и сохраните ключ в [Bitbucket Pipelines variables](https://support.atlassian.com/bitbucket-cloud/docs/variables-and-secrets/). Предположим, у вас есть проект `myproj` в нём есть окружение `prod`, создайте сервисный ключ и сохраните его в переменную `TUNA_API_KEY_MYPROJ_PROD` в Bitbucket Pipelines variables. Ниже пример того как это может выглядеть в Job: **Переменные окружения** ```yaml pipelines: tags: "v*": - step: name: Production Build deployment: prod script: - export TUNA_API_KEY=$TUNA_API_KEY_MYPROJ_PROD - export TUNA_SECRETS_PROJECT=$BITBUCKET_REPO_SLUG - export TUNA_SECRETS_CONFIG=prod - export TUNA_SECRETS_FORMAT=env - export TUNA_SECRETS_NO_FILE=true - source <(tuna secrets download) - goreleaser release ``` **Флаги** ```yaml pipelines: tags: "v*": - step: name: Release deployment: prod script: - source <(tuna --api-key=$TUNA_API_KEY_MYPROJ_PROD secrets download --project=$BITBUCKET_REPO_SLUG --config=prod) --format=env --no-file) - goreleaser release ``` Заметьте, что `project = $BITBUCKET_REPO_SLUG` мы получаем прямо из окружения, это возможно, если имя проекта в `BITBUCKET_REPO_SLUG` и Tuna Secrets совпадают, **config** - задаётся явно. --- ### Инструкции #### [📄️Direnv](https://tuna.am/docs/secrets/guides/direnv.md) [Интеграция с direnv](https://tuna.am/docs/secrets/guides/direnv.md) --- ### Direnv Узнайте, как автоматически загружать переменные окружения в вашей среде разработки. `direnv` — это инструмент, который автоматически загружает переменные окружения при переходе `cd` в каталог и удаляет их при выходе из этого каталога. В этом руководстве показано, как использовать его вместе с Tuna. Внимание Мы не рекомендуем загрузку всех секретов в окружение оболочки таким образом. Однако некоторым разработчикам может понадобиться такая функциональность. Это исключительно руководство по использованию Tuna Secrets с `direnv` и не является рекомендацией данного инструмента или рабочего процесса. #### Требования * Установите [direnv](https://direnv.net/) * Совместимая с `direnv` оболочка #### Настройка проекта Для этого сначала необходимо выполнить команду `tuna secrets setup` в проекте. Убедитесь, что вы выполнили процесс настройки и связали каталог с проектом и конфигурацией. #### Создание файла `.envrc` В корне каталога проекта создайте файл `.envrc` со следующим содержимым: подсказка **Вариант 1** появился позже, так как флаг `env-no-quotes` появился в более поздней версии клиента. **Вариант 1** ```shell export <(tuna secrets download --no-file --format env-no-quotes) ``` **Вариант 2** ```shell set -a source <(tuna secrets download --no-file --format env) set +a ``` Команда `set -a` включает автоматический экспорт всех последующих присвоений переменных, а `set +a` отключает эту функцию. *** После сохранения вы можете получить предупреждение от `direnv`: ```shell direnv: error /path/to/project/.envrc is blocked. Run `direnv allow` to approve its content ``` По умолчанию `direnv` не будет загружать содержимое файла `.envrc`, пока вы его не подтвердите. Поскольку вы только что создали его, разрешите выполнение командой: ```shell direnv allow ``` После этого вы увидите сообщение о загрузке переменных окружения: ```shell direnv: loading /path/to/project/.envrc direnv: export +YOUR_VARIABLE ``` Когда вы покинете каталог, `direnv` выгрузит переменные: ```shell direnv: unloading ``` > **Приведенное решение не гарантирует корректную работу со всеми значениями секретов. В частности, могут возникать ошибки с многострочными секретами. Direnv также может некорректно обрабатывать секреты, содержащие символы `?`, `*` и \`\`\`. Также возможны проблемы с другими символами (например, `$` и `#`).** #### Переопределение отдельных переменных В некоторых случаях может потребоваться локальное переопределение, которое неудобно задавать через [конфигурации](https://tuna.am/docs/secrets.md#%D0%BA%D0%BE%D0%BD%D1%84%D0%B8%D0%B3%D1%83%D1%80%D0%B0%D1%86%D0%B8%D0%B8). В этом случае вы можете изменить файл `.envrc`, чтобы он искал другой файл и, если он существует, подключал его после загрузки секретов из Tuna. Назовем этот файл `.env.local`, и ваш `.envrc` будет выглядеть так: ```shell set -a source <(tuna secrets download --no-file --format env) test -f .env.local && source .env.local set +a ``` Он будет работать так же, как и прежде, но если файл `.env.local` существует, переменные окружения, определенные в нём, будут иметь приоритет перед загруженными из Tuna. --- ### Техническая поддержка Страница является неотъемлемой частью [Договора-оферты](https://tuna.am/tos.md) (п. 17.3). #### Каналы обращения | Канал | Для чего | | ------------------------------------------------------------ | ---------------------------------------------------------------------------------------- | | | Основной канал: вопросы по работе сервисов, подписке, оплате и документам | | | Жалобы на злоупотребления, см. [Злоупотребления и жалобы](https://tuna.am/docs/abuse.md) | | [Telegram-сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy) | Общение с командой и другими пользователями, быстрые вопросы | Обращения по вопросам подписки направляйте с адреса электронной почты, указанного в личном кабинете, — так мы сможем идентифицировать аккаунт без дополнительных проверок. #### Режим работы Поддержка работает в рабочие дни с 10:00 до 17:00 по ереванскому времени (Asia/Yerevan, UTC+4). Обращения, поступившие в нерабочее время, принимаются в очередь и обрабатываются в ближайший рабочий день. Инциденты, затрагивающие доступность платформы, обрабатываются по мере выявления, в том числе вне указанного режима. #### Сроки реакции | Тариф | Срок реакции на первичное обращение | | -------------------------- | ------------------------------------ | | Бесплатный, Новичок, Профи | 3 рабочих дня | | Легенда | 1 рабочий день, приоритетная очередь | Срок реакции — это срок первого содержательного ответа, а не срок устранения неисправности. Мы не гарантируем устранение неисправности в конкретный срок (п. 17.4 [Договора-оферты](https://tuna.am/tos.md)). Индивидуальные условия обслуживания, включая гарантированные сроки восстановления и повышенные требования к доступности, оформляются отдельным соглашением — напишите на . #### Что входит в поддержку * Диагностика проблем с работой сервисов платформы и клиентского ПО. * Помощь в настройке туннелей, шлюзов, политик трафика и других сервисов в пределах документации. * Вопросы по тарифам, подписке, оплате и закрывающим документам. * Приём сообщений об ошибках и уязвимостях. #### Что в поддержку не входит * Настройка инфраструктуры, серверов и сетевого оборудования на стороне пользователя. * Разработка, доработка и отладка приложений пользователя. * Интеграции и работы, выходящие за пределы документации, — выполняются по отдельному соглашению (п. 17.5 [Договора-оферты](https://tuna.am/tos.md)). #### Как ускорить решение Приложите к обращению: * какой компонент используется и его версию — клиент командной строки, приложение для рабочего стола, бастион или другой компонент платформы (у консольных компонентов версию покажет команда `version`); * операционную систему и способ установки; * команду или действие, которое вы выполняли, и полный текст ошибки; * имя туннеля, домена или идентификатор ресурса в личном кабинете; * время возникновения проблемы с указанием часового пояса. Перед обращением загляните в [Диагностику проблем](https://tuna.am/docs/troubleshooting.md) — частые случаи разобраны там. Удаляйте из журналов и снимков экрана данные, не относящиеся к проблеме: пароли, токены и содержимое запросов нам для диагностики не нужны. --- ### Команда В этом разделе документации описаны возможности и функции при работе с Tuna в [команде](https://my.tuna.am/team). ![team-main](/assets/images/team-main-26fa049b61101e8df3969ff4ca542754.png) #### Обзор Каждый пользователь платформы Tuna может состоять в нескольких командах, быть создателем или участником. Переключение между персональным и командными аккаунтами осуществляется с помощью селектора в левом верхнем углу экрана, там же есть кнопка создания новой команды. ![team-selector](/assets/images/team-selector-7ec3d42d4174364d633ed74639fa345d.png) #### Для кого? ☝ Мы помогаем компаниям и стартапам занимающемся разработкой, часто такие коллективы имеют распределённую команду. С Tuna вы можете значительно ускорить разработку и администрирование, упростив взаимодействие между участниками не в ущерб безопасности. * публикация локальных стендов * передача файлов друг-другу напрямую * удалённый доступ на рабочие станции и серверы в приватных сетях * безопасная передача паролей * публикация Демо стендов заказчику Всё это и множество других сценариев использования, что вы можете придумать для себя сами, сделает ваш опыт при работе с Tuna исключительным. #### Навигация #### [📄️Участники](https://tuna.am/docs/team/members.md) [Управление участниками команды, роли доступа](https://tuna.am/docs/team/members.md) #### [📄️Роли](https://tuna.am/docs/team/roles.md) [Роли доступа пользователей в команде](https://tuna.am/docs/team/roles.md) #### [📄️Интеграции](https://tuna.am/docs/team/integrations.md) [Настройка интеграций для отправки уведомлений в сторонние сервисы](https://tuna.am/docs/team/integrations.md) #### [📄️Контакты](https://tuna.am/docs/team/contacts.md) [Группы контактов для отправки уведомлений от мониторов](https://tuna.am/docs/team/contacts.md) #### [📄️Статистика](https://tuna.am/docs/team/statistics.md) [Общие количественные показатели использования ресурсов в команде](https://tuna.am/docs/team/statistics.md) #### [📄️Туннели](https://tuna.am/docs/team/tunnels.md) [Список активных туннелей всех пользователей в команде.](https://tuna.am/docs/team/tunnels.md) #### [📄️Домены](https://tuna.am/docs/team/domains.md) [Список зарезервированных доменов всех пользователей в команде.](https://tuna.am/docs/team/domains.md) #### [📄️TCP порты](https://tuna.am/docs/team/tcp_ports.md) [Список зарезервированных статичных TCP портов всех пользователей в команде.](https://tuna.am/docs/team/tcp_ports.md) #### [📄️SSH ключи](https://tuna.am/docs/team/ssh_public_keys.md) [Список публичных SSH ключей всех пользователей в команде.](https://tuna.am/docs/team/ssh_public_keys.md) #### [📄️Доменные зоны](https://tuna.am/docs/team/domain_zones.md) [Управление собственными доменными зонами (wildcard)](https://tuna.am/docs/team/domain_zones.md) #### [📄️TLS сертификаты](https://tuna.am/docs/team/tls_certificates.md) [Управление TLS сертификатами в команде](https://tuna.am/docs/team/tls_certificates.md) #### [📄️IP политики](https://tuna.am/docs/team/ip_policies.md) [Глобальные на команду политики доступа к туннелям по подсетям](https://tuna.am/docs/team/ip_policies.md) #### [📄️Мастер-ключи](https://tuna.am/docs/team/passwords.md) [Управление менеджером паролей участников](https://tuna.am/docs/team/passwords.md) #### [📄️Аудит логи](https://tuna.am/docs/team/audit_events.md) [Аудит действий участников команды](https://tuna.am/docs/team/audit_events.md) #### [📄️Организация](https://tuna.am/docs/team/organization.md) [🏢 Оплата по счёту для компаний и ИП](https://tuna.am/docs/team/organization.md) #### [📄️Настройки](https://tuna.am/docs/team/settings.md) [Управление базовыми настройками команды, безопасность и прочее](https://tuna.am/docs/team/settings.md) --- ### Аудит логи [В этом разделе](https://my.tuna.am/team_audit_events) размещен список действий всех участников в команде. Доступен фильтр по пользователям, типу объектов и действия. ![audit_events](/assets/images/audit_events-3fdc6bef8021cc66654d32fca66040a9.png) подсказка Этот раздел доступен **Основателю** и **Владельцам**. #### Обзор Здесь вы всегда сможете отследить кто, когда, как взаимодействовал с ресурсами, например добавлял/удалял участников, домены, порты и так далее. к сведению По умолчанию Аудит логи **выключены**, включить их можно в [настройках](https://tuna.am/docs/team/settings.md) команды, в разделе **Безопасность**. --- ### Контакты [Перейти в личный кабинет](https://my.tuna.am/team_contacts) Контакты — это группы получателей уведомлений. Каждая группа может содержать email адреса и [интеграции](https://tuna.am/docs/team/integrations.md) (Telegram, Slack и т.д.). ![Главная страница мониторов](/docs/img/team/contacts.png) *** #### Концепция Система уведомлений построена на трёх уровнях: ```shell ┌────────────────────────┐ ┌──────────────────┐ ┌──────────────────────┐ │ Монитор или отчёт │────▶│ Группа контактов │────▶│ Контакт │ │ │ │ "DevOps" │ │ (email/integration) │ └────────────────────────┘ └──────────────────┘ └──────────────────────┘ ``` 1. **Монитор или отчёт** — источник событий 2. **Группа контактов** — набор получателей для определённой цели 3. **Контакт** — конкретный получатель (email или интеграция) Такая структура позволяет: * Гибко управлять получателями уведомлений * Использовать одну группу для нескольких мониторов * Легко добавлять/удалять получателей *** #### Группы контактов Группа контактов — это именованный набор получателей уведомлений. ![Главная страница мониторов](/docs/img/team/contacts_groups.png) ##### Примеры использования | Группа | Назначение | Контакты | | ------------------- | ----------------- | -------------------------------------- | | **DevOps** | Критичные сервисы | Email команды, Telegram, Slack #alerts | | **Первая линия** | Все алерты | Email поддержки | | **Backend** | Backend сервисы | Telegram разработчиков | | **Ночные дежурные** | Ночные алерты | Telegram дежурного | *** #### Типы контактов | Тип | Иконка | Описание | | --------------- | ------ | -------------------------- | | **Email** | | Email адрес | | **Telegram** | | Telegram чат/группа | | **Slack** | | Slack канал | | **Discord** | | Discord канал | | **VK Teams** | | VK Teams чат | | **Google Chat** | | Google Chat | | **Webhook** | | Произвольный HTTP endpoint | *** #### Связанные разделы * [Интеграции](https://tuna.am/docs/team/integrations.md) — настройка каналов уведомлений * [Мониторы](https://tuna.am/docs/monitors.md) — уведомления о срабатываниях * [Отчёты](https://tuna.am/docs/reports.md) — уведомления о новых отчётах --- ### Доменные зоны [В этом разделе](https://my.tuna.am/team_domain_zones) вы можете добавить свои доменные зоны (wildcard). ![domain_zones](/assets/images/domain_zones-561cf25dd9ba3a4321037fb19807bf2a.png) подсказка Этот раздел доступен **Основателю**, **Владельцам** и **Администраторам**. #### Обзор Владение доменной зоной уникально в рамках платформы Tuna. Если вы верифицировали владение зоной, к примеру, `tuna-dev.ru`, то с этого момента только участники вашей команды могут резервировать домены по маске `*.tuna-dev.ru`. Можно резервировать зоны второго и выше уровня, например, можно добавить отдельно `foo.tuna-dev.ru` и `bar.tuna-dev.ru`. Внимание Подключение зоны в первую очередь нужно для вашей безопасности, вы и ранее могли бы указать `*.your-domain.ru` в настройках DNS на нужную ноду, но тогда любой пользователь платформы смог бы подключить **Свой домен** в этой зоне и тем самым смог бы скомпрометировать вас. ![domain_zone-add](/assets/images/domain_zone-add-da33cf65180b722dc6bfbde25e44b791.png) При добавлении зоны нужно будет указать регион к которому будет привязана ваша зона, саму зону и опционально [TLS сертификат](https://tuna.am/docs/team/tls_certificates.md). Далее необходимо будет пройти верификацию, так мы убедимся, что вы действительно владеете доменом. ![domain_zones-verify](/assets/images/domain_zones-verify-8976edef4e6e4768f81af07827fa699c.png) #### Использование ##### Поддомены в зоне После успешного прохождения проверки владения пользователи смогут начать её использовать. На странице [управления доменами](https://my.tuna.am/domains), пользователь увидит все доступные зоны в команде привязанные к данному региону. ![domain-add](/assets/images/domain-add-0ed6d8a0d3b5fd9a224cc2d3175e6b6b.png) Это сильно упрощает конфигурацию, так как пользователю достаточно указать только нужный поддомен. Если вы не указали для зоны свой [TLS сертификат](https://tuna.am/docs/team/tls_certificates.md), будет выпущен уникальный для этого домена [Let's encrypt](https://letsencrypt.org/) сертификат. ##### Cвой wildcard TLS сертификат Если вы добавили и указали свой [TLS сертификат](https://tuna.am/docs/team/tls_certificates.md), то для всех поддоменов в этой зоне будет использоваться ваш сертификат и Let's encrypt не будет выпускаться. Это значительно ускоряет добавление новых поддоменов. А также даёт вам возможность использовать любые покупные сертификаты, самоподписанные или например от [Минцифры](https://www.gosuslugi.ru/tls). ![domain_zones-tls](/assets/images/domain_zones-tls-8cfa29c8835ad88220c78546050962ea.png) Также появляется возможность использовать свою зону как зону по умолчанию в данном регионе. Это значит, что все динамически созданные [HTTP туннели](https://tuna.am/docs/tunnels/http.md) будут иметь домен в вашей зоне. Например при запуске `tuna http -f .` вы сразу получите адрес `4l7mqf-212-49-103-2.your-domain.ru` вместо стандартного `4l7mqf-212-49-103-2.ru.tuna.am`, т.е. не нужно указывать флаг `--domain` и использовать какой-то статичный домен, вы получаете брендированный (white label) домен *из коробки*! примечание Можно скрывать IP адреса пользователей в динамических доменах, подробнее в разделе [домены](https://tuna.am/docs/team/domains.md). --- ### Домены [В этом разделе](https://my.tuna.am/team_domains) отображаются зарезервированные домены всех участников в команде. Доступен фильтр по пользователям. Вы можете удалить домен любого пользователя, кроме [бесплатного постоянного поддомена](https://tuna.am/docs/tunnels/http.md#free-subdomain) — его удалить или передать нельзя. ![domains](/assets/images/domains-ed8b4c8b83ad1c07d925597dc17be54e.png) подсказка Этот раздел доступен **Основателю**, **Владельцам** и **Администраторам**. #### Обзор Также в Легенде появляется возможность скрывать IP адреса пользователей в динамических доменах. ![domains-dynamic-hide-ip-off](/assets/images/domains-dynamic-hide-ip-off-fd38f9f77e39b86a731201e0fadc8a50.png)
*Поведение по умолчанию* ![domains-dynamic-hide-ip-on](/assets/images/domains-dynamic-hide-ip-on-ce47a0ee44dd8b0919c460910fa4e536.png)
*Включено скрытие IP* примечание Как формируется адрес динамических доменов и почему в нём фигурирует IP адрес пользователя описано [тут](https://tuna.am/docs/abuse.md#%D0%B0%D0%BD%D0%BE%D0%BD%D0%B8%D0%BC%D0%BD%D0%BE%D1%81%D1%82%D1%8C). Включить эту опцию вы можете в [настройках](https://tuna.am/docs/team/settings.md) команды, в разделе **Безопасность**. ![domains-dynamic-hide-ip](/assets/images/domains-dynamic-hide-ip-c22345a443508954db3f726418cad977.png) --- ### Интеграции [Перейти в личный кабинет](https://my.tuna.am/team_integrations) Интеграции позволяют отправлять уведомления о событиях мониторов и отчётов в различные мессенджеры и системы оповещения. ![Главная страница интеграций](/docs/img/team/integrations.png) к сведению Доступно только по [подписке](https://tuna.am/#pricing) в тарифе **Легенда**. *** #### Поддерживаемые интеграции | Интеграция | Описание | | ---------------- | ----------------------------------------- | | **Telegram** | Уведомления в Telegram чат или группу | | **Slack** | Уведомления в Slack канал через Webhook | | **Discord** | Уведомления в Discord канал через Webhook | | **VK Teams** | Уведомления в VK Teams (бывший MyTeam) | | **Google Chat** | Уведомления в Google Chat через Webhook | | **Webhook** | Произвольный HTTP Webhook | *** #### Telegram Отправка уведомлений в Telegram чат или группу. ##### Настройка 1. Откройте Telegram и найдите бота **@TunaAmBot** 2. Начните диалог с ботом командой `/start` 3. Для группового чата — добавьте бота в группу и выполните `/start@TunaAmBot` 4. Бот отправит ссылку для подтверждения 5. Перейдите по ссылке — интеграция будет создана автоматически ##### Параметры | Параметр | Описание | | ------------ | ---------------------------------------------- | | **Название** | Имя интеграции для идентификации | | **Chat ID** | Идентификатор чата (заполняется автоматически) | *** #### Slack Отправка уведомлений в Slack канал через Incoming Webhook. ##### Настройка 1. Перейдите в настройки вашего Slack workspace 2. Создайте новый Incoming Webhook: [Документация Slack](https://docs.slack.dev/messaging/sending-messages-using-incoming-webhooks/) 3. Скопируйте URL webhook 4. В Tuna создайте интеграцию Slack и вставьте URL ##### Параметры | Параметр | Описание | | --------------- | ----------------------------------- | | **Название** | Имя интеграции для идентификации | | **Канал** | Название канала (например, #alerts) | | **Webhook URL** | URL Incoming Webhook | *** #### Discord Отправка уведомлений в Discord канал через Webhook. ##### Настройка 1. Откройте настройки Discord канала 2. Перейдите в раздел **Integrations** → **Webhooks** 3. Создайте новый Webhook: [Документация Discord](https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks) 4. Скопируйте URL webhook 5. В Tuna создайте интеграцию Discord и вставьте URL ##### Параметры | Параметр | Описание | | --------------- | -------------------------------- | | **Название** | Имя интеграции для идентификации | | **Webhook URL** | URL Discord Webhook | *** #### VK Teams Отправка уведомлений в VK Teams (бывший MyTeam). ##### Настройка 1. Откройте VK Teams и найдите бота **@metabot** 2. Создайте нового бота и получите токен 3. Получите Chat ID чата, куда будут отправляться уведомления 4. В Tuna создайте интеграцию VK Teams Подробнее: [Получение токена VK Teams](https://teams.vk.com/profile/70001) ##### Параметры | Параметр | Описание | | ------------ | ----------------------------------------------------------- | | **Название** | Имя интеграции для идентификации | | **Chat ID** | Идентификатор чата | | **Token** | Токен бота (формат: `000.0000000000.0000000000:0000000000`) | *** #### Google Chat Отправка уведомлений в Google Chat через Webhook. ##### Настройка 1. Откройте нужный чат в Google Chat 2. Перейдите в настройки чата → **Webhooks** 3. Создайте новый Webhook: [Документация Google](https://developers.google.com/workspace/chat/quickstart/webhooks#create-webhook) 4. Скопируйте URL webhook 5. В Tuna создайте интеграцию Google Chat и вставьте URL ##### Параметры | Параметр | Описание | | --------------- | -------------------------------- | | **Название** | Имя интеграции для идентификации | | **Webhook URL** | URL Google Chat Webhook | *** #### Webhook (Generic) Отправка уведомлений на произвольный HTTP endpoint. ##### Настройка 1. Создайте endpoint на вашем сервере для приёма уведомлений 2. В Tuna создайте интеграцию Webhook и укажите URL ##### Параметры | Параметр | Описание | | --------------- | -------------------------------- | | **Название** | Имя интеграции для идентификации | | **Webhook URL** | URL вашего endpoint | ##### Формат запроса При событии Tuna отправляет POST запрос с JSON телом: ```json { "monitor_id": "2aB3cD4eF5gH6iJ7kL8m", "monitor_name": "My Service", "event_type": "fail", "message": "Monitor is down", "timestamp": "2024-01-15T10:30:00Z" } ``` *** #### Тестирование интеграции Перед сохранением интеграции вы можете отправить тестовое сообщение, чтобы убедиться в корректности настройки. 1. Заполните параметры интеграции 2. Нажмите кнопку **Тест** 3. Проверьте получение сообщения в целевом сервисе 4. Сохраните интеграцию *** #### Использование в контактах После создания интеграции её можно добавить в [группу контактов](https://tuna.am/docs/team/contacts.md). При событии монитора уведомления будут отправлены во все интеграции, добавленные в выбранные группы контактов. --- ### IP политики [В этом разделе](https://my.tuna.am/team_ip_policies) настраиваются политики доступа к туннелям с определенных IP адресов и подсетей. ![team_ip_policies_1](/assets/images/team_ip_policies_1-b6efb1916fbb84bbbcc4e979cba39ceb.png) подсказка Этот раздел доступен **Основателю**, **Владельцам** и **Администраторам**. #### Обзор Если вы хотите быть уверенный, что все туннели и шлюзы доступны только для определённых подсетей, вы можете создать глобальные на команду IP политики и запретить или разрешить те или иные подсети по CIDR. ![team_ip_policies_2](/assets/images/team_ip_policies_2-3032d9646251b7e280198f20bd0fc49d.png) --- ### Участники [В этом разделе](https://my.tuna.am/team) размещены функции для управления участниками в команде. ![members](/assets/images/members-50b66a5143adc2e591a6ef8899d9ae7e.png) подсказка Этот раздел доступен **Основателю**, **Владельцам** и **Администраторам**. ##### Добавление и удаление Нажмите **+Пригласить в команду**, укажите Почту и Роль, пользователь получит письмо с ссылкой-приглашением. Если у пользователя нет учётной записи в личном кабинете [my.tuna.am](https://my.tuna.am/), ему необходимо будет сначала зарегистрироваться и после этого перейти по ссылке-приглашению, для вступления в команду. ![members-invite](/assets/images/members-invite-a27aab53d80f7f297ea0728cb8a8f68e.png) ##### Роли в команде * **Основатель** - создатель команды, может её удалить. Имеет все привилегии, может приглашать/удалять членов команды, назначать роли, просматривать статистику, управлять подпиской, менять настройки команды, просматривать аудит логи, просматривать и управлять всеми ресурсами всех участников команды. Основатель может быть только 1, его роль нельзя изменить и его нельзя удалить. * **Владелец** - все те же привилегии, что и у основателя, но не может его удалить/изменить роль или удалить команду. Владельцев может быть несколько. * **Администратор** - может приглашать/удалять членов команды, назначать роли, просматривать статистику, просматривать и управлять всеми ресурсами всех участников команды. * **Пользователь** - может только использовать ресурсы которые выделены ему в команде, создавать туннели, резервировать TCP порты и домены, доступ к общим папкам с паролями. ![members-roles](/assets/images/members-roles-28cb3367274256c2b62f44bd931aa074.png) Администраторы имеют доступ не ко всем пунктам меню: ![members-admin](/assets/images/members-admin-85e6856e6ad83447fd50ca756a165fb1.png) ##### Использование места в подписке Вы можете указать будет ли пользователь учитываться в подписке. Можно добавить пользователя, но отключить его, т.е. не платить за него. Например, руководитель создаёт команду и приглашает в нее разработчиков, покупает подписку на количество разработчиков, но не платит за себя, так как сам не создаёт туннели, не подключается к бастион серверам и не пользуется ресурсами. При этом имеет полный контроль, доступ к аудиту, менеджеру паролей, управлению подпиской и т.д. ![members-disable](/assets/images/members-disable-9f26005e6b4ea4001577dfa2d3593b25.png) --- ### Организация [В этом разделе](https://my.tuna.am/team_organization) можно добавить реквизиты организации для последующей оплаты услуг Банковским переводом. ![organization](/assets/images/organization-34130844df77451a8c1307208d30a4fc.png) подсказка Этот раздел доступен **Основателю** и **Владельцам**. примечание В настоящий момент доступно только для организаций в России. ##### Инструкция для перехода на оплату по счёту 1. Добавьте E-mail бухгалтера в [контакты команды](https://my.tuna.am/team_settings) в разделе [Настройки](https://tuna.am/docs/team/settings.md) 2. Укажите реквизиты [организации](https://my.tuna.am/team_organization) в разделе [Организация](https://tuna.am/docs/team/organization.md) 3. На странице управления [подпиской](https://my.tuna.am/subscription) укажите платёжное средство - **Банковский перевод** 4. Нажмите купить подписку (сформируется счёт и отправится всем контактам из 1-го пункта) 5. После поступления денег подписка автоматически активируется --- ### Мастер-ключи [В этом разделе](https://my.tuna.am/team_passwords) вы можете увидеть список всех участников, кто пользуется менеджером паролей. ![passwords](/assets/images/passwords-8468be3f6ccf356e2779504ba7f4ddf1.png) подсказка Этот раздел доступен **Основателю** и **Владельцам**. #### Обзор [Менеджер паролей](https://tuna.am/docs/passwords.md) в команде предоставляет безопасный (согласно модели [нулевого знания](https://en.wikipedia.org/wiki/Zero-knowledge_proof)) и простой и способ делиться паролями, секретами, лицензиями и другими важными данными для доступа к командным сервисам или инфраструктуре, будь то почтовый ящик тех. поддержки или реквизиты подключения к продуктовой базе данных. Подробнее о том как работаем [Менеджер паролей](https://tuna.am/docs/passwords.md) описано в отдельном разделе. Внимание Доступ к своему хранилищу паролей имеет **ТОЛЬКО** его владелец. Если пользователь потерял свой Мастер-ключ восстановить доступ к хранилищу невозможно! Вы можете только удалить хранилище со всеми паролями и пользователь сможет создать его заново. --- ### Роли [В этом разделе](https://my.tuna.am/team_roles) вы можете создать роли доступа для разграничения прав пользователей в команде. ![team_roles](/assets/images/team_roles-95216624e6e5412fae22205348d9dd29.png) подсказка Этот раздел доступен **Основателю**, **Владельцам** и **Администраторам**. ##### Обзор Роли могут ограничить использование определённых видов туннелей, по умолчанию всем пользователям доступны все типы, или разрешить доступ к бастион серверам. После добавления роли её необходимо применить к [пользователю](https://tuna.am/docs/team/members.md). ![](/docs/img/team/team_role_add_1.png) ![](/docs/img/team/team_role_view_1.png) --- ### Настройки [В этом разделе](https://my.tuna.am/team_settings) размещено управление базовыми настройками команды, настройками безопасности и её удаление. ![settings](/assets/images/settings-afd72dfd79d0093cb1cad8f680f9d132.png) подсказка Этот раздел доступен **Основателю** и **Владельцам**. #### Обзор ##### Название команды Название команды все участники будут видеть в левом верхнем переключателе, поэтому стоит сделать его понятным всем. ![team-selector](/assets/images/team-selector-7ec3d42d4174364d633ed74639fa345d.png) ##### Контакты Тут вы можете добавить адреса эл. почты, которые будут использоваться для информирования о предстоящих платежах и выставления счетов, например добавьте вашего бухгалтера который оплачивает все счета. Подробнее об оплате по счёту описано в разделе [Организация](https://tuna.am/docs/team/organization.md). ##### Безопасность Включение [Аудит логов](https://tuna.am/docs/team/audit_events.md) и [скрытие IP адреса пользователей](https://tuna.am/docs/team/domains.md) в динамических доменах. ##### Удаление [Основатель](https://tuna.am/docs/team/members.md) может удалить команду. осторожно Все зарезервированные ресурсы будут удалены без возможности восстановления. ![team-delete](/assets/images/team-delete-49b95bdd1c84090644b73260a24b8d3e.png) --- ### SSH ключи [В этом разделе](https://my.tuna.am/team_public_keys) отображаются публичные [SSH ключи](https://tuna.am/docs/guides/ssh-keys.md) всех участников в команде. Доступен фильтр по пользователям. Вы можете удалить ключ любого пользователя. ![ssh_public_keys](/assets/images/ssh_public_keys-8e45d783ce81fb3a8b499589231fbef9.png) подсказка Этот раздел доступен **Основателю**, **Владельцам** и **Администраторам**. --- ### Статистика [В этом разделе](https://my.tuna.am/team_statistics) вы можете увидеть общие количественные показатели использования ресурсов в команде. ![statistics](/assets/images/statistics-9159cb3f9ab17705b25497fa4191cff2.png) подсказка Этот раздел доступен **Основателю**, **Владельцам** и **Администраторам**. --- ### TCP порты [В этом разделе](https://my.tuna.am/team_tcp_ports) отображаются зарезервированные статичные TCP порты всех участников в команде. Доступен фильтр по пользователям. Вы можете удалить порт любого пользователя. ![tcp_ports](/assets/images/tcp_ports-53ab105d8348d56367745346a15e302a.png) подсказка Этот раздел доступен **Основателю**, **Владельцам** и **Администраторам**. --- ### TLS сертификаты [В этом разделе](https://my.tuna.am/team_tls_certificates) вы можете управлять своими TLS сертификатами. Сертификатами могут использоваться в [доменных зонах](https://tuna.am/docs/team/domain_zones.md). ![tls_certificates](/assets/images/tls_certificates-764491682239fe3cb267a38e3049cd4c.png) подсказка Этот раздел доступен **Основателю**, **Владельцам** и **Администраторам**. #### Обзор Вы можете загрузить любые покупные сертификаты, [Let's encrypt](https://letsencrypt.org/), самоподписанные или например от [Минцифры](https://www.gosuslugi.ru/tls). Сертификат нельзя изменить, можно только добавить или удалить. --- ### Туннели [В этом разделе](https://my.tuna.am/team_tunnels) отображаются активные в настоящий момент туннели всех участников в команде. Доступен фильтр по пользователям. Вы можете завершить работу любого туннеля удалив его. ![tunnels](/assets/images/tunnels-ee5bbc47c6459a16beb824b77209bbf5.png) подсказка Этот раздел доступен **Основателю**, **Владельцам** и **Администраторам**. --- ### Политики трафика #### Обзор Функция позволяет описать правила и действия обработки трафика для входящих запросов и более гибко настроить взаимодействие с вашим приложением. к сведению Доступно только по [подписке](https://tuna.am/#pricing) в тарифе **Легенда**. Чтобы понять, зачем нужны политики и как они работают, разберём пример включения базовой авторизации только для префикса `/admin`: ```yaml --- rules: - name: Authorization for admin panel expressions: - req.URL.Path contains "/admin" actions: - name: Enable basic auth type: basic_auth config: userList: admin: password ``` Тут описано 1 правило(rules), в нём есть выражение(expressions), оно содержит условие в котором мы проверяем, что запрос предназначается для префикса `/admin`, если условие истинно, наступает действие(actions), в примере мы применяем базовую авторизацию, задаём список из пар `username`, `password`. Если пользователь проходит авторизацию, то далее трафик направляется к вашему сервису. Это правило позволит вам открыть доступ к разрабатываемому сайту для всех, например для заказчиков или коллег, но при этом вы можете запретить доступ к приватным частям сайта. Это лишь один пример, нижу вы найдёте полное описание и больше живых примеров.
Чтобы вам было проще написать нужное правило мы добавили [отладчик](https://my.tuna.am/policy_debug) прямо в личном кабинете, там вы можете проверить корректно ли работает правило, а так же приведено несколько примеров: [![policy_debug](/docs/img/policy_debug.png)](https://my.tuna.am/policy_debug) #### Правила (rules) Правила состоят из действий - `actions` (*обязательно*), которые должны вступить в силу и выражений - `expressions` (*не обязательно*), фильтрующих трафик, к которому они применяются. Правила оцениваются и выполняются последовательно в порядке их описания, без прерывания их выполнения. Т.е. если запрос подпадает сразу под несколько правил, то все действия также будет применены к данному запросу. Также можно указать имя `name`. Правила описываются в формате **YAML**, где они хранятся — см. [ниже](#policy-source). Например существует 2 правила. В первом мы включаем базовую авторизацию для всех запросов к префиксу `/admin`. Во втором проверяем есть ли заголовок `Accept-Language` и присутствует ли в нём русский язык `ru-RU`. Клиент сначала должен будет ввести username и password, а далее сработает запрет по заголовку `Accept-Language` если в значении заголовка есть `ru-RU`. ```yaml --- rules: - expressions: - req.URL.Path contains "/admin" actions: - type: basic_auth config: userList: admin: admin - expressions: - any(req.Headers["Accept-Language"], {# matches "ru-RU"}) actions: - type: deny ``` ##### Выражения (expressions) примечание Сайт с описанием синтаксиса [expr-lang](https://expr-lang.org/) Выражения основаны на синтаксисе [expr-lang](https://expr-lang.org/). Это богатый язык с множеством функций, операциями сравнения, вхождения, работы с строками и многим другим. Перечисление выражений в списке воспринимается как логическое **И** (`and`). Пример блокировки `POST` запросов от ботов: ```yaml --- rules: - expressions: - lower(req.UserAgent) matches "(chatgpt-user|gptbot)" - req.Method in ["POST"] actions: - type: deny ``` ###### Переменные с данными из запроса Чтобы работать с входящим запросом есть несколько переменные для получения информации или метаданных: | Название | Описание | | ----------------- | ------------------------------------------------------------------------------------------------------------------- | | req.Proto | Содержит версию протокола HTTP, которая была использована при отправке запроса (например `HTTP/1.1` или `HTTP/2.0`) | | req.Host | Содержит хост URL, включая порт, если он указан (алиас для req.URL.Host) | | req.Method | Содержит метод запроса `GET` / `POST` и другие | | req.URL | Полный URL запроса (имеет свои методы, которые описаны в таблице ниже) | | req.UserAgent | Содержимое заголовка User-Agent | | req.RemoteAddr | IP адрес клиента с которого пришёл запрос | | req.ContentLength | Возвращает длину тела запроса в байтах, если она известна, берётся из заголовка `Content-Length`. | | req.Headers | Список всех заголовков | Переменные внутри **req.URL** позволяют получить отдельные части URL: | Название | Описание | | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | | req.URL.Scheme | Содержит схему URL, которая определяет протокол (например, http, https, ftp и т.д.). | | req.URL.Opaque | Содержит непрозрачные (закодированные) данные URL, которые не могут быть напрямую разобраны на части, такие как схема, хост и путь. | | req.URL.User | Содержит информацию о пользователе, содержащую имя пользователя и, возможно, пароль в URL. | | req.URL.Host | Содержит хост URL, включая порт, если он указан (например, `example.com:8080`). | | req.URL.Path | Содержит путь URL, который указывает на конкретный ресурс (например, `/articles/2024/`). | | req.URL.RawPath | Содержит закодированную версию пути (если она отличается), может быть полезен для случаев, когда путь содержит специальные символы. | | req.URL.RawQuery | Содержит закодированные параметры запроса без символа `?` (например, `name=John&age=30`). | | req.URL.Fragment | Содержит фрагмент URL, который указывает на определенную часть документа, без символа `#` (например, `section2`). | | req.URL.RawFragment | Содержит закодированную версию фрагмента, если он содержит специальные символы (например, пробелы или символы Unicode). | Метаданные запроса: | Название | Описание | | -------------- | ------------------------------------------------------ | | meta.Time | Точное время в которое пришёл запрос, +- текущее время | | meta.RequestID | Индивидуальный идентификатор запроса | ###### Встроенные функции Помимо достаточно богатого синтаксиса [expr-lang](https://expr-lang.org/), доступны также и встроенные функции для быстрой работы с данными. | Название | Описание | Пример | | ---------- | --------------------------------------------------------- | ---------------------------------------- | | IpInRange | Проверяет входит ли IP в подсеть | IpInRange(req.RemoteAddr, "127.0.0.0/8") | | IsIPV6 | Проверяет является ли строка IPv6 адресом | IsIPV6(req.RemoteAddr) | | IsIPV4 | Проверяет является ли строка IPv6 адресом | IsIPV4(req.RemoteAddr) | | IsIP | Проверяет является ли строка IP адресом | IsIP(req.RemoteAddr) | | RandInt | Генерация случайного целого числа | RandInt(0, 10) | | RandDouble | Генерация случайного дробного числа в диапазоне от 0 до 1 | RandDouble() | ###### Примеры expressions Проверяем, что запрос пришёл по `https`: ```yaml - expressions: - req.URL.Scheme == "https" ``` Запрос содержит префикс `/admin`: ```yaml - expressions: - req.URL.Path contains "/admin" ``` Запрос не из подсети `10.0.0.0/8`: ```yaml - expressions: - not IpInRange(req.RemoteAddr, "10.0.0.0/8") ``` ##### Действия (actions) Выполнение действий зависит от того истинно ли условие в выражениях (`expressions`), если выражение отсутствует, то действие выполняется всегда. Действие должно содержать тип `type` и конфигурацию `config` (не всегда обязательно). Также можно указать имя `name`. ###### Типы действий (type) Доступно несколько типов действий, одни модифицируют запрос, другие отвечают за самостоятельную обработку. Можно указывать несколько типов, они будут обработаны по порядку. ###### add_headers Добавить заголовки. Можно добавлять заголовки как при передаче их к вышестоящему приложению `context: request`, так и при ответе клиенту `context: response`. Ключевое слово `headers` определяет карту ключ=значение, где ключ - название заголовка, а значение - содержимое заголовка. ```yaml --- rules: - actions: - type: add_headers config: context: request headers: foo: bar qwe: rty - actions: - type: add_headers config: context: response headers: foo: bar qwe: rty ``` ###### remove_headers Удалить заголовки. Можно удалять заголовки как при передаче их к вышестоящему приложению `context: request`, так и при ответе клиенту `context: response`. Ключевое слово `headers` определяет список заголовков. ```yaml --- rules: - actions: - type: remove_headers config: context: request headers: - foo - qwe - actions: - type: remove_headers config: context: response headers: ["foo", "qwe"] ``` ###### basic_auth Включить базовую авторизацию. Ключевое слово `userList` определяет карту ключ=значение, где ключ - `username`, а значение - `password`. ```yaml --- rules: - actions: - type: basic_auth config: userList: admin: admin foma: kiniaev ащьф: лштшфум ``` ###### url_rewrite Перезаписать URI. Ключевое слово `from` определяет *path* с которого нужно перезаписать запрос к вышестоящему серверу, а `to` определяет *path* который будет передан к к вышестоящему серверу. Также работают регулярные выражения. ```yaml --- rules: - actions: - type: url_rewrite config: from: /foo to: /bar ``` ###### redirect Перенаправление URL. Ключевое слово `to` определяет *Location* на который перенаправлять, также можно переопределить `statusCode` (по умолчанию 307). Ключевое слово `headers` определяет карту ключ=значение, где ключ - название заголовка, а значение - содержимое заголовка. ```yaml --- rules: - actions: - type: redirect config: to: /foobar statusCode: 304 headers: foo: bar ``` ###### deny Запретить обращение к вышестоящему приложению. Можно переопределить `statusCode` (по умолчанию 403). ```yaml --- rules: - actions: - type: deny config: statusCode: 451 ``` ###### restrict_ips Ограничить обращения по подсетям. Ключевое слово `allow` определяет список подсетей с которых разрешены обращения. Ключевое слово `deny` определяет список подсетей с которых запрещены обращения. ```yaml --- rules: - actions: - type: restrict_ips config: allow: - 127.0.0.1/32 deny: - 10.0.0.10/32 ``` ###### rate_limit Ограничить обращения по количеству запросов. Ключевое слово `rate` определяет промежуток времени, а `capacity` количество запросов которые можно совершить. При превышении этого порога, клиент начнёт получать `429 Too Many Requests`. ```yaml --- rules: - actions: - type: rate_limit config: rate: "60s" capacity: 2 ``` ###### custom_response Пользовательский ответ. Обязательный параметр `statusCode` определяет HTTP статус. Можно также передать тело, содержимое задаётся в параметре `content`. И заголовки, `headers` определяет карту ключ=значение, где ключ - название заголовка, а значение - содержимое заголовка. ```yaml --- rules: - actions: - type: custom_response config: statusCode: 200 content: | User-agent: * Disallow: / headers: content-type: "text/plain" ``` ###### reverse_proxy Реверс-прокси в другой сервис. С помощью этого действия можно направлять отдельные запросы в сторонний сервис – это может быть полезно, к примеру, при разработке микро-сервисов. Обязательный параметр `url` указывает альтернативную точку для реверс-прокси, необязательный параметр `onError` определяет поведение, при котором запрос не удалось передать в сторонний сервис: * `halt` (по умолчанию) – обработка запроса при ошибке будет прервана; * `continue` – запрос будет обрабатываться дальше согласно нижестоящим правилам. Стандартное поведение: ```yaml --- rules: - actions: - type: reverse_proxy config: url: "http://127.0.0.1:8000" ``` С параметром `onError` в значении `continue`: ```yaml --- rules: - actions: - type: reverse_proxy config: url: "http://127.0.0.1:8000" onError: continue - type: custom_response config: statusCode: 500 content: Unavailable ``` В данном случае, если ресурс `http://127.0.0.1:8000` недоступен, в ответ на запрос будет возвращен HTTP 500 и текст `Unavailable`. ###### compress_response Сжать ответ. Сжимает ответ, если вышестоящее приложение не сделало этого само. Необязательный параметр `algorithms` задаёт список разрешённых алгоритмов: `gzip`, `deflate`, `br`, `zstd` (по умолчанию все четыре). Если указать другое значение, политика не пройдёт проверку. ```yaml --- rules: - actions: - type: compress_response config: algorithms: [br, gzip] - type: reverse_proxy config: url: "https://example.com" ``` Само действие ничего не отвечает клиенту. Оно сжимает ответ, который сформируют следующие действия и правила (`reverse_proxy`, `custom_response` и другие), поэтому ставить его нужно **до** действия, которое формирует ответ. Если сработало несколько `compress_response`, применяется первое. Алгоритм выбирается по заголовку `Accept-Encoding` клиента с учётом весов `q` и `*`. При равном весе выигрывает алгоритм, указанный в заголовке раньше. Если клиент не просит ни один из разрешённых алгоритмов или запрещает их через `q=0`, ответ уходит без сжатия. При сжатии в ответ добавляются заголовки `Content-Encoding` и `Vary: Accept-Encoding`, а `Content-Length` и `Accept-Ranges` удаляются. Строгий `ETag` становится слабым (`W/"..."`). Ответ сжимается на лету, без буферизации, поэтому SSE и потоковые ответы продолжают работать: события не накапливаются. Ответ не сжимается, если: * у него уже есть заголовок `Content-Encoding`; * это частичный ответ (`Content-Range`); * запрос пришёл с методом `HEAD`; * статус ответа 1xx, 204 или 304; * соединение переключается на WebSocket или другой протокол через `Upgrade`; * содержимое уже сжато по своей природе: `image/*` (кроме SVG), `video/*`, `audio/*`, `font/woff*`, архивы (zip, gzip, 7z, rar, bzip2, xz, lzma, zstd, brotli). Проверить сжатие можно GET-запросом (`curl -I` отправляет `HEAD`, а такой ответ не сжимается): ```bash curl -s -o /dev/null -D - -H 'Accept-Encoding: br' https://<домен>/ ``` В заголовках ответа должны быть `content-encoding: br` и `vary: Accept-Encoding`. Без заголовка `Accept-Encoding` ответ приходит несжатым. #### Где хранятся правила По умолчанию правила читаются из файла `.tuna.yml` в текущем каталоге. Путь к файлу можно переопределить флагом `--policy-file` или переменной окружения `TUNA_POLICY_FILE`. ##### Загрузка по ссылке Начиная с версии **0.36.0** правила для `tuna http` можно загрузить по ссылке флагом `--policy-url` или переменной окружения `TUNA_POLICY_URL`. Так одну политику удобно держать в репозитории или хранилище и использовать на разных машинах: ```shell tuna http 8080 --policy-url=https://gitlab.com/example/policies/-/raw/main/policy.yml ``` * Ссылка — только `https`. `http` допускается лишь для `localhost`, `127.0.0.1` и `::1`. * Редиректы допускаются (до 10), каждый проверяется по тому же правилу. * Формат — YAML или JSON со структурой как в `.tuna.yml`. Из ответа берётся только `rules`, остальные поля игнорируются. * Ответ должен быть `200`, не пустым и не больше 1 МБ. Таймаут — 15 секунд. * Политика загружается один раз при запуске. Чтобы применить изменения, перезапустите туннель. * С `--policy-url` локальный `.tuna.yml` для политики не читается. Вместе с `--policy-file` или `TUNA_POLICY_FILE` флаг использовать нельзя. warning Политика по ссылке может всё то же, что и локальная, в том числе проксировать запросы в вашу локальную сеть через `reverse_proxy`. Загружайте её только из источника, которому доверяете. ##### Ошибки политики Начиная с версии **0.36.0** туннель не запускается, если политику не удалось загрузить: * файл, указанный в `--policy-file` или `TUNA_POLICY_FILE`, не найден; * файл, в том числе `.tuna.yml` по умолчанию, не разбирается; * ответ по ссылке не загрузился или не разбирается. Если `.tuna.yml` в текущем каталоге просто нет, туннель запускается без политики. Туннель с политикой запускается только с подпиской в тарифе **Легенда**, без неё tuna завершится с ошибкой `Traffic policy is available only in Team subscription`. Подписка проверяется при запуске: если она закончится, пока туннель работает, туннель и политика продолжат работать до перезапуска. В более ранних версиях tuna в обоих случаях выводила предупреждение и запускала туннель. #### Примеры ##### Блокировка запросов по заголовкам Блокируем запросы, если нет заголовка `X-Api-Version`, и отвечаем HTTP 400, если ниже 3: ```yaml --- rules: - name: Блокируем API v0 expressions: - len(req.Headers["X-Api-Version"]) == 0 actions: - name: Запретить type: deny - name: 400 на API v1 и v2 expressions: - req.Headers["X-Api-Version"][0] in ["1", "2"] actions: - name: Ответить 400 JSON type: custom_response config: statusCode: 400 headers: content-type: "application/json" content: | {"msg":"Вы используете старую версию API, минимальная версия 3"} ``` ##### Реверс-прокси в сторонние сервисы по префиксу и заголовкам Перенаправляем запросы к `/v1` в сторонний сервис на порту **8000**, а запросы с User-Agent содержащий *mobile* к сервису на порту **3000**. При этом команда запуска `tuna http 8080` по умолчанию проксирует все запросы на **8080**. ```yaml --- rules: - expressions: - hasPrefix(req.URL.Path, "/v1") - lower(req.UserAgent) contains "mobile" actions: - type: reverse_proxy config: url: "http://127.0.0.1:3000" - expressions: - hasPrefix(req.URL.Path, "/v1") actions: - type: reverse_proxy config: url: "http://127.0.0.1:8000" ``` ##### Пользовательский ответ в выходные дни ```yaml --- rules: - expressions: - now().Weekday().String() in ["Saturday", "Sunday"] actions: - type: custom_response config: statusCode: 200 content: Take a rest! ``` ##### Базовая аутентификация ```yaml --- rules: - expressions: - req.URL.Path contains "/admin" actions: - type: basic_auth config: userList: admin: password ``` ##### Несколько действий без выражений Ограничение запросов с `127.0.0.1` и `10.0.0.10`, а для всех остальных ограничить количество запросов в секунду до 2х. ```yaml --- rules: - actions: - type: restrict_ips config: allow: - 127.0.0.1/32 deny: - 10.0.0.10/32 - actions: - type: rate_limit config: rate: "1s" capacity: 2 ``` ##### Перезапись (rewrite) с регулярным выражением ```yaml --- rules: - expressions: - hasPrefix(req.URL.Path, "/blog") actions: - type: url_rewrite config: from: "/blog/([0-9]+)/([a-zA-Z]+)/" to: /index.php?p=$1&title=$2" ``` --- ### Устранение неполадок Здесь мы постарались собрать все возможные неполадки с которыми встречались наши пользователи и описать их решение. Большая часть проблем связана с сетевыми проблемами или пользовательским окружением. подсказка Многие ошибки и проблемы могут быть уже решены в последней версии клиента, поэтому прежде чем проводить диагностику или обращаться за помощью к [нам](mailto:info@tuna.am) или [сообществу](https://telegram.me/+Kgbtt0_gJwI5ZmEy), убедитесь, что у вас установлена последняя версия клиента. Инструкция по обновлению есть [тут](https://tuna.am/docs/guides/update.md). #### Самостоятельная диагностика сетевой доступности Если у вас появляются ошибки при создании туннеля, выполните команду `tuna diagnose` для получения диагностической информации, отчет поможет лучше понять, где именно проблема. ```shell Please wait, testing connectivity... TLS connectivity: Google.com: ok [1.46189625s] Yandex.ru: ok [1.246520375s] tuna API: ok [1.484186875s] tuna NL location: ok [739.467083ms] tuna RU location: ok [597.777167ms] TCP connectivity: tuna NL location: ok [75.757708ms] tuna RU location: ok [34.079541ms] ``` Как правило, tuna использует порт `443` для подключения к нодам при создании туннеля. Если проверки `TCP connectivity` не проходят, проверьте нет ли фаервола который может ограничивать подключения. #### Распространённые ошибки ##### Subdomains unavailable for free plan Ошибка при запуске с `--subdomain` на бесплатном тарифе. Без подписки работает только ваш [бесплатный постоянный поддомен](https://tuna.am/docs/tunnels/http.md#free-subdomain): другие имена, в том числе зарезервированные раньше по подписке, недоступны. Проверьте имя поддомена в [личном кабинете](https://my.tuna.am/domains) и что клиент авторизован вашим токеном, а не токеном другого аккаунта. ##### Domain unavailable for free plan То же для `--domain`: без подписки можно указать только свой бесплатный поддомен целиком, например `--domain=brave-otter-4821.ru.tuna.am`. Собственные домены и поддомены других пользователей доступны только по [подписке](https://tuna.am/#pricing). ##### Tunnel limit reached Если вы видите ошибку `Tunnel limit reached` (Исчерпан лимит по туннелям), хотя вы знаете, что на самом деле это не так, это может также означать, что есть зависший активный туннель. Удалите зависший туннель в [панели управления туннелями](https://my.tuna.am/tunnels) и обновите клиент tuna. ##### Tunnel already active ```shell ERRO[09:01:09] Failed to get connection settings: Tunnel already active Code: BadRequest Request ID: 2008cc71bdf725853748bb91d69c4669, retrying in 1s ERRO[09:01:10] Failed to get connection settings: Tunnel already active Code: BadRequest Request ID: 0118213a8f8d341f002ec30ee1499768, retrying in 2s ERRO[09:01:12] Failed to get connection settings: Tunnel already active Code: BadRequest Request ID: 608d043eb16376a619b671eb0d33dc0b, retrying in 4s ``` Данная ошибка `Tunnel already active` означают, что туннель уже существует, возможно он завис, или запущен у вас где-то в фоне. подсказка Проблема с переподключениями (reconnect) устранена клиентах * tuna-cli v0.28.0 * tuna-desktop v0.2.0 #### Тестирование скорости туннелей Если вам нужно оценить пропускную способность туннеля, ниже описаны способы тестирования для HTTP и TCP туннелей. к сведению Мы не накладываем никаких ограничений на скорость передачи данных через туннели. Итоговая скорость зависит от пропускной способности вашего интернет-канала и сетевых задержек на маршруте: от конечного пользователя до [ноды](https://tuna.am/docs/tunnels/guides/locations.md), через которую построен туннель, и от ноды до клиента Tuna. Для тестов понадобится файл достаточного размера. Можно заранее скачать ISO-образ с зеркала Яндекса, например [Ubuntu Server](https://mirror.yandex.ru/ubuntu-releases/24.04/ubuntu-24.04.2-live-server-amd64.iso): **Windows** ```powershell curl.exe -L -o ubuntu-server.iso https://mirror.yandex.ru/ubuntu-releases/24.04/ubuntu-24.04.2-live-server-amd64.iso ``` **Unix** ```shell curl -L -o ubuntu-server.iso https://mirror.yandex.ru/ubuntu-releases/24.04/ubuntu-24.04.2-live-server-amd64.iso ``` ##### HTTP туннели ###### Скорость отдачи (download с клиента) Запустите встроенный файловый сервер, указав каталог с тестовым файлом: **Windows** ```powershell tuna http -f C:\path\to\directory ``` **Unix** ```shell tuna http -f /path/to/directory ``` Где путь — каталог, в котором лежит скачанный ранее файл. После запуска туннеля скачайте файл по полученной ссылке с помощью `curl`: **Windows** ```powershell curl.exe -o NUL https://your-tunnel-url.tuna.am/ubuntu-server.iso ``` **Unix** ```shell curl -o /dev/null https://your-tunnel-url.tuna.am/ubuntu-server.iso ``` `curl` покажет скорость скачивания — это и есть скорость отдачи данных через туннель. ###### Скорость загрузки (upload на клиент) Запустите встроенный WebDAV-сервер: ```shell tuna http --webdav ``` Затем загрузите файл через туннель на машину, где запущен клиент Tuna: **Windows** ```powershell curl.exe -T ubuntu-server.iso https://your-tunnel-url.tuna.am/ubuntu-server.iso ``` **Unix** ```shell curl -T ubuntu-server.iso https://your-tunnel-url.tuna.am/ubuntu-server.iso ``` Скорость загрузки, которую покажет `curl`, отражает пропускную способность туннеля в направлении к клиенту. ##### TCP туннели Для тестирования TCP туннелей используйте утилиту [iperf3](https://iperf.fr/). Запустите iperf3-сервер на машине с клиентом Tuna и пробросьте порт через TCP туннель: ```shell iperf3 -s -p 5201 tuna tcp -p 5201 ``` С другой машины подключитесь к туннелю: ```shell iperf3 -c your-tunnel-host -p your-tunnel-port ``` Установите iperf3 из репозитория вашей ОС или скачайте готовую сборку с [официального сайта](https://iperf.fr/iperf-download.php): ```shell # Windows (winget) winget install ar51an.iPerf3 # macOS brew install iperf3 # Debian / Ubuntu sudo apt install iperf3 # RHEL / CentOS sudo yum install iperf3 # Fedora sudo dnf install iperf3 # openSUSE sudo zypper install iperf3 # Arch Linux sudo pacman -S iperf3 # ALT Linux sudo apt-get install iperf3 # NixOS nix-env -iA nixpkgs.iperf3 # FreeBSD sudo pkg install iperf3 ``` --- ### Туннели Функционал позволяющий с помощью утилиты [tuna cli](https://tuna.am/docs/guides/install/install-cli.md) или GUI приложения [Tuna Desktop](https://tuna.am/docs/guides/install/install-desktop.md) создавать обратные реверс-прокси [HTTP](https://tuna.am/docs/tunnels/http.md), [TCP](https://tuna.am/docs/tunnels/tcp.md) и [SSHd](https://tuna.am/docs/tunnels/ssh.md) туннели. Вы сможете получить прямой доступ из интернета к запущенным локально сайтам или приложениям. Просто запустите в консоли короткую команду, получаете в ответ ссылку, а ваш друг из любой точки мира перейдя по ней попадёт на сайт запущенный на вашем ПК в локальной сети, и всё это без VPN, требований в "белом" IP, без проброса портов на роутере. *** #### [🗃HTTP](https://tuna.am/docs/tunnels/http.md) [1 элемент](https://tuna.am/docs/tunnels/http.md) #### [📄️TCP](https://tuna.am/docs/tunnels/tcp.md) [Предоставить доступ к базе данных, SSH, RDP](https://tuna.am/docs/tunnels/tcp.md) #### [📄️SSHd](https://tuna.am/docs/tunnels/ssh.md) [Предоставить доступ по SSH без SSH сервера](https://tuna.am/docs/tunnels/ssh.md) #### [📄️Postgres](https://tuna.am/docs/tunnels/postgres.md) [Предоставить доступ к базе данных PostgreSQL с инспектором запросов.](https://tuna.am/docs/tunnels/postgres.md) #### [📄️Redis](https://tuna.am/docs/tunnels/redis.md) [Предоставить доступ к Redis с инспектором запросов.](https://tuna.am/docs/tunnels/redis.md) #### [📄️Kubernetes](https://tuna.am/docs/tunnels/kubernetes.md) [Временный доступ к Kubernetes API без VPN и без передачи своих учётных данных.](https://tuna.am/docs/tunnels/kubernetes.md) #### [1С](https://tuna.am/docs/tunnels/1c.md) [Опубликовать базу 1С:Предприятие в интернет без установки и настройки веб-сервера.](https://tuna.am/docs/tunnels/1c.md) #### [📄️Trigger](https://tuna.am/docs/tunnels/trigger.md) [Выполнение действий по наступлению события](https://tuna.am/docs/tunnels/trigger.md) #### [📄️Порты](https://tuna.am/docs/tunnels/ports.md) [Резервирование статичных портов для TCP, SSHd, Postgres, Redis и Trigger туннелей](https://tuna.am/docs/tunnels/ports.md) #### [📄️Интерфейс в терминале](https://tuna.am/docs/tunnels/tui.md) [Полноэкранный интерфейс tuna CLI для HTTP, TCP, SSHd, Postgres, Redis и Kubernetes туннелей, горячие клавиши и отключение](https://tuna.am/docs/tunnels/tui.md) #### [📄️Политики трафика](https://tuna.am/docs/traffic-policy.md) [Политики обработки трафика входящих запросов](https://tuna.am/docs/traffic-policy.md) #### [🗃Инструкции](https://tuna.am/docs/tunnels/guides.md) [7 элементов](https://tuna.am/docs/tunnels/guides.md) #### [🗃Примеры](https://tuna.am/docs/tunnels/examples.md) [64 элемента](https://tuna.am/docs/tunnels/examples.md) --- ### Публикация базы 1С:Предприятие к сведению Доступно только по [подписке](https://tuna.am/#pricing). #### Обзор Команда `tuna 1c` публикует базу 1С:Предприятие и открывает к ней доступ из интернета: через веб-клиент в браузере или тонкий клиент 1С. Ставить и настраивать веб-сервер, пробрасывать порты и получать «белый» IP не нужно. У 1С нет собственного HTTP-сервера: веб-клиент и тонкий клиент по HTTP обслуживает модуль расширения веб-сервера, который загружается в Apache или IIS. `tuna 1c` делает всю эту работу сама: 1. находит установленную платформу 1С и её модуль расширения веб-сервера; 2. при первом запуске скачивает Apache httpd с `releases.tuna.am` в кэш (`%LocalAppData%\tuna`); 3. запускает его на `127.0.0.1` и публикует в нём базу; 4. открывает [HTTP-туннель](https://tuna.am/docs/tunnels/http.md) к этому веб-серверу. База доступна по адресу `<адрес туннеля>/1c/`, корень адреса перенаправляет туда же. #### Требования * **[Подписка](https://tuna.am/#pricing) tuna.** На бесплатном тарифе команда не запустится: сервер ответит `1C unavailable for free plan`. * **Windows x64.** Команда есть только в сборке tuna для Windows x64. Платформа 1С при этом может быть и 32-, и 64-битной. В сборках для Linux, macOS и Windows ARM64 команды нет. * **Компонент «Модули расширения веб-сервера»** в установке 1С. Без него tuna сообщит, что модуль не найден. [Как его установить](#web-module). * **Лицензия 1С, допускающая подключение через веб-сервер.** [Учебная версия](#training) не подходит. При первом запуске tuna также установит Microsoft Visual C++ Redistributable, если его нет в системе: без него Apache не запускается. Windows может запросить подтверждение (UAC). ##### Установка модулей расширения веб-сервера Компонент входит в дистрибутив платформы, но по умолчанию может быть не отмечен. Добавить его в уже установленную 1С: 1. Откройте «Параметры» → «Приложения» → «Установленные приложения», найдите «1С:Предприятие 8» и в меню «…» нажмите «Изменить». В Windows 10 и старше то же самое делается через «Панель управления» → «Программы и компоненты». ![1С:Предприятие 8 в списке установленных приложений Windows, пункт «Изменить»](/docs/img/tuna_1c_install_apps.png) 2. В установщике выберите режим «Изменить» и нажмите «Далее». ![Режим «И�зменить» в установщике 1С](/docs/img/tuna_1c_install_modify.png) 3. В списке компонентов нажмите на значок у «Модулей расширения веб-сервера» и выберите «Данный компонент будет установлен на локальный жесткий диск». ![Включение компонента «Модули расширения веб-сервера» в установщике 1С](/docs/img/tuna_1c_install_component.png) 4. Нажмите «Далее» и дождитесь окончания установки. Проверить результат можно командой `tuna 1c discover`: рядом с установкой появится путь к `wsap24.dll`. #### Быстрый старт Один раз выберите установку 1С и базу в мастере: ```shell tuna 1c setup ``` Мастер спросит установку 1С, базу, локальный порт и место сохранения. Шаг с единственным вариантом он пропускает. Опубликуйте базу и сразу закройте её паролем: ```shell tuna 1c --basic-auth="login:password" ``` В шапке [интерфейса в терминале](https://tuna.am/docs/tunnels/tui.md) будут: | Строка | Что в ней | | ------------ | ---------------------------------------------------------------------------- | | `Forwarding` | Публичный адрес туннеля | | `Local` | Локальный адрес публикации, по нему базу можно открыть с этого же компьютера | | `1C client` | Готовый параметр `/WS"…"` для запуска тонкого клиента | | `Platform` | Каталог и разрядность используемой платформы 1С | | `Warning` | Предупреждения: база открыта без защиты, используется учебная версия | Откройте адрес из строки `Forwarding` в браузере или [подключите тонкий клиент](#thin-client). Если мастер не нашёл 1С или базу, загляните в раздел [Диагностика](#diagnostics). #### Примеры примечание Все актуальные флаги, подсказки и примеры можно посмотреть вызвав справку: ```shell tuna 1c --help ``` Почти для всех флагов есть аналогичные [переменные окружения](https://tuna.am/docs/guides/environment-variables.md). ##### Какую базу публиковать Базу можно указать тремя способами: ```shell tuna 1c "Моя база" tuna 1c "C:\Bases\MyBase" tuna 1c "Srvr=localhost;Ref=MyBase" ``` 1. Имя базы из списка стартера 1С — того же, что вы видите в окне запуска 1С. 2. Каталог файловой базы. 3. Строка подключения к серверной базе. Без аргумента tuna берёт базу из [сохранённых настроек](#setup). Если их нет и в списке стартера одна база — публикует её, если несколько — предложит выбрать. предупреждение Публикация серверных баз (`Srvr=…;Ref=…`) поддерживается, но на рабочем кластере 1С мы её пока не проверяли. Если столкнётесь с проблемой, [напишите нам](https://t.me/tuna_support). ##### Сохранённые настройки `tuna 1c setup` записывает выбор в секцию `1c` [конфигурационного файла](https://tuna.am/docs/guides/config-file.md) — общего `tuna.yml` или `.tuna.yml` в текущем каталоге: ```yaml 1c: home: 'C:\Program Files (x86)\1cv8' platform: 'x86' name: 'Моя база' infobase: 'File="C:\Bases\MyBase";' port: 8314 ``` Аргумент и флаги командной строки важнее настроек из файла, а `.tuna.yml` в текущем каталоге перекрывает общий `tuna.yml`. Чтобы изменить настройки, запустите мастер ещё раз или поправьте файл вручную. ##### Установка 1С в нестандартном каталоге tuna ищет платформу в `C:\Program Files\1cv8` и `C:\Program Files (x86)\1cv8`. Если 1С установлена в другое место или нужно выбрать одну из нескольких установок, укажите каталог и разрядность: ```shell tuna 1c "C:\Bases\MyBase" --1c-home="D:\1cv8" --1c-platform=x86 ``` ##### Локальный порт По умолчанию веб-сервер занимает случайный свободный порт на `127.0.0.1`. Зафиксировать порт: ```shell tuna 1c "C:\Bases\MyBase" --1c-port=8314 ``` ##### Постоянный адрес Адрес туннеля задаётся так же, как у [HTTP-туннеля](https://tuna.am/docs/tunnels/http.md#address): поддоменом или своим доменом. С постоянным адресом пользователям не придётся менять ссылку и параметр `/WS` после перезапуска. ```shell tuna 1c "Моя база" --subdomain=my-1c tuna 1c "Моя база" --domain=1c.example.com ``` ##### С указанием токена Можно указать специфичный токен через флаг `--token` или переменную окружения `TUNA_TOKEN`. Переопределение происходит в соответствии с политикой [очерёдности конфигурации](https://tuna.am/docs/guides/config-ordering.md). ```shell tuna 1c "Моя база" --token=tt_*** ``` ##### С указанием региона для подключения Можно указать специфичный [регион](https://tuna.am/docs/tunnels/guides/locations.md) через флаг `--location`/`-l` или переменную окружения `TUNA_LOCATION`. Переопределение происходит в соответствии с политикой [очерёдности конфигурации](https://tuna.am/docs/guides/config-ordering.md). ```shell tuna 1c "Моя база" --location=ru ``` #### Подключение клиентов ##### Веб-клиент Откройте адрес туннеля в браузере, tuna перенаправит на `/1c/`: ```text https://<адрес туннеля>/1c/ ``` ![Веб-клиент 1С, открытый по адресу туннеля](/docs/img/tuna_1c_web_client.png) ##### Тонкий клиент Скопируйте параметр из строки `1C client` в шапке и запустите тонкий клиент: ```shell 1cv8c.exe ENTERPRISE /WS"https://<адрес туннеля>/1c" ``` Тот же адрес можно добавить в список баз стартера: «Добавить» → «Добавление в список существующей информационной базы» → «На веб-сервере». #### Безопасность осторожно `tuna 1c` открывает базу всему интернету: адрес туннеля может подобрать или найти кто угодно. Между посторонним и вашими данными остаётся только окно входа 1С. Если запустить команду без `--basic-auth` и `--key-auth`, tuna покажет предупреждение. Что стоит сделать: * **Закрыть публикацию паролем** — tuna спросит его раньше, чем запрос дойдёт до 1С: ```shell tuna 1c "Моя база" --basic-auth="login:password" ``` * **Задать надёжные пароли всем пользователям базы.** Пользователь без пароля или с простым паролем — это открытая дверь в базу. Особенно проверьте учётные записи с правами администратора. * **Ограничить доступ по IP**, если адреса пользователей известны: ```shell tuna 1c "Моя база" --cidr-allow="203.0.113.0/24" ``` Работают и остальные способы [защиты доступа](https://tuna.am/docs/tunnels/http.md#access) HTTP-туннеля: `--key-auth`, `--cidr-deny`, `--rate-limit`. Запросы к базе видны в [инспекторе](https://tuna.am/docs/tunnels/http/inspect.md), отключить его можно флагом `--inspect=false`. #### Лицензии 1С tuna публикует базу, но не меняет правила лицензирования 1С: сколько пользователей могут работать через веб-сервер одновременно, определяет ваша лицензия. ##### Учебная версия не подходит Учебная версия платформы (каталог `1cv8t`) допускает одно подключение к базе, и его занимает сама публикация. Войти в базу не получится ни веб-клиентом, ни тонким. tuna предупредит об этом в шапке и в выводе `tuna 1c discover`. ##### Лицензия для разработчиков Для пробы не обязательно покупать лицензию 1С: подойдёт бесплатная лицензия для разработчиков, её выдаёт [developer.1c.ru](https://developer.1c.ru/). С ней мы и проверяли команду. Это лицензия 1С, она не заменяет [подписку](https://tuna.am/#pricing) tuna. Условия и ограничения лицензии смотрите на сайте 1С. В нашей проверке одновременно работал один веб-клиент: пока вкладка с базой не закрыта или сеанс не завершился по тайм-ауту, войти из другого браузера не получится. #### Файлы публикации Для каждой базы tuna создаёт каталог публикации в `%LocalAppData%\tuna\1c\`. В нём лежат: | Файл | Назначение | | ------------------------- | -------------------------------------------------------- | | `default.vrd` | Описание публикации 1С | | `httpd.conf` | Конфигурация Apache, создаётся заново при каждом запуске | | `access.log`, `error.log` | Журналы веб-сервера | Существующий `default.vrd` tuna не перезаписывает, поэтому его можно править вручную — например, включить OData или HTTP-сервисы. Вернуть исходный файл: ```shell tuna 1c "Моя база" --reset-vrd ``` Свой каталог публикации задаётся флагом `--1c-publish-dir`: ```shell tuna 1c "Моя база" --1c-publish-dir="C:\tuna-1c\my-base" ``` #### Диагностика Команда `tuna 1c discover` показывает, что tuna нашла на компьютере: установки 1С, путь к модулю расширения веб-сервера в каждой из них и базы из списка стартера. ```shell tuna 1c discover ``` | Что в выводе | Что делать | | ------------------------------------------------------------------- | --------------------------------------------------------------------- | | У установки написано `web server extension module is not installed` | [Установите компонент](#web-module) | | У модуля пометка `training edition, single connection` | Это [учебная версия](#training), войти в базу через неё не получится | | Установок нет | Укажите каталог флагом [`--1c-home`](#home) | | Баз нет | Передайте [каталог базы или строку подключения](#infobase) аргументом | Если база опубликовалась, но не открывается, посмотрите `error.log` в [каталоге публикации](#publish-dir). #### Справочник флагов | Флаг | Переменная окружения | Описание | | ----------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------ | | `--1c-home` | `TUNA_1C_HOME` | Каталог установки 1С:Предприятие | | `--1c-platform` | `TUNA_1C_PLATFORM` | Разрядность платформы: `x64` или `x86` | | `--1c-port` | `TUNA_1C_PORT` | Локальный порт веб-сервера, по умолчанию случайный свободный | | `--1c-publish-dir` | `TUNA_1C_PUBLISH_DIR` | Каталог с файлами публикации | | `--reset-vrd` | | Создать `default.vrd` заново, даже если он есть | | `--basic-auth` | `TUNA_BASIC_AUTH` | [Логин и пароль](https://tuna.am/docs/tunnels/http.md#basic-auth) для доступа к публикации | | `--key-auth` | `TUNA_KEY_AUTH` | [Ключ](https://tuna.am/docs/tunnels/http.md#key-auth) в заголовке `X-Token` | | `--cidr-allow`, `--cidr-deny` | `TUNA_CIDR_ALLOW`, `TUNA_CIDR_DENY` | [Доступ по подсетям IP](https://tuna.am/docs/tunnels/http.md#cidr) | | `--rate-limit` | `TUNA_RATE_LIMIT` | [Ограничение частоты запросов](https://tuna.am/docs/tunnels/http.md#rate-limit) | | `--subdomain`, `-s` | `TUNA_SUBDOMAIN` | [Поддомен](https://tuna.am/docs/tunnels/http.md#address) | | `--domain`, `-d` | `TUNA_DOMAIN` | [Собственный домен](https://tuna.am/docs/tunnels/http.md#custom-domain) | | `--location`, `-l` | `TUNA_LOCATION` | [Регион](https://tuna.am/docs/tunnels/guides/locations.md) подключения | | `--inspect` | `TUNA_INSPECT` | Включить или отключить [инспектор запросов](https://tuna.am/docs/tunnels/http/inspect.md) | | `--qr` | `TUNA_QR_CODE` | Показать [QR-код](https://tuna.am/docs/tunnels/http.md#qr) с адресом | | `--token` | `TUNA_TOKEN` | Токен | #### Ограничения Команда новая. Мы проверяли её на Windows 11 с 32-битной платформой 1С 8.3.27 и файловой базой: вход веб-клиентом и тонким клиентом по публичному адресу, запуск по имени базы и без аргументов после `tuna 1c setup`, `--1c-port`, `--basic-auth` в браузере. Пока не проверены: * тонкий клиент вместе с `--basic-auth`; * 64-битная платформа 1С и 1С 8.5; * серверные базы на рабочем кластере 1С; * каталоги баз с кириллицей и пробелами в пути; * отчёты и печатные формы в веб-клиенте; * запуск [сервисом](https://tuna.am/docs/tunnels/guides/service.md). Если что-то из этого не работает у вас, [напишите нам](https://t.me/tuna_support) — поможем разобраться. --- ### Примеры Примеры и пошаговые инструкции по настройке туннелей для различных устройств и сценариев. #### [📄️AFFiNE](https://tuna.am/docs/tunnels/examples/affine.md) [Использование AFFiNE вместе с tuna](https://tuna.am/docs/tunnels/examples/affine.md) #### [📄️Airflow](https://tuna.am/docs/tunnels/examples/airflow.md) [Использование Airflow вместе с tuna](https://tuna.am/docs/tunnels/examples/airflow.md) #### [📄️amoCRM](https://tuna.am/docs/tunnels/examples/amocrm.md) [Разработка amoCRM Webhook вместе с tuna](https://tuna.am/docs/tunnels/examples/amocrm.md) #### [📄️Apache](https://tuna.am/docs/tunnels/examples/apache.md) [Использование Apache httpd вместе с tuna](https://tuna.am/docs/tunnels/examples/apache.md) #### [📄️Black Candy](https://tuna.am/docs/tunnels/examples/black-candy.md) [Использование Black Candy вместе с tuna](https://tuna.am/docs/tunnels/examples/black-candy.md) #### [📄️Cassandra](https://tuna.am/docs/tunnels/examples/cassandra.md) [Использование Cassandra вместе с tuna](https://tuna.am/docs/tunnels/examples/cassandra.md) #### [📄️ClickHouse](https://tuna.am/docs/tunnels/examples/clickhouse.md) [Использование ClickHouse вместе с tuna](https://tuna.am/docs/tunnels/examples/clickhouse.md) #### [📄️CloudPayments](https://tuna.am/docs/tunnels/examples/cloudpayments.md) [Обработка событий CloudPayments вместе с tuna](https://tuna.am/docs/tunnels/examples/cloudpayments.md) #### [📄️CockroachDB](https://tuna.am/docs/tunnels/examples/cockroachdb.md) [Использование CockroachDB вместе с tuna](https://tuna.am/docs/tunnels/examples/cockroachdb.md) #### [📄️Docker](https://tuna.am/docs/tunnels/examples/docker.md) [Использование tuna вместе с Docker](https://tuna.am/docs/tunnels/examples/docker.md) #### [📄️Docusaurus](https://tuna.am/docs/tunnels/examples/docusaurus.md) [Написание документации вместе с tuna](https://tuna.am/docs/tunnels/examples/docusaurus.md) #### [📄️Elasticsearch](https://tuna.am/docs/tunnels/examples/elasticsearch.md) [Использование Elasticsearch вместе с tuna](https://tuna.am/docs/tunnels/examples/elasticsearch.md) #### [📄️Emby Server](https://tuna.am/docs/tunnels/examples/emby-server.md) [Написание документации вместе с tuna](https://tuna.am/docs/tunnels/examples/emby-server.md) #### [📄️Flask](https://tuna.am/docs/tunnels/examples/flask.md) [Разработка на Flask вместе с tuna](https://tuna.am/docs/tunnels/examples/flask.md) #### [📄️FTP](https://tuna.am/docs/tunnels/examples/ftp.md) [Использование FTP вместе с tuna](https://tuna.am/docs/tunnels/examples/ftp.md) #### [📄️Ghost](https://tuna.am/docs/tunnels/examples/ghost.md) [Использование Ghost вместе с tuna](https://tuna.am/docs/tunnels/examples/ghost.md) #### [📄️Gitea](https://tuna.am/docs/tunnels/examples/gitea.md) [Использование Gitea вместе с tuna](https://tuna.am/docs/tunnels/examples/gitea.md) #### [📄️GitLab](https://tuna.am/docs/tunnels/examples/gitlab.md) [Разработка GitLab Webhook вместе с tuna](https://tuna.am/docs/tunnels/examples/gitlab.md) #### [📄️GitVerse](https://tuna.am/docs/tunnels/examples/gitverse.md) [Использование GitVerse вместе с tuna](https://tuna.am/docs/tunnels/examples/gitverse.md) #### [📄️Gogs](https://tuna.am/docs/tunnels/examples/gogs.md) [Использование Gogs вместе с tuna](https://tuna.am/docs/tunnels/examples/gogs.md) #### [📄️Grafana](https://tuna.am/docs/tunnels/examples/grafana.md) [Использование Grafana вместе с tuna](https://tuna.am/docs/tunnels/examples/grafana.md) #### [📄️GraphQL](https://tuna.am/docs/tunnels/examples/graphql.md) [Использование GraphQL вместе с tuna](https://tuna.am/docs/tunnels/examples/graphql.md) #### [📄️gRPC](https://tuna.am/docs/tunnels/examples/grpc.md) [Использование gRPC вместе с tuna](https://tuna.am/docs/tunnels/examples/grpc.md) #### [📄️Herd](https://tuna.am/docs/tunnels/examples/herd.md) [Использование Herd вместе с tuna](https://tuna.am/docs/tunnels/examples/herd.md) #### [📄️Immich](https://tuna.am/docs/tunnels/examples/immich.md) [Использование Immich вместе с tuna](https://tuna.am/docs/tunnels/examples/immich.md) #### [📄️InfluxDB](https://tuna.am/docs/tunnels/examples/influxdb.md) [Использование InfluxDB вместе с tuna](https://tuna.am/docs/tunnels/examples/influxdb.md) #### [📄️JetKVM](https://tuna.am/docs/tunnels/examples/jetkvm.md) [Удалённый доступ к JetKVM через интернет с помощью Tuna](https://tuna.am/docs/tunnels/examples/jetkvm.md) #### [📄️Kiwi TCMS](https://tuna.am/docs/tunnels/examples/kiwi-tcms.md) [Использование Kiwi TCMS вместе с tuna](https://tuna.am/docs/tunnels/examples/kiwi-tcms.md) #### [📄️Kubernetes](https://tuna.am/docs/tunnels/examples/kubernetes.md) [Использование tuna вместе с Kubernetes](https://tuna.am/docs/tunnels/examples/kubernetes.md) #### [📄️MAMP](https://tuna.am/docs/tunnels/examples/mamp.md) [Использование MAMP вместе с tuna](https://tuna.am/docs/tunnels/examples/mamp.md) #### [📄️MariaDB](https://tuna.am/docs/tunnels/examples/mariadb.md) [Использование MariaDB вместе с tuna](https://tuna.am/docs/tunnels/examples/mariadb.md) #### [📄️Mattermost](https://tuna.am/docs/tunnels/examples/mattermost.md) [Разработка Mattermost Webhook вместе с tuna](https://tuna.am/docs/tunnels/examples/mattermost.md) #### [📄️Minecraft](https://tuna.am/docs/tunnels/examples/minecraft.md) [Использование Minecraft вместе с tuna](https://tuna.am/docs/tunnels/examples/minecraft.md) #### [📄️Minio](https://tuna.am/docs/tunnels/examples/minio.md) [Использование Minio вместе с tuna](https://tuna.am/docs/tunnels/examples/minio.md) #### [📄️MongoDB](https://tuna.am/docs/tunnels/examples/mongodb.md) [Использование MongoDB вместе с tuna](https://tuna.am/docs/tunnels/examples/mongodb.md) #### [📄️MsSQL](https://tuna.am/docs/tunnels/examples/mssql.md) [Использование MsSQL вместе с tuna](https://tuna.am/docs/tunnels/examples/mssql.md) #### [📄️MySQL](https://tuna.am/docs/tunnels/examples/mysql.md) [Использование MySQL вместе с tuna](https://tuna.am/docs/tunnels/examples/mysql.md) #### [📄️NanoKVM (Sipeed)](https://tuna.am/docs/tunnels/examples/nanokvm.md) [Удалённый доступ к NanoKVM через интернет с помощью Tuna](https://tuna.am/docs/tunnels/examples/nanokvm.md) #### [📄️Netdata](https://tuna.am/docs/tunnels/examples/netdata.md) [Использование Netdata вместе с tuna](https://tuna.am/docs/tunnels/examples/netdata.md) #### [📄️NGINX](https://tuna.am/docs/tunnels/examples/nginx.md) [Использование NGINX вместе с tuna](https://tuna.am/docs/tunnels/examples/nginx.md) #### [📄️Ollama](https://tuna.am/docs/tunnels/examples/ollama.md) [Использование Ollama вместе с tuna](https://tuna.am/docs/tunnels/examples/ollama.md) #### [📄️OSPanel](https://tuna.am/docs/tunnels/examples/ospanel.md) [Использование OSPanel вместе с tuna](https://tuna.am/docs/tunnels/examples/ospanel.md) #### [📄️Paddle](https://tuna.am/docs/tunnels/examples/paddle.md) [Обработка событий Paddle вместе с tuna](https://tuna.am/docs/tunnels/examples/paddle.md) #### [📄️phpMyAdmin](https://tuna.am/docs/tunnels/examples/phpmyadmin.md) [Использование phpMyAdmin вместе с tuna](https://tuna.am/docs/tunnels/examples/phpmyadmin.md) #### [📄️PocketBase](https://tuna.am/docs/tunnels/examples/pocketbase.md) [Использование PocketBase вместе с tuna](https://tuna.am/docs/tunnels/examples/pocketbase.md) #### [📄️PostgreSQL](https://tuna.am/docs/tunnels/examples/postgresql.md) [Использование PostgreSQL вместе с tuna](https://tuna.am/docs/tunnels/examples/postgresql.md) #### [📄️Qdrant](https://tuna.am/docs/tunnels/examples/qdrant.md) [Использование Qdrant вместе с tuna](https://tuna.am/docs/tunnels/examples/qdrant.md) #### [📄️RabbitMQ](https://tuna.am/docs/tunnels/examples/rabbitmq.md) [Использование RabbitMQ вместе с tuna](https://tuna.am/docs/tunnels/examples/rabbitmq.md) #### [📄️Raspberry Pi](https://tuna.am/docs/tunnels/examples/raspberry-pi.md) [Удаленный доступ к Raspberry Pi](https://tuna.am/docs/tunnels/examples/raspberry-pi.md) #### [📄️RDP](https://tuna.am/docs/tunnels/examples/rdp.md) [Использование RDP вместе с tuna](https://tuna.am/docs/tunnels/examples/rdp.md) #### [📄️Redis](https://tuna.am/docs/tunnels/examples/redis.md) [Использование Redis вместе с tuna](https://tuna.am/docs/tunnels/examples/redis.md) #### [📄️Robokassa](https://tuna.am/docs/tunnels/examples/robokassa.md) [Обработка событий Robokassa вместе с tuna](https://tuna.am/docs/tunnels/examples/robokassa.md) #### [📄️ScyllaDB](https://tuna.am/docs/tunnels/examples/scylladb.md) [Использование ScyllaDB вместе с tuna](https://tuna.am/docs/tunnels/examples/scylladb.md) #### [📄️SMTP](https://tuna.am/docs/tunnels/examples/smtp.md) [Использование SMTP вместе с tuna](https://tuna.am/docs/tunnels/examples/smtp.md) #### [📄️SSH](https://tuna.am/docs/tunnels/examples/ssh.md) [Использование SSH вместе с tuna](https://tuna.am/docs/tunnels/examples/ssh.md) #### [📄️Superset](https://tuna.am/docs/tunnels/examples/superset.md) [Использование Superset вместе с tuna](https://tuna.am/docs/tunnels/examples/superset.md) #### [📄️Temporal](https://tuna.am/docs/tunnels/examples/temporal.md) [Использование Temporal вместе с tuna](https://tuna.am/docs/tunnels/examples/temporal.md) #### [📄️TimescaleDB](https://tuna.am/docs/tunnels/examples/timescaledb.md) [Использование TimescaleDB вместе с tuna](https://tuna.am/docs/tunnels/examples/timescaledb.md) #### [📄️Transmission](https://tuna.am/docs/tunnels/examples/transmission.md) [Использование transmission-daemon вместе с tuna](https://tuna.am/docs/tunnels/examples/transmission.md) #### [📄️Vite](https://tuna.am/docs/tunnels/examples/vite.md) [Использование Vite вместе с tuna](https://tuna.am/docs/tunnels/examples/vite.md) #### [📄️WampServer](https://tuna.am/docs/tunnels/examples/wampserver.md) [Использование WampServer вместе с tuna](https://tuna.am/docs/tunnels/examples/wampserver.md) #### [📄️WebAsk](https://tuna.am/docs/tunnels/examples/webask.md) [Разработка WebAsk Webhook вместе с tuna](https://tuna.am/docs/tunnels/examples/webask.md) #### [📄️ЮKassa](https://tuna.am/docs/tunnels/examples/yookassa.md) [Обработка событий ЮKassa вместе с tuna](https://tuna.am/docs/tunnels/examples/yookassa.md) #### [📄️Yucca](https://tuna.am/docs/tunnels/examples/yucca.md) [Доступ к камерам вместе с tuna](https://tuna.am/docs/tunnels/examples/yucca.md) --- ### tuna и AFFiNE #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите AFFiNE сервер Инструкцию по установке можно найти в [официальной документации](https://docs.affine.pro/docs/self-host-affine). #### Шаг 3. Запустите tuna AFFiNE использует порт `3010` по умолчанию: ```bash tuna http localhost:3010 ``` --- ### tuna и Airflow #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите Airflow сервер Инструкцию по установке можно найти в [официальной документации](https://airflow.apache.org/docs/apache-airflow/stable/installation/index.html). #### Шаг 3. Запустите tuna Airflow использует порт `8080` по умолчанию: ```bash tuna http 8080 ``` --- ### tuna и amoCRM #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите сервер для обработки событий от amoCRM Информацию о структуре входящий запросов можно узнать в [официальной документации](https://www.amocrm.ru/developers/content/crm_platform/webhooks-format). #### Шаг 3. Запустите tuna В аргументах запуска укажите порт вашего сервера: ```bash tuna http 8080 ``` Или с указанием статичного адреса: ```bash tuna http 8080 --subdomain=amocrm-webhook ``` #### Шаг 4. Создайте новый Webhook Изучите [инструкцию по добавлению Вебхука](https://www.amocrm.ru/developers/content/crm_platform/webhooks-format), в качестве значения "URL сайта" укажите адрес полученный от tuna (например, `https://amocrm-webhook.ru.tuna.am`) и путь к методу вашего сервера для обработки событий (например, `/event`). --- ### tuna и Apache #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите Apache #### Шаг 3. Запустите tuna Специальные настройки не требуются, но для корректного роутинга запросов может потребоваться передача заголовка `Host`, например: ```shell tuna http --request-header="host:tuna.am" 80 ``` --- ### tuna и Black Candy #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите Black Candy сервер Инструкцию по установке можно найти в [официальной документации](https://github.com/blackcandy-org/blackcandy/blob/master/README.md#installation). #### Шаг 3. Запустите tuna Black Candy использует порт `3000` по умолчанию: ```bash tuna http 3000 ``` --- ### tuna и Cassandra #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите Cassandra сервер Инструкцию по установке можно найти в [официальной документации](https://cassandra.apache.org/doc/latest/cassandra/getting-started/cassandra-quickstart.html). #### Шаг 3. Запустите tuna Cassandra использует порт `9042` по умолчанию: ```bash tuna tcp 9042 ``` --- ### tuna и ClickHouse #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите ClickHouse сервер Инструкцию по установке можно найти в [официальной документации](https://clickhouse.com/docs/en/getting-started/quick-start). #### Шаг 3. Запустите tuna ClickHouse использует множество портов, описание которых можно найти в [официальной документации](https://clickhouse.com/docs/en/guides/sre/network-ports), для предоставления доступа к HTTP API можно воспользоваться командой: ```shell tuna http 8123 ``` Для доступа по нативному протоколу: ```shell tuna tcp 9000 ``` --- ### tuna и CloudPayments #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите сервер для обработки HTTP-уведомлений Информацию о входящих уведомлениях CloudPayments можно найти в [официальной документации](https://developers.cloudpayments.ru/#uvedomleniya). #### Шаг 3. Запустите tuna В аргументах запуска укажите порт вашего сервера: ```bash tuna http 8080 ``` Или с указанием статичного адреса: ```bash tuna http 8080 --subdomain=billing ``` #### Шаг 4. Укажите адрес для входящих уведомлений Из раздела [сайты](https://merchant.cloudpayments.ru/next/sites) перейдите в нужный вам сайт, далее, в разделе Уведомления, нужно задать адреса для получения уведомлений: ![cloudpayments](/assets/images/cloudpayments1-582a3da86daff4c1122f63df3017faf5.png) Каждый URL состоит из адреса полученного от tuna (например, `https://billing.ru.tuna.am`) и пути к методу вашего сервера для обработки событий (например, `/payments/pay`). После всех настроек вы можете воспользоваться [тестовыми платежными средствами](https://developers.cloudpayments.ru/#testirovanie) для отладки взаимодействия. --- ### tuna и CockroachDB #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите CockroachDB сервер Инструкцию по установке можно найти в [официальной документации](https://www.cockroachlabs.com/docs/v24.3/install-cockroachdb-linux). #### Шаг 3. Запустите tuna CockroachDB использует порт `26257` по умолчанию: ```bash tuna tcp 26257 ``` --- ### tuna и Docker Пример запуска tuna для предоставления доступа к серверу, запущенному с помощью Docker и Docker Compose. #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Склонируйте репозиторий с примерами ```shell git clone https://gitlab.com/yuccastream/tuna-examples.git cd tuna-examples/docker-compose ``` к сведению Если вы хотите, чтобы клиент tuna тоже запускался с помощью docker-compose, то изучите пример из каталога `tuna-examples/docker-compose-v2`. #### Шаг 3. Запустите сервер ```shell docker compose up -d ``` Убедитесь, что контейнер запущен: ```shell docker compose ps NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS docker-compose-web-1 docker-compose-web "python3 app.py" web 9 minutes ago Up 2 seconds 0.0.0.0:8000->8000/tcp ``` #### Шаг 4. Запустите tuna В аргументах запуска укажите порт вашего сервера: ```bash tuna http 8000 ``` Для остановки и удаления всех запущенных контейнеров воспользуйтесь командой `docker compose rm -sf`. --- ### tuna и Docusaurus #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите Docusaurus сервер В [официальной документации](https://docusaurus.io/docs/installation) можно найти инструкцию по созданию нового проекта, далее запускаем сервер разработки: ```shell yarn start ``` Во время запуска будет написан адрес размещения: ```shell [INFO] Starting the development server... [SUCCESS] Docusaurus website is running at: http://localhost:3000/ ``` #### Шаг 3. Запустите tuna ```bash tuna http localhost:3000 ``` --- ### tuna и Elasticsearch #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите Elasticsearch сервер Инструкцию по установке можно найти в [официальной документации](https://www.elastic.co/guide/en/elasticsearch/reference/current/getting-started.html#getting-started). #### Шаг 3. Запустите tuna Elasticsearch использует порт `9200` по умолчанию: ```bash tuna http 9200 ``` --- ### tuna и Emby Server #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите Emby Server Инструкцию по установке можно найти в [официальной документации](https://emby.media/download.html). #### Шаг 3. Запустите tuna Ghost использует порт `8096` по умолчанию: ```bash tuna http 8096 ``` --- ### tuna и Flask #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите сервер на фреймворке Flask Пример кода сервера (пояснения можно найти в [официальной документации](https://flask.palletsprojects.com/en/3.0.x/quickstart/)): ```python from flask import Flask app = Flask(__name__) @app.route("/") def hello_world(): return "

Hello, World!

" ``` #### Шаг 3. Запустите tuna Flask использует порт 5000 по умолчанию: ```bash tuna http 5000 ``` --- ### tuna и FTP, SFTP FTP требует нескольких портов для работы, поэтому tuna для этой задачи не подойдет, но данные можно передавать через SFTP – расширение для SSH. #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите SSH сервер #### Шаг 3. Запустите tuna SSH сервер использует порт `22` по умолчанию: ```bash tuna tcp 22 ``` #### Альтернативы 1. У tuna есть встроенный файловый сервер, который предоставляет легкий способ для передачи файлов: ```bash tuna http --file-server ./ ``` 2. Так же есть встроенный [SSH сервер](https://tuna.am/docs/tunnels/ssh.md), который так же подойдет для этих целей --- ### tuna и Ghost #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите Ghost сервер Инструкцию по установке можно найти в [официальной документации](https://ghost.org/docs/install/). #### Шаг 3. Запустите tuna Ghost использует порт `2368` по умолчанию: ```bash tuna http 2368 ``` --- ### tuna и Gitea #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите Gitea сервер Инструкцию по установке можно найти в [официальной документации](https://docs.gitea.com/category/installation). #### Шаг 3. Запустите tuna Gitea использует порт `3000` по умолчанию: ```bash tuna http 3000 ``` --- ### tuna и GitLab GitLab позволяет добавлять в группах и проектах Webhook – ссылки на которые будут отправляться сообщения об определенных событиях, например, создании тега, добавлении комментария, редактировании задачи. #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите сервер для обработки событий от GitLab Информацию о структуре входящий запросов можно узнать в [официальной документации](https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html). #### Шаг 3. Запустите tuna В аргументах запуска укажите порт вашего сервера: ```bash tuna http 8080 ``` Или с указанием статичного адреса: ```bash tuna http 8080 --subdomain=gitlab-webhook ``` #### Шаг 4. Создайте новый Webhook Перейдите в раздел Webhooks настроек проекта, укажите адрес входящий сообщений и укажите события, которые хотиле получать: ![gitlab](/assets/images/gitlab1-9f923b11f6e30445c68100087e26f6fe.png) URL состоит из адреса полученного от tuna (например, `https://gitlab-webhook.ru.tuna.am`) и пути к методу вашего сервера для обработки событий (например, `/event`). --- ### tuna и GitVerse GitVerse позволяет добавлять в проектах [Webhook](https://gitverse.ru/docs/developers/webhooks/) – ссылки на которые будут отправляться сообщения об определенных событиях, например, о добавлении комментария. #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите сервер для обработки событий от GitVerse Пример входящего события Заголовки: ```js { "Content-Type": "application/json", "X-GitHub-Delivery": "0218f02f-cfb6-42d5-a08c-3c2709442b0a", "X-GitHub-Event": "push", "X-GitHub-Event-Type": "push", "X-Gitverse-Delivery": "0218f02f-cfb6-42d5-a08c-3c2709442b0a", "X-Gitverse-Event": "push", "X-Gitverse-Event-Type": "push", "X-Gitverse-Signature": "", "X-Gogs-Delivery": "0218f02f-cfb6-42d5-a08c-3c2709442b0a", "X-Gogs-Event": "push", "X-Gogs-Event-Type": "push", "X-Gogs-Signature": "", "X-Hub-Signature": "sha1=", "X-Hub-Signature-256": "sha256=" } ``` Тело запроса: ```js { "ref": "refs/heads/master", "before": "0000000000000000000000000000000000000000", "after": "990564d83c961519f581e8c539f30aa101ffbaa0", "compare_url": "https://gitverse.ru/", "commits": [ { "id": "990564d83c961519f581e8c539f30aa101ffbaa0", "message": "create: new_file\n", "url": "https://gitverse.ru/leoderoko/tuna-webhook-test/commit/990564d83c961519f581e8c539f30aa101ffbaa0", "author": { "name": "leoderoko", "email": "193755leoderoko@users.no-reply.gitverse.ru", "username": "" }, "committer": { "name": "GitVerse", "email": "noreply@gitverse.ru", "username": "" }, "verification": null, "timestamp": "2026-04-28T05:19:19Z", "added": [ "new_file" ], "removed": [], "modified": [] } ], "total_commits": 1, "head_commit": { "id": "990564d83c961519f581e8c539f30aa101ffbaa0", "message": "create: new_file", "url": "https://gitverse.ru/leoderoko/tuna-webhook-test/commit/990564d83c961519f581e8c539f30aa101ffbaa0", "author": { "name": "leoderoko", "email": "193755leoderoko@users.no-reply.gitverse.ru", "username": "" }, "committer": { "name": "GitVerse", "email": "noreply@gitverse.ru", "username": "" }, "verification": null, "timestamp": "2026-04-28T05:19:19Z", "added": [ "new_file" ], "removed": [], "modified": [] }, "repository": { "id": 250007, "owner": { "id": 193755, "login": "leoderoko", "login_name": "", "source_id": 0, "full_name": "", "email": "193755leoderoko@users.no-reply.gitverse.ru", "avatar_url": "https://gitverse.ru/avatars/9fc126f12ab01cadf5a370c07e92c23e", "html_url": "https://gitverse.ru/leoderoko", "language": "", "is_admin": false, "last_login": "0001-01-01T00:00:00Z", "created": "2026-02-07T17:44:11Z", "restricted": false, "active": false, "prohibit_login": false, "location": "", "website": "", "description": "", "visibility": "public", "followers_count": 0, "following_count": 0, "starred_repos_count": 0, "username": "leoderoko" }, "name": "tuna-webhook-test", "full_name": "leoderoko/tuna-webhook-test", "description": "", "empty": false, "private": true, "fork": false, "template": false, "parent": null, "mirror": false, "size": 22, "language": "", "languages_url": "http://gitverse-backend-http:3000/api/v1/repos/leoderoko/tuna-webhook-test/languages", "html_url": "http://gitverse-backend-http:3000/leoderoko/tuna-webhook-test", "url": "http://gitverse-backend-http:3000/api/v1/repos/leoderoko/tuna-webhook-test", "link": "", "ssh_url": "git@gitverse.ru:leoderoko/tuna-webhook-test.git", "clone_url": "https://gitverse.ru/leoderoko/tuna-webhook-test.git", "original_url": "", "website": "", "stars_count": 0, "forks_count": 0, "watchers_count": 0, "open_issues_count": 0, "open_pr_counter": 0, "release_counter": 0, "default_branch": "master", "archived": false, "created_at": "2026-04-28T05:09:11Z", "updated_at": "2026-04-28T05:19:21Z", "archived_at": "1970-01-01T00:00:00Z", "permissions": { "admin": true, "push": true, "pull": true }, "has_issues": false, "has_wiki": false, "has_pull_requests": true, "has_projects": false, "projects_mode": "all", "has_releases": true, "has_packages": false, "has_actions": true, "ignore_whitespace_conflicts": false, "allow_merge_commits": true, "allow_rebase": true, "allow_rebase_explicit": true, "allow_squash_merge": true, "allow_fast_forward_only_merge": true, "allow_rebase_update": true, "default_delete_branch_after_merge": false, "default_merge_style": "merge", "default_allow_maintainer_edit": false, "avatar_url": "", "internal": false, "mirror_interval": "", "object_format_name": "sha1", "mirror_updated": "0001-01-01T00:00:00Z", "repo_transfer": null, "topics": [], "licenses": null }, "pusher": { "id": 193755, "login": "leoderoko", "login_name": "", "source_id": 0, "full_name": "", "email": "193755leoderoko@users.no-reply.gitverse.ru", "avatar_url": "https://gitverse.ru/avatars/9fc126f12ab01cadf5a370c07e92c23e", "html_url": "https://gitverse.ru/leoderoko", "language": "", "is_admin": false, "last_login": "0001-01-01T00:00:00Z", "created": "2026-02-07T17:44:11Z", "restricted": false, "active": false, "prohibit_login": false, "location": "", "website": "", "description": "", "visibility": "public", "followers_count": 0, "following_count": 0, "starred_repos_count": 0, "username": "leoderoko" }, "sender": { "id": 193755, "login": "leoderoko", "login_name": "", "source_id": 0, "full_name": "", "email": "193755leoderoko@users.no-reply.gitverse.ru", "avatar_url": "https://gitverse.ru/avatars/9fc126f12ab01cadf5a370c07e92c23e", "html_url": "https://gitverse.ru/leoderoko", "language": "", "is_admin": false, "last_login": "0001-01-01T00:00:00Z", "created": "2026-02-07T17:44:11Z", "restricted": false, "active": false, "prohibit_login": false, "location": "", "website": "", "description": "", "visibility": "public", "followers_count": 0, "following_count": 0, "starred_repos_count": 0, "username": "leoderoko" } } ``` #### Шаг 3. Запустите tuna В аргументах запуска укажите порт вашего сервера: ```bash tuna http 8080 ``` Или с указанием статичного адреса: ```bash tuna http 8080 --subdomain=gitverse-webhook ``` #### Шаг 4. Создайте новый Webhook Перейдите в раздел Вебхуки настроек проекта, укажите адрес входящий сообщений и укажите события, которые хотиле получать: ![gitverse](/assets/images/gitverse1-bd5131d750b8a4e9b8072866fad04da3.png) URL состоит из адреса полученного от tuna (например, `https://gitverse-webhook.ru.tuna.am`) и пути к методу вашего сервера для обработки событий (например, `/event`). --- ### tuna и Gogs #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите Gogs сервер Инструкцию по установке можно найти в [официальной документации](https://gogs.io/docs/installation), для запуска с помощью Docker обратитесь к документации в [репозитории проекта](https://github.com/gogs/gogs/tree/main/docker). #### Шаг 3. Запустите tuna Gogs использует порт `3000` по умолчанию: ```bash tuna http 3000 ``` --- ### tuna и Grafana #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите Grafana сервер Инструкцию по установке можно найти в [официальной документации](https://grafana.com/docs/grafana/latest/#installing-grafana). #### Шаг 3. Запустите tuna Grafana использует порт `3000` по умолчанию: ```bash tuna http 3000 ``` --- ### tuna и GraphQL #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите GraphQL сервер #### Шаг 3. Запустите tuna В аргументах запуска укажите порт вашего сервера, например: ```bash tuna http 4000 ``` --- ### tuna и gRPC #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите gRPC сервер #### Шаг 3. Запустите tuna Для работы с gRPC нужно использовать TCP туннель, например: ```bash tuna tcp 8080 ``` --- ### tuna и Laravel Herd #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите Herd сервер Инструкцию по установке можно найти в [официальной документации](https://herd.laravel.com/docs/1/getting-started/installation). #### Шаг 3. Запустите tuna Herd использует порт `80` по умолчанию для доступа к вашему веб-проекту: ```bash tuna http 80 ``` Для корректного роутинга запросов может потребоваться передача заголовка Host, например: ```bash tuna http --request-header="host:tuna.am" 80 ``` --- ### tuna ❤️ Immich [Immich](https://immich.app/?utm_source=tuna.am) - сервис для самостоятельного хранения фотографий, аналог [Google Photos](https://www.google.com/photos/about/?utm_source=tuna.am). Tuna поможет открыть доступ к вашему серверу с Immich в локальной сети. Мы писали [статью](https://vc.ru/dev/1107380-kak-hranit-fotoarhiv-u-sebya-a-ne-v-google-ili-yandekse) об использовании Immich на Raspberry PI 4. ![immich-login](/docs/img/examples/immich.png) #### Шаг 1. Установите Immich Инструкцию по установке можно найти в [официальной документации](https://immich.app/docs/install/docker-compose). #### Шаг 2. Настройте запуск tuna 1. Добавьте в файл `.env` токен: ```bash TUNA_TOKEN=tt_*** ``` 2. Добавьте в файл `docker-compose.yml` сервис с tuna и отредактируйте аргументы: ```yaml tuna: container_name: immich_tuna image: yuccastream/tuna:latest command: http immich-server:2283 --location=ru --subdomain=<ваш_поддомен> --inspect=false env_file: - .env restart: always depends_on: - immich-server ``` примечание В immich-server версии [v1.118.0](https://github.com/immich-app/immich/releases/tag/v1.118.0), изменился порт подключения по умолчанию. Ранее это был **3001**, начиная с версии v1.118 - **2283**. Если вы используете версию до v1.118.0, то вместо `immich-server:2283`, укажите `immich-server:3001`. #### Шаг 3. Запустите tuna Выполните: ```bash docker compose pull && docker compose up -d ``` Сервис будет доступен в браузере и мобильном приложении по указанному вами поддомену. --- ### tuna и InfluxDB #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите InfluxDB сервер Инструкцию по установке можно найти в [официальной документации](https://docs.influxdata.com/influxdb/v2/install/). #### Шаг 3. Запустите tuna InfluxDB использует порт `8086` по умолчанию: ```bash tuna http 8086 ``` --- ### tuna ❤️ JetKVM [JetKVM](https://jetkvm.com/) — это компактное IP-KVM устройство на базе Rockchip RV1106 (ARM Cortex-A7). Оно позволяет удалённо управлять компьютером: видеть экран, управлять клавиатурой и мышью, монтировать образы дисков — всё через веб-интерфейс в браузере. По умолчанию JetKVM доступен только в локальной сети. С помощью Tuna вы можете открыть доступ к нему через интернет — без «белого» IP, без VPN, без проброса портов на роутере. ![Tuna + JetKVM](/docs/img/tunnels/guides/jetkvm_tuna.png) к сведению Данная инструкция протестирована на JetKVM с системной версией **v0.2.7** и выше. На более ранних версиях `/userdata/init.d/` не поддерживается — обновите JetKVM через веб-интерфейс (Settings → Device → Check for updates). *** #### Подготовка Помимо установки инструкция по настройке разделена на 2 типа, в зависимости от наличия платной подписки Tuna. 1. [На бесплатном тарифе](#%D1%82%D0%B8%D0%BF-1-%D0%B1%D0%B5%D1%81%D0%BF%D0%BB%D0%B0%D1%82%D0%BD%D1%8B%D0%B9-%D1%82%D0%B0%D1%80%D0%B8%D1%84--http-%D1%82%D1%83%D0%BD%D0%BD%D0%B5%D0%BB%D1%8C) 2. [С платной подпиской](#%D1%82%D0%B8%D0%BF-2-%D0%BF%D0%BE%D0%B4%D0%BF%D0%B8%D1%81%D0%BA%D0%B0--ssh-%D0%B8-http-%D1%82%D1%83%D0%BD%D0%BD%D0%B5%D0%BB%D0%B8) ##### Что потребуется * JetKVM с системной версией **v0.2.7 или новее** * **Developer Mode** включен в веб-интерфейсе JetKVM (Settings → Advanced → Developer Mode) * **SSH-ключ** добавлен через веб-интерфейс JetKVM * Аккаунт на [tuna.am](https://my.tuna.am/) (бесплатный или с подпиской) * Токен авторизации со [страницы токена](https://my.tuna.am/token) ##### Особенности системы JetKVM JetKVM работает на кастомной embedded Linux (Buildroot + Rockchip SDK). Важные отличия от обычного Linux: | Особенность | Значение | | ----------------- | ---------------------------------------------- | | Оболочка | `/bin/sh` (BusyBox ash). **bash отсутствует** | | SSH-сервер | Dropbear (нет scp, sftp, rsync) | | Init-система | BusyBox init + скрипты в `/userdata/init.d/` | | Persistent-раздел | `/userdata/` — сохраняется при OTA-обновлениях | Структура хранилища: | Путь | Назначение | Сохраняется при OTA | | ------------ | ----------------------- | ------------------- | | `/` | Корневая ФС | Нет | | `/userdata/` | Пользовательские данные | **Да** | Мы будем хранить tuna в `/userdata/tuna/`, чтобы бинарник и конфигурация сохранялись при обновлениях. ##### Подключение по SSH Включите Developer Mode в веб-интерфейсе JetKVM и добавьте публичный RSA-ключ (Settings → Advanced → Developer Mode). Затем подключитесь: ```bash ssh root@ ``` Или откройте терминал в веб интерфейсе: ![JetKVM terminal](/docs/img/tunnels/guides/jetkvm_terminal.png) подсказка IP-адрес можно найти на встроенном экране JetKVM или в DHCP-таблице роутера. ##### Установка tuna на JetKVM Подключитесь к JetKVM по SSH и установите бинарник: ```bash mkdir -p /userdata/tuna INSECURE=true INSTALL_DIR=/userdata/tuna sh -c "$(wget -qO- http://releases.tuna.am/tuna/get.sh)" ``` Почему `INSECURE=true`? На JetKVM отсутствуют корневые CA-сертификаты, поэтому wget не может проверить SSL-сертификат сервера. Флаг `INSECURE=true` переключает скрипт на загрузку по HTTP. Это безопасно, так как бинарник tuna после загрузки можно проверить по контрольной сумме. подсказка Раздел `/userdata` сохраняется при OTA-обновлениях, поэтому tuna не придётся переустанавливать после обновления прошивки. Сохраните [токен](https://my.tuna.am/token) авторизации: ```bash /userdata/tuna/tuna --config=/userdata/tuna/.tuna.yml config save-token <ВАШ_ТОКЕН> ``` подсказка Рекомендуем создать дополнительный токен для устройства. *** #### Система автозапуска JetKVM В отличие от NanoKVM, где автозапуск настраивается через `/etc/inittab` с директивой `respawn`, на JetKVM используются init-скрипты в директории `/userdata/init.d/`, каталог нужно создать. ```bash mkdir -p /userdata/init.d ``` При загрузке init-система JetKVM выполняет все скрипты из `/userdata/init.d/`, чьи имена соответствуют паттерну `S??*` (например, `S99tuna-http`). Скрипты вызываются с аргументом `start`, при остановке — с аргументом `stop`. Критические правила для init-скриптов Несоблюдение этих правил может привести к тому, что устройство **перестанет загружаться**: 1. **Используйте `#!/bin/sh`** — на JetKVM нет `/bin/bash`. Шебанг `#!/bin/bash` приведёт к ошибке и может заблокировать загрузку. 2. **Не используйте расширение `.sh`** — файлы с расширением `.sh` включаются через `source` (а не вызываются как отдельный процесс). Команда `exit` в таком скрипте завершит весь init-процесс. 3. **Не блокируйте загрузку** — все долгоживущие процессы должны запускаться **в фоне** с `&`. Если скрипт не возвращает управление, загрузка зависнет. 4. **Обрабатывайте аргумент `start`** — init-система вызывает скрипт как `S99tuna-http start`. Без `case "$1"` скрипт может выполниться некорректно. Нет автоматического перезапуска В отличие от NanoKVM (где `inittab respawn` автоматически перезапускает упавший процесс), на JetKVM `/etc/inittab` перезаписывается при OTA-обновлениях. Поэтому мы используем цикл `while true` внутри init-скрипта для автоперезапуска при падении. Тестируйте перед перезагрузкой Всегда запускайте скрипт вручную (`/userdata/init.d/S99tuna-http start`) и убедитесь, что промпт вернулся. Если после запуска консоль «зависла» — скрипт заблокирует загрузку при перезагрузке. *** #### Тип 1. Бесплатный тариф — HTTP-туннель На бесплатном тарифе доступен HTTP-туннель с динамическим адресом. Этого достаточно, чтобы открыть веб-интерфейс JetKVM в интернет и управлять компьютером через браузер. Ограничения бесплатного тарифа * Динамический адрес меняется при каждом переподключении туннеля * Чтобы адрес не менялся, добавьте в команду запуска свой [бесплатный постоянный поддомен](https://tuna.am/docs/tunnels/http.md#free-subdomain): `--subdomain=<ваш-поддомен>` * Текущий адрес всегда можно посмотреть в [личном кабинете](https://my.tuna.am/tunnels) ##### Создание init-скрипта ```bash cat << 'INITEOF' > /userdata/init.d/S99tuna-http #!/bin/sh PIDFILE=/tmp/tuna-http.pid LOGFILE=/tmp/tuna-http.log wait_network() { i=0 while ! ip route | grep -q default; do sleep 1 i=$((i + 1)) if [ "$i" -ge 60 ]; then echo "$(date): network timeout" >> "$LOGFILE" return 1 fi done return 0 } start() { echo "$(date): starting tuna-http" >> "$LOGFILE" ( wait_network || exit 1 while true; do /userdata/tuna/tuna \ --config=/userdata/tuna/.tuna.yml \ --log="$LOGFILE" \ http \ --inspect=false \ --basic-auth=tuna:SecurePasswd \ --https-redirect \ 80 >> "$LOGFILE" 2>&1 echo "$(date): tuna-http exited, restarting in 5s" >> "$LOGFILE" sleep 5 done ) & echo $! > "$PIDFILE" } stop() { if [ -f "$PIDFILE" ]; then kill "$(cat "$PIDFILE")" 2>/dev/null pkill -f "/userdata/tuna/tuna.*http" 2>/dev/null rm -f "$PIDFILE" fi } case "$1" in start) start ;; stop) stop ;; restart) stop; sleep 1; start ;; *) echo "Usage: $0 {start|stop|restart}" ;; esac INITEOF chmod +x /userdata/init.d/S99tuna-http ``` ##### Пояснение init-скрипта | Элемент | Описание | | ---------------------- | ------------------------------------------------------------------------------------------- | | `S99tuna-http` | Имя **без** `.sh` — init вызывает скрипт с аргументом `start`, а не включает через `source` | | `wait_network()` | Ожидает появления default route (максимум 60 секунд) | | `( ... ) &` | Субшелл запускается **в фоне** — не блокирует загрузку | | `while true` | Автоматический перезапуск tuna при падении (пауза 5 секунд) | | `echo $! > "$PIDFILE"` | Сохраняет PID субшелла для корректной остановки | | `pkill -f` | При остановке убивает и обёртку, и дочерний процесс tuna | ##### Пояснение флагов tuna | Флаг | Обязательный | Описание | | ------------------------------ | ------------ | -------------------------------------------------------------------------------------------------------------------------- | | `--inspect=false` | Нет | Отключает инспектор трафика (не нужен для KVM), чтобы не расходовать RAM | | `--basic-auth=admin:ВашПароль` | Нет | Дополнительная HTTP-авторизация ([подробнее](#%D0%B7%D0%B0%D1%87%D0%B5%D0%BC-%D0%BD%D1%83%D0%B6%D0%B5%D0%BD---basic-auth)) | | `--https-redirect` | Нет | Перенаправляет HTTP на HTTPS | | `80` | Да | Порт веб-интерфейса JetKVM | Также можно [ограничить доступ по IP-подсетям](#%D0%BE%D0%B3%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BF%D0%BE-ip-%D0%BF%D0%BE%D0%B4%D1%81%D0%B5%D1%82%D1%8F%D0%BC). ##### Проверка Запустите скрипт вручную: ```bash /userdata/init.d/S99tuna-http start ``` Убедитесь, что промпт вернулся (скрипт не заблокировал консоль). Проверьте, что процесс запущен: ```bash ps | grep tuna ``` В выводе должна быть строка с `/userdata/tuna/tuna ... http ...`. Если процесса нет — смотрите раздел [Диагностика неполадок](#%D0%B4%D0%B8%D0%B0%D0%B3%D0%BD%D0%BE%D1%81%D1%82%D0%B8%D0%BA%D0%B0-%D0%BD%D0%B5%D0%BF%D0%BE%D0%BB%D0%B0%D0%B4%D0%BE%D0%BA). В логах вы увидите URL вашего туннеля: ```bash cat /tmp/tuna-http.log ``` Также текущий адрес доступен в [личном кабинете](https://my.tuna.am/). *** #### Тип 2. Подписка — SSH и HTTP туннели С [подпиской](https://tuna.am/#pricing) вы получаете: * **Фиксированный поддомен** для HTTP-туннеля — адрес не меняется * **SSH-туннель** — прямой доступ к консоли JetKVM из любой точки мира ##### HTTP-туннель с фиксированным адресом ```bash cat << 'INITEOF' > /userdata/init.d/S99tuna-http #!/bin/sh PIDFILE=/tmp/tuna-http.pid LOGFILE=/tmp/tuna-http.log wait_network() { i=0 while ! ip route | grep -q default; do sleep 1 i=$((i + 1)) if [ "$i" -ge 60 ]; then echo "$(date): network timeout" >> "$LOGFILE" return 1 fi done return 0 } start() { echo "$(date): starting tuna-http" >> "$LOGFILE" ( wait_network || exit 1 while true; do /userdata/tuna/tuna \ --config=/userdata/tuna/.tuna.yml \ --log="$LOGFILE" \ http \ --subdomain=jetkvm \ --inspect=false \ --basic-auth=admin:ВашПароль \ --https-redirect \ 80 >> "$LOGFILE" 2>&1 echo "$(date): tuna-http exited, restarting in 5s" >> "$LOGFILE" sleep 5 done ) & echo $! > "$PIDFILE" } stop() { if [ -f "$PIDFILE" ]; then kill "$(cat "$PIDFILE")" 2>/dev/null pkill -f "/userdata/tuna/tuna.*http" 2>/dev/null rm -f "$PIDFILE" fi } case "$1" in start) start ;; stop) stop ;; restart) stop; sleep 1; start ;; *) echo "Usage: $0 {start|stop|restart}" ;; esac INITEOF chmod +x /userdata/init.d/S99tuna-http ``` Отличие от бесплатной версии — флаг `--subdomain=jetkvm`, который закрепляет за вами постоянный адрес. После перезапуска туннеля URL останется прежним. к сведению Поддомен из примера уже может быть занят. Зарезервируйте свой поддомен заранее в [личном кабинете](https://my.tuna.am/domains), затем используйте его в флаге `--subdomain=ваш-поддомен`. ###### Пояснение флагов HTTP-туннеля | Флаг | Обязательный | Описание | | ------------------------------ | ------------ | -------------------------------------------------------------------------------------------------------------------------- | | `--subdomain=jetkvm` | Нет | Фиксирует постоянный адрес туннеля (только с подпиской) | | `--inspect=false` | Нет | Отключает инспектор трафика (не нужен для KVM), чтобы не расходовать RAM | | `--basic-auth=admin:ВашПароль` | Нет | Дополнительная HTTP-авторизация ([подробнее](#%D0%B7%D0%B0%D1%87%D0%B5%D0%BC-%D0%BD%D1%83%D0%B6%D0%B5%D0%BD---basic-auth)) | | `--https-redirect` | Нет | Перенаправляет HTTP на HTTPS | | `80` | Да | Порт веб-интерфейса JetKVM | Также можно [ограничить доступ по IP-подсетям](#%D0%BE%D0%B3%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BF%D0%BE-ip-%D0%BF%D0%BE%D0%B4%D1%81%D0%B5%D1%82%D1%8F%D0%BC). ##### SSH-туннель SSH-туннель позволяет подключаться к консоли JetKVM через интернет. Это удобно для администрирования, обновления прошивки и диагностики. ```bash cat << 'INITEOF' > /userdata/init.d/S98tuna-ssh #!/bin/sh PIDFILE=/tmp/tuna-ssh.pid LOGFILE=/tmp/tuna-ssh.log wait_network() { i=0 while ! ip route | grep -q default; do sleep 1 i=$((i + 1)) if [ "$i" -ge 60 ]; then echo "$(date): network timeout" >> "$LOGFILE" return 1 fi done return 0 } start() { echo "$(date): starting tuna-ssh" >> "$LOGFILE" ( wait_network || exit 1 while true; do /userdata/tuna/tuna \ --config=/userdata/tuna/.tuna.yml \ --log="$LOGFILE" \ ssh \ --port=jetkvm-ssh \ --record-session=false \ --password-auth=false >> "$LOGFILE" 2>&1 echo "$(date): tuna-ssh exited, restarting in 5s" >> "$LOGFILE" sleep 5 done ) & echo $! > "$PIDFILE" } stop() { if [ -f "$PIDFILE" ]; then kill "$(cat "$PIDFILE")" 2>/dev/null pkill -f "/userdata/tuna/tuna.*ssh" 2>/dev/null rm -f "$PIDFILE" fi } case "$1" in start) start ;; stop) stop ;; restart) stop; sleep 1; start ;; *) echo "Usage: $0 {start|stop|restart}" ;; esac INITEOF chmod +x /userdata/init.d/S98tuna-ssh ``` ###### Пояснение флагов SSH-туннеля | Флаг | Обязательный | Описание | | ------------------------ | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `--port=jetkvm-ssh` | Нет | Фиксирует порт SSH-туннеля. Без этого флага порт будет назначаться случайно при каждом запуске. [Алиас для порта](https://my.tuna.am/tcp_ports) нужно зарезервировать заранее перед запуском. | | `--record-session=false` | Нет | Отключает запись SSH-сессий на диск. На embedded устройствах с ограниченным хранилищем рекомендуется отключать, чтобы не занимать место. | | `--password-auth=false` | Нет | Запрещает подключение по паролю — доступ только по SSH-ключам ([подробнее](#%D0%B0%D1%83%D1%82%D0%B5%D0%BD%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F-%D0%B2-ssh-%D1%82%D1%83%D0%BD%D0%BD%D0%B5%D0%BB%D0%B5)) | Также можно задать [статичный логин и пароль](#%D0%B0%D1%83%D1%82%D0%B5%D0%BD%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F-%D0%B2-ssh-%D1%82%D1%83%D0%BD%D0%BD%D0%B5%D0%BB%D0%B5) или [ограничить доступ по IP-подсетям](#%D0%BE%D0%B3%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BF%D0%BE-ip-%D0%BF%D0%BE%D0%B4%D1%81%D0%B5%D1%82%D1%8F%D0%BC). ##### Проверка туннелей Запустите оба скрипта вручную: ```bash /userdata/init.d/S99tuna-http start /userdata/init.d/S98tuna-ssh start ``` Убедитесь, что оба процесса запущены: ```bash ps | grep tuna ``` В выводе должны быть две строки — с `http` и `ssh`. Если какого-то процесса нет — смотрите раздел [Диагностика неполадок](#%D0%B4%D0%B8%D0%B0%D0%B3%D0%BD%D0%BE%D1%81%D1%82%D0%B8%D0%BA%D0%B0-%D0%BD%D0%B5%D0%BF%D0%BE%D0%BB%D0%B0%D0%B4%D0%BE%D0%BA). Посмотрите логи: ```bash cat /tmp/tuna-http.log cat /tmp/tuna-ssh.log ``` В логах HTTP-туннеля будет URL, а в логах SSH-туннеля — инструкция для подключения с указанием адреса и порта. *** #### Управление туннелями Автоперезапуск при падении обеспечивается циклом `while true` внутри init-скрипта. Для управления туннелями используйте следующие команды. ##### Проверка статуса ```bash ps | grep tuna ``` ##### Остановка туннеля ```bash # Остановить HTTP-туннель /userdata/init.d/S99tuna-http stop # Остановить SSH-туннель /userdata/init.d/S98tuna-ssh stop ``` ##### Запуск туннеля ```bash # Запустить HTTP-туннель /userdata/init.d/S99tuna-http start # Запустить SSH-туннель /userdata/init.d/S98tuna-ssh start ``` ##### Перезапуск туннеля ```bash # Перезапустить HTTP-туннель /userdata/init.d/S99tuna-http restart # Перезапустить SSH-туннель /userdata/init.d/S98tuna-ssh restart ``` ##### Полное отключение автозапуска Чтобы туннель не запускался при загрузке — переименуйте скрипт, убрав префикс `S`: ```bash # Отключить автозапуск HTTP-туннеля mv /userdata/init.d/S99tuna-http /userdata/init.d/disabled-tuna-http # Включить обратно mv /userdata/init.d/disabled-tuna-http /userdata/init.d/S99tuna-http ``` *** #### Восстановление после OTA-обновления Бинарник, конфигурация и init-скрипты хранятся в `/userdata/`, который **сохраняется при OTA-обновлениях**. После обновления прошивки через веб-интерфейс JetKVM туннели продолжат работать без дополнительных действий. к сведению В отличие от NanoKVM, на JetKVM не нужно восстанавливать `/etc/inittab` после обновления — автозапуск через `/userdata/init.d/` полностью переживает OTA. При полной перепрошивке (когда `/userdata` был очищен) потребуется заново установить бинарник, сохранить токен и создать init-скрипты. *** #### Дополнительные настройки безопасности ##### Зачем нужен `--basic-auth` У JetKVM есть собственная авторизация в веб-интерфейсе. Однако, учитывая [историю уязвимостей в IoT-устройствах](https://owasp.org/www-project-internet-of-things/), мы настоятельно рекомендуем добавить дополнительный уровень защиты. При открытии доступа через интернет лучше перестраховаться — флаг `--basic-auth` добавит стандартную HTTP-авторизацию (логин и пароль в браузере) ещё до того, как запрос дойдёт до JetKVM. ```bash --basic-auth=mylogin:MyStr0ngP@ss ``` Важно Задайте **свои** логин и пароль. Не используйте значения из примеров. ##### Аутентификация в SSH-туннеле **Вариант 1. По SSH-ключам (рекомендуется)** Флаг `--password-auth=false` отключает вход по паролю. Для подключения потребуется предварительно добавить публичный SSH-ключ в [личном кабинете](https://my.tuna.am/public_keys). Подробная инструкция: [Настройка SSH-ключей](https://tuna.am/docs/guides/ssh-keys.md) warning Туннельные ноды имеют публичный адрес. Злоумышленники могут просканировать порты и начать подбор пароля. Для долгоживущих SSH-туннелей настоятельно рекомендуем отключить парольную аутентификацию. **Вариант 2. Статичный логин и пароль** Если SSH-ключи не подходят, можно задать фиксированные учётные данные: ```bash --auth=user:pass ``` Замените `user` и `pass` на свои значения. ##### Ограничение по IP-подсетям Для HTTP и SSH туннелей можно ограничить доступ по IP-адресам. Разрешить доступ только с определённых подсетей: ```bash --cidr-allow="203.0.113.0/24" ``` Запретить доступ из определённых подсетей: ```bash --cidr-deny="198.51.100.0/24" ``` Можно комбинировать — разрешить подсеть, но исключить отдельные адреса: ```bash --cidr-allow="10.0.0.0/24" --cidr-deny="10.0.0.33/32" ``` Осторожно Используйте фильтрацию по IP с осторожностью. Если вы ошибётесь с подсетью или ваш IP-адрес изменится — вы потеряете удалённый доступ к JetKVM. Убедитесь, что у вас есть альтернативный способ управления устройством (например, локальный доступ). *** #### Диагностика неполадок ##### Устройство не загружается после добавления init-скрипта Экстренное восстановление Если JetKVM перестал загружаться после добавления скрипта в `/userdata/init.d/`, наиболее частые причины: 1. **Шебанг `#!/bin/bash`** — bash на JetKVM отсутствует 2. **Скрипт блокирует загрузку** — процесс не запущен в фоне (`&`) 3. **Расширение `.sh`** — скрипт был включён через `source`, что сломало init-процесс 4. **Синтаксическая ошибка** — прерывает выполнение init **Способы восстановления:** * **UART serial console** — если есть доступ к UART-порту JetKVM, подключитесь через serial console (115200 baud) и удалите или переименуйте проблемный скрипт * **Factory reset** — нажмите и удерживайте кнопку сброса на JetKVM (внимание: это может очистить `/userdata/`) ##### Процесс tuna не запускается Проверьте, что процесс присутствует в списке: ```bash ps | grep tuna ``` Если в выводе нет строк с `/userdata/tuna/tuna` — проверьте: 1. Скрипт существует и имеет права на выполнение: ```bash ls -la /userdata/init.d/S9*tuna* ``` 2. Скрипт запускается без ошибок: ```bash /userdata/init.d/S99tuna-http start ``` 3. Бинарник tuna работает: ```bash /userdata/tuna/tuna version ``` ##### Просмотр логов Логи туннелей записываются в `/tmp/` и доступны до перезагрузки устройства: ```bash # Логи HTTP-туннеля cat /tmp/tuna-http.log # Логи SSH-туннеля cat /tmp/tuna-ssh.log ``` Для наблюдения за логами в реальном времени: ```bash tail -f /tmp/tuna-http.log ``` ##### Типичные ошибки в логах | Ошибка | Причина | Решение | | ------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------ | | `token is invalid` | Неверный или просроченный токен | Повторите `config save-token` с актуальным токеном со [страницы](https://my.tuna.am/token) | | `Domain already reserved` | Поддомен занят другим пользователем | Выберите другое имя через `--subdomain=` | | `port alias not found` | Алиас порта не зарезервирован | Зарезервируйте алиас в [личном кабинете](https://my.tuna.am/tcp_ports) | | `connection refused` | Нет доступа к интернету | Проверьте сеть: `ping -c 3 8.8.8.8` | | `exec format error` | Неправильная архитектура бинарника | Убедитесь, что используете `tuna_linux_arm` (ARMv7) | ##### Нет доступа к интернету Проверьте, что JetKVM имеет сетевое подключение: ```bash # Проверить наличие IP-адреса ip addr # Проверить маршрут по умолчанию ip route # Проверить доступ в интернет ping -c 3 8.8.8.8 ``` ##### Логи пропали после перезагрузки Логи хранятся в `/tmp/`, который очищается при перезагрузке. Это нормальное поведение. Если нужно сохранять логи между перезагрузками, измените путь в init-скриптах: ```bash LOGFILE=/userdata/tuna/tuna-http.log ``` warning Частая запись логов может сократить ресурс хранилища. Используйте это только для временной отладки. ##### Туннель работал и перестал 1. Проверьте логи на наличие ошибок 2. Убедитесь, что токен всё ещё действителен в [личном кабинете](https://my.tuna.am/token) 3. Проверьте, что скрипт в `/userdata/init.d/` на месте и исполняем: ```bash ls -la /userdata/init.d/S9*tuna* ``` *** #### Ссылки * [JetKVM — официальный сайт](https://jetkvm.com/) * [JetKVM — GitHub](https://github.com/jetkvm/kvm) * [JetKVM — документация](https://jetkvm.com/docs) * [HTTP-туннель — все флаги](https://tuna.am/docs/tunnels/http.md) * [SSH-туннель — все флаги](https://tuna.am/docs/tunnels/ssh.md) * [Настройка SSH-ключей](https://tuna.am/docs/guides/ssh-keys.md) * [Запуск tuna как сервис](https://tuna.am/docs/tunnels/guides/service.md) *** #### Мониторинг доступности Помимо туннелей для удалённого доступа, вы можете настроить мониторинг доступности JetKVM. Heartbeat-мониторинг будет отправлять вам уведомления, если устройство потеряет связь с интернетом или перестанет отвечать. **Полная инструкция:** [Мониторинг доступности JetKVM](https://tuna.am/docs/monitors/examples/jetkvm.md) --- ### tuna и Kiwi TCMS #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите Kiwi TCMS сервер Инструкцию по установке можно найти в [официальной документации](https://kiwitcms.readthedocs.io/en/latest/set_dev_env.html). #### Шаг 3. Запустите tuna Kiwi TCMS использует порт `8000` по умолчанию: ```bash tuna http 8000 ``` --- ### tuna и Kubernetes Пример запуска tuna для предоставления доступа к сервису в запущенном кластере Kubernetes. #### Шаг 1. Склонируйте репозиторий с примерами ```shell git clone https://gitlab.com/yuccastream/tuna-examples.git cd tuna-examples/kubernetes ``` #### Шаг 2. Запустите сервис Создайте отдельный namespace для экспериментов и запустите тестовый сервис: ```shell kubectl create namespace tuna-example kubectl -n tuna-example apply -k podinfo ``` #### Шаг 3. Запустите tuna Убедитесь, что в файле `tuna/deployment.yaml` указан корректный токен для работы, без него tuna не заработает, затем выполните команду: ```shell kubectl -n tuna-example apply -k tuna ``` Дождитесь, когда тестовый сервис и tuna перейдут в статус `Running`: ```shell kubectl -n tuna-example get pods NAME READY STATUS RESTARTS AGE podinfo-6779cc5586-t78q4 1/1 Running 0 2m14s tuna-64d9b5c698-7sr96 1/1 Running 0 25s ``` Затем посмотрите журнал событий tuna для получения ссылки: ```shell kubectl -n tuna-example logs -l app.kubernetes.io/name=tuna INFO[13:00:00] Welcome to Tuna INFO[13:00:00] Account: test (Paid till 05.04.2024) INFO[13:00:00] Web Interface: http://127.0.0.1:4040 INFO[13:00:00] Forwarding https://yae6hu-10-21-32-25.ru.tuna.am -> podinfo:9898 ``` Для удаления всех созданных сущностей воспользуйтесь командой `kubectl delete namespace tuna-example`. --- ### tuna и MAMP #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите MAMP или MAMP Pro #### Шаг 3. Запустите tuna Специальные настройки не требуются, но для корректного роутинга запросов потребуется передача заголовка `Host`, например: ```shell tuna http --request-header="host:tuna.am" 80 ``` --- ### tuna и MariaDB #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите MariaDB сервер Инструкцию по установке можно найти в [официальной документации](https://mariadb.com/kb/en/installing-and-using-mariadb-via-docker/). #### Шаг 3. Запустите tuna MariaDB использует порт `3306` по умолчанию: ```bash tuna tcp 3306 ``` В результате запуска команды на экран будет выведен адрес подключения (например, `ru.tuna.am:12345`), который теперь можно использовать для подключения к MariaDB. --- ### tuna и Mattermost Помимо Mattermost App возможно создавать Outgoing Webhook – ссылки, на которые будут отправляться сообщения, если в указанном канале упомянулось какое-то ключевое слово. #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите сервер для обработки событий от Mattermost Информацию о структуре входящий запросов можно узнать в [официальной документации](https://developers.mattermost.com/integrate/webhooks/outgoing/). #### Шаг 3. Запустите tuna В аргументах запуска укажите порт вашего сервера: ```bash tuna http 8080 ``` Или с указанием статичного адреса: ```bash tuna http 8080 --subdomain=mattermost-webhook ``` #### Шаг 4. Создайте новый Webhook Перейдите в раздел Интеграции, затем "Исходящие вебхуки" и нажмите на кнопку "Добавить исходящий Webhook". Заполните появившуюся форму, а в качестве значения "URL обратного вызова" укажите адрес полученный от tuna (например, `https://mattermost-webhook.ru.tuna.am`) и путь к методу вашего сервера для обработки событий (например, `/event`). --- ### tuna ❤️ Minecraft [Minecraft](https://www.minecraft.net/ru-ru?utm_source=tuna.am) - популярная компьютерная инди-игра в жанре песочницы. Tuna поможет открыть доступ к Minecraft (java edition) в локальной сети. Мы писали подробную инструкцию [как запустить локально Minecraft сервер в Docker и открыть доступ друзьям с помощью Tuna](https://dtf.ru/howto/2821468-instrukciya-zapuskaem-minecraft-lokalno-v-docker-i-otkryvaem-dostup-druzyam-s-pomoshyu-tuna), в любой операционной системе. *** к сведению Для публикации Minecraft необходимо создание [TCP туннеля](https://tuna.am/docs/tunnels/tcp.md), это доступно только по [подписке](https://tuna.am/#pricing). Но вам не обязательно запускать свой сервер Minecraft, чтобы поиграть с друзьями, можно и просто открыть доступ к своей игре: #### Шаг 1. Запустите Minecraft (java edition) * Создайте *Одиночную игру* * Нажмите **esc** * Выберете *Откройте для сети* * Задайте порт, например `45678` * Нажмите *Открыть мир для сети* #### Шаг 2. Установите клиент tuna Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 3. Запустите tuna Выполните: ```bash tuna tcp 45678 ``` Сообщите друзьям ссылку для подключения как в примере, **без** указания схемы `tcp://`: ![minecraft_link](/docs/img/examples/minecraft_link.png) подсказка Если вам нужно знать реальный IP клиентов, то некоторые сборки, например [Velocity](https://docs.papermc.io/velocity/configuration/#advanced-section), поддерживают Proxy Protocol. Необходимо включить его в конфиге игры и в клиенте `tuna`. В аргументе нужно передать версию 1 или 2, что соответствует версии Proxy Protocol, 1 - текстовый , 2 - бинарный. ```shell tuna tcp 45678 --proxy-protocol=1 # или tuna tcp 45678 --proxy-protocol=2 ``` --- ### tuna и Minio #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите Minio сервер Для запуска с помощью Docker можно воспользоваться командой: ```bash docker run -p 9000:9000 quay.io/minio/minio server /data ``` #### Шаг 3. Запустите tuna Minio использует порт `9000` по умолчанию: ```bash tuna tcp 9000 ``` --- ### tuna и MongoDB #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите MongoDB сервер Инструкцию по установке можно найти в [официальной документации](https://www.mongodb.com/docs/manual/installation/). #### Шаг 3. Запустите tuna MongoDB использует порт `27017` по умолчанию: ```bash tuna tcp 27017 ``` В результате запуска команды на экран будет выведен адрес подключения (например, `ru.tuna.am:12345`), который теперь можно использовать для подключения к MongoDB. --- ### tuna и MsSQL #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите MsSQL сервер #### Шаг 3. Запустите tuna MsSQL использует порт `1433` по умолчанию: ```bash tuna tcp 1433 ``` В результате запуска команды на экран будет выведен адрес подключения (например, `ru.tuna.am:12345`), который теперь можно использовать для подключения к MsSQL. --- ### tuna и MySQL #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите MySQL сервер #### Шаг 3. Запустите tuna MySQL использует порт `3306` по умолчанию: ```bash tuna tcp 3306 ``` В результате запуска команды на экран будет выведен адрес подключения (например, `ru.tuna.am:12345`), который теперь можно использовать для подключения к MySQL. --- ### tuna ❤️ NanoKVM [NanoKVM](https://wiki.sipeed.com/hardware/en/kvm/NanoKVM/introduction.html) — это компактное IP-KVM устройство от Sipeed на базе RISC-V (Cube/PCIe) или ARM64 (Pro) или ARMv7 (GxxKVM/JxxKVM). Оно позволяет удалённо управлять компьютером: видеть экран, управлять клавиатурой и мышью, монтировать образы дисков — всё через веб-интерфейс в браузере. По умолчанию NanoKVM доступен только в локальной сети. С помощью Tuna вы можете открыть доступ к нему через интернет — без «белого» IP, без VPN, без проброса портов на роутере. ![Tuna + NanoKVM](/docs/img/tunnels/guides/nanokvm_tuna.png) к сведению Мы тестировали данную инструкцию только на [NanoKVM Cube](https://wiki.sipeed.com/hardware/en/kvm/NanoKVM/introduction.html), но вероятнее всего это будет работать на всех устройствах линейки NanoKVM. *** #### Подготовка Помимо установи инструкция по настройке разделена на 2 типа, в зависимости от наличия платной подписки Tuna. 1. [На бесплатном тарифе](#%D1%82%D0%B8%D0%BF-1-%D0%B1%D0%B5%D1%81%D0%BF%D0%BB%D0%B0%D1%82%D0%BD%D1%8B%D0%B9-%D1%82%D0%B0%D1%80%D0%B8%D1%84--http-%D1%82%D1%83%D0%BD%D0%BD%D0%B5%D0%BB%D1%8C) 2. [С платной подпиской](#%D1%82%D0%B8%D0%BF-2-%D0%BF%D0%BE%D0%B4%D0%BF%D0%B8%D1%81%D0%BA%D0%B0--ssh-%D0%B8-http-%D1%82%D1%83%D0%BD%D0%BD%D0%B5%D0%BB%D0%B8) ##### Что потребуется * NanoKVM, подключённый к локальной сети и доступный по SSH или терминал в веб интерфейсе * Аккаунт на [tuna.am](https://my.tuna.am/) (бесплатный или с подпиской) * Токен авторизации со [страницы токена](https://my.tuna.am/token) ##### Структура хранилища NanoKVM NanoKVM имеет три раздела: | Раздел | Точка монтирования | Назначение | | ---------------- | ------------------ | ----------------------- | | `/dev/mmcblk0p1` | `/boot` | Загрузчик, ядро | | `/dev/mmcblk0p2` | `/` | Корневая ФС (Buildroot) | | `/dev/mmcblk0p3` | `/data` | Данные, ISO-образы | Раздел `/data` сохраняется при обновлениях приложения и remote rsync, поэтому мы будем хранить tuna именно там. ##### Установка tuna на NanoKVM Подключитесь к NanoKVM по SSH и установите бинарник: ```bash ssh root@ ``` Или откройте терминал в веб интерфейсе: ![NanoKVM terminal](/docs/img/tunnels/guides/terminal.png) Установите tuna с помощью скрипта, указав `/data/tuna` в качестве директории установки: **curl** ```bash mkdir -p /data/tuna INSTALL_DIR=/data/tuna sh -c "$(curl -sSLf https://releases.tuna.am/tuna/get.sh)" ``` **wget** ```bash mkdir -p /data/tuna INSTALL_DIR=/data/tuna sh -c "$(wget -qO- https://releases.tuna.am/tuna/get.sh)" ``` подсказка Раздел `/data` смонтирован как exFAT с `fmask=0022`, файлы автоматически получают права `0755` — бинарник можно запускать сразу после копирования. Кроме того, `/data` сохраняется при обновлениях, поэтому tuna не придётся переустанавливать. Сохраните [токен](https://my.tuna.am/token) авторизации: ```bash /data/tuna/tuna --config=/data/tuna/.tuna.yml config save-token <ВАШ_ТОКЕН> ``` подсказка Рекомендуем создать дополнительный токен для устройства. *** #### Тип 1. Бесплатный тариф — HTTP-туннель На бесплатном тарифе доступен HTTP-туннель с динамическим адресом. Этого достаточно, чтобы открыть веб-интерфейс NanoKVM в интернет и управлять компьютером через браузер. Ограничения бесплатного тарифа * Динамический адрес меняется при каждом переподключении туннеля * Чтобы адрес не менялся, добавьте в команду запуска свой [бесплатный постоянный поддомен](https://tuna.am/docs/tunnels/http.md#free-subdomain): `--subdomain=<ваш-поддомен>` * Текущий адрес всегда можно посмотреть в [личном кабинете](https://my.tuna.am/tunnels) ##### Создание скрипта запуска ```bash cat << 'EOF' > /data/tuna/tuna-http.sh #!/bin/sh # Ждём сеть while ! ip route | grep -q default; do sleep 1 done exec /data/tuna/tuna \ --config=/data/tuna/.tuna.yml \ --log=/tmp/tuna-http.log \ http \ --inspect=false \ --basic-auth=tuna:SecurePasswd \ --https-redirect \ 80 EOF chmod +x /data/tuna/tuna-http.sh ``` ##### Пояснение флагов | Флаг | Обязательный | Описание | | ------------------------------ | ------------ | -------------------------------------------------------------------------------------------------------------------------- | | `--inspect=false` | Нет | Отключает инспектор трафика (не нужен для KVM), чтобы не расходовать RAM | | `--basic-auth=admin:ВашПароль` | Нет | Дополнительная HTTP-авторизация ([подробнее](#%D0%B7%D0%B0%D1%87%D0%B5%D0%BC-%D0%BD%D1%83%D0%B6%D0%B5%D0%BD---basic-auth)) | | `--https-redirect` | Нет | Перенаправляет HTTP на HTTPS | | `80` | Да | Порт веб-интерфейса NanoKVM | Также можно [ограничить доступ по IP-подсетям](#%D0%BE%D0%B3%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BF%D0%BE-ip-%D0%BF%D0%BE%D0%B4%D1%81%D0%B5%D1%82%D1%8F%D0%BC). ##### Настройка автозапуска Добавьте строку в `/etc/inittab`, чтобы init автоматически запускал и перезапускал туннель: ```bash cat << 'EOF' >> /etc/inittab # Tuna HTTP tunnel (respawn = auto-restart) tweb::respawn:/data/tuna/tuna-http.sh EOF ``` Применить без перезагрузки: ```bash kill -HUP 1 ``` ##### Проверка Убедитесь, что процесс запущен: ```bash ps -ef | grep tuna ``` В выводе должна быть строка с `/data/tuna/tuna ... http ...`. Если процесса нет — смотрите раздел [Диагностика неполадок](#%D0%B4%D0%B8%D0%B0%D0%B3%D0%BD%D0%BE%D1%81%D1%82%D0%B8%D0%BA%D0%B0-%D0%BD%D0%B5%D0%BF%D0%BE%D0%BB%D0%B0%D0%B4%D0%BE%D0%BA). В логах вы увидите URL вашего туннеля: ```bash cat /tmp/tuna-http.log ``` Также текущий адрес доступен в [личном кабинете](https://my.tuna.am/). *** #### Тип 2. Подписка — SSH и HTTP туннели С [подпиской](https://tuna.am/#pricing) вы получаете: * **Фиксированный поддомен** для HTTP-туннеля — адрес не меняется * **SSH-туннель** — прямой доступ к консоли NanoKVM из любой точки мира Ну и в целом особо ограничений нет, можете ещё несколько туннелей запустить и прокинуть доступ например к web интерфейсу роутера, SSH или RDP управляемого или любого другого компьютера в локальной сети. ##### HTTP-туннель с фиксированным адресом ```bash cat << 'EOF' > /data/tuna/tuna-http.sh #!/bin/sh # Ждём сеть while ! ip route | grep -q default; do sleep 1 done exec /data/tuna/tuna \ --config=/data/tuna/.tuna.yml \ --log=/tmp/tuna-http.log \ http \ --subdomain=nanokvm \ --inspect=false \ --basic-auth=admin:ВашПароль \ --https-redirect \ 80 EOF chmod +x /data/tuna/tuna-http.sh ``` Отличие от бесплатной версии — флаг `--subdomain=nanokvm`, который закрепляет за вами постоянный адрес. После перезапуска туннеля URL останется прежним. к сведению Поддомен из примера уже занят. Зарезервируйте свой поддомен заранее в [личном кабинете](https://my.tuna.am/domains), затем используйте его в флаге `--subdomain=ваш-поддомен`. ###### Пояснение флагов HTTP-туннеля | Флаг | Обязательный | Описание | | ------------------------------ | ------------ | -------------------------------------------------------------------------------------------------------------------------- | | `--subdomain=nanokvm` | Нет | Фиксирует постоянный адрес туннеля (только с подпиской) | | `--inspect=false` | Нет | Отключает инспектор трафика (не нужен для KVM), чтобы не расходовать RAM | | `--basic-auth=admin:ВашПароль` | Нет | Дополнительная HTTP-авторизация ([подробнее](#%D0%B7%D0%B0%D1%87%D0%B5%D0%BC-%D0%BD%D1%83%D0%B6%D0%B5%D0%BD---basic-auth)) | | `--https-redirect` | Нет | Перенаправляет HTTP на HTTPS | | `80` | Да | Порт веб-интерфейса NanoKVM | Также можно [ограничить доступ по IP-подсетям](#%D0%BE%D0%B3%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BF%D0%BE-ip-%D0%BF%D0%BE%D0%B4%D1%81%D0%B5%D1%82%D1%8F%D0%BC). ##### SSH-туннель SSH-туннель позволяет подключаться к консоли NanoKVM через интернет. Это удобно для администрирования, обновления прошивки и диагностики. ```bash cat << 'EOF' > /data/tuna/tuna-ssh.sh #!/bin/sh # Ждём сеть while ! ip route | grep -q default; do sleep 1 done exec /data/tuna/tuna \ --config=/data/tuna/.tuna.yml \ --log=/tmp/tuna-ssh.log \ ssh \ --port=nanokvm-ssh \ --record-session=false \ --password-auth=false EOF chmod +x /data/tuna/tuna-ssh.sh ``` ###### Пояснение флагов SSH-туннеля | Флаг | Обязательный | Описание | | ------------------------ | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `--port=nanokvm-ssh` | Нет | Фиксирует порт SSH-туннеля. Без этого флага порт будет назначаться случайно при каждом запуске. [Алиас для порта](https://my.tuna.am/tcp_ports) нужно зарезервировать заранее перед запуском. | | `--record-session=false` | Нет | Отключает запись SSH-сессий на диск. На embedded устройствах с ограниченным хранилищем рекомендуется отключать, чтобы не занимать место. | | `--password-auth=false` | Нет | Запрещает подключение по паролю — доступ только по SSH-ключам ([подробнее](#%D0%B0%D1%83%D1%82%D0%B5%D0%BD%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F-%D0%B2-ssh-%D1%82%D1%83%D0%BD%D0%BD%D0%B5%D0%BB%D0%B5)) | Также можно задать [статичный логин и пароль](#%D0%B0%D1%83%D1%82%D0%B5%D0%BD%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F-%D0%B2-ssh-%D1%82%D1%83%D0%BD%D0%BD%D0%B5%D0%BB%D0%B5) или [ограничить доступ по IP-подсетям](#%D0%BE%D0%B3%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BF%D0%BE-ip-%D0%BF%D0%BE%D0%B4%D1%81%D0%B5%D1%82%D1%8F%D0%BC). ##### Настройка автозапуска обоих туннелей Добавьте строки в `/etc/inittab`: ```bash cat << 'EOF' >> /etc/inittab # Tuna tunnels (respawn = auto-restart) tssh::respawn:/data/tuna/tuna-ssh.sh tweb::respawn:/data/tuna/tuna-http.sh EOF ``` Применить без перезагрузки: ```bash kill -HUP 1 ``` ##### Проверка туннелей Убедитесь, что оба процесса запущены: ```bash ps -ef | grep tuna ``` В выводе должны быть две строки — с `http` и `ssh`. Если какого-то процесса нет — смотрите раздел [Диагностика неполадок](#%D0%B4%D0%B8%D0%B0%D0%B3%D0%BD%D0%BE%D1%81%D1%82%D0%B8%D0%BA%D0%B0-%D0%BD%D0%B5%D0%BF%D0%BE%D0%BB%D0%B0%D0%B4%D0%BE%D0%BA). Посмотрите логи: ```bash cat /tmp/tuna-http.log cat /tmp/tuna-ssh.log ``` В логах HTTP-туннеля будет URL, а в логах SSH-туннеля — инструкция для подключения с указанием адреса и порта. *** #### Управление туннелями С `inittab respawn` процесс tuna автоматически перезапускается при падении. Для управления используйте следующие команды: ##### Проверка статуса ```bash ps -ef | grep tuna ``` ##### Остановка туннеля Нельзя просто завершить процесс — init тут же его перезапустит. Сначала закомментируйте строку в `/etc/inittab`: ```bash # Остановить HTTP-туннель sed -i 's/^tweb:/#tweb:/' /etc/inittab && kill -HUP 1 # Остановить SSH-туннель sed -i 's/^tssh:/#tssh:/' /etc/inittab && kill -HUP 1 ``` ##### Запуск туннеля Раскомментируйте строку обратно: ```bash # Запустить HTTP-туннель sed -i 's/^#tweb:/tweb:/' /etc/inittab && kill -HUP 1 # Запустить SSH-туннель sed -i 's/^#tssh:/tssh:/' /etc/inittab && kill -HUP 1 ``` *** #### Восстановление после перепрошивки Бинарник и скрипты в `/data/tuna/` сохраняются при обновлении приложения через веб-интерфейс и при remote rsync. После полной перепрошивки (Etcher) потребуется заново скопировать бинарник и создать скрипты. При remote rsync нужно восстановить только строки в `/etc/inittab`: ```bash cat << 'EOF' >> /etc/inittab # Tuna tunnels (respawn = auto-restart) tssh::respawn:/data/tuna/tuna-ssh.sh tweb::respawn:/data/tuna/tuna-http.sh EOF kill -HUP 1 ``` к сведению Если вы также используете [мониторинг доступности](https://tuna.am/docs/monitors/examples/nanokvm.md), не забудьте восстановить соответствующую строку в `/etc/inittab`. *** #### Дополнительные настройки безопасности ##### Зачем нужен `--basic-auth` У NanoKVM есть собственная авторизация в веб-интерфейсе. Однако, учитывая [историю уязвимостей в IoT-устройствах](https://owasp.org/www-project-internet-of-things/), мы настоятельно рекомендуем добавить дополнительный уровень защиты. При открытии доступа через интернет лучше перестраховаться — флаг `--basic-auth` добавит стандартную HTTP-авторизацию (логин и пароль в браузере) ещё до того, как запрос дойдёт до NanoKVM. ```bash --basic-auth=mylogin:MyStr0ngP@ss ``` Важно Задайте **свои** логин и пароль. Не используйте значения из примеров. ##### Аутентификация в SSH-туннеле **Вариант 1. По SSH-ключам (рекомендуется)** Флаг `--password-auth=false` отключает вход по паролю. Для подключения потребуется предварительно добавить публичный SSH-ключ в [личном кабинете](https://my.tuna.am/public_keys). Подробная инструкция: [Настройка SSH-ключей](https://tuna.am/docs/guides/ssh-keys.md) warning Туннельные ноды имеют публичный адрес. Злоумышленники могут просканировать порты и начать подбор пароля. Для долгоживущих SSH-туннелей настоятельно рекомендуем отключить парольную аутентификацию. **Вариант 2. Статичный логин и пароль** Если SSH-ключи не подходят, можно задать фиксированные учётные данные: ```bash --auth=user:pass ``` Замените `user` и `pass` на свои значения. ##### Ограничение по IP-подсетям Для HTTP и SSH туннелей можно ограничить доступ по IP-адресам. Разрешить доступ только с определённых подсетей: ```bash --cidr-allow="203.0.113.0/24" ``` Запретить доступ из определённых подсетей: ```bash --cidr-deny="198.51.100.0/24" ``` Можно комбинировать — разрешить подсеть, но исключить отдельные адреса: ```bash --cidr-allow="10.0.0.0/24" --cidr-deny="10.0.0.33/32" ``` Осторожно Используйте фильтрацию по IP с осторожностью. Если вы ошибётесь с подсетью или ваш IP-адрес изменится — вы потеряете удалённый доступ к NanoKVM. Убедитесь, что у вас есть альтернативный способ управления устройством (например, локальный доступ). *** #### Диагностика неполадок ##### Процесс tuna не запускается Проверьте, что процесс присутствует в списке: ```bash ps -ef | grep tuna ``` Если в выводе нет строк с `/data/tuna/tuna` — убедитесь, что записи в `/etc/inittab` не закомментированы: ```bash grep tuna /etc/inittab ``` Строки должны начинаться с `tssh::` или `tweb::`, а не с `#`. Если они закомментированы — раскомментируйте и перечитайте конфигурацию: ```bash kill -HUP 1 ``` ##### Просмотр логов Логи туннелей записываются в `/tmp/` и доступны до перезагрузки устройства: ```bash # Логи HTTP-туннеля cat /tmp/tuna-http.log # Логи SSH-туннеля cat /tmp/tuna-ssh.log ``` Для наблюдения за логами в реальном времени: ```bash tail -f /tmp/tuna-http.log ``` ##### Типичные ошибки в логах | Ошибка | Причина | Решение | | ------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------ | | `token is invalid` | Неверный или просроченный токен | Повторите `config save-token` с актуальным токеном со [страницы](https://my.tuna.am/token) | | `Domain already reserved` | Поддомен занят другим пользователем | Выберите другое имя через `--subdomain=` | | `port alias not found` | Алиас порта не зарезервирован | Зарезервируйте алиас в [личном кабинете](https://my.tuna.am/tcp_ports) | | `connection refused` | Нет доступа к интернету | Проверьте сеть: `ping -c 3 8.8.8.8` | ##### Нет доступа к интернету Проверьте, что NanoKVM имеет сетевое подключение: ```bash # Проверить наличие IP-адреса ip addr # Проверить маршрут по умолчанию ip route # Проверить доступ в интернет ping -c 3 8.8.8.8 ``` ##### Логи пропали после перезагрузки Логи хранятся в `/tmp/`, который очищается при перезагрузке. Это нормальное поведение. Если нужно сохранять логи между перезагрузками, измените путь в скриптах запуска на `/data/tuna/`: ```bash --log=/data/tuna/tuna-http.log ``` warning На NanoKVM раздел `/data` — exFAT, частая запись логов может сократить ресурс SD-карты. Используйте это только для временной отладки. ##### Туннель работал и перестал 1. Проверьте, не обновлялась ли прошивка — после remote rsync нужно восстановить записи в `/etc/inittab` (см. [Восстановление после перепрошивки](#%D0%B2%D0%BE%D1%81%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BF%D0%BE%D1%81%D0%BB%D0%B5-%D0%BF%D0%B5%D1%80%D0%B5%D0%BF%D1%80%D0%BE%D1%88%D0%B8%D0%B2%D0%BA%D0%B8)) 2. Проверьте логи на наличие ошибок 3. Убедитесь, что токен всё ещё действителен в [личном кабинете](https://my.tuna.am/token) *** #### Ссылки * [NanoKVM — официальная документация](https://wiki.sipeed.com/hardware/en/kvm/NanoKVM/introduction.html) * [NanoKVM — репозиторий на GitHub](https://github.com/sipeed/NanoKVM) * [Обновление NanoKVM](https://wiki.sipeed.com/hardware/en/kvm/NanoKVM/system/updating.html) * [Перепрошивка NanoKVM](https://wiki.sipeed.com/hardware/en/kvm/NanoKVM/system/flashing.html) * [HTTP-туннель — все флаги](https://tuna.am/docs/tunnels/http.md) * [SSH-туннель — все флаги](https://tuna.am/docs/tunnels/ssh.md) * [Настройка SSH-ключей](https://tuna.am/docs/guides/ssh-keys.md) * [Запуск tuna как сервис](https://tuna.am/docs/tunnels/guides/service.md) *** #### Мониторинг доступности Помимо туннелей для удалённого доступа, вы можете настроить мониторинг доступности NanoKVM. Heartbeat-мониторинг будет отправлять вам уведомления, если устройство потеряет связь с интернетом или перестанет отвечать. **Полная инструкция:** [Мониторинг доступности NanoKVM](https://tuna.am/docs/monitors/examples/nanokvm.md) --- ### tuna и Netdata #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите Netdata сервер Инструкцию по установке можно найти в [официальной документации](https://learn.netdata.cloud/docs/installing/). #### Шаг 3. Запустите tuna Netdata использует порт `19999` по умолчанию: ```bash tuna http 19999 ``` --- ### tuna и NGINX #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите NGINX #### Шаг 3. Запустите tuna Специальные настройки не требуются, но для корректного роутинга запросов может потребоваться передача заголовка `Host`, например: ```bash tuna http --request-header="host:tuna.am" 80 ``` Информацию о том, как NGINX обрабатывает запросы можно найти в [официальной документации](https://nginx.org/en/docs/http/request_processing.html). --- ### tuna и Ollama #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите Ollama Инструкцию по установке можно найти в [официальной документации](https://github.com/ollama/ollama/tree/main/docs#getting-started). #### Шаг 3. Запустите tuna Ollama использует порт `11434` по умолчанию: ```bash tuna http 11434 --request-header="host:localhost:11434" ``` Обратите внимание, что API будет доступен всем, если потребуется ограничить доступ, есть несколько способов: * [защита базовой аутентификацией](https://tuna.am/docs/tunnels/http.md#basic-auth) * [защита API токеном](https://tuna.am/docs/tunnels/http.md#key-auth) * [политики трафика](https://tuna.am/docs/traffic-policy.md#basic_auth) Пример защиты базовой аутентификацией может выглядеть так: ```bash tuna http 11434 --request-header="host:localhost:11434" --basic-auth="login:password" ``` Все запросы, без передачи корректных реквизитов, будут получать `401` ошибку. --- ### tuna и Open Server Panel #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите OSPanel сервер Инструкцию по установке можно найти в [официальной документации](https://ospanel.io/docs/#ustanovka). #### Шаг 3. Запустите tuna OSPanel использует порт `80` по умолчанию для доступа к вашему веб-проекту: ```bash tuna http 80 ``` Для корректного роутинга запросов может потребоваться передача заголовка `Host`, например: ```bash tuna http --request-header="host:tuna.am" 80 ``` Комментарий из сообщества в Telegram: Если используется NGINX и настроен редирект с HTTP на HTTPS, то нужно указывать схему, например: ```bash tuna http --request-header="host:tuna.am" https://127.0.0.1 ``` Aleksandr G. --- ### tuna и Paddle #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите сервер для обработки HTTP-уведомлений Информацию о входящих уведомлениях Paddle можно найти в [официальной документации](https://developer.paddle.com/webhooks/overview). #### Шаг 3. Запустите tuna В аргументах запуска укажите порт вашего сервера: ```bash tuna http 8080 ``` Или с указанием статичного адреса: ```bash tuna http 8080 --subdomain=paddle-webhook ``` #### Шаг 4. Укажите адрес для входящих уведомлений Подробная инструкция по настройке отправки событий можно найти в [официальной документации](https://developer.paddle.com/webhooks/notification-destinations). --- ### tuna и phpMyAdmin #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите phpMyAdmin Инструкцию по установке можно найти в [официальной документации](https://docs.phpmyadmin.net/en/latest/setup.html). #### Шаг 3. Запустите tuna phpMyAdmin использует порт `8080` по умолчанию: ```bash tuna http 8080 ``` --- ### tuna и PocketBase #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите PocketBase сервер Инструкцию по установке можно найти в [официальной документации](https://pocketbase.io/docs/). #### Шаг 3. Запустите tuna PocketBase использует порт `8090` по умолчанию: ```bash tuna http 8090 ``` --- ### tuna и PostgreSQL #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите PostgreSQL сервер Для запуска с помощью Docker можно воспользоваться командой: ```bash docker run -p 5432:5432 -e POSTGRES_PASSWORD=postgres postgres:15 ``` #### Шаг 3. Запустите tuna PostgreSQL использует порт `5432` по умолчанию: ```bash tuna postgres 5432 ``` В результате запуска команды на экран будет выведен адрес подключения (например, `ru.tuna.am:12345`), который теперь можно использовать для подключения к PostgreSQL, например: ```bash psql -h ru.tuna.am -p 12345 -U postgres -d postgres ``` При запуске [Postgres туннеля](https://tuna.am/docs/tunnels/postgres.md) вам будет предоставлена ссылка на инспектор для просмотра сессий и выполняемых запросов. --- ### tuna и Qdrant #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите Qdrant сервер Инструкцию по установке можно найти в [официальной документации](https://qdrant.tech/documentation/quickstart/). #### Шаг 3. Запустите tuna Qdrant использует порт `6333` по умолчанию для HTTP: ```bash tuna http 6333 ``` И порт `6334` для gRPC: ```bash tuna tcp 6334 ``` --- ### tuna и RabbitMQ #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите RabbitMQ сервер Инструкцию по установке можно найти в [официальной документации](https://www.rabbitmq.com/docs/download). #### Шаг 3. Запустите tuna RabbitMQ использует порт `5672` по умолчанию: ```bash tuna tcp 5672 ``` В результате запуска команды на экран будет выведен адрес подключения (например, `ru.tuna.am:12345`), который теперь можно использовать для подключения к RabbitMQ. Вы можете предоставить доступ к RabbitMQ Management, он использует порт `15672` по умолчанию: ```bash tuna http 15672 ``` --- ### tuna и Raspberry Pi #### Шаг 1. Скачайте клиент Зайдите на Raspberry Pi по SSH: ```shell ssh root@raspberrypi.local ``` Установите tuna одной командой: **curl** ```shell sh -c "$(curl -sSLf https://releases.tuna.am/tuna/get.sh)" ``` **wget** ```shell sh -c "$(wget -qO- https://releases.tuna.am/tuna/get.sh)" ``` Установите токен для работы клиента, его можно скопировать на [отдельной странице](https://my.tuna.am/token): ```shell tuna config save-token <ТОКЕН> ``` #### Шаг 2. Запустите tuna ```shell tuna tcp 22 ``` В результате запуска команды на экран будет выведен адрес подключения (например, `ru.tuna.am:12345`), который теперь можно использовать для подключения к SSH серверу на Raspberry Pi, например: ```shell ssh -p 12345 user@ru.tuna.am ``` --- ### tuna и RDP #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите RDP сервер #### Шаг 3. Запустите tuna Как правило, для RDP используется порт `3389`: ```bash tuna tcp 3389 ``` Будьте внимательны, предоставление публичного доступа к подобным службам может быть небезопасно. --- ### tuna и Redis #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите Redis сервер #### Шаг 3. Запустите tuna Redis использует порт `6379` по умолчанию: ```bash tuna redis 6379 ``` В результате запуска команды на экран будет выведен адрес подключения (например, `ru.tuna.am:12345`), который теперь можно использовать для подключения к Redis. При запуске [Redis туннеля](https://tuna.am/docs/tunnels/redis.md) вам будет предоставлена ссылка на инспектор для просмотра сессий и выполняемых команд. --- ### tuna и Robokassa #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите сервер для обработки HTTP-уведомлений Информацию о входящих уведомлениях Robokassa можно найти в [официальной документации](https://docs.robokassa.ru/pay-interface/#notification), там же вы найдете [примеры кода](https://docs.robokassa.ru/code-examples/#notifications). #### Шаг 3. Запустите tuna В аргументах запуска укажите порт вашего сервера: ```bash tuna http 8080 ``` Или с указанием статичного адреса: ```bash tuna http 8080 --subdomain=billing ``` #### Шаг 4. Укажите адрес для входящих уведомлений Из раздела [Мои магазины](https://partner.robokassa.ru/Shops) перейдите в нужный вам магазин, далее, в раздел Настройки на вкладку Технические настройки, здесь в поле Result URL нужно задать адреса для получения уведомлений: ![robokassa](/assets/images/robokassa1-56fce8a6f231b668383b17687a6453f2.png) URL состоит из адреса полученного от tuna (например, `https://billing.ru.tuna.am`) и пути к методу вашего сервера для обработки событий (например, `/payments/pay`). После всех настроек вы можете воспользоваться [тестовыми платежными средствами](https://docs.robokassa.ru/testing-mode/) для отладки взаимодействия. --- ### tuna и ScyllaDB #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите ScyllaDB сервер Инструкцию по установке можно найти в [официальной документации](https://opensource.docs.scylladb.com/stable/getting-started/install-scylla/index.html). #### Шаг 3. Запустите tuna ScyllaDB использует множество портов, описание которых можно найти в [официальной документации](https://opensource.docs.scylladb.com/stable/operating-scylla/admin.html#networking), для предоставления доступа к CQL можно воспользоваться командой: ```shell tuna tcp 9042 ``` Для доступа к REST API: ```shell tuna tcp 10000 ``` --- ### tuna и SMTP #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите SMTP сервер #### Шаг 3. Запустите tuna SMTP сервер использует порт `25` по умолчанию, либо `465` для безопасного соединения: ```bash tuna tcp 25 ``` В результате запуска команды на экран будет выведен адрес подключения (например, `ru.tuna.am:12345`), который теперь можно использовать для подключения к SMTP серверу. --- ### tuna и SSH #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите SSH сервер #### Шаг 3. Запустите tuna SSH сервер использует порт `22` по умолчанию: ```bash tuna tcp 22 ``` В результате запуска команды на экран будет выведен адрес подключения (например, `ru.tuna.am:12345`), который можно использовать для подключения к SSH серверу, например: ```bash ssh -p 12345 user@ru.tuna.am ``` #### Альтернативы У tuna есть встроенный [SSH сервер](https://tuna.am/docs/tunnels/ssh.md), с помощью команды `tuna ssh` можно быстро организовать доступ по SSH без установки и настройки сервера. --- ### tuna и Superset #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите Superset сервер Инструкцию по установке можно найти в [официальной документации](https://apache-superset.readthedocs.io/en/latest/installation.html). #### Шаг 3. Запустите tuna Superset использует порт `8088` по умолчанию: ```bash tuna http 8088 ``` --- ### tuna и Temporal #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите Temporal сервер Инструкцию по настройке окружения можно найти в [официальной документации](https://learn.temporal.io/getting_started/). #### Шаг 3. Запустите tuna Temporal использует порт `7233` по умолчанию для API: ```bash tuna http localhost:7233 ``` И порт `8233` для Web-интерфейса: ```bash tuna http localhost:8233 ``` --- ### tuna и TimescaleDB #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите TimescaleDB сервер Инструкцию по установке можно найти в [официальной документации](https://docs.timescale.com/self-hosted/latest/install/). #### Шаг 3. Запустите tuna TimescaleDB использует порт `5432` по умолчанию: ```bash tuna tcp 5432 ``` --- ### tuna и Transmission #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите transmission-daemon Инструкцию по установке можно найти в [официальной документации](https://transmissionbt.com/download). #### Шаг 3. Запустите tuna transmission-daemon использует порт `9091` по умолчанию: ```bash tuna http 9091 ``` --- ### tuna и Vite #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите Vite сервер Инструкцию по установке можно найти в [официальной документации](https://vitejs.dev/guide/). #### Шаг 3. Запустите tuna Vite сервер использует порт 5173 по умолчанию: ```bash tuna http localhost:5173 ``` --- ### tuna и WampServer #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите WampServer #### Шаг 3. Запустите tuna Специальные настройки не требуются, но для корректного роутинга запросов потребуется передача заголовка `Host`, например: ```shell tuna http --request-header="host:tuna.am" 80 ``` --- ### tuna и WebAsk #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите сервер для обработки событий от WebAsk Информацию о структуре входящий запросов можно узнать в [официальной документации](https://webask.io/help/webhooks). #### Шаг 3. Запустите tuna В аргументах запуска укажите порт вашего сервера: ```bash tuna http 8080 ``` Или с указанием статичного адреса: ```bash tuna http 8080 --subdomain=webask-webhook ``` #### Шаг 4. Создайте новый Webhook Изучите [инструкцию по добавлению Вебхука](https://webask.io/help/webhooks), в качестве значения "URL обратного вызова" укажите адрес полученный от tuna (например, `https://webask-webhook.ru.tuna.am`) и путь к методу вашего сервера для обработки событий (например, `/event`). --- ### tuna и ЮKassa #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите сервер для обработки HTTP-уведомлений Информацию о входящих уведомлениях ЮKassa можно найти в [официальной документации](https://yookassa.ru/developers/using-api/webhooks), там же можно найти инструкцию по созданию [тестового магазина](https://yookassa.ru/developers/payment-acceptance/testing-and-going-live/testing#test-store). #### Шаг 3. Запустите tuna В аргументах запуска укажите порт вашего сервера: ```bash tuna http 8080 ``` Или с указанием статичного адреса: ```bash tuna http 8080 --subdomain=billing ``` #### Шаг 4. Укажите адрес для входящих уведомлений На странице [HTTP-уведомления](https://yookassa.ru/my/merchant/integration/http-notifications), в разделе Интеграция, нужно указать адрес для получения уведомлений, таких как, изменение статуса платежа или возврат: ![yookassa](/assets/images/yookassa1-46e782a6d5ec4f70ea0c4bccb968e144.png) URL состоит из адреса полученного от tuna (например, `https://billing.ru.tuna.am`) и пути к методу вашего сервера для обработки событий (например, `/payments/yookassa`). После всех настроек вы можете воспользоваться [тестовыми платежными средствами](https://yookassa.ru/developers/payment-acceptance/testing-and-going-live/testing#test-bank-card) для отладки взаимодействия. --- ### tuna и Yucca #### Шаг 1. Скачайте клиент Инструкция доступна на [странице](https://tuna.am/docs/guides/install.md). #### Шаг 2. Запустите Yucca сервер Инструкцию по установке можно найти в [официальной документации](https://docs.yucca.app/ru/install/). #### Шаг 3. Запустите tuna Yucca использует порт `9910` по умолчанию: ```bash tuna http 9910 ``` --- ### Инструкции #### [📄️Подключение своего домена](https://tuna.am/docs/tunnels/guides/connect-self-domain.md) [Как подключить свой домен к tuna.am](https://tuna.am/docs/tunnels/guides/connect-self-domain.md) #### [📄️Обнаружение портов](https://tuna.am/docs/tunnels/guides/detect.md) [Запуск своего приложения в обёртке tuna с автоматическим обнаружением порта](https://tuna.am/docs/tunnels/guides/detect.md) #### [📄️Доступные регионы](https://tuna.am/docs/tunnels/guides/locations.md) [Доступные регионы для подключения](https://tuna.am/docs/tunnels/guides/locations.md) #### [📄️Множественный запуск туннелей](https://tuna.am/docs/tunnels/guides/multi-tunnels.md) [Одновременный запуск нескольких туннелей](https://tuna.am/docs/tunnels/guides/multi-tunnels.md) #### [📄️Запуск в обёртке](https://tuna.am/docs/tunnels/guides/run.md) [Запуск своего приложения в обёртке tuna с автоматическим обнаружением порта и созданием туннеля](https://tuna.am/docs/tunnels/guides/run.md) #### [📄️Запуск в фоне](https://tuna.am/docs/tunnels/guides/service.md) [Запуск в фоновом режиме с помощью Systemd](https://tuna.am/docs/tunnels/guides/service.md) #### [📄️HTTP туннели с SSH клиентом](https://tuna.am/docs/tunnels/guides/ssh-reverse.md) [Создание HTTP туннеля с помощью встроенного SSH клиента, без установки tuna](https://tuna.am/docs/tunnels/guides/ssh-reverse.md) --- ### Подключение своего домена В этой статье мы подробно расскажем как подключить к платформе Tuna собственный домен и опубликовать локальный сайт в интернет без публичного IP, сложных конфигураций сети вроде VPN и без публикации кода на какой либо сервер или хостинг. Публикация на собственном домене может быть интересна для Демо стендов, когда вы презентуете какое-то решение заказчику. Клиент видит законченное решение при этом вы не потратили и минуты на подготовку окружения, а также можете править какое-то мелочи прямо на ходу. Впрочем кейсов применения может быть значительно больше. #### Подключение домена ##### Покупка домена Для начала вам понадобится собственный домен (если у вас его нет), вы можете купить его например у [Рег.ру](https://www.reg.ru/?utm_source=tuna.am) или [namecheap](https://www.namecheap.com/?utm_source=tuna.am) или любого другого регистратора доменов. Для примеров в этой статье мы используем домен `tuna-dev.ru`. ##### Подключение к Tuna и получение настроек Перейдите на [страницу управления доменами](https://my.tuna.am/domains) в личном кабинете и нажмите **Добавить домен** cправа вверху. ![](/docs/img/connect-self-domain/add-domain.png) Выберете Регион, Тип - **Свой домен**, в поле Домен введите свой домен. В нашем случае это `api.tuna-dev.ru`. Если у вас Unicode домен например в одной из таких зон `.РФ, .ДЕТИ, .ҚАЗ`, то нужно указывать конвертированный [punycode](https://www.reg.ru/web-tools/punycode?utm_source=tuna.am) вариант. ![](/docs/img/connect-self-domain/adding-in-my.png) После указания своего домена вы увидите нужные настройки для DNS. ##### Настройка DNS Перейдите в панель управления DNS записями. Потребуется создать **CNAME** или **A** запись в настройках DNS вашего домена. Если у вас указана **AAAA** запись для выбранного домена, то её нужно удалить, так как работа по IPv6 пока не поддерживается. ![](/docs/img/connect-self-domain/add-cname.png) ##### Ожидание подтверждения После создания DNS записи, можно вернуться в личный кабинет и нажать **Добавить**, домен перейдёт в режим проверки. ![](/docs/img/connect-self-domain/check-status.png) Валидация обычно занимает от 15 минут до 2 часов, но может растянуться и на пару дней, зависит от TTL на DNS запись. Процесс проверки ограничен **24 часами**, и разбит на 2 основных этапа: * **Проверка DNS** - проверяем, что ваш домен настроен корректно * **Проверка TLS** - выпускаем [Let's Encrypt](https://letsencrypt.org/?utm_source=tuna.am) сертификат для вашего домена Если процесс добавления завершился ошибкой DNS, [проверьте](https://www.reg.ru/nettools/dig?utm_source=tuna.am), что вы верно создали DNS запись и она указывает на нужный сервер. Если всё корректно, возможно ещё не обновился DNS кэш и нужно ждать, тогда просто возобновите проверку. Если процесс добавления завершился ошибкой TLS, проверьте нет ли явных ошибок в настройке DNS: AAAA записи, рекурсивно зацикленные указатели. Если самостоятельно разобраться не получается, обратитесь в [поддержку](mailto:info@tuna.am). ##### Использование После успешной верификации домена, вы получите письмо с уведомлением. ![](/docs/img/connect-self-domain/domain-verified.png) Теперь его можно начать использовать, для этого к команде `tuna http <ваш_порт>` укажите флаг `--domain` или его короткий вариант `-d` или [переменную окружения](https://tuna.am/docs/guides/environment-variables.md) и ваш домен, например: ```shell tuna http 8080 --domain=api.tuna-dev.ru ``` ```shell tuna http 8080 -d api.tuna-dev.ru ``` ```shell export TUNA_DOMAIN=api.tuna-dev.ru tuna http 8080 ``` --- ### Обнаружение портов Если вы хотите лишь обнаружить какой порт начала слушать ваша программа, это можно сделать с помощью команды `tuna detect`. На обнаружение выделяется время, по умолчанию 5 сек, но это поведение можно определить с помощью флага `--seconds` или переменной окружения `TUNA_DETECT_SECONDS`, по истечении этого периода tuna завершит работу и все дочерние процессы. Пример запуска: ```shell tuna detect -- nc -l 23554 ``` Пример работы: ```shell tuna detect -- nc -l 23554 INFO[16:18:12] Waiting for available ports... INFO[16:18:12] 5 INFO[16:18:13] 4 INFO[16:18:13] Found port: 23554 INFO[16:18:14] 3 INFO[16:18:15] 2 INFO[16:18:16] 1 INFO[16:18:17] Here is your tunnel commands: INFO[16:18:17] 1. tuna tcp 23554 ``` ![tuna_detect](/assets/images/tuna_detect-35f718721bdbb52c4189c38be84b54a2.gif) --- ### Доступные регионы Регион определяет через какой туннельный сервер будет происходить подключение, в настоящий момент доступно 2 региона: | Регион | Код | По умолчанию | | ---------- | ---- | ------------ | | Россия | `ru` | \* | | Нидерланды | `nl` | | Вы можете переопределить регион через: 1. [Конфигурационный файл](https://tuna.am/docs/guides/config-file.md): Отредактируйте параметр в файле: ```shell location: nl ``` Или задайте его командой: ```shell tuna config save-location nl ``` 2. [Переменную окружения](https://tuna.am/docs/guides/environment-variables.md): ```shell TUNA_LOCATION=ru ``` 3. Аргумент командной строки: ```shell tuna http 8080 --location=nl ``` --- ### Множественный запуск туннелей В проектах где нужно опубликовать несколько сервисов, может потребоваться запустить сразу несколько туннелей. примечание Все актуальные флаги, подсказки и примеры можно посмотреть вызвав справку: ```shell tuna start --help ``` #### Конфигурация Вы можете описать все туннели в глобальном [конфигурационном файле](https://tuna.am/docs/guides/config-file.md) или локальном (только для секции **tunnels**). Если текущем каталоге найден локальный файл по имени `.tuna.yml`, то он переопределяет секцию `tunnels` из глобального. Так вы можете создать `.tuna.yml` в корне репозитория и это сразу будет работать для всех разработчиков в команде. Путь к локальному файлу можно переопределить с помощью флага `--tunnels-file` или переменной окружения `TUNA_START_TUNNELS_FILE` к команде `tuna start`. ```shell tuna start --tunnels-file=/ваш/путь/.tuna.yml web ``` Пример конфигурации, где описан запуск четырех туннелей: ```yaml --- tunnels: web: commandLine: tuna http localhost:5173 --subdomain=web tags: [frontend, ui] api: commandLine: tuna http 8080 --subdomain=api tags: [backend, api] postgres: commandLine: tuna tcp 5432 --port=postgres tags: backend redis: commandLine: tuna tcp 6379 --port=redis tags: frontend ``` Из чего состоит каждый сервис на примере первого: ```yaml web: commandLine: tuna http localhost:5173 --subdomain=web tags: [frontend, ui] ``` 1. `web` - имя туннеля, должно быть уникальным в списке всех туннелей 2. `commandLine` - команда для создания туннеля 3. `tags` - необязательное поле, может содержать строку или список строк. Тегами можно определять запуск части туннелей. #### Запуск За запуск отвечает команда `tuna start`, можно разделять запуск в зависимости от потребностей. ##### По имени сервиса Запустить туннель только для сервиса api: ```shell tuna start api ``` Запустить туннель только для api и postgres: ```shell tuna start api postgres ``` Передать имя можно и в переменной окружения `TUNA_START`: ```shell export TUNA_START="api" tuna start ``` ##### По тегу Запустить все туннели с тегом `frontend`: ```shell tuna start --tags=frontend ``` Запустить все туннели с тегом `frontend` или `backend`: ```shell tuna start --tags=frontend,backend ``` Передать tags можно и в переменной окружения `TUNA_START_TAGS`: ```shell export TUNA_START_TAGS="frontend" tuna start ``` ##### Все сразу Запустить все описанные туннели: ```shell tuna start --all ``` Или с переменной окружения `TUNA_START_ALL`: ```shell export TUNA_START_ALL=true tuna start ``` --- ### Запуск в обёртке Вы можете запустить своё приложение обёрнутое в запуск через tuna, тогда порт который слушает ваш сервер будет обнаружен автоматически и для него будет запущен туннель. Если при проверке tuna сможет получить ответ на HTTP запрос от приложения, то стартует HTTP туннель с динамическим поддоменом, иначе TCP. #### Пример Пример использования описан у нас в [блоге](https://tuna.am/blog/invoices.md#tuna-run). ![tuna_run](/assets/images/tuna_run-6efa86afeb5224d166817a19bbc239f1.gif) #### Запуск Запуск осуществляется командой `tuna run`. Пример с JavaScript приложением: ```shell tuna run -- yarn start ``` Пример с Python: ```shell tuna run -- python3 -m http.server 8000 ``` --- ### Запуск процесса в фоновом режиме, как сервис Фоновый запуск полезен, если вы хотите организовать постоянный доступ извне к службам или панели управления на удалённом компьютере. #### Создание и управление сервисами Создание и управление сервисами доступно во всех поддерживаемых платформах. Для создания работы с сервисами используется команда `tuna service` или `tuna svc`. примечание Все актуальные флаги, подсказки и примеры можно посмотреть вызвав справку: ```shell tuna service --help tuna service install --help tuna service start --help tuna service restart --help tuna service stop --help tuna service uninstall --help ``` ##### Создание сервиса к сведению В Windows нужно выполнять команды в PowerShell от имени администратора, в Linux и FreeBSD потребуется sudo или root пользователь. В macOS сервис создаётся под текущим пользователем и привилегии не нужны. Команда `tuna service install` указывает, что нужно зарегистрировать новый сервис. Можно создать несколько сервисов с разными именами, передавая имя через флаг `--name` или переменную окружения `TUNA_SERVICE_NAME`, по умолчанию **tuna**. После `--` описывается команда которая будет запускаться в сервисе. ```shell tuna service install -- tuna --config=С:\Users\Administrator\AppData\Local\tuna\tuna.yml http 8080 --subdomain=web ``` В примере выше явно передан полный путь к [конфигурационному файлу](https://tuna.am/docs/guides/config-file.md), это может быть необходимо так как сервис создаётся из под администратора, а файл с токеном находится в профиле текущего пользователя. С большей вероятностью это потребуется в Windows, Linux и FreeBSD и не потребуется в macOS. Также вы можете передать токен явно в аргументах: ```shell tuna service install --name=tuna-web -- tuna http 8080 --subdomain=web --token= ``` Для большей безопасности в Linux, FreeBSD и macOS токен будет вырезан из аргументов запуска и передан как переменная окружения, так что вы не увидите токен в списке процессов. Внимание Так как в Windows, Linux и FreeBSD сервис создаётся от привилегированного пользователя, по умолчанию процесс будет также запущен от него, в целях безопасности не рекомендуется запускать tuna от привилегированного пользователя. Поэтому вы можете указать явно пользователя от имени которого будет запускаться процесс с помощью флага `--user`или переменную окружения `TUNA_SERVICE_INSTALL_USER`. В Windows также может потребоваться передать и пароль пользователя с помощью флага `--password`или переменную окружения `TUNA_SERVICE_INSTALL_PASSWORD`. ```shell tuna service install --user=ubuntu -- tuna http 8080 --subdomain=web --token= ``` ##### Запуск сервиса Запуск осуществляется командой `tuna service start`. Пример с передачей имени: ```shell tuna service start --name=tuna-web ``` ##### Перезапуск сервиса Перезапуск осуществляется командой `tuna service restart`. Пример с передачей имени: ```shell tuna service restart --name=tuna-web ``` ##### Проверка статуса сервиса Проверка статуса осуществляется командой `tuna service status`. Пример с передачей имени: ```shell tuna service status --name=tuna-web ``` ##### Остановка сервиса Остановка осуществляется командой `tuna service stop`. Пример с передачей имени: ```shell tuna service stop --name=tuna-web ``` ##### Удаление сервиса Удаление осуществляется командой `tuna service uninstall`. Пример с передачей имени: ```shell tuna service uninstall --name=tuna-web ``` #### Отладка и поиск проблем Если сервис не работает или работает некорректно, в первую очередь необходимо проверить журналы сервиса. Tuna представляет лишь верхнеуровневую обвязку для создания и запуска сервиса, способ отладки будет зависеть от вашей системы. **Windows** Для управления службой tuna в Windows, можно воспользоваться инструментом **Службы (Services)**. В списке служб найдите `tuna` (или имя вашей службы). Щелкните правой кнопкой мыши на службу и выберите нужное действие: Запустить, Остановить или Перезапустить. Для просмотра журналов службы tuna, можно воспользоваться инструментом **Просмотр событий (Event Viewer)** или PowerShell. В **Просмотре событий** откройте **Windows Logs > Application или System**, чтобы найти журналы, связанные с вашей службой. Просмотр журналов через PowerShell: ```powershell Get-EventLog -LogName System -Source tuna ``` **macOS** подсказка По умолчанию macOS имеет политики управления энергией, которые заставляют компьютер засыпать и тогда сервис станет недоступным, но это поведение можно настроить, если вы хотите использовать компьютер с macOS в режиме сервера. Посмотреть текущий план питания можно с помощью команды `pmset -g`. Для постоянной работы в фоне выставьте следующие значения: ```shell sudo pmset -a sleep 0 sudo pmset -a autorestart 1 sudo pmset -a networkoversleep 1 sudo pmset -a tcpkeepalive 1 sudo pmset -a powernap 0 sudo pmset -a womp 1 ``` При создании сервиса будет создан файл `<имя_сервиса>.plist` в директории `~/Library/LaunchAgents`. Для управления сервисом используйте команду `launchctl`. Для просмотра журналов откройте приложение **Console из Applications > Utilities**, перейдите к разделу `system.log` или используйте поисковую строку для поиска по ключевым словам, таким как `tuna`. Просмотр журналов в терминале: ```shell log show --predicate 'process == "tuna"' --info ``` **Linux** примечание Отладка описана только для **systemd**, если вы используете дистрибутив с **sysvinit** или **openrc** мы предполагаем, что вы опытный пользователь Linux и сможете самостоятельно отладить работу сервиса. При создании сервиса будет создан файл `<имя_сервиса>.service` в директории `/etc/systemd/system`. Для управления сервисом используйте команду `systemctl`. Просмотр журналов: ```shell sudo journalctl -xe -f -u <имя_сервиса> ``` **FreeBSD** При создании сервиса будет создан файл `<имя_сервиса>` в директории `/usr/local/etc/rc.d/`. Для управления сервисом используйте команду `service`. По умолчанию stdout и stderr должен собираться в системный журнал. #### Запуск сервиса в Docker Compose В качестве альтернативы можно использовать запуск сервиса с Docker Compose Создайте `compose.yml` файл с описанием сервиса: ```yaml --- name: tuna services: web: image: yuccastream/tuna:latest command: http 3000 --subdomain=web restart: always network_mode: "host" environment: - TUNA_TOKEN=<ваш_токен> ``` Важно Опция `network_mode: "host"`, аналог `--net=host`, по умолчанию доступна только в Linux. Чтобы это заработало в Windows и macOS требуется включить эту бета функцию в Docker Desktop. Чтобы включить эту функцию, перейдите на вкладку **Features in development** в **Settings** , а затем выберите **Enable host networking**. Запуск сервиса: ```shell docker compose up -d ``` Остановка сервиса: ```shell docker compose down -v ``` Просмотр журналов: ```shell docker compose -f web ``` --- ### HTTP туннели с SSH клиентом Обратный SSH туннель `ssh -R` - это альтернативный механизм создания туннеля без установки и использования клиента **tuna**. Для создания туннеля используется стандартный SSH клиент, как правило, он присутствует во всех Unix подобных ОС. Внимание Функция на стадии BETA тестирования, в настоящий момент поддерживается создание только HTTP туннелей с динамическим поддоменом. #### Запуск Для начала добавьте ваш публичный [SSH ключ](https://my.tuna.am/public_keys), сразу после этого можете подключаться. Например, HTTP туннель для сервиса на порту 8080: ```shell ssh -R 443:localhost:8080 ssh-ru.tuna.am http ``` ![](/docs/img/ssh-r.gif) --- ### HTTP туннель Начиная с версии **0.36.0** tuna показывает в терминале [полноэкранный интерфейс](https://tuna.am/docs/tunnels/tui.md) с лентой запросов, их деталями и повтором. HTTP туннель открывает доступ из интернета к сайту, API, GraphQL или WebSocket-серверу, запущенному у вас локально. Туннели работают на всех тарифах без ограничения по времени. На бесплатном тарифе доступны динамический адрес и один [бесплатный постоянный поддомен](#free-subdomain). #### Быстрый старт ```shell tuna http 8080 ``` В консоли появится публичный HTTPS-адрес вида `https://4l7mqf-212-49-103-2.ru.tuna.am` — запросы на него попадут в приложение на `localhost:8080`. Рядом будет ссылка на [инспектор запросов](https://tuna.am/docs/tunnels/http/inspect.md), где видно каждый запрос и ответ. примечание Все флаги с подсказками — в справке: ```shell tuna http --help ``` У каждого флага есть [переменная окружения](https://tuna.am/docs/guides/environment-variables.md) — см. [справочник флагов](#flags). #### Готовые сценарии Флаги свободно комбинируются. Несколько типовых задач: | Задача | Команда | | --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | | Показать сайт заказчику под паролем по постоянному адресу | `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"` | | Открыть сервис, который проверяет заголовок `Host` | `tuna http 11434 --request-header="host:localhost:11434"` | | Опубликовать собранный SPA (React, Vue) | `tuna http --file-server-spa ./dist` | В Docker, CI и systemd удобнее передавать те же настройки переменными окружения: ```shell TUNA_TOKEN=tt_*** TUNA_SUBDOMAIN=brave-otter-4821 TUNA_INSPECT=false tuna http 8080 ``` #### Что можно опубликовать Первый аргумент `tuna http` — адрес приложения, которое нужно открыть: | Аргумент | Куда уйдёт запрос | | --------------------------------- | ------------------------------------------------------------- | | `8080` | `http://localhost:8080` | | `localhost:8080`, `10.0.0.1:8080` | указанный хост и порт, в том числе другая машина в вашей сети | | `https://localhost:443` | приложение, которое само принимает HTTPS | | `unix:///run/gunicorn.sock` | приложение на unix-сокете | Вместо адреса можно раздать каталог встроенным сервером: [`--file-server`](#file-server), [`--file-server-spa`](#spa) или [`--webdav`](#webdav). ##### Приложение на HTTPS ```shell tuna http https://localhost:443 ``` По умолчанию сертификат приложения не проверяется, подойдёт и самоподписанный. Включить проверку — `--tls-skip-verify=false`. ##### Unix-сокет Если приложение принимает HTTP на unix-сокете, как, например, gunicorn, укажите путь к сокету с префиксом `unix://`: ```shell tuna http unix:///run/gunicorn.sock ``` [Инспектор](https://tuna.am/docs/tunnels/http/inspect.md), повтор запросов и [политики трафика](https://tuna.am/docs/traffic-policy.md) работают так же, как с портом. TLS к приложению за сокетом не поддерживается, флаг `--tls-skip-verify` к нему не применяется. Если приложение не отвечает, на странице ошибки 502 будет указан путь к сокету (`unix:///run/gunicorn.sock`), а не `localhost` с портом. Требования к пути, права доступа и поведение при отсутствии сокета те же, что у [TCP-туннеля](https://tuna.am/docs/tunnels/tcp.md#unix-socket). ##### Файловый сервер Отдаёт файлы из каталога и показывает список файлов: ```shell tuna http --file-server ./ ``` ##### Одностраничное приложение (SPA) Для собранных [одностраничных приложений](https://ru.wikipedia.org/wiki/%D0%9E%D0%B4%D0%BD%D0%BE%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5) (React, Vue, Angular): на любой несуществующий путь отдаётся `index.html`, поэтому работает клиентский роутинг. ```shell tuna http --file-server-spa ./dist ``` ##### WebDAV Каталог можно подключить как сетевой диск по протоколу WebDAV — с чтением и записью: ```shell tuna http --webdav ./ ``` warning Файловый сервер и WebDAV открывают каталог всему интернету. Закройте доступ [паролем](#basic-auth) или [ключом](#key-auth). #### Адрес туннеля | Адрес | Как получить | Тариф | | ---------------------------------------------------- | ---------------------------- | ------------------------------------ | | Динамический, `4l7mqf-212-49-103-2.ru.tuna.am` | без флагов | любой | | Бесплатный постоянный, `brave-otter-4821.ru.tuna.am` | `--subdomain=<ваш-поддомен>` | любой, один на аккаунт | | Любой свободный поддомен, `billing.ru.tuna.am` | `--subdomain=billing` | [подписка](https://tuna.am/#pricing) | | Собственный домен, `api.example.com` | `--domain=api.example.com` | [подписка](https://tuna.am/#pricing) | Защита от злоупотреблений На бесплатном тарифе посетитель из браузера при первом заходе видит страницу-предупреждение о том, что сайт открыт через tuna. API-клиентов и вебхуки она не касается, а пропустить её можно заголовком `tuna-skip-browser-warning`. Зачем это нужно и как мы в целом боремся с фишингом и вредоносным контентом — на странице [Злоупотребления и жалобы](https://tuna.am/docs/abuse.md). ##### Динамический адрес Выдаётся автоматически при каждом запуске и меняется при переподключении. Адрес строится по схеме `<случайная-часть>-<ваш-IP>.<локация>.tuna.am`: IP-адрес источника виден в ссылке, так что анонимно разместить вредоносный контент не получится — подробнее в разделе [Анонимность](https://tuna.am/docs/abuse.md#%D0%B0%D0%BD%D0%BE%D0%BD%D0%B8%D0%BC%D0%BD%D0%BE%D1%81%D1%82%D1%8C). В постоянном поддомене IP-адреса нет. Подходит для разовой демонстрации или отладки. Если нужен адрес, который не изменится, — для вебхуков, колбэков платёжных систем, закладки в браузере — используйте постоянный поддомен. ##### Бесплатный постоянный поддомен У каждого пользователя есть один постоянный поддомен — бесплатно и на любом тарифе. Имя выдаётся случайно в формате `<прилагательное>-<существительное>-<4 цифры>`, например `brave-otter-4821`, и одинаково во всех локациях: `brave-otter-4821.ru.tuna.am` и `brave-otter-4821.nl.tuna.am`. Свой поддомен можно посмотреть в [личном кабинете](https://my.tuna.am/domains): он отмечен меткой «Бесплатный», рядом готовая команда запуска. Также его подсказывает клиент при запуске туннеля без флагов: ```shell Your permanent free domain: brave-otter-4821.ru.tuna.am. Use it with --subdomain=brave-otter-4821 ``` По умолчанию туннель, как и раньше, получает динамический адрес — постоянный поддомен нужно указать явно: ```shell tuna http 8080 --subdomain=brave-otter-4821 ``` В другой локации: ```shell tuna http 8080 --subdomain=brave-otter-4821 --location=nl ``` Или полным именем: ```shell tuna http 8080 --domain=brave-otter-4821.ru.tuna.am ``` Нужен токен Поддомен привязан к вашему аккаунту, поэтому клиент должен быть авторизован вашим токеном. Сохраните его один раз командой `tuna login` или `tuna config save-token <ТОКЕН>` (токен есть на [отдельной странице](https://my.tuna.am/token)), либо передавайте через переменную окружения `TUNA_TOKEN` — например, в Docker и CI. Без токена или с токеном другого аккаунта поддомен не заработает. * Выбрать или сменить имя нельзя — поддомен с любым именем доступен по [подписке](https://tuna.am/#pricing). * Удалить поддомен или передать его другому пользователю нельзя, `tuna domain clear` его пропускает. * При смене тарифа поддомен сохраняется и не расходует лимит доменов подписки. * Если вы зарегистрировались раньше, поддомен появится при первом открытии раздела [Домены](https://my.tuna.am/domains) или при первом запуске туннеля без флагов. ##### Зарезервированный поддомен По подписке можно занять любой свободный поддомен — после перезапуска туннеля адрес останется прежним: ```shell tuna http 8080 --subdomain=billing ``` То же через [переменную окружения](https://tuna.am/docs/guides/environment-variables.md): ```shell TUNA_SUBDOMAIN="billing" tuna http 8080 ``` Поддомен резервируется автоматически при первом запуске с флагом. Все ваши домены — в [личном кабинете](https://my.tuna.am/domains). Внимание Ошибка `Domain already reserved` означает, что поддомен в этой локации уже занят другим пользователем — выберите другое имя. ##### Собственный домен Добавьте **свой домен** следуя инструкциям в [личном кабинете](https://my.tuna.am/domains), после проверки DNS и выпуска Let's Encrypt сертификата можно пользоваться: ```shell tuna http 8080 --domain=my-api-project.example.com ``` Пошагово — в статье [Подключение своего домена](https://tuna.am/docs/tunnels/guides/connect-self-domain.md). ##### Локация Туннель поднимается в [локации](https://tuna.am/docs/tunnels/guides/locations.md) `ru`, если не указано иное. Выберите ближайшую к пользователям сайта: ```shell tuna http 8080 --location=nl ``` ##### QR-код Флаг `--qr` печатает в консоли QR-код со ссылкой на туннель — удобно, чтобы открыть сайт на телефоне. ```shell tuna http 5173 --qr ``` ![](/docs/img/examples/qr.png) #### Защита доступа Туннель доступен всему интернету. Проверки ниже выполняются в клиенте tuna — запрос, который их не прошёл, до приложения не дойдёт. | Флаг | Кого пропускает | | ---------------------------------------- | -------------------------------------- | | [`--basic-auth`](#basic-auth) | знающих логин и пароль | | [`--key-auth`](#key-auth) | запросы с ключом в заголовке `X-Token` | | [`--cidr-allow`, `--cidr-deny`](#cidr) | запросы из разрешённых подсетей | | [`--ua-allow`, `--ua-deny`](#user-agent) | запросы с подходящим `User-Agent` | | [`--verify-webhook`](#verify-webhook) | вебхуки с верной подписью | | [`--rate-limit`](#rate-limit) | не больше N запросов в секунду | | [`--https-redirect`](#https-redirect) | только HTTPS, HTTP перенаправляется | Флаги со списками (`--basic-auth`, `--key-auth`, `--cidr-*`, `--ua-*`, `--*-header`) можно повторять. В переменных окружения значения перечисляются через запятую. ##### Пароль (basic auth) Браузер покажет окно ввода логина и пароля: ```shell tuna http 8080 --basic-auth="login:password" ``` Несколько пользователей — повторите флаг: ```shell tuna http 8080 --basic-auth="anna:pass1" --basic-auth="ivan:pass2" ``` Из скрипта: ```shell curl -u login:password https://brave-otter-4821.ru.tuna.am/ ``` ##### Ключ в заголовке (API token) Для API и сервисов без браузера. Запрос пройдёт, только если в заголовке `X-Token` передан один из ключей: ```shell tuna http 8080 --key-auth="my-secret-key" ``` ```shell curl -H "X-Token: my-secret-key" https://brave-otter-4821.ru.tuna.am/ ``` ##### Доступ по подсетям IP Белый список [подсетей](https://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%B4%D1%81%D0%B5%D1%82%D1%8C) в CIDR-формате — остальным доступ закрыт: ```shell tuna http 8080 --cidr-allow="203.0.113.0/24" --cidr-allow="198.51.100.7/32" ``` Или, наоборот, закрыть доступ отдельным подсетям: ```shell tuna http 8080 --cidr-deny="10.0.0.1/32" ``` ##### Доступ по User-Agent Совпадение ищется по подстроке. Запретить `curl` и разрешить всех остальных: ```shell tuna http 8080 --ua-deny=curl ``` Разрешить только Chrome: ```shell tuna http 8080 --ua-allow=Chrome ``` примечание `User-Agent` легко подделать — используйте этот фильтр против ботов и случайных сканеров, а не как защиту. ##### Проверка подписи вебхуков tuna пропустит только вебхуки, подписанные секретом, который вы задали у провайдера. Остальные запросы получат `401 Unauthorized`. ```shell tuna http 8080 --verify-webhook=gitlab --verify-webhook-secret=1234 ``` Поддерживаемые провайдеры: `gitlab`, `github`, `sentry`, `linear`. Для других сервисов и более сложной логики используйте [политики трафика](https://tuna.am/docs/traffic-policy.md). ##### Ограничение частоты запросов (rate limit) Защитит локальное приложение от перегрузки — не больше N запросов в секунду: ```shell tuna http 8080 --rate-limit=2 ``` При превышении лимита клиент получит `429 Too Many Requests`. ##### Только HTTPS Туннель по умолчанию отвечает и по HTTP, и по HTTPS. С флагом `--https-redirect` запросы по HTTP перенаправляются на HTTPS: ```shell tuna http 8080 --https-redirect ``` #### Заголовки и CORS ##### Заголовки запроса Добавить или заменить заголовок до того, как запрос попадёт в приложение. Частый случай — сервис принимает запросы только со «своим» `Host`, как Ollama или dev-серверы: ```shell tuna http 11434 --request-header="host:localhost:11434" ``` ##### Заголовки ответа Добавить или заменить заголовок в ответе клиенту: ```shell tuna http 8080 --response-header="env:test" --response-header="x-robots-tag:noindex" ``` ##### CORS Флаг `--cors` или переменная `TUNA_CORS=true` добавит CORS заголовки ко всем ответам. По умолчанию выставляются следующие заголовки: ```shell 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`](#response-header). Запросы типа **OPTIONS** обрабатываются автоматически `200 OK`, не доходя до проксируемого сервера. примечание Если у вас возникают сложности в работе с CORS, рекомендуем ознакомиться с [данной статьёй](https://habr.com/ru/companies/macloud/articles/553826/). Так же рекомендуем [CORS Tester](https://corsfix.com/tools/cors-tester) для проверки ваших CORS заголовков. #### Другие возможности ##### Политики трафика Когда флагов не хватает — маршрутизация по путям, условия, свои ответы — опишите правила в файле [политик трафика](https://tuna.am/docs/traffic-policy.md). По умолчанию читается `.tuna.yml` из текущего каталога, другой путь — `--policy-file`. Флаг `--policy-url` загружает правила по [ссылке](https://tuna.am/docs/traffic-policy.md#policy-url). Ошибка в политике останавливает запуск туннеля, подробнее — в разделе [Ошибки политики](https://tuna.am/docs/traffic-policy.md#policy-errors). ##### Инспектор запросов Включён по умолчанию и доступен на `http://127.0.0.1:4040`. Инспектор хранит запросы в памяти, поэтому на серверах и встраиваемых устройствах его лучше выключать: `--inspect=false`. Подробнее — на странице [инспектора](https://tuna.am/docs/tunnels/http/inspect.md). ##### Отчёты об ошибках Флаг `--capture-key` встраивает в HTML-страницы виджет [отчётов](https://tuna.am/docs/reports.md): тестировщик отправляет баг со скриншотом, не меняя код сайта. ```shell tuna http 3000 --capture-key=YOUR_CAPTURE_KEY ``` ##### Токен Обычно токен сохраняется один раз командой `tuna login`. Указать другой токен можно флагом `--token` или переменной `TUNA_TOKEN`, переопределение идёт по [очерёдности конфигурации](https://tuna.am/docs/guides/config-ordering.md): ```shell tuna http 8080 --token=tt_*** ``` #### Справочник флагов | Флаг | Переменная окружения | Описание | | ------------------------- | ---------------------------- | -------------------------------------------------------------------------- | | `-s`, `--subdomain` | `TUNA_SUBDOMAIN` | [Поддомен](#address) в зоне tuna.am | | `-d`, `--domain` | `TUNA_DOMAIN` | [Полное имя домена](#custom-domain) | | `-l`, `--location` | `TUNA_LOCATION` | [Локация](#location): `ru` (по умолчанию), `nl` | | `-f`, `--file-server` | `TUNA_FILE_SERVER` | [Раздать каталог](#file-server) | | `-F`, `--file-server-spa` | `TUNA_FILE_SERVER_SPA` | [Раздать SPA](#spa) | | `--webdav` | `TUNA_WEBDAV` | [WebDAV-сервер](#webdav) для каталога | | `--basic-auth` | `TUNA_BASIC_AUTH` | [Логин и пароль](#basic-auth), `login:password` | | `--key-auth` | `TUNA_KEY_AUTH` | [Ключ](#key-auth) в заголовке `X-Token` | | `--cidr-allow` | `TUNA_CIDR_ALLOW` | [Разрешённые подсети](#cidr) | | `--cidr-deny` | `TUNA_CIDR_DENY` | [Запрещённые подсети](#cidr) | | `--ua-allow` | `TUNA_UA_ALLOW` | [Разрешённые User-Agent](#user-agent) | | `--ua-deny` | `TUNA_UA_DENY` | [Запрещённые User-Agent](#user-agent) | | `--verify-webhook` | `TUNA_VERIFY_WEBHOOK` | [Провайдер вебхуков](#verify-webhook) | | `--verify-webhook-secret` | `TUNA_VERIFY_WEBHOOK_SECRET` | Секрет подписи вебхуков | | `--rate-limit` | `TUNA_RATE_LIMIT` | [Запросов в секунду](#rate-limit) | | `--https-redirect` | `TUNA_HTTPS_REDIRECT` | [Перенаправлять HTTP на HTTPS](#https-redirect) | | `--request-header` | `TUNA_REQUEST_HEADER` | [Заголовок запроса](#request-header), `key:value` | | `--response-header` | `TUNA_RESPONSE_HEADER` | [Заголовок ответа](#response-header), `key:value` | | `--cors` | `TUNA_CORS` | [CORS-заголовки](#cors) и ответ на `OPTIONS` | | `--policy-file` | `TUNA_POLICY_FILE` | [Файл политик](#traffic-policy), по умолчанию `.tuna.yml` | | `--policy-url` | `TUNA_POLICY_URL` | [Ссылка на политики](#traffic-policy), только https | | `--inspect` | `TUNA_INSPECT` | [Инспектор](#inspect), по умолчанию включён | | `--tls-skip-verify` | `TUNA_TLS_SKIP_VERIFY` | [Не проверять сертификат](#https-upstream) приложения, по умолчанию `true` | | `--qr` | `TUNA_QR_CODE` | [QR-код](#qr) со ссылкой | | `--capture-key` | `TUNA_CAPTURE_KEY` | [Виджет отчётов](#capture-key) | | `--token` | `TUNA_TOKEN` | [Токен](#token) авторизации | #### Поведение ##### Hop-by-hop **НЕ** поддерживаются hop-by-hop заголовки за исключением заголовка `Connection: upgrade`, необходимого для работы Websocket соединений. ##### WebSocket Поддерживается протокол с двусторонним соединением между клиентом (например, браузером) и сервером, дополнительные настройки не требуются. Передаваемые данные **НЕ** будут отображены в [инспекторе](https://tuna.am/docs/tunnels/http/inspect.md). ##### Server-sent events Поддерживается технология отправки уведомлений от сервера к веб-браузеру, никакие дополнительные настройки не требуются. Передаваемые данные **НЕ** будут отображены в [инспекторе](https://tuna.am/docs/tunnels/http/inspect.md). примечание При включенном инспекторе важно, что бы клиент отправлял заголовок `Accept: text/event-stream`, иначе инспектор будет пытаться перехватить запрос и это вызовет задержки. Браузер передаёт этот заголовок по умолчанию. ##### HTTP и HTTPS При старте туннеля отображается ссылка на HTTPS, но обращаться можно и по HTTP. Запретить обращение по HTTP можно добавив флаг `--https-redirect`. ##### Порядок обработки флагов и правил Флаги влияющие на поведение обработки трафика всегда выполняются в определённой последовательности, вне зависимости от того в какой очерёдности они переданы в аргументах. 1. [https-redirect](#https-redirect) 2. [cors](#cors) 3. [cidr-allow](#cidr) 4. [cidr-deny](#cidr) 5. [ua-allow](#user-agent) 6. [ua-deny](#user-agent) 7. [rate-limit](#rate-limit) 8. [key-auth](#key-auth) 9. [basic-auth](#basic-auth) 10. [policy-file / policy-url](#traffic-policy) 11. [verify-webhook](#verify-webhook) 12. [request-header](#request-header) 13. [response-header](#response-header) ##### Самостоятельное управление CORS заголовками Если вы хотите управлять CORS заголовками самостоятельно на нижестоящем сервере и при этом используете авторизацию в tuna при помощи `--basic-auth` или `--key-auth`. То [**Preflight запросы**](https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request) - **не будут работать**, так как эти *OPTIONS* запросы не содержат `Authorization`, `X-Token` и любые другие специфичные заголовки. Решение на выбор: 1. Не использовать авторизацию в tuna. 2. Управлять CORS заголовками в tuna, а не самостоятельно. 3. Обрабатывать `OPTIONS` и авторизацию отдельно при помощи более гибких [политик трафика](https://tuna.am/docs/traffic-policy.md). ❓ Как это выглядит на схеме ###### Случай 1 Вы управляете CORS на нижестоящем Caddy сервере и включаете авторизацию в tuna. ![Схема изобращающая Случай 1](/docs/img/tunnels/cors/case1.png) ###### Случай 2 Вы управляете CORS на нижестоящем Caddy сервере и **НЕ** включаете авторизацию в tuna. ![Схема изобращающая Случай 2](/docs/img/tunnels/cors/case2.png) ###### Случай 3 Вы управляете CORS и авторизацией в tuna. ![Схема изобращающая Случай 3](/docs/img/tunnels/cors/case3.png) --- ### Инспектор запросов #### Обзор В инспекторе запросов можно производить отладку входящих запросов, смотреть заголовки и другую информацию, которая может облегчить работу при разработке приложений. Он доступен для команд `tuna http`, `tuna postgres`, `tuna redis` и управляется флагом `--inspect` или переменной окружения `TUNA_INSPECT`. #### Управление Инспектор запросов включен по умолчанию и доступен по адресу `http://127.0.0.1:4040`, если порт `4040` занят, то будет выбран следующий по списку свободный. Выключить инспектор можно флагом `--inspect=false` или переменной `TUNA_INSPECT=false`. Адрес или порт можно переопределить с помощью переменной окружения `TUNA_INSPECT_ADDR` или параметра `inspectAddr` в [конфигурационном файле](https://tuna.am/docs/guides/config-file.md). * `TUNA_INSPECT_ADDR=0.0.0.0` - слушать на всех интерфейсах * `TUNA_INSPECT_ADDR=0.0.0.0:8080` - слушать на всех интерфейсах на порту `8080`, если порт занят, то будет выбран следующий по списку свободный * `TUNA_INSPECT_ADDR=8080` - слушать на адресе `127.0.0.1` на порту `8080`, если порт занят, то будет выбран следующий по списку свободный Потребление оперативной памяти Инспектор хранит запросы в оперативной памяти. Отключайте инспектор (`--inspect=false`) в продакшене и на встраиваемых устройствах (IP-KVM, Raspberry Pi и т.д.) чтобы не допустить утечек памяти. Итоговый адрес будет написан в консоли при запуске: ![inspector-link](/docs/img/examples/inspect1.png) #### Интерфейс Перейдя по ссылке вы увидите минималистичный WEB интерфейс с списком выполненных запросов, в любой запрос можно перейти и посмотреть более подробную информацию о заголовках и прочем. ##### Список запросов ![list](/docs/img/inspect/list.png) Вы также можете повторять запросы, в том числе с изменением. ![repeat](/docs/img/inspect/repeat.png) ##### Настройки Тут отображается общая информация и текущая конфигурация [политик трафика](https://tuna.am/docs/traffic-policy.md). ![settings](/docs/img/inspect/settings.png) ##### Инструменты Для большего удобства мы встроили инструменты разработчика прямо в инспектор. ![tools](/docs/img/inspect/tools.png) На отдельной вкладке вы можете найти: * CSV в JSON * Base64 Encode/Decode * JSON Форматер * YAML в JSON * URL Encode/Decode * Timestamp в Дату * Query-параметры в JSON * JSON в CSV * JSON в YAML * Конвертер Систем Счисления * Regex Тестер * JWT Парсер * Hash Генератор * UUID Генератор * Lorem Ipsum Генератор *Если вы не нашли нужный инструмент, [напишите нам](mailto:info@tuna.am) и мы рассмотрим запрос.* ##### QR-код В QR-коде содержится ссылка на туннель, это удобно для мобильных устройств. ![qr](/docs/img/inspect/qr.png) --- ### Kubernetes туннель к сведению Доступно только по [подписке](https://tuna.am/#pricing). #### Обзор Kubernetes туннель даёт коллеге или подрядчику временный доступ к вашему кластеру через обычный `kubectl`: без VPN, без открытия API-сервера наружу и без передачи ваших учётных данных. Клиент читает локальный kubeconfig, поднимает reverse-proxy к API-серверу и HTTP-туннель к нему. Гость получает одноразовую ссылку на готовый kubeconfig. В нём адрес туннеля с валидным TLS-сертификатом и гостевой токен. Прокси проверяет этот токен и подставляет вместо него ваши настоящие учётные данные, поэтому они не покидают вашу машину. #### Быстрый старт ```shell tuna kubernetes --context=staging --service-account=shop/debug --ttl=4h ``` Клиент откроет терминальный интерфейс: в шапке видны сервисный аккаунт, namespace, ограничения и срок действия, ниже — лента запросов гостя. Инструкция для гостя: ```shell curl -sfO https://<адрес туннеля>/tuna/<секрет>/kubeconfig.yaml KUBECONFIG=./kubeconfig.yaml kubectl get pods ``` Через туннель работают `get`, `list`, `watch`, `logs`, `exec` (включая stdin), `port-forward`, `pods/proxy` и запись: `scale`, `create`, `delete`. Запросы гостя видны в [инспекторе](https://tuna.am/docs/tunnels/http/inspect.md) как обычные HTTP-запросы. У команды есть короткий алиас `tuna k8s`. #### Примеры примечание Все актуальные флаги, подсказки и примеры можно посмотреть вызвав справку: ```shell tuna kubernetes --help ``` Почти для всех флагов есть аналогичные [переменные окружения](https://tuna.am/docs/guides/environment-variables.md). ##### Kubeconfig и контекст Клиент берёт один файл kubeconfig: из флага `--kubeconfig`, иначе из `$KUBECONFIG`, иначе `~/.kube/config`. Список файлов через `:` в `$KUBECONFIG` не поддерживается. Контекст по умолчанию — `current-context`: ```shell tuna kubernetes --kubeconfig=./staging.yaml --context=staging ``` Поддерживаются клиентский сертификат, `token`, `tokenFile` и exec-плагины, которые выдают токен. Exec-плагины, выдающие сертификат, не поддерживаются. С `auth-provider` клиент завершится с ошибкой. ##### Сервисный аккаунт Без `--service-account` гость работает с **вашими** правами в кластере, клиент предупредит об этом. Создайте для гостя сервисный аккаунт с минимальными правами по RBAC и передайте его во флаге: ```shell tuna kubernetes --service-account=shop/debug ``` Формат — `[namespace/]name`. Без namespace берётся namespace контекста, а если его нет — `default`. Токен сервисного аккаунта клиент выпускает сам через TokenRequest API и продлевает каждый час. ##### Ограничения доступа Ограничения ниже работают поверх RBAC и только сужают права, но не расширяют их. | Флаг | Что делает | | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- | | `--namespace=shop` | Только один namespace. Кластерные ресурсы (`nodes`, список namespaces), `-A` и другие namespace запрещены. Сам namespace доступен только на чтение | | `--read-only` | Только чтение (`GET`, `HEAD`, `OPTIONS`). Запрещены `exec`, `attach` и `port-forward`; логи и `pods/proxy` доступны | | `--no-delete` | Запрещено удаление, остальная запись разрешена | | `--deny-resource=secrets,configmaps` | Запрещены указанные ресурсы, имя сравнивается без учёта регистра | | `--deny-subresource=exec,attach` | Запрещены субресурсы: `exec`, `attach`, `portforward`, `log`, `proxy` | С `--namespace` и `--read-only` не работают `kubectl auth whoami` и `kubectl auth can-i`: это POST-запросы к кластерным ресурсам. Заголовки `Impersonate-*` прокси срезает, поэтому `kubectl --as` через туннель не работает. ##### Пресеты `--preset` включает готовый набор ограничений: | Пресет | Что разрешено | | ---------- | --------------------------------------------------------------------------------------- | | `view` | Только чтение, без `secrets`, без `exec`, `attach`, `portforward` и `proxy` | | `observer` | Только чтение подов и их логов, без `exec`, `attach`, `portforward` и `proxy` | | `debug` | Всё, кроме удаления. `secrets` не скрыты: через `exec` до них всё равно можно добраться | | `open` | Без дополнительных ограничений | ```shell tuna kubernetes --preset=debug --namespace=shop ``` Пресет и флаги суммируются и не ослабляют друг друга: `--preset=debug --read-only` даёт только чтение. В пресете `observer` разрешены только ресурсы `pods`, поэтому `kubectl logs deploy/api` не сработает, нужно указывать под: `kubectl logs pod/api-7c9f8d6b5-x2k4q`. ##### Срок действия и число скачиваний ```shell tuna kubernetes --ttl=4h --download-limit=1 ``` `--ttl` задаёт срок действия доступа, по умолчанию `0` — бессрочно. После истечения `kubectl` получит ответ `this access has expired, ask for a new link`. `--download-limit` ограничивает число скачиваний kubeconfig, по умолчанию `1`, `0` снимает лимит. Сверх лимита ссылка отвечает `410`, а вы увидите в логе предупреждение о попытке скачивания. Если гость получил `410` при первом же скачивании, значит, конфиг до него забрал кто-то другой: остановите туннель и выдайте новую ссылку. ##### Постоянный адрес При переподключении с новым адресом клиент выпускает новый токен и новую ссылку, а срок действия и лимит скачиваний отсчитываются заново. Чтобы адрес не менялся, используйте зарезервированный поддомен или свой домен: ```shell tuna kubernetes --subdomain=k8s-staging tuna kubernetes --domain=k8s.example.com ``` Гостевые токены живут только в памяти процесса: после перезапуска клиента старые ссылки и kubeconfig перестают работать. ##### С указанием токена Можно указать специфичный токен через флаг `--token` или переменную окружения `TUNA_TOKEN`. Переопределение происходит в соответствии с политикой [очерёдности конфигурации](https://tuna.am/docs/guides/config-ordering.md). ```shell tuna kubernetes --token=tt_*** ``` ##### С указанием региона для подключения Можно указать специфичный [регион](https://tuna.am/docs/tunnels/guides/locations.md) через флаг `--location`/`-l` или переменную окружения `TUNA_LOCATION`. Переопределение происходит в соответствии с политикой [очерёдности конфигурации](https://tuna.am/docs/guides/config-ordering.md). ```shell tuna kubernetes --location=nl ``` ##### Запуск как сервис Туннель можно запускать [сервисом](https://tuna.am/docs/tunnels/guides/service.md) или через [множественный запуск](https://tuna.am/docs/tunnels/guides/multi-tunnels.md): ```shell tuna service install --name=k8s-staging -- tuna kubernetes --context=staging --service-account=shop/debug --subdomain=k8s-staging ``` --- ### Порты Резервирование статичных [портов](https://my.tuna.am/tcp_ports). ![list](/assets/images/list-d0c77d23112dce9b180bc7555939041f.webp) #### Обзор На странице с [портами](https://my.tuna.am/tcp_ports) вы можете зарезервировать статичный адрес в нужном регионе и использовать его в [TCP](https://tuna.am/docs/tunnels/tcp.md), [SSHd](https://tuna.am/docs/tunnels/ssh.md), [Postgres](https://tuna.am/docs/tunnels/postgres.md), [Redis](https://tuna.am/docs/tunnels/redis.md) и [Trigger](https://tuna.am/docs/tunnels/trigger.md) туннелях. к сведению Доступно только по [подписке](https://tuna.am/#pricing). Нажмите кнопку Добавить, выберете нужный регион и введите алиас (имя), по которому можно будет в дальнейшем использовать нужный порт: ![add](/assets/images/add-114e3a733af3af0ee7b28f625486fca7.webp) После добавления вы увидите уведомление с примером использования: ![notify](data:image/webp;base64,UklGRo4hAABXRUJQVlA4IIIhAABQfQCdASrkAdYAPjEYikQiIaER+ayEIAMEs7d+Lcy3Yr9uWd+x/4pJpv5TQ0Temn8PxbeQf+D9s3zr9Hv+V9QD9S/GA9+3mA/VX9jfem/4P+d9jn7I+wB/Qv6H6pHqm/2P/C+wB/Hv576aH/a/wnwof2T/Pftv8Bf65f+r2APQA6m/pR/J/xl73v5p+Sf9w9H/w34f+dfjl+9fNJiHfDfpf86/uH7O/2r9uPfb+o/kp5z+9T91/If4AvyD+J/zz8kP7Z+3HuO/uHbM5f/jfQC9Zflv95/tf7Z/17zZf0r+sfsx/bf/h8j/j/9S/rf5Yf0D7AP4h/I/7p/YP2u/w///+kv8j4MP03/Q/rp8Af8S/lX+b/sH+U/5/9m///2p/r/+t/t/+Q/9P+e9pX5t/XP9V/kf9F/6/9J///wF/kv8y/x/9k/yH/U/v//+/733W+vf9nv//7pP6v//UX3vGifteJljSt6CUzShhRfIATf34cFZGG9gEd4gXngvK7w/mNVVtMOD6QhAPeGYfAj8+c5yTnLdffESrJYjllQmCOFerrp7EqIapmlDCi+QOBUQ+a3hB40lUtO8HVyZ2DBNZj2fD5A4FRd40reglM0oKmZMm4z0AsIz+QGQ6cq/vqW0rGiJgAXG0N+viDmJyFXeTu+qWrEF9u08D1bk8PyR6i7X2c83N6yEZO+w8Vyla95ZULCUaILZHIs4hOey8CMzPjwMaVQA5t6aeL2R6f5o3uEF/YOFT0tFQvppeS4WiBnryFF8gb32JvWkSm0WAN4E4Lhyklq50mIQ2uMXo7aiK/6XlQvhGyS9jUZ9zzkgqIVGJJ5sU4r2w2jLKHI13KdPeg7fMZdwnuZWh04YcpAOXdgKlHxX3OzR+5sN6jgHb4RsCky36dGxu9MU9QpD2GweXUysEjgVF3hVCo3rLBLPH0tAStlpfIlkerjZCqOl2lJ43LIONvNoNbR6V06q876qCGFF8gcCoudYmNjhfLUdwPJFrleKPdHKz4lrTB/u7MX0hQRTAJ7eTcgFUpHHPedFEEBnRW5cMwe7WedbVr/w3qOkd280e8gSNFmSRg0sn1KXYAeAA1ErrLa1p6GELC1j6PN0V4gNdFSjrkRuQH4t8ddoV3XbDfEsF7G2RojL7IA1h5jebFegaix6iLTLfMzckJ8xbSYqmUybeHEJY9yNgBKNhNyNhNyNg7b76Mt3jSt6CUzShhRfIBRl/i3zDDTMr1mmaL5A4FRd40reglNFgqC3KIDk9USp2wGDgILH6nf74xzgopjbtNVGNDHsreglM0oYUXyAfDM3zUc+xvPLpCFb9LHFvKmaUMKL5A4FRd40reglKgAA/v5JhGOXHTb15lM0V4myZGiI3IEKxIwCG57/wo2u2dfW9tK9qtm1wiOeF2aMMBOTzuY7nSdRNIxk/j77qK/WvWDEHkEkGA2qnbaFm2ixknZPBUW8N9vm+Va8GUdByt4CxgHxNlJgaOpUdAv6IuC6O64tlJMwWmXfwOX5YjbFUJRCoCwbIH0lN+vml+Nz177VX9NGcxfDDDdjQX3nP7RjYE4LSmdwi/tcsdX/T84et8PwU53aYtTi/mgInIUwBpoDyf+5xwETshQqz+iH7PMS4SsyGk2IkVO2uumsjV2dYvBLtTJ5s1JjlHj5hFzf2Ti4E2vUjEr8Z/gqFWMmxiUbyvIV+iY/KP9S+xVgRX/6RsivlWKgONXMBF16NzILRh+6eeGjbsA9kpi522ovmUdyyn2bEQSJ3EI8qaj2ttnjhOrhpexg1WPKprE+qPJKSUK7U3aNXjurW4j/NqhDUrY8abqHUdKnTpFTdB58TyexBj0/AvkgaGP+/y9lPxvAkahKuiNkJQrlDjGip2vd7psM0tVPuRD6B0jiwXskeJbxtfR3RedKhiKvu/aMHkQKahz3lvHap8eHiLyB5CulOdRNICSLRYnGu+JT8uDB21wlH0sBDrsvsmd0IaQ/yKLREX3H/lnV0+1lUj7jV3rexeOhanhUO1pVFYOub9FcKZm9Mff2WhtIYZBhNJ+vCj76tJP0a7f5ChCFqz8qKvMP0/6oZsl84qIG7IhtZahJZB9LwjRN9Lb27O1E96ikriHUWwxwNORjFtCgYAPH1mfEGAxwE9rCeZOqPzgcjf9Frv5g1QTLEclZ53SBeCFACLICtdhGLVmrRCaZca6bdRqNljhY1zqW4hHml9WrwaGatLFR9oD+mpyDZ866v42JfLUEvNwExTm7h/NpuREor/IaCbnEWromUHqfiniuIjgApRfTv//krWif/OjJ6QRugr3Fa6x8KAbuHfEP2cYLhbR8PCnCVmNATV/98b9OVrEgoFtMiom0LWust3voqs6ZE78VZLwv/zj52eMgyMxqCxiuXvZrfAoFzzU7i43bNL5C+nPB5QKEQ8Dy12kZEQIFWR/7a17w3XJJhK4KcA4DQtdiZDlhb9eB6F2OQjbE2ddcWE85sK87cuUHwPj5DJrHwgKwvR38BUjRxGTYbn1kNvAGu+Kf0xVMHy2r7ECkRml3E3G8pnBaEEhid21rcW4hEMG10GG2LqniJ4lmZqAMgBWJHLRs0r2E1pV6448/EDi323o0MK9nzUxth3//Zr49Umz+5r+pJLb8y1X7EueupweC15kd1gRSrYDFcfGZZQWBwEGv5LafeXwPGxUT0i4LR27sP3d/ZKIWp6ZL8ryi1yxnQBZfgBonOk3ldzbmilqv4Mfq3WELYq7fNFJp9KhKUExwZiKJQmxoz15lLwchvF91+nQ2VynvVmM2fAKd1ziHS1Q6Pv87IVbqp5QAAAAAAAD3hRVfJkcE4mC9R14KKWXWHzvW79t6EnkU/+FL8P2ifkVY7FwfcPf0h6WREHTKmpH5UaLIO8LwKBPtKYN1mY7fzv2UaZ/pb/SE1dYJvsUoYe7cMHLnLd3ND665+Hnio/Q5lhDQDiibxasqMXNW/5TpgtxQ96t2nEoHp1UmJ/4OQsVs8tGkTs13iJENQJ6RJOhs6AY9GqHoALBvxsbC1EMSM8bc/soNVrmTvvMZ17tWID3EDFSiK9hnmVHbHYknNSbLb7dfYs8iloM6HyKVXZbOXrLrsve3vN5C71qY+O7QOCLBhZCRxctn0UqbqL0FEc45m9bb0QSjxqPyChLrF7MbNTeX3p2SYuaxiJm98wrPtjgbvz8quQXTcjMSUVA9hVxaShoAF0i5gL2kEikRMSEwsqAyD9i7KQQmWJ6Bigr/80X2M9WgrrH/V9L6qWKEnF1pUpKgf9mn30hmmH082EI36eRULQXc5AOZLbxG5nuuMj6jyXQk3PjGs82WDYwrj7zuDz+pimnqj9EL7gg32Ba/LE1cAmNoiQVP4fC8YRfZz25ZaBnbm5L76wV8HYD9+opP0Q3ozjWffgqcCytd8krM07ODELx1OECB8d3Ic9cYmmmGKCPtyKSCY/UhqtHvS+wl+ao5IA/mMlxdAmxIuliOn2i3kEQpFPgFOH0UiCtiuzL2SxhtryHULStPWJtkLE2xtco5MBCYMIFke1eG0fVnE+0xbm1bIvrZ8Oz4dR/BkSfCWF0Y9spTGS3PTCsNvu5pgyMHRQLwxJRCbnsWavyelL+YhDbX+AdttUmNZpMs3hIZLNIZDRWIlUpFNPzqILxHGjaCx023zGRNeC7Uw3HmVJ3iBC1YLKMQau55qMHluCYzOcIF+yhgR5yqXSoNWr7yDCKiPYLmlLjHFnI+10ozYFyXYel0140xeJv6PhaTEwsIRMu3uhKlm7VpeQOf/s6rBr0P1Hl5J+IWBQYaKeU9tr1TO3xNByzqZlb5RmhCivf8D1y27UppXWDj9ADiB9PWZ/1ylcYUKlbin/vlYobMkXSsxedfQahUIlnYWvVCh0qlEPor4CBtQJS4tUjwzY4Dqe6urHrnE+C/y/GVRYIOdnJ7HXXh+rdNKUyrnPJV1idzoK/C7l3uayJeFxaSG3d/ZPw3196hUgcmK2i1GZhTcCv0E0ny2uCstHLGxBnmxGYgbS/E+4xela5u28b4tbwaWY6Cz7FGmlciGLSfymFDRBV86Zr6sIAnKBonixDpSU9ee8KWyPppX4u+j5MVWNjMZPOE/YozgyEeyr+S/Z3hSXNPXimzWiGgksKvNiLwe2fCDM0SwipoEzenkN5/XztPr2kgiqBFWnoVdzM2wgrfeKw/Fqa2KmpOrTsZXYfp8I9EIA7SGAlonTBVDa+Df4XUnXwfGrE+RNzEyXMPF0QBKMktVZ+2d6vCGEHgMa7EQulMIfQu6qL2jemibOw/EzqGTL7litz+rys/r2wicZzEVuY/4Jewxuot72VgaoPUPZjhSRlr0/0spaXhEDa86pu6hKRNwsJxPNxFj7mZ+/pnNq/S35VfQj9NlJzwd6BEErl5sZbfKFoAmhjqtQNsJmc0BWmPTzCpBZScdM/eJi+mogIeq8h4SyDiCAIzH9JQ2tZb5wHIbHCDCiz8qd8erC9D2kevwU0JpPjoDpb7wt3ai7D2dAJ+vL+O0ExxVyjouyMJY00pWToGb/ywkqTavxY76ZOPhvWv/K47IAaEL0rdMsQ7ExU785Og/YhbQkoB7ZDYGPPFWpz1DB6bYiUpUfOkcTToCrTUS5P9PV0NVANDw71ILpUCLnDRjtIQDmJZBmDfaVs9rn7HJcTn3nmeLW021B2ttLIOoqvRKaPWjeRQLRdLn6ua35ihmH9nIDP8qKx2KXJdhqRijhcR1GEEBgphhJ81e76Xzgpf3u4W9X+l9PH5TJCMGRC6tyowyiWaNJIAlVQmIfCvb0Drqox0Mrtn85+psyx3inVRQqGxLqKpgehFYRJmkGBSzYFDtx2MqQAazw/JTEVPX5VV+NPkaTDDs/aQh7vgjdQhvDbsAaPbqGbUmocClCiz4DWgu13oJ3dtMC/FtKVdDGcYMxYJqZQ8z8ZoXLxaWc+Ery/NQd0eii71A+grQ7uZexmZib5talZbSBET7Hpp5BZ43+vd/FDXoYx8ROFAb/uG4yTP5AXDHUtUPsh2Qd+KpAC2gt6LDBcr2KB3ffmAMb3aYRCQ9bF+nmjcIkOXjOfQVKvEkzvyTivpTSwNqGcwv4TbBUbqzfz2eikxe1xGt1s224JvtViI9hcoA+dS+uhl2h7sudU3ty6JBm4qa/4asmjmU26es/NDNFXvjq5GBTDFv4JxwdaeXH53zOlPm5ByDNK104zN7kYO2X6bYXB2KPn/zUDOQPsgF+9W6osw7YcaCYe0S/O+ScD/6mfza3jDTbA2jYIXC06zuidXTv0MRZPmawrRoutjT9Jkm++1+4P6SfiNWpMFOBa9w+RPcWTwqtXtwM8o2QQA8ca4r0Ghr6g6UQTPZImyg0+VCxXcy/ZPVsDuz24BUANyhuokLAGqYi0jHOUgrR3LfrDCq+tA8MgdQsYpWPuGw7ZT4HfxvGmfdys3OoJN9PjQt2Hxz6Q9NvQV2SzqLXgKst7nKMq8I/9yFK1SaE0zNzNkEtTp+N1Gk42bXpYrc+TYljFhovvsBzjAVdMgGqWXGPSr2SIEpgc1t2Rfr1MxdUElvu4k6Jr0jDPNIT4AIP+sA3NBUf0oQeqPVU12bI0eSuZzu1XJCOOkTS+QH4CzphxFt7NhVhlANb/+/Ghm6+Y+F1E2ALb2OS6hZ6KoD08PtPzmt8syPOtw+u7DFKJkRLvwnl7bXdm8MsH49mClow/vf3mk0vd2YojjldcV3FTRtCEF8ppW1H/owlwALj/9+iUgVrhk6zNrBu4fHSPPLngUaFkG3NFFwkZ/wchamPGEXuMiwMFHArXM4Kcrr+3JCPl08ftZSPhtMvjOJRAHIKoEizXey/wah8USzlgjQa2OqsM1tUCqGaI5sVcmIqRwJ98D0mDuzoIRGu6GOyrqp8jvsXeyf9+tDnUuSxlwksEyMs2rYllgbTrTFWaLrCmUtA2fux6sMMqkmdIMcwvtNROJMOGPVQbDNx83om0mv2KKYvZVAHAroOX4VE+Kpzq8Fx7OYwzSR5Qm9TaI5V1oAXnfqDuj+3KgzssBZMyrZbMupz2QM2EWLVHAHblt5q5dQvFs98pWk7ZazFYLtkDeDClgWeQot5pAtqB++bnRHv8Ulm2Y0Lm8tbW/JblPP+/Zqbjvufu8tKHzZqnrTldguirjZSjhGxq1lvL9YMX7NTGWjTRtvaTaYCKLyE2QcZ9KIy/ha4WiEWk8y9fCa7ocNq5GsUzVXjpz1FdhSuo9MUpmhH7P3R2C6fqMKxSHJMOV5QfYxc/Ne+c/9CTukBLyDo6/ym5OiFrsbkHr/RearpRhK1wafttS5osNKoTefWarEwAcjKV6LxOCDUZJr68xI14jOw70yBOvNejmy5RwvJhSIHm46DU9B5yWGYDA7cnP1sezwOc1dxb+77cqv25BgtSR8dS9pBIpETFzarXC8P1g+IGCvP1EZq/sGppj8kPPykRpJ3bbYHDxeGN0w6+cdtk6UJvw/KY7RKTx+NAOerFFvhkcOczaOer2qfeBhQkY/TEY0ptIYlPYSzkZcAuIMLpfqsLybp8eXZQbEqnmXB6EMSqcgUyiNqHAxLP/obbd36Qg1b4Jk4T/INSVOOA3YanX/7Tm0pYDzQOuB+bwKCZRoTMm9waUmn9cY+L+97YDtBQCh/ST8Rq1J5KPs6SUDdW6EqSv4lEdZe4aUmy3qBlz7ujWU7qTmBDkiZqcjVGVHf4Q2OuizaAcK22A5uPPQOl+kGFfAKGYLW5r4rITn0Yv9N1stOTw9xSx79yydqWlSWF+cA4GHcwkQQh0gGnwabgLIrOIJ4oT5LgF73PSPnltd+m7Mr1DGroq0lcCPYTqCxLQhcUXtdYsQ7NazA92LNoZl2nTY5uaZsmrP0j0ssGfM/rtO2YZ5jkCez5JF1VzpIUdKx23aMWv24yHrwz2pSbr6T7XED4DbctvuaimPgl779sG8b+P+N70/Jc1dCsF+FT7ZciW/VjJiV39cITNizNYYV/wVwFdOpiEjG9VWdnLlKWPaetxzM5Bvqy3vYQdTUFyPnVeii4WEpSpydew7dFSXsY7qf92+m+DK/pSnvWemVslFeJHZ7FDwIIK37BkMTz3CHqIQ4q1v8oUAUG8EQLiy9ulvNrRwKHS0+ubS+gOc8V+WRts4p+f2nFobPRNYgaXkHgIoKhFvplbmvwo9b6obDjyojIoxc2UfJ6dUqm4wTArimlqBGtHMJuYaHNAjCagBrJtQ7YOa3doWkAtO4jGf8EIk7GPd8P/thXy+DEfUM+9VqcHOz7wFXnhlrUiFb2AO2+ywLPbLQWHJtgChCLuhAJ+Rehb0WadK2WO903+9EYcnPHlqnQvPmTYujLGu5b1mzHlXxRHYudgCImDjOpZgf/GlbHYY63tajnAZIG6O/hAWNKz2VIWu09AlujzjD5iX0u0JGABRXMmxQEHQdVRpjoGMYeuin9yjV30xX4vtTqLRjrWhAxyZOm8cTWL2rA3SmKHGqx6wbjvBtlXztcdg6msmqcQmwNrC8oHpw3MfCmmFTZZhPXr86+quLSSpLrYKW9yCoFVR6bBUoq5MFWCrSKCCvhXNTPaEjS2rQQquPboV4kupEq89fdaXTXnPyJ4rJIWYeQkitrH8WbQE2FKizapHs+lrNTEYJRs+ijjkygM5a+RhFXl+pt/nIfibxZC5PJwGDviBjZcHkwqPoJJkMH5fKmqIlreZdtyqn4vGubt/MQOrvUK0g1oo/HVO+lCmQwyJZBHqqfQptbbc/q7PR0r3e+P3Am7gS7eVZaDHyZEzN8D6SRWE3dYRuN/oXLVFtY0uRAOgvsGn0SRPz32oochC84JzyY9+7UcBfDi0Zledvqc6nVklns539s64XCPZwMS6ijxZX8LVicNU1gLFN+Lja1mer8q1V4x+Skdrc93DwdxaoGVsMhth4O/St4cyAEiidlfMMF7xHmn2A05FnBf1+rS8AgAXZv9WCKC1sAAAADeb2huAVOgrQQ6Hch10JYAAAR2ouK+cMyzeMFztGIVUi++AAB1TGqBvfAOgAAAGQJaJG+orjMuM8D5du2+ygaXy5LFIVd5JRvEjxRbRLzhfiWC4BlmJcV8DwtN6VPaPj0GgRUECzgO9CMYRkQ7TZNU6+TSJr/Ac1/U+r4qE+Q8JD+//3YVfCaEh4BvQLiGir7ju1aso91tRW8UoMdWt+LP/rMc8SkvNmTY6F3FfrW425pZDS+lo9wSrpcgPNOJ6FbhJ8fEA0bOx7ib+vfFCJqzrz0+f74h8hvKyaVCQpjcsVa4ECScDRy8FSh5oouj4lKAjegJDgCKUD8ev3O6x3yBcMM3htpfDPT2by/VrxuFSqrMaltjjdRIqIAou7QEtae84gnxVFbudvnrCvdl9RchWxVAHih8aCdOPK3g1Iq0+adeSS9zDNMF6+u8VTsExF8rnMxuK/M1dW7AjFueFQ+ISBrFxupmNSdJokR/PJ/ksfalqTEoetrHFDOsmxBQX6VQlcvrRcA0mho4wyVmycs0OuVjHpXyPsNbEHCVq053S88bx8KHHUFowsvUkFZ+Xgw66Ep6f2J3fX4pKHuMcRsiVPusDAjgJUJi4Z68l2Wyr9vRf9EDsgxiRRGPF+RxfM0LMu45JznGH8bWPsu+eDNQw40EY8/SW8YDCcCoZdFr9q+GqIy+0D/B/RWw8fr+st9gscuUNVn/sp7ijUWgGmqdDhd/PE2nixAl0GFturNpynDdvc2yibWftImi4RvCYjgHSNsOGgEoiIg40htxNMcDKwos68No19OU57L7kzcUhhaiaPn3mhykHByKGcaAeU7c52HKT1c9PesPVHYknU4SvOj6SXa/KB78vA9VaUjyDG1D/lPAIM+2BGh7/bb8nDcicUfeUvVjh/jjRBqaMfhGJR6FFsqwcX6qaLdXjYDRhljcRgLe/IMqqUO7pOrXM06m35W/XOLV6VA37jVaKEJV5tJNJuPcBeejBGctBCEfmmci7p1UYzLgRfuUQVPDVMiZKG4jd640HZCickralgjNkNxB6+vd/P62XaYl5acC2fuV40gMzaEaISz3UEj7xNKt9Pnm2198olc038QWnMYZJYWmCQQf7f13hsLLH/ObcBp4W8P7LGRnNT0nfvjqY2OIPnaOMle9l2UrdlkjYctfiKqjbvoW1RYVt+pF5IJ5peei9U8ZYT6tUWVXdlgXLgkW5nZzJ55I3lVzTI8VC/hg7y+/yHf/wmyVo/Lyywa1WGmluFOssh/Q+WlaprCs54aiEntx7nWtdNlcLFTW+XuepwoeY+4LgjAxAHpLCaRDjwoX54os+z1t3JfbkLbBl0PGCvZQkIKizxKxhHSXmqNrDwvdriZomlEuTfa4jIkPFq9Prdr++lTtgdy1hEUwKS07nO/FtuMn3bAKMk/tpbASVf3d9u/Yo/EiZODBO8FNgvU7cuc8+BNwxZ/y1ePIYAOJ46lQuqhXb+hIx3WCm70Ynl7a4AElf56Ffx21oKtWRj2ajoYOnpGGvCuvIya/L7WYOb1P+b793yJsKAiCg5Qk0QS8jl4NWApvycumYUESs/mTVLNdfC4WBYFW/eH9FCrh5jBdBLj8YxvpnWVWGsXTknKqlMKaxpxyfbUumz2JxH0htaDJJ8V9SdLBXvP9dHYhbwWab02vy/6CcBvYROC2LOT8Q8xN7FuB+Kc6Q5RhWXSYPLNxRUt11q/LRTqlcrthv7Ep7sZWIabkjxqNyyGTXC45jCCTgzSFQuZv7ORIMOb/UU+1Oa0UlY6f7Y5akxZDvf8qDhPIqThYW2n9MOhvWkORkUHSeb3AC765+XiNNq/ERWuR8KacwdYoSXhl8EbbhW93IJd0GpmU5Mh3HDMEq2z9y3p/T1y5dUXhHOHe/caPrP7SCL/DUw2FdReta4wPgWPYXqiKXPuLr25Ys6zzndPvpBMDJiJoty4Bwwa7/x0Q90Y2ejPPdKOAKz/t3SfgzKfrCLX7D/LKKTGnUUkEFf8beeBQ7uF0b+Q43EBmshMkZdgyt2gA4v1HCFAyvktqWEPkGPDLfVFniPh6/1sPoVqpthj4AXmbOwqnuRjEVXdjiTRpOdXZWS2V4CQdfkiZ0Zmaj0Of4XHS+/Z+DH3pcO36wSEybFLz2oE9Q8J9X5yriu3Ly/fWEZxQ8e/D9E3O1O9x1zJU0BiROST5PpLtmtM6nmMOfe6dB8xcKrHS1a7tD2nprAkNWBSHkaP85SaRnji2S9aeE2c1AI9BGAPGpbiiBa2AAF++GFgvQ/vmdT0Mc0UyCQj6/kRQ/Fg1JJKqUdBifp8jHqS5ja4/2W4mWYtRLNjI1pbPtXCEPq3T1xlugPqG2Jg4rPEODavSsKR7mww0vTlCJJIeTwAc6PTPBWp6u5VcHRn8/4AEdpSabH6UxbNzDY+J/TTlGkyaCkNEm/3mLrp/vLbVnt+NMfKkAWnWECHoXmKTeI04eQo4aQeRB615CRLTk07DYVClwj9kU0E6UinNArN9UwYQJeACj8a2CTMMrG7QGXgw9yXzoImydqtJfEUvBa4BATE2YNVcPZTJDfnsa/U7qqAP6S0R8AAOWsI2AAEkJyWJfe+IuMIlCdfBBVXjweSkQegoWkjScpOdyKNQw1cakEAApscJaQxi4ldLaLk5qKneNyBQmY6y6xniTyGvlfwFBLXFEHNp9DKLc3ynZRIIGrkeLB81y5X9eOCulmTcbgudcv2mhaSC0W5MO6gEJl3cqtxZLTFnfZ4k6CGLgTdKzgfKKxiP4+olKEoECv+UmQ+a/XnXUjvgF5Pc1vHsxQoDZ/4mvlSbEvmYqa9G8S1a9uI1Vmmm79tedP7eG5H5Xp0tI0RWNz0YZRukuQCxS2VOFXQdOzzC5QnCvPWXok3i4zPCDoJSplPoqhriEypcqaLI+ELitVfCn5z+RJkAMp7PGAWG9VcH1zbJXa37GkfI/ylsk4SZ9IqES0eGysWX4ZZbKO1FHRXKVrC6cFeqTMO4PB/LNi8EPTSqr2QWofeoDANTD9QnsBDSgaYmG7Lp0PUpwm7sVdi3Jj9EWuKt9+jPOf6POCrB3jCpkzLt4g55M9SquV42bWxiCfiNBKYDoCZ5VEYaSYWQWCl9yaSUmJcQUB0OE+ncYG2s80zbM7pm5afLG3v486k102GNvmc0lDiKvWSxSYbNCQOivpyC9BL3Xn6b6J9wh8XyQeGlToa8jypAqsUaLRGt9+YfI67p5LSe/x5FJu75EX6aGtIYNYcKZqVgB5uUlRNq59KtyMz2KVj6gbrflpJ131MD/tw4tN55pp3lij4O3jNkLbAxPDXWK5boGy48bnTE+2f347Ifd9StAiQWsjKLu+3p2DqQ4J2OCmHy6zfAfGYVU9B7SAJ+ZS6kfj2ZXOpK7/95mqRA5Q1NxknQrl9Lve0l8+J2eu2F95bIn1LI+jo7EC7+0SE2F4AAsNJgqZJWp8UAAAAA) подсказка Порт `5432` приведен в качестве примера, адрес и порт вашего приложения может отличаться. В дальнейшем можно просматривать детали: ![preview](/docs/img/ports/preview.webp) #### Примеры использования примечание Больше примеров вы найдёте в разделе с [примерами](https://tuna.am/docs/tunnels/examples.md). ##### PostgreSQL 1. Зарезервируйте порт с нужным алиасом, например `postgres`. 2. Запустите туннель: ```sh tuna postgres --port=postgres 5432 ``` к сведению Для PostgreSQL у нас реализован специальный тип туннелей - [postgres](https://tuna.am/docs/tunnels/postgres.md) с возможностью инспектирования SQL запросов, но вы можете использовать и обычный [TCP](https://tuna.am/docs/tunnels/tcp.md) туннель для подключения. ```sh tuna tcp --port=postgres 5432 ``` 3. Подключитесь к базе данных через туннель: ```sh psql "postgres://:@ru.tuna.am:38400/?sslmode=disable" ``` или ```sh psql -h ru.tuna.am -p 38400 -U postgres postgres ``` примечание При подключении через [postgres](https://tuna.am/docs/tunnels/postgres.md) туннель, SSL не поддерживается. ##### Redis 1. Зарезервируйте порт с нужным алиасом, например `redis`. 2. Запустите туннель: ```sh tuna redis --port=redis 6379 ``` к сведению Для Redis у нас реализован специальный тип туннелей - [redis](https://tuna.am/docs/tunnels/redis.md) с возможностью инспектирования запросов, но вы можете использовать и обычный [TCP](https://tuna.am/docs/tunnels/tcp.md) туннель для подключения. ```sh tuna tcp --port=redis 6379 ``` 3. Подключитесь через туннель: ```sh redis-cli -h ru.tuna.am -p 38400 -a ``` ##### SSH 1. Зарезервируйте порт с нужным алиасом, например `ssh`. 2. Запустите туннель: ```sh tuna ssh --port=ssh ``` к сведению У нас реализован специальный тип туннелей с встроенным [SSH сервером](https://tuna.am/docs/tunnels/ssh.md), но вы можете использовать и обычный [TCP](https://tuna.am/docs/tunnels/tcp.md) туннель для подключения к стандартному SSH серверу. ```sh tuna tcp --port=ssh 22 ``` 3. Подключитесь через туннель: ```sh ssh -p 38400 @ru.tuna.am ``` ##### Trigger к сведению Подробнее про работу триггер туннелей читайте в отдельной [инструкции](https://tuna.am/docs/tunnels/trigger.md). 1. Зарезервируйте порт с нужным алиасом, например `trigger-http`. 2. Запустите туннель: ```sh tuna trigger webhook --port=trigger-http /usr/local/bin/trigger.sh ``` 3. Подключитесь через туннель: ```sh curl -sSLf http://ru.tuna.am:38400 ``` ##### MySQL 1. Зарезервируйте порт с нужным алиасом, например `mysql`. 2. Запустите туннель: ```sh tuna tcp --port=mysql 6379 ``` 3. Подключитесь через туннель: ```sh mysql --host=ru.tuna.am --port=38400 --user= --password --database= --ssl-mode=disabled ``` ##### RTSP / IP camera 1. Зарезервируйте порт с нужным алиасом, например `rtsp`. 2. Запустите туннель: ```sh tuna tcp --port=rtsp 192.168.0.11:554 ``` 3. Подключитесь через туннель: ```sh ffmpeg -rtsp_transport tcp -i rtsp://:@ru.tuna.am:38400/stream1 ``` ##### Minecraft к сведению Для Minecraft нас есть подробная [инструкция](https://tuna.am/docs/tunnels/examples/minecraft.md). 1. Зарезервируйте порт с нужным алиасом, например `minecraft`. 2. Запустите туннель: ```sh tuna tcp --port=minecraft 25565 ``` 3. Подключитесь в лаунчере через туннель, используя присвоенный адрес, **например** - `ru.tuna.am:38400` --- ### Postgres туннель к сведению Доступно только по [подписке](https://tuna.am/#pricing). #### Обзор Postgres туннель позволяет предоставить доступ к базе данных PostgreSQL и отслеживать выполняемые SQL запросы в инспекторе. примечание Postgres туннели рассчитаны на отладку и работу локально или в тестовых окружениях, не поддерживают подключение через SSL, поэтому нужно использовать `sslmode=disable`. Мы не рекомендуем использовать этот тип туннелей в производственных средах. Начиная с версии **0.36.0** tuna показывает в терминале [полноэкранный интерфейс](https://tuna.am/docs/tunnels/tui.md) с сессиями и SQL-запросами. #### Примеры примечание Все актуальные флаги, подсказки и примеры можно посмотреть вызвав справку: ```shell tuna postgres --help ``` Почти для всех флагов есть аналогичные [переменные окружения](https://tuna.am/docs/guides/environment-variables.md). ##### Базовый пример ```shell tuna postgres 5432 ``` ##### С передачей IP-адреса ```shell tuna postgres 10.0.0.1:5432 ``` ##### С указанием токена Можно указать специфичный токен через флаг `--token` или переменную окружения `TUNA_TOKEN`. Переопределение происходит в соответствии с политикой [очерёдности конфигурации](https://tuna.am/docs/guides/config-ordering.md). ```shell tuna postgres 5432 --token=tt_*** ``` ##### С указанием региона для подключения Можно указать специфичный [регион](https://tuna.am/docs/tunnels/guides/locations.md) через флаг `--location`/`-l` или переменную окружения `TUNA_LOCATION`. Переопределение происходит в соответствии с политикой [очерёдности конфигурации](https://tuna.am/docs/guides/config-ordering.md). ```shell tuna postgres 5432 --location=nl ``` ##### Статичный порт В качестве значения флага `--port`/`-p` может выступать алиас или назначенный порт. Порты можно резервировать в [личном кабинете](https://my.tuna.am/tcp_ports) и после перезапуска туннеля адрес останется прежним. Подробнее о портах читайте в отдельной [инструкции](https://tuna.am/docs/tunnels/ports.md). ```shell tuna postgres 5432 --port=postgres tuna postgres 5432 --port=35000 ``` ##### Ограничение доступа по подсетям IP Вы можете определить белый список [подсетей](https://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%B4%D1%81%D0%B5%D1%82%D1%8C) в CIDR-формате: ```shell tuna postgres 5432 --cidr-allow="10.0.0.1/32" ``` Либо запретить доступ из определенных подсетей: ```shell tuna postgres 5432 --cidr-deny="10.0.0.1/32" ``` Можно комбинировать, например указать широкую сеть и вычесть частные IP: ```shell tuna postgres 5432 --cidr-allow="10.0.0.1/24" --cidr-deny="10.0.0.33/32" ``` Также можно передавать списки через запятую: ```shell tuna postgres 5432 --cidr-allow="10.0.0.1/24,192.168.0.1/24" --cidr-deny="10.0.0.33/32,192.168.0.33/32" ``` #### Инспектор запросов В инспекторе запросов можно производить отладку входящих запросов, смотреть заголовки и другую информацию, которая может облегчить работу при разработке приложений. Он управляется флагом `--inspect` или переменной окружения `TUNA_INSPECT`. ##### Управление Инспектор запросов включен по умолчанию и доступен по адресу `http://127.0.0.1:4040`, если порт `4040` занят, то будет выбран следующий по списку свободный. Адрес или порт можно переопределить с помощью переменной окружения `TUNA_INSPECT_ADDR` или параметра `inspectAddr` в [конфигурационном файле](https://tuna.am/docs/guides/config-file.md). * `TUNA_INSPECT_ADDR=0.0.0.0` - слушать на всех интерфейсах * `TUNA_INSPECT_ADDR=0.0.0.0:8080` - слушать на всех интерфейсах на порту `8080`, если порт занят, то будет выбран следующий по списку свободный * `TUNA_INSPECT_ADDR=8080` - слушать на адресе `127.0.0.1` на порту `8080`, если порт занят, то будет выбран следующий по списку свободный Итоговый адрес будет написан в консоли при запуске: ![cli_postgres](/docs/img/inspect/cli_postgres.webp) ##### Интерфейс Слева отображается список сессий, а справа вывод команд, которые были выполнены внутри сессий. ![web_postgres](/docs/img/inspect/web_postgres.webp) --- ### Redis туннель к сведению Доступно только по [подписке](https://tuna.am/#pricing). #### Обзор Redis туннель позволяет предоставить доступ к базе данных Redis и отслеживать выполняемые запросы в инспекторе. примечание Redis туннели рассчитаны на отладку и работу локально или в тестовых окружениях, не поддерживают подключение через SSL. Мы не рекомендуем использовать этот тип туннелей в производственных средах. Начиная с версии **0.36.0** tuna показывает в терминале [полноэкранный интерфейс](https://tuna.am/docs/tunnels/tui.md) с сессиями и командами Redis. #### Примеры примечание Все актуальные флаги, подсказки и примеры можно посмотреть вызвав справку: ```shell tuna redis --help ``` Почти для всех флагов есть аналогичные [переменные окружения](https://tuna.am/docs/guides/environment-variables.md). ##### Базовый пример ```shell tuna redis 6379 ``` ##### С передачей IP-адреса ```shell tuna redis 10.0.0.1:6379 ``` ##### С указанием токена Можно указать специфичный токен через флаг `--token` или переменную окружения `TUNA_TOKEN`. Переопределение происходит в соответствии с политикой [очерёдности конфигурации](https://tuna.am/docs/guides/config-ordering.md). ```shell tuna redis 6379 --token=tt_*** ``` ##### С указанием региона для подключения Можно указать специфичный [регион](https://tuna.am/docs/tunnels/guides/locations.md) через флаг `--location`/`-l` или переменную окружения `TUNA_LOCATION`. Переопределение происходит в соответствии с политикой [очерёдности конфигурации](https://tuna.am/docs/guides/config-ordering.md). ```shell tuna redis 6379 --location=nl ``` ##### Статичный порт В качестве значения флага `--port`/`-p` может выступать алиас или назначенный порт. Порты можно резервировать в [личном кабинете](https://my.tuna.am/tcp_ports) и после перезапуска туннеля адрес останется прежним. Подробнее о портах читайте в отдельной [инструкции](https://tuna.am/docs/tunnels/ports.md). ```shell tuna redis 6379 --port=redis tuna redis 6379 --port=35000 ``` ##### Ограничение доступа по подсетям IP Вы можете определить белый список [подсетей](https://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%B4%D1%81%D0%B5%D1%82%D1%8C) в CIDR-формате: ```shell tuna redis 6379 --cidr-allow="10.0.0.1/32" ``` Либо запретить доступ из определенных подсетей: ```shell tuna redis 6379 --cidr-deny="10.0.0.1/32" ``` Можно комбинировать, например указать широкую сеть и вычесть частные IP: ```shell tuna redis 6379 --cidr-allow="10.0.0.1/24" --cidr-deny="10.0.0.33/32" ``` Также можно передавать списки через запятую: ```shell tuna redis 6379 --cidr-allow="10.0.0.1/24,192.168.0.1/24" --cidr-deny="10.0.0.33/32,192.168.0.33/32" ``` #### Инспектор запросов В инспекторе запросов можно производить отладку входящих запросов, смотреть заголовки и другую информацию, которая может облегчить работу при разработке приложений. Он управляется флагом `--inspect` или переменной окружения `TUNA_INSPECT`. ##### Управление Инспектор запросов включен по умолчанию и доступен по адресу `http://127.0.0.1:4040`, если порт `4040` занят, то будет выбран следующий по списку свободный. Адрес или порт можно переопределить с помощью переменной окружения `TUNA_INSPECT_ADDR` или параметра `inspectAddr` в [конфигурационном файле](https://tuna.am/docs/guides/config-file.md). * `TUNA_INSPECT_ADDR=0.0.0.0` - слушать на всех интерфейсах * `TUNA_INSPECT_ADDR=0.0.0.0:8080` - слушать на всех интерфейсах на порту `8080`, если порт занят, то будет выбран следующий по списку свободный * `TUNA_INSPECT_ADDR=8080` - слушать на адресе `127.0.0.1` на порту `8080`, если порт занят, то будет выбран следующий по списку свободный Итоговый адрес будет написан в консоли при запуске: ![cli_redis](/docs/img/inspect/cli_redis.webp) ##### Интерфейс Слева отображается список сессий, а справа вывод команд, которые были выполнены внутри сессий. ![web_redis](/docs/img/inspect/web_redis.webp) --- ### SSHd туннель к сведению Доступно только по [подписке](https://tuna.am/#pricing). #### Обзор Tuna содержит встроенный SSH-сервер, это позволяет создать туннель и предоставить удаленный доступ по SSH без необходимости запускать SSH сервер и какой-либо конфигурации со стороны пользователя. Помимо функционала обычного SSH-сервера, tuna позволяет записывать сессии пользователей и просматривать их. Начиная с версии **0.36.0** tuna показывает в терминале [полноэкранный интерфейс](https://tuna.am/docs/tunnels/tui.md): инструкцию для подключения, ленту сессий и их просмотр в реальном времени. *** к сведению Создание SSHd туннеля доступно только в Unix-подобных операционных системах (macOS, Linux, FreeBSD), Windows не поддерживается. #### Примеры примечание Все актуальные флаги, подсказки и примеры можно посмотреть вызвав справку: ```shell tuna ssh --help ``` Почти для всех флагов есть аналогичные [переменные окружения](https://tuna.am/docs/guides/environment-variables.md). ##### Базовый пример ```shell tuna ssh ``` После запуска будет выведена инструкция для подключения: ```shell Connection instruction: 1. echo "[ru.tuna.am]:12524 ssh-ed25519 xxx" >> ~/.ssh/known_hosts 2. ssh -p 12524 ru.tuna.am 3. ru.tuna.am's password: fsk3xdpgqpje7m5l ``` По умолчанию принимается любой логин, а пароль генерируется автоматически и выводится в консоли. warning Адрес туннельных нод является публичным, злоумышленники могут просканировать порты, найти запущенные SSHd туннели и вести подбор пароля. По этому мы не рекомендуем использовать аутентификацию по паролю, особенно для долгоживущих SSHd туннелей [запущенных как сервис](https://tuna.am/docs/tunnels/guides/service.md). Ниже есть инструкция как включить *аутентификацию по ssh ключу* и *запретить аутентификацию с помощью пароля* ##### Статичный пароль Логин и пароль можно определить статически, с помощью флага `--auth` или переменной окружения `TUNA_SSH_AUTH`: ```shell tuna ssh --auth="*:pass" ``` Где `*` означает, что проверка имени производиться не будет, для ограничения по имени пользователя следует использовать следующий формат: ```shell tuna ssh --auth="user:pass" ``` ##### Аутентификация по ssh ключу Для аутентификации по ключам, необходимо предварительно добавить публичный ключ в разделе [SSH ключи](https://tuna.am/docs/guides/ssh-keys.md) в [личном кабинете](https://my.tuna.am/public_keys). А также на этой же странице, в настройках, включить - **Разрешить подключения с помощью своих SSH ключей**. В случае команды у вас может быть какой то общий ключ, и вы можете - **Разрешить подключения участникам команды** 1. На странице [SSH ключей](https://my.tuna.am/public_keys) - добавить публичный ключ. 2. Разрешить подключения в SSH туннелях с помощью своих SSH ключей: ![](/docs/img/ssh-keys.png) ##### Запретить аутентификацию с помощью пароля ```shell tuna ssh --password-auth=false ``` ##### С указанием токена Можно указать специфичный токен через флаг `--token` или переменную окружения `TUNA_TOKEN`. Переопределение происходит в соответствии с политикой [очерёдности конфигурации](https://tuna.am/docs/guides/config-ordering.md). ```shell tuna ssh --token=tt_*** ``` ##### С указанием региона для подключения Можно указать специфичный [регион](https://tuna.am/docs/tunnels/guides/locations.md) через флаг `--location`/`-l` или переменную окружения `TUNA_LOCATION`. Переопределение происходит в соответствии с политикой [очерёдности конфигурации](https://tuna.am/docs/guides/config-ordering.md). ```shell tuna ssh --location=nl ``` ##### Статичный порт В качестве значения флага `--port`/`-p` может выступать алиас или назначенный порт. Порты можно резервировать в [личном кабинете](https://my.tuna.am/tcp_ports) и после перезапуска туннеля адрес останется прежним. Подробнее о портах читайте в отдельной [инструкции](https://tuna.am/docs/tunnels/ports.md). ```shell tuna ssh --port=ssh tuna ssh --port=35000 ``` ##### Ограничение доступа по подсетям IP Вы можете определить белый список [подсетей](https://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%B4%D1%81%D0%B5%D1%82%D1%8C) в CIDR-формате: ```shell tuna ssh --cidr-allow="10.0.0.1/32" ``` Либо запретить доступ из определенных подсетей: ```shell tuna ssh --cidr-deny="10.0.0.1/32" ``` Можно комбинировать, например указать широкую сеть и вычесть частные IP: ```shell tuna ssh --cidr-allow="10.0.0.1/24" --cidr-deny="10.0.0.33/32" ``` Также можно передавать списки через запятую: ```shell tuna ssh --cidr-allow="10.0.0.1/24,192.168.0.1/24" --cidr-deny="10.0.0.33/32,192.168.0.33/32" ``` #### Запись SSH сессий Запись сессий включено по умолчанию, управляется флагом `--record-session` или переменной окружения `TUNA_RECORD_SESSION`: ```shell tuna ssh --record-session=false ``` #### Управление и просмотр SSH сессий Для просмотра записей и их управления есть отдельная команда `tuna ssh-session`. ##### Вывести список Выполняется командой `tuna ssh-session list`: ```shell tuna ssh-session list INFO[11:14:12] 2024-10-28 11:13:49. 2o3u9YtqncQ5JfCtrj73WjFHDqR (jidckii, active) ``` ##### Просмотр записи Выполняется командой `tuna ssh-session watch [session]`: ```shell tuna ssh-session watch 2o3u9YtqncQ5JfCtrj73WjFHDqR tuna:jidckii> ^C tuna:jidckii> exit ``` ##### Удалить все записи ```shell tuna ssh-session clear ``` #### Поведение ##### SFTP SFTP поддерживается, ничего дополнительно настраивать не нужно. --- ### TCP туннель #### Обзор TCP туннель позволяет предоставить доступ к любому сервису, использующему TCP-протокол, наиболее популярные примеры: * Базы данных ([mySQL](https://tuna.am/docs/tunnels/examples/mysql.md), [PostgreSQL](https://tuna.am/docs/tunnels/examples/postgresql.md), [MSSQL](https://tuna.am/docs/tunnels/examples/mssql.md)) * ПО для удаленного доступа ([SSH](https://tuna.am/docs/tunnels/examples/ssh.md), [RDP](https://tuna.am/docs/tunnels/examples/rdp.md)) * Игровые серверы ([Minecraft](https://tuna.am/docs/tunnels/examples/minecraft.md)) Начиная с версии **0.36.0** tuna показывает в терминале [полноэкранный интерфейс](https://tuna.am/docs/tunnels/tui.md). к сведению Создание TCP туннеля доступно только по [подписке](https://tuna.am/#pricing). #### Примеры примечание Все актуальные флаги, подсказки и примеры можно посмотреть вызвав справку: ```shell tuna tcp --help ``` Почти для всех флагов есть аналогичные [переменные окружения](https://tuna.am/docs/guides/environment-variables.md). ##### Базовый пример ```shell tuna tcp 5432 ``` ##### С передачей IP-адреса ```shell tuna tcp 10.0.0.1:5432 ``` ##### Unix-сокет Вместо порта можно указать unix-сокет, байты из туннеля передаются в него как есть. Путь указывается с префиксом `unix://` и должен быть абсолютным: ```shell tuna tcp unix:///var/run/app.sock ``` * Путь без префикса (`/var/run/app.sock`), относительный (`unix://tmp/app.sock`) или пустой (`unix://`) не принимается. * Флаги `--cidr-allow`, `--cidr-deny` и `--proxy-protocol` работают так же, как с портом. * Если сокета нет при запуске, tuna выведет предупреждение и продолжит работу. К сокету она подключается на каждое входящее соединение, поэтому сокет может появиться позже, перезапускать туннель не нужно. * tuna подключается к сокету от имени пользователя, который её запустил. У него должны быть права на запись в сокет, иначе подключение завершится ошибкой `permission denied`. * Unix-сокеты поддерживают только `tuna tcp` и [`tuna http`](https://tuna.am/docs/tunnels/http.md#unix-socket), специализированные команды вроде `tuna ssh`, `tuna postgres` и `tuna redis` — нет. * На Windows работа не гарантируется, именованные каналы (`npipe://` в Docker Desktop) не поддерживаются. ###### Доступ к Docker API осторожно Доступ к `docker.sock` равнозначен root-доступу к хосту: через Docker API можно запустить контейнер с примонтированной корневой файловой системой. Не публикуйте сокет без `--cidr-allow`, ограничьте доступ своим IP-адресом. ```shell tuna tcp unix:///var/run/docker.sock --cidr-allow="203.0.113.10/32" ``` Пользователь, от имени которого запущена tuna, должен состоять в группе `docker`, иначе подключение к сокету завершится ошибкой `permission denied`. На своей машине укажите адрес туннеля из вывода tuna: ```shell docker -H tcp://ru.tuna.am:12345 ps ``` ##### С указанием токена Можно указать специфичный токен через флаг `--token` или переменную окружения `TUNA_TOKEN`. Переопределение происходит в соответствии с политикой [очерёдности конфигурации](https://tuna.am/docs/guides/config-ordering.md). ```shell tuna tcp 8080 --token=tt_*** ``` ##### С указанием региона для подключения Можно указать специфичный [регион](https://tuna.am/docs/tunnels/guides/locations.md) через флаг `--location`/`-l` или переменную окружения `TUNA_LOCATION`. Переопределение происходит в соответствии с политикой [очерёдности конфигурации](https://tuna.am/docs/guides/config-ordering.md). ```shell tuna tcp 8080 --location=nl ``` ##### Генерация QR кода с ссылкой При добавлении флага `--qr` для ссылки будет сгенерирован QR код и напечатан в консоли. Это может быть удобно если вы тестируете сайт на мобильном устройстве. ![](/docs/img/examples/qr.png) ##### Статичный порт В качестве значения флага `--port`/`-p` может выступать алиас или назначенный порт. Порты можно резервировать в [личном кабинете](https://my.tuna.am/tcp_ports) и после перезапуска туннеля адрес останется прежним. Подробнее о портах читайте в отдельной [инструкции](https://tuna.am/docs/tunnels/ports.md). ```shell tuna tcp 5432 --port=postgres tuna tcp 5432 --port=35000 ``` ##### Ограничение доступа по подсетям IP Вы можете определить белый список [подсетей](https://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%B4%D1%81%D0%B5%D1%82%D1%8C) в CIDR-формате: ```shell tuna tcp 3389 --cidr-allow="10.0.0.1/32" ``` Либо запретить доступ из определенных подсетей: ```shell tuna tcp 3389 --cidr-deny="10.0.0.1/32" ``` Можно комбинировать, например указать широкую сеть и вычесть частные IP: ```shell tuna tcp 3389 --cidr-allow="10.0.0.1/24" --cidr-deny="10.0.0.33/32" ``` Также можно передавать списки через запятую: ```shell tuna tcp 3389 --cidr-allow="10.0.0.1/24,192.168.0.1/24" --cidr-deny="10.0.0.33/32,192.168.0.33/32" ``` ##### Proxy Protocol Позволяет передавать оригинальный IP и Port клиента, если ваше приложение поддерживает это. В аргументе нужно передать версию 1 или 2, что соответствует версии Proxy Protocol, 1 - текстовый , 2 - бинарный. Haproxy или Nginx поддерживают оба и определяют автоматически. ```shell tuna tcp 8443 --proxy-protocol=1 tuna tcp 8443 --proxy-protocol=2 ``` --- ### Trigger туннель #### Обзор Триггеры - команды, выполняемые по определенному событию, tuna поддерживает два типа событий: * HTTP запрос (Webhook) * Письмо (SMTP) Начиная с версии **0.36.0** команда получает данные события: тело запроса или письмо приходит на stdin, метод, путь, заголовки и адреса — в переменных окружения. к сведению Создание Trigger туннеля доступно только по [подписке](https://tuna.am/#pricing). ##### Пример примечание Все актуальные флаги, подсказки и примеры можно посмотреть вызвав справку: ```shell tuna trigger --help tuna trigger webhook --help tuna trigger smtp --help ``` Почти для всех флагов есть аналогичные [переменные окружения](https://tuna.am/docs/guides/environment-variables.md). ##### Скрипт для запуска Например создайте скрипт `/tmp/trigger.sh` который будет создавать файл и записывать в него фразу `Hello tuna`: /tmp/trigger.sh ```shell #!/bin/sh set -xe touch /tmp/test_file.txt echo "Hello tuna" > /tmp/test_file.txt ``` Затем сделайте его исполняемым с помощью команды `chmod +x /tmp/trigger.sh`. Команда запускается в фоне на каждое событие. Её stdout попадает в лог tuna на уровне `debug` (`--log-level=debug`), stderr — на уровне `error`. #### HTTP запрос (Webhook) ```shell tuna trigger webhook /tmp/trigger.sh ``` tuna сгенерирует ссылку: ```log INFO[13:00:00] Welcome to Tuna INFO[13:00:00] Forwarding tcp://ru.tuna.am:16502 -> 127.0.0.1:35839 INFO[13:00:00] Send an HTTP request to http://ru.tuna.am:16502 to execute the command "/tmp/trigger.sh" ``` Теперь вы можете отправить запрос по указанному адресу, а tuna выполнит указанный скрипт, например: ```shell curl -sSLf http://ru.tuna.am:16502 ``` tuna отвечает на запрос сразу, не дожидаясь завершения команды. ##### Данные запроса Тело запроса передаётся команде на stdin как есть, в том числе бинарное. Остальное — в переменных окружения: | Переменная | Значение | | ---------------------------- | --------------------------------------------------------------- | | `TUNA_REQUEST_METHOD` | Метод запроса, например `POST` | | `TUNA_REQUEST_PATH` | Путь в URL-кодировке, например `/hooks/a%20b` | | `TUNA_REQUEST_QUERY` | Строка запроса без `?`, например `id=1&debug=true` | | `TUNA_REQUEST_HEADER_` | Значение заголовка, например `TUNA_REQUEST_HEADER_CONTENT_TYPE` | Имя заголовка переводится в верхний регистр, все символы кроме `A-Z` и `0-9` заменяются на `_`: `Content-Type` → `TUNA_REQUEST_HEADER_CONTENT_TYPE`, `X-GitLab-Event` → `TUNA_REQUEST_HEADER_X_GITLAB_EVENT`. Значения повторяющихся заголовков склеиваются через `, `. `Host` тоже передаётся: `TUNA_REQUEST_HEADER_HOST`. Скрипт, который выводит всё, что получил: /tmp/trigger.sh ```shell #!/bin/sh echo "Method: $TUNA_REQUEST_METHOD" echo "Path: $TUNA_REQUEST_PATH" echo "Query: $TUNA_REQUEST_QUERY" echo "Headers:" env | grep '^TUNA_REQUEST_HEADER_' | sed 's/^TUNA_REQUEST_HEADER_/ /' | sort echo "Body:" cat ``` ```shell tuna trigger webhook --log-level=debug /tmp/trigger.sh curl -sSf "http://ru.tuna.am:16502/deploy?env=prod" -H "Content-Type: application/json" -d '{"ref":"main"}' ``` Пример реакции только на нужное событие — запуск деплоя по push в `main` из GitLab: /tmp/deploy.sh ```shell #!/bin/sh set -e [ "$TUNA_REQUEST_HEADER_X_GITLAB_EVENT" = "Push Hook" ] || exit 0 jq -e '.ref == "refs/heads/main"' > /dev/null || exit 0 /opt/app/deploy.sh ``` ##### Проверка секрета С флагом `--secret` tuna принимает только запросы с тем же значением в заголовке `X-Webhook-Secret`, остальным отвечает `400` и команду не запускает. Сам заголовок в переменные окружения не передаётся. ```shell tuna trigger webhook --secret=s3cr3t /tmp/trigger.sh curl -sSf http://ru.tuna.am:16502 -H "X-Webhook-Secret: s3cr3t" ``` ##### Ограничения Тело запроса — не больше 10 МБ. На запрос побольше tuna ответит `413`, команда не запустится. #### Письмо (SMTP) ```shell tuna trigger smtp /tmp/trigger.sh ``` tuna сгенерирует ссылку: ```log INFO[13:00:00] Welcome to Tuna INFO[13:00:00] Forwarding tcp://ru.tuna.am:19284 -> 127.0.0.1:1025 INFO[13:00:00] Send a message to SMTP server ru.tuna.am:19284 to execute the command "/tmp/trigger.sh" ``` Теперь вы можете отправить письмо по указанному адресу, а tuna выполнит указанный скрипт, например: ```shell curl -s \ --url "smtp://ru.tuna.am:19284" \ --mail-from "tuna@example.com" \ --mail-rcpt "tuna@example.com" \ --upload-file /tmp/trigger.sh ``` Команда запускается на каждое принятое письмо. Подключение без письма или без авторизации команду не запускает. Чтобы принимать письма только с логином и паролем, задайте флаги `--username` и `--password`: ```shell tuna trigger smtp --username=tuna --password=s3cr3t /tmp/trigger.sh curl -s --url "smtp://ru.tuna.am:19284" --user "tuna:s3cr3t" \ --mail-from "tuna@example.com" --mail-rcpt "tuna@example.com" --upload-file mail.eml ``` ##### Данные письма Письмо целиком (заголовки и тело в формате RFC 5322) передаётся команде на stdin. Адреса и заголовки — в переменных окружения: | Переменная | Значение | | ------------------------- | -------------------------------------------------------------- | | `TUNA_MAIL_FROM` | Отправитель из конверта (`MAIL FROM`) | | `TUNA_MAIL_TO` | Получатели из конверта (`RCPT TO`) через `,` | | `TUNA_MAIL_HEADER_` | Значение заголовка письма, например `TUNA_MAIL_HEADER_SUBJECT` | Имена заголовков строятся так же, как [у webhook](#webhook-payload). Закодированные значения вида `=?utf-8?b?...?=` раскодируются, если кодировка — `utf-8`, `us-ascii` или `iso-8859-1`. Остальные приходят как есть. /tmp/trigger.sh ```shell #!/bin/sh echo "From: $TUNA_MAIL_FROM" echo "To: $TUNA_MAIL_TO" echo "Subject: $TUNA_MAIL_HEADER_SUBJECT" echo "Message:" cat ``` ##### Локальный адрес SMTP-сервера SMTP-сервер триггера слушает `127.0.0.1:1025`. Если порт занят другим приложением, например Proton Mail Bridge, укажите другой адрес флагом `--listen-address` или переменной `TUNA_TRIGGER_SMTP_LISTEN_ADDRESS`: ```shell tuna trigger smtp --listen-address=127.0.0.1:2525 /tmp/trigger.sh ``` ##### Ограничения Письмо — не больше 10 МБ. На письмо побольше tuna ответит кодом `552`, команда не запустится. #### Переменные окружения команды Переменные события добавляются к окружению, с которым запущена tuna, остальные переменные команда тоже видит. Linux ограничивает одну переменную окружения 128 КБ. Если заголовок длиннее, команда не запустится, а в логе tuna появится `Failed to run command: ... argument list too long`. #### Общие флаги ##### С указанием токена Можно указать специфичный токен через флаг `--token` или переменную окружения `TUNA_TOKEN`. Переопределение происходит в соответствии с политикой [очерёдности конфигурации](https://tuna.am/docs/guides/config-ordering.md). ```shell tuna trigger webhook --token=tt_*** tuna trigger smtp --token=tt_*** ``` ##### С указанием региона для подключения Можно указать специфичный [регион](https://tuna.am/docs/tunnels/guides/locations.md) через флаг `--location`/`-l` или переменную окружения `TUNA_LOCATION`. Переопределение происходит в соответствии с политикой [очерёдности конфигурации](https://tuna.am/docs/guides/config-ordering.md). ```shell tuna trigger webhook --location=nl tuna trigger smtp --location=nl ``` ##### Статичный порт В качестве значения флага `--port`/`-p` может выступать алиас или назначенный порт. Порты можно резервировать в [личном кабинете](https://my.tuna.am/tcp_ports) и после перезапуска туннеля адрес останется прежним. Подробнее о портах читайте в отдельной [инструкции](https://tuna.am/docs/tunnels/ports.md). ```shell tuna trigger webhook --port=postgres tuna trigger webhook --port=35000 tuna trigger smtp --port=postgres tuna trigger smtp --port=35000 ``` --- ### Интерфейс в терминале Начиная с версии **0.36.0** команды `tuna http`, `tuna tcp`, `tuna ssh`, `tuna postgres`, `tuna redis` и `tuna kubernetes` показывают полноэкранный интерфейс (TUI) вместо текстового лога. Он включается сам, если вывод идёт в терминал. #### Что на экране В шапке всегда видны: * аккаунт; * адрес туннеля (Forwarding) и локальный адрес, куда он ведёт; * адрес [инспектора](https://tuna.am/docs/tunnels/http/inspect.md); * статус подключения: `online` или `reconnecting`; * сообщения от сервера. Если туннель запущен с ограничениями доступа или опциями, ниже появляются строки **Access** и **Options**: например, `basic auth (1) · cidr deny 203.0.113.0/24` и `rate limit 20/s · cors`. Выводятся только заданные настройки. Пароли и ключи не показываются — вместо них их количество. Основная часть экрана зависит от типа туннеля: | Туннель | Что показывает | | ---------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [HTTP](https://tuna.am/docs/tunnels/http.md) | Ленту запросов (новые сверху) и метрики: всего запросов, rpm, p50, p90, число ответов 4xx и 5xx. По Enter открываются детали запроса: заголовки и отформатированное тело JSON | | [Postgres](https://tuna.am/docs/tunnels/postgres.md), [Redis](https://tuna.am/docs/tunnels/redis.md) | Слева список сессий: `●` — активна, `○` — закрыта, `•` — есть непросмотренные события. Справа события выбранной сессии с подсветкой: запросы, число строк в ответе, ошибки | | [SSHd](https://tuna.am/docs/tunnels/ssh.md) | Инструкцию для подключения и ленту сессий, в том числе отказы в доступе. Enter на активной сессии открывает её просмотр в реальном времени, на завершённой — воспроизведение записи | | [Kubernetes](https://tuna.am/docs/tunnels/kubernetes.md) | В шапке сервисный аккаунт, namespace, ограничения и срок действия доступа, ниже — лента запросов гостя | | [TCP](https://tuna.am/docs/tunnels/tcp.md) | Лог туннеля | #### Горячие клавиши Общие для всех туннелей: | Клавиша | Действие | | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `Ctrl+C` | Остановить туннель и выйти. Другого способа выйти нет, `q` только возвращает назад. На экране QR-кода и при просмотре SSH-сессии `Ctrl+C` только закрывает их | | `c` | Скопировать адрес туннеля | | `i` | Открыть инспектор в браузере | | `l` | Показать или скрыть лог (кроме TCP, где лог — основной экран) | | `Q` | Показать QR-код адреса туннеля, `Enter` или `Ctrl+C` возвращают назад, туннель продолжает работать | | `↑` `↓` | Выбрать запись | | `g` / `G` | Перейти к новым / старым записям | | `Esc`, `q` | Назад из деталей и лога | `g` или `↑` на первой записи включают режим слежения: выделение само переходит на новые записи по мере их появления. HTTP: | Клавиша | Действие | | ------- | ----------------------------------------------------------- | | `Enter` | Детали запроса | | `r` | Повторить запрос | | `/` | Фильтр по методу, пути или статусу, `Esc` сбрасывает фильтр | | `o` | Открыть адрес туннеля в браузере | Postgres и Redis: | Клавиша | Действие | | ------- | ---------------------------------------------- | | `Tab` | Переключиться между списком сессий и событиями | | `y` | Скопировать запрос | SSHd: | Клавиша | Действие | | ------- | ------------------------------------------------------------------------------------------------------------------------------ | | `Enter` | Смотреть активную сессию или воспроизвести запись завершённой. `Ctrl+C` закрывает только просмотр, туннель продолжает работать | Флаг `--qr` при включённом интерфейсе один раз показывает экран с QR-кодом после подключения, `Enter` или `Ctrl+C` возвращают к основному экрану. При `--inspect=false` запросы и сессии не записываются, поэтому лента HTTP, Postgres и Redis остаётся пустой. #### Отключение Чтобы вернуть текстовый лог, запустите туннель с одним из флагов: ```shell tuna http 8080 --log=stdout tuna http 8080 --log=stderr tuna http 8080 --log-format=json ``` Или задайте переменную окружения `TUNA_TUI=0`. С `--log=/path/to/file.log` интерфейс остаётся, а лог параллельно пишется в файл. Интерфейс не включается сам, если: * вывод перенаправлен в файл или пайп, туннель запущен [как сервис](https://tuna.am/docs/tunnels/guides/service.md) или через systemd; * задана переменная `CI` или `NONINTERACTIVE`; * `TERM=dumb`; * tuna запущена ИИ-агентом (заданы `AI_AGENT`, `CLAUDECODE` или `CURSOR_AGENT`). В этом случае интерфейс можно включить через `TUNA_TUI=1`. Команда `tuna start` работает с текстовым выводом, как раньше. --- ### Вебхуки [Перейти в личный кабинет](https://my.tuna.am/webhooks) Функционал позволяющий легко узнать, что находится в запросе который посылает какой либо сервис. В частности понять какая реально приходит информация в теле запроса, заголовки, IP источника и так далее. ![webhooks](/docs/img/webhooks/main.png) *** #### HTTP Вебхуки Отладка и обработка входящих HTTP запросов. ##### Простой ответ Вы можете также редактировать ответ, в частности: код, заголовок `Content-Type` и тело ответа. Окно редактирования можно вызвать в меню справа, тут же есть и другие опции, вроде ссылки, очистки истории или удаления. ![webhook_edit](/docs/img/webhooks/edit.png) ![webhook_menu](/docs/img/webhooks/menu.png) Пример вызова с помощью `curl`: ![webhook_terminal](/docs/img/webhooks/terminal.png) ##### Политика трафика Помимо простого ответа можно описать сложные правила обработки вебхука, имитируя к примеру ответ API. На отдельно странице есть полная инструкция про [Политики трафика](https://tuna.am/docs/traffic-policy.md). ![Скриншот с политикой трафика в вебхуке](/docs/img/webhooks/reply_tp.png) ##### Пересылка запроса в туннель Если у вас есть запущенные туннели вы можете переслать в него принятый запрос. ![Скриншот с пересылкой запроса в туннель](/docs/img/webhooks/resend_to_tunnel.png) ##### Другое В области обзора на запрос есть горячие ссылки для проверки IP источника в разных сервисах. ![webhook_hotlinks](/docs/img/webhooks/hotlinks.png) #### SMTP Вебхуки SMTP вебхуки позволяют имитировать отправку почты и принимать письма для отладки. Письма никуда не пересылаются и вы не можете использовать сервис для реальной рассылки почты. ##### Приём почты ![Скриншот SMTP Вебхуки](/docs/img/webhooks/mail.png) Вы можете отправить письмо на указанный ящик с любой реальной почты, на странице вы увидите тело сообщения в текстовом представлении и все SMTP заголовки. Таким образом вы можете в том числе использовать SMTP вебхуки как приватную временную почту, но учитывайте, что сообщения в вебхуках автоматически очищаются с течением времени. Либо для отладки как работают ваши рассылки в testing / dev окружениях. ##### Отправка почты Ещё чаще при разработке для отладки рассылок нужно проверять, а рассылаются ли сообщения всем кому нужно и не отправляются ли кому не нужно. В таком случае вы можете использовать отправку на SMTP сервер `smtp.tuna.am:25` писем с любым адресом назначения, указав адрес ящика вебхука как ящик отправителя. Пример с отправкой письма при помощи **curl** есть ниже в примерах. #### Примеры В репозиториях GitLab и GitHub можно создавать вебхуки для определённых или всех действий, например открытие PR или push. Мы к примеру используем это для нотификации своему боту, который далее пишет в телеграм об открытии MR или добавляет лейблы к новому Issue. Вы можете использовать Tuna Webhooks для понимания, что именно приходит в теле запроса, какие заголовки и так далее. ##### 🦊 GitLab Webhooks ![webhook_gitlab](/docs/img/webhooks/gitlab.png) ![webhook_gitlab_body](/docs/img/webhooks/gitlab_body.png) ##### 🐱 GitHub Webhooks ![webhook_github](/docs/img/webhooks/github.png) ![webhook_github_body](/docs/img/webhooks/github_body.png) ##### 🔵 Юкасса HTTP-уведомления ![webhook_yookassa](/docs/img/webhooks/yookassa.png) ![webhook_yookassa_body](/docs/img/webhooks/yookassa_body.png) ##### 📬 Отправка e-mail с помощью curl *замените `XXX` на свой адрес вебхука* Создайте `email.txt` файл с содержимым: ```txt From: XXX@smtp.tuna.am To: John Doe Subject: Test Email This is the body. ``` Выполните команду, для отправки: ```sh curl -s --url 'smtp://smtp.tuna.am:25' --mail-rcpt 'to@example.com' --mail-from 'XXX@smtp.tuna.am' --upload-file email.txt ``` --- ### Какие планы? У нас есть бэклог в который мы пишем все наши хотелки и хотелки клиентов, вот некоторые из них: * \~~Очень просят статичные TCP порты и мы постараемся сделать это к следующему большому релизу~~ * \~~Свой домен, статичный поддомен это хорошо, но иногда свой домен может быть преимуществом~~ * \~~Новый сайт и личный кабинет, текущий сделан на коленке и содержит не весь функционал, а хочется красиво 🙂~~ * \~~Документация. Сейчас её нет вообще, а ведь там можно описать как устанавливать клиент из репозиториев, которые уже есть, какие-то рецепты и так далее...~~ * \~~Новый UI для инспектора запросов HTTP~~ * \~~Чтение тела запроса, для отображения в инспекторе~~ * \~~Запись действий клиента SSH сессии. Сейчас клиент может подключиться, но какие он вводит команды, неизвестно~~ * \~~Тариф для команд~~ * \~~Оплата по счёту для организаций~~ * \~~Многофакторная аутентификация, для большей безопасности~~ * \~~Вход через социальные сети~~ * \~~Доменные зоны (wildcard)~~ * \~~Менеджер паролей~~ * \~~Бастион SSH - Zero Trust доступ к серверам~~ * Единый вход (SSO) * Оплата международными картами * Запуск туннельной ноды tuna-node в собственном окружении (on-premise) * \~~Инфраструктурные секреты~~ * Объединение агентов в виртуальные сети * *Бесконечные* доски для совместной работы, рисования, планирования и прототипирования * Простые бэкапы баз данных * Бастион ALPN - Zero Trust доступ к приложениям и базам данных * Бастион Kubernetes * Бастион API Gateway * Бастион Proxy - доступ к серверам в DMZ и серых сетях --- ## Dpa ### Условия обработки данных Заказчика **Редакция от: 13 августа 2026 г.** #### 1. Предмет и роли сторон 1.1. Настоящие Условия определяют порядок обработки Индивидуальным предпринимателем Аминовым Львом Александровичем (далее — «Исполнитель», «Обработчик») персональных данных, содержащихся в Данных Заказчика, и являются неотъемлемой частью [Договора-оферты](https://tuna.am/tos.md) (п. 15.2). 1.2. В отношении персональных данных, содержащихся в Данных Заказчика, Заказчик выступает оператором (контролёром), а Исполнитель — обработчиком (процессором), действующим по поручению Заказчика. 1.3. В отношении данных аккаунта, платёжных данных, Служебных данных (п. 2.13 Договора) и данных посетителей сайта Исполнитель действует как самостоятельный оператор. Порядок такой обработки описан в [Политике конфиденциальности](https://tuna.am/policy.md) и настоящими Условиями не регулируется. 1.4. Настоящие Условия составлены с учётом требований Закона Республики Армения «О защите персональных данных», а в отношении Заказчиков, на которых распространяется действие Общего регламента по защите данных Европейского союза (GDPR, Регламент (ЕС) 2016/679), — с учётом требований статьи 28 указанного Регламента. 1.5. Термины, не определённые в настоящих Условиях, используются в значениях, установленных [Договором-офертой](https://tuna.am/tos.md). #### 2. Состав обработки 2.1. **Предмет обработки** — предоставление Сервисов платформы Tuna в соответствии с Договором. 2.2. **Срок обработки** — срок действия Договора с учётом сроков удаления данных, установленных разделом 8. 2.3. **Характер и цель обработки** — хранение, передача, отображение и иная техническая обработка Данных Заказчика, необходимая для работы Сервисов, обеспечения их работоспособности и безопасности. 2.4. **Категории субъектов данных** определяются Заказчиком и могут включать его работников, участников его Организации, его клиентов и иных лиц, чьи данные Заказчик передаёт в Сервисы. 2.5. **Категории персональных данных** определяются Заказчиком. В зависимости от используемых Сервисов они могут включать: | Сервис | Что технически обрабатывается | | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ | | Туннели и шлюзы | Трафик, передаваемый транзитом между Заказчиком и его пользователями; технические данные соединений (IP-адреса, время, объём, адреса назначения) | | Вебхуки, инспектор запросов | Содержимое входящих HTTP-запросов, сохраняемое для отладки | | Приложения (Zero Trust доступ) | Идентификаторы и атрибуты пользователей, проходящих аутентификацию, журналы доступа | | Бастион | Идентификаторы пользователей, журналы и параметры SSH-сессий | | Секреты | Конфигурационные данные приложений Заказчика в зашифрованном виде | | Пароли | Данные хранилища в зашифрованном виде; ключи расшифровки Исполнителю не передаются | | Отчёты | Скриншоты, записи экрана, технические сведения о сессии пользователей сайта Заказчика | | Встречи, доски | Аудио- и видеопотоки, сообщения чата, материалы совместной работы | | Мониторы, статус-страницы | Адреса проверяемых ресурсов, результаты проверок, контакты для уведомлений | 2.6. Заказчик самостоятельно определяет состав данных, передаваемых в Сервисы, и не размещает в них данные, обработка которых требует мер защиты, не предусмотренных Договором и документацией (п. 13.5 Договора). #### 3. Обязанности Исполнителя 3.1. Исполнитель обрабатывает Данные Заказчика только по документированному поручению Заказчика, которым признаются настоящие Условия, Договор и действия Заказчика при использовании Сервисов. 3.2. Исполнитель не использует Данные Заказчика для собственных целей, в том числе для обучения моделей машинного обучения и для рекламы. Настоящий пункт не ограничивает обработку Служебных данных, в отношении которых Исполнитель действует как самостоятельный оператор (п. 1.3 настоящих Условий, п. 13.8 Договора). Служебные данные не включают содержимое Данных Заказчика, а равно журналы доступа Приложений и журналы сессий Бастиона, которые Сервис ведёт для Заказчика и в отношении которых Исполнитель остаётся обработчиком. 3.3. Исполнитель обеспечивает, чтобы лица, имеющие доступ к Данным Заказчика, были связаны обязательством конфиденциальности. 3.4. Исполнитель принимает организационные и технические меры защиты, соразмерные рискам, включая: * шифрование трафика при передаче (TLS); * шифрование чувствительных данных при хранении; * модель нулевого знания для менеджера паролей; * разграничение прав доступа и минимизацию круга лиц, имеющих доступ к продуктивной среде; * ведение журналов доступа и событий безопасности; * резервное копирование инфраструктуры и регулярное обновление компонентов. 3.5. Исполнитель незамедлительно уведомляет Заказчика, если, по его мнению, поручение Заказчика нарушает применимое законодательство о защите персональных данных. 3.6. Исполнитель уведомляет Заказчика о нарушении безопасности, затронувшем Данные Заказчика, без неоправданной задержки после того, как ему стало известно о таком нарушении, и предоставляет информацию, необходимую Заказчику для исполнения его собственных обязанностей по уведомлению. 3.7. Исполнитель оказывает Заказчику разумное содействие в исполнении запросов субъектов данных и в проведении оценки воздействия на защиту данных в объёме, доступном Исполнителю с учётом характера обработки. 3.8. Если Исполнитель получает запрос субъекта данных, относящийся к Данным Заказчика, он не отвечает на него по существу, а перенаправляет его Заказчику. #### 4. Обязанности Заказчика 4.1. Заказчик гарантирует наличие правового основания для обработки персональных данных, передаваемых им в Сервисы, включая получение необходимых согласий и уведомление субъектов данных. 4.2. Заказчик самостоятельно обеспечивает реализацию прав субъектов данных, исполнение обязанностей оператора и соблюдение требований законодательства, применимого к его деятельности, включая уведомление уполномоченных органов, если оно требуется. 4.3. Заказчик самостоятельно настраивает права доступа участников своей Организации, своевременно отзывает доступ у выбывших участников и определяет, какие данные подлежат маскированию в тех Сервисах, где такая возможность предусмотрена документацией. 4.4. Заказчик самостоятельно определяет и соблюдает сроки хранения данных, размещаемых в Сервисах, в пределах технических возможностей, предусмотренных документацией. #### 5. Привлечение суб-обработчиков 5.1. Заказчик даёт Исполнителю общее согласие на привлечение суб-обработчиков для предоставления Сервисов. 5.2. Исполнитель заключает с каждым суб-обработчиком соглашение, устанавливающее не менее строгие обязательства по защите данных, чем предусмотренные настоящими Условиями, и отвечает за действия суб-обработчиков как за собственные. 5.3. На дату настоящей редакции привлекаются следующие категории суб-обработчиков: | Категория | Назначение | Расположение | | -------------------------------------------- | ---------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | Провайдеры хостинга и сетевой инфраструктуры | Размещение серверов платформы, туннельных и мониторинговых узлов, баз данных | Российская Федерация, Германия, Нидерланды и иные страны, указанные в разделе [Регионы](https://tuna.am/docs/tunnels/guides/locations.md) | | Functional Software, Inc. (Sentry) | Мониторинг ошибок приложений | США | 5.4. Актуальный перечень регионов, доступных для подключения туннелей и для проверок мониторинга, публикуется в разделе [Регионы](https://tuna.am/docs/tunnels/guides/locations.md) и изменяется по мере развития инфраструктуры. Регион Заказчик выбирает самостоятельно при запуске туннеля или настройке монитора и учитывает это при работе с данными, содержащими персональные данные. 5.5. Появление нового региона, использование которого Заказчик выбирает самостоятельно, не является изменением перечня суб-обработчиков и не требует уведомления по п. 5.6, поскольку обработка в таком регионе начинается по решению самого Заказчика. 5.6. Об изменении перечня суб-обработчиков, влияющем на обработку Данных Заказчика независимо от выбора Заказчика (в частности, при переносе серверов платформы и баз данных), Исполнитель уведомляет через Личный кабинет или по электронной почте не менее чем за 14 календарных дней. Если Заказчик обоснованно возражает против нового суб-обработчика, он вправе расторгнуть Договор до вступления изменения в силу; в этом случае неиспользованная часть оплаченной Подписки возвращается пропорционально. #### 6. Трансграничная передача 6.1. Обработка Данных Заказчика осуществляется на инфраструктуре, расположенной в Российской Федерации, Германии и Нидерландах, а также, в части мониторинга ошибок, в США. Перечень стран изменяется по мере появления новых регионов; актуальный перечень публикуется в разделе [Регионы](https://tuna.am/docs/tunnels/guides/locations.md). 6.2. В отношении субъектов данных, находящихся в Европейской экономической зоне, передача в государства, не признанные Европейской комиссией обеспечивающими адекватный уровень защиты, осуществляется на основании стандартных договорных условий. 6.3. Заказчик, на которого распространяются требования локализации персональных данных, самостоятельно определяет допустимость использования конкретного региона и Сервиса. #### 7. Раскрытие уполномоченным органам 7.1. Исполнитель раскрывает Данные Заказчика уполномоченным органам только на основании официального запроса, оформленного в соответствии с законодательством, и в объёме, необходимом для исполнения требований закона. 7.2. Если это не запрещено законом, Исполнитель уведомляет Заказчика о поступившем запросе до его исполнения. #### 8. Возврат и удаление данных 8.1. В течение срока действия Договора Заказчик самостоятельно управляет своими данными и вправе удалять и выгружать их средствами, предусмотренными документацией. 8.2. После прекращения Договора или удаления аккаунта Данные Заказчика удаляются в срок не более 30 календарных дней, за исключением данных, подлежащих хранению в силу требований законодательства. 8.3. Резервные копии баз данных хранятся не более 30 дней с момента создания и удаляются по истечении срока ротации. 8.4. Технические журналы, содержащие метаданные соединений, хранятся не более 90 дней и используются для обеспечения безопасности, диагностики и рассмотрения жалоб на злоупотребления. #### 9. Подтверждение соответствия 9.1. По письменному запросу Заказчика Исполнитель предоставляет информацию, необходимую для подтверждения соблюдения настоящих Условий. 9.2. Проверка проводится не чаще одного раза в 12 месяцев, за исключением случаев, когда её проведение требуется уполномоченным органом или вызвано подтверждённым нарушением безопасности. Стороны согласовывают формат и сроки проверки заранее; проверка не должна нарушать конфиденциальность данных других клиентов и работу платформы. #### 10. Ответственность и изменение Условий 10.1. Ответственность сторон по настоящим Условиям ограничивается пределами, установленными разделом 19 [Договора-оферты](https://tuna.am/tos.md). 10.2. Исполнитель вправе изменять настоящие Условия в порядке, предусмотренном разделом 22 [Договора-оферты](https://tuna.am/tos.md). Актуальная редакция публикуется по адресу [/dpa/](https://tuna.am/dpa.md) с указанием даты. 10.3. Для Заказчиков, которым требуется подписанное соглашение об обработке персональных данных на бумаге или в форме электронного документа, такое соглашение заключается по запросу на адрес . --- ## Policy ### Политика конфиденциальности **Редакция от: 30 сентября 2026 г.** #### 1. Общие положения 1.1. Настоящая Политика определяет порядок обработки персональных данных Индивидуальным предпринимателем Аминовым Львом Александровичем, учётный номер налогоплательщика (ՀՎՀՀ/TIN): 71062923, Республика Армения (далее — «Оператор», «мы»). 1.2. Политика составлена в соответствии с Законом Республики Армения «О защите персональных данных» (ՀՕ-49-Ն от 18 мая 2015 года). В отношении лиц, находящихся в Европейской экономической зоне, дополнительно применяются положения Общего регламента по защите данных Европейского союза (GDPR, Регламент (ЕС) 2016/679). В терминологии GDPR Оператор выступает контролёром данных (data controller) в пределах, указанных в разделе 3. 1.3. Политика распространяется на обработку данных: * посетителей сайта , документации и его поддоменов; * пользователей личного кабинета и API ; * пользователей клиентского программного обеспечения Tuna; * лиц, обращающихся в техническую поддержку. 1.4. Использование сайта, личного кабинета и сервисов платформы означает ознакомление с настоящей Политикой. Условия использования сервисов определяются [Договором-офертой](https://tuna.am/tos.md). 1.5. Актуальная редакция Политики размещена по адресу [/policy/](https://tuna.am/policy.md). #### 2. Термины 2.1. **Персональные данные** — любая информация, относящаяся прямо или косвенно к определённому или определяемому физическому лицу. 2.2. **Обработка** — любое действие с персональными данными: сбор, запись, хранение, использование, передача, удаление и иные операции. 2.3. **Пользователь** — посетитель сайта, пользователь личного кабинета, API или клиентского программного обеспечения. 2.4. **Заказчик** — лицо, заключившее [Договор-оферту](https://tuna.am/tos.md) и использующее сервисы платформы Tuna. 2.5. **Данные Заказчика** — данные, которые Заказчик и его пользователи передают, размещают или пропускают через сервисы платформы. #### 3. Разграничение ролей 3.1. В отношении данных аккаунта, платёжных данных, технических журналов, обращений в поддержку и данных посетителей сайта Оператор действует как самостоятельный оператор (контролёр). Порядок такой обработки описан в настоящей Политике. 3.2. В отношении персональных данных, содержащихся в Данных Заказчика, оператором (контролёром) выступает сам Заказчик: он определяет цели и способы обработки, а Оператор действует как обработчик (процессор) по его поручению. Условия такой обработки установлены [Условиями обработки данных Заказчика](https://tuna.am/dpa.md). 3.3. Трафик, передаваемый через туннели и шлюзы, обрабатывается транзитом. Оператор не анализирует его содержимое, за исключением технически необходимой обработки для маршрутизации, применения настроенных Заказчиком политик обработки трафика, обеспечения безопасности и рассмотрения жалоб на злоупотребления. 3.4. Менеджер паролей построен по модели нулевого знания: ключи расшифровки формируются на стороне пользователя и Оператору не передаются. Оператор технически не имеет доступа к содержимому хранилища паролей. 3.5. Отдельные сервисы по своей природе предполагают хранение содержимого данных на инфраструктуре Оператора (вебхуки, отчёты, секреты, материалы встреч и досок). Состав таких данных определяет Заказчик; ограничения установлены разделами 13 и 14 [Договора-оферты](https://tuna.am/tos.md). #### 4. Категории обрабатываемых данных ##### 4.1. Посетители сайта и документации * IP-адрес, тип и версия браузера и операционной системы, язык, разрешение экрана; * источник перехода, посещённые страницы, время и длительность визита; * поисковые запросы в документации; * идентификаторы файлов печенья. ##### 4.2. Пользователи личного кабинета * адрес электронной почты; * имя, если указано Пользователем; * хеш пароля либо идентификатор учётной записи у провайдера OpenID/SSO, если вход выполняется через него; * данные ключей доступа WebAuthn (публичный ключ и идентификатор ключа), если Пользователь включил такой способ входа; * данные о приобретённых подписках, тарифах и дополнительных лицензиях; * сведения о платежах: сумма, валюта, дата, статус, идентификатор транзакции, маскированные реквизиты платёжного средства (тип карты и последние четыре цифры), токен сохранённого платёжного средства; * реквизиты, необходимые для выставления счёта и оформления закрывающих документов, если оплата производится по счёту; * IP-адрес, дата и время входа, журналы действий в личном кабинете и события аудита организации. Полные номера банковских карт, CVV-коды и иные полные платёжные реквизиты Оператору не передаются и им не хранятся — их обрабатывают платёжные провайдеры (п. 7.1). ##### 4.3. Пользователи клиентского программного обеспечения и API При подключении клиентского программного обеспечения и при обращениях к API обрабатываются: * идентификатор аккаунта и используемый токен доступа; * IP-адрес подключения; * версия клиентского программного обеспечения, тип и версия операционной системы, архитектура; * параметры создаваемых ресурсов: адреса и имена туннелей, регион подключения, время начала и завершения сессии, объём переданного трафика. Часть указанных данных, в первую очередь IP-адреса, относится к персональным данным, в связи с чем к ним применяется настоящая Политика. В адресах туннелей с динамически выделяемым именем IP-адрес источника используется в составе доменного имени — это антифрод-мера, описанная в разделе [Злоупотребления](https://tuna.am/docs/abuse.md); скрыть его можно в настройках организации. ##### 4.4. Обращения в техническую поддержку и жалобы на злоупотребления * адрес электронной почты и содержание переписки; * имя пользователя и содержание сообщений при обращении в Telegram-чат; * сведения, добровольно предоставленные для диагностики: журналы работы клиентского ПО, конфигурации, снимки экрана; * сведения, содержащиеся в жалобе на злоупотребление, включая данные заявителя. Пользователю следует удалять из передаваемых материалов сведения, не относящиеся к решаемой проблеме. #### 5. Цели и правовые основания обработки | Данные | Цель | Правовое основание | | -------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | | Учётная запись личного кабинета | Регистрация, предоставление доступа к сервисам, управление подпиской | Исполнение договора | | Платёжные данные | Приём оплаты, продление подписки, возвраты | Исполнение договора | | Реквизиты и документы об оплате | Бухгалтерский и налоговый учёт | Выполнение требований законодательства | | Технические данные подключений (п. 4.3) | Предоставление сервисов, тарификация и контроль лимитов, диагностика | Исполнение договора | | Журналы доступа и события безопасности | Защита от несанкционированного доступа, противодействие злоупотреблениям, рассмотрение жалоб | Законный интерес Оператора и третьих лиц | | Обезличенные и агрегированные производные технических журналов | Статистика, планирование мощностей, улучшение и разработка сервисов, обучение моделей машинного обучения для этих целей (п. 13.8 [Договора-оферты](https://tuna.am/tos.md)) | Обработка обезличенных данных; персональные данные для этих целей не используются | | Обращения в поддержку | Оказание технической поддержки | Исполнение договора; законный интерес | | Данные веб-аналитики и печенье | Анализ посещаемости, улучшение сайта | Законный интерес Оператора | | Запись действий на странице («Вебвизор») на сайте и в документации | Диагностика проблем в интерфейсе | Согласие Пользователя | | Адрес электронной почты для рассылок | Информирование о продуктах, обновлениях и предложениях | Согласие Пользователя | | Сервисные уведомления (предстоящее списание, изменение условий, инциденты) | Исполнение обязательств по договору | Исполнение договора | 5.1. Сервисные уведомления направляются независимо от согласия на маркетинговые рассылки, поскольку необходимы для исполнения договора. Отказаться от них, продолжая пользоваться сервисами, невозможно. 5.2. Оператор не осуществляет обработку специальных категорий персональных данных для собственных целей и не принимает решений, основанных исключительно на автоматизированной обработке и порождающих юридические последствия для Пользователя. Автоматические ограничения, применяемые при превышении лимитов и выявлении злоупотреблений, могут быть обжалованы в порядке п. 12.8 [Договора-оферты](https://tuna.am/tos.md). #### 6. Печенье и веб-аналитика 6.1. На сайте используются файлы [печенья](https://ru.wikipedia.org/wiki/Cookie) (cookie) следующих категорий: * **Необходимые** — обеспечивают работу сайта и личного кабинета: сессия, аутентификация, выбранный язык и тема оформления, сохранение выбора в отношении печенья. Устанавливаются без согласия, поскольку без них сервис не работает. * **Аналитические** — используются сервисом Яндекс.Метрика для сбора обезличенной статистики посещаемости. Устанавливаются при посещении сайта на основании законного интереса Оператора в анализе посещаемости. Отказаться от них можно, запретив файлы печенья в настройках браузера. 6.2. При первом посещении сайта или документации Пользователю предлагается разрешить или запретить запись действий на странице (п. 6.4). Выбор общий для сайта и документации. Без согласия запись не ведётся. Изменить или отозвать своё решение можно в любой момент здесь: Выбор ещё не сделан. Изменить настройки печенья 6.3. Сервис Яндекс.Метрика предоставляется ООО «ЯНДЕКС» и предполагает передачу данных на серверы, расположенные на территории Российской Федерации. Условия обработки данных сервисом доступны в [политике конфиденциальности Яндекса](https://yandex.ru/legal/confidential/). Счётчик используется совместно для сайта, документации и личного кабинета, что позволяет Оператору видеть путь Пользователя между ними. 6.4. На сайте, в документации и в личном кабинете применяется функция записи действий пользователя на странице («Вебвизор»). На сайте и в документации она включается только после согласия Пользователя (п. 6.2). Запись нужна для диагностики проблем в интерфейсе и разбора обращений в поддержку. Поля ввода и данные, отнесённые к чувствительным, при записи маскируются и в записи не попадают. На сайте и в документации от записи можно отказаться, не давая согласия или отозвав его (п. 6.2). Если вы возражаете против записи ваших действий в личном кабинете, напишите на — мы исключим вас из сбора. 6.5. На сайте установлен встраиваемый скрипт собственного сервиса Оператора [«Отчёты»](https://tuna.am/docs/reports.md). Он собирает технические сведения о сессии, действия на странице и снимок экрана и передаёт их Оператору при создании отчёта об ошибке. Чувствительные поля при этом маскируются в порядке, описанном в [документации сервиса](https://tuna.am/docs/reports/privacyOptions.md). Данные обрабатываются Оператором и третьим лицам не передаются. 6.6. Поиск по документации работает на сервисе Algolia DocSearch: поисковые запросы и технические параметры обращения передаются сервису для выполнения поиска. Отдельные ресурсы сайта (шрифты, стили, скрипты проигрывателя терминальных записей) загружаются с публичной сети доставки контента jsDelivr, которой при загрузке становится известен IP-адрес Пользователя. 6.7. Отказ от записи действий на странице не ограничивает доступ к сайту, документации и личному кабинету. #### 7. Передача данных третьим лицам 7.1. Для оказания услуг Оператор привлекает следующие категории получателей данных: | Категория получателя | Передаваемые данные | Назначение | | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | PayPro Global (PayPro Global Inc. и её аффилированные лица, Канада, США, Европейский союз) | Имя, адрес электронной почты, платёжные реквизиты, страна плательщика, сумма и параметры платежа | Приём оплаты в долларах США, выставление счетов, расчёт и уплата налогов, обработка возвратов и автопродления. Выступает авторизованным реселлером (merchant of record) и в отношении собираемых им данных является самостоятельным контролёром | | ООО НКО «ЮМани» (сервис ЮKassa, Российская Федерация) | Адрес электронной почты, платёжные реквизиты, сумма и параметры платежа | Приём оплаты банковской картой в рублях | | Агент по приёму платежей (п. 10.3 [Договора-оферты](https://tuna.am/tos.md), Российская Федерация) | Наименование и реквизиты плательщика, адрес электронной почты, сумма и параметры платежа | Выставление счетов и приём оплаты от юридических лиц и индивидуальных предпринимателей на территории Российской Федерации | | Провайдеры хостинга и сетевой инфраструктуры (Российская Федерация, Германия, Нидерланды и иные страны, указанные в разделе [Регионы](https://tuna.am/docs/tunnels/guides/locations.md)) | Данные, размещаемые на серверах Оператора | Размещение и функционирование платформы, туннельных и мониторинговых узлов, личного кабинета и баз данных | | Functional Software, Inc. (сервис Sentry, США) | Технические сведения об ошибке, IP-адрес, идентификатор пользователя, контекст запроса | Выявление и устранение неисправностей | | Провайдер отправки электронной почты | Адрес электронной почты, имя, содержание и статус доставки письма | Отправка сервисных уведомлений и рассылок | | ООО «ЯНДЕКС» (Яндекс.Метрика, Российская Федерация) | Данные, указанные в п. 4.1 | Анализ посещаемости сайта; запись действий на странице — только после согласия | | Algolia (сервис DocSearch) | Поисковый запрос, IP-адрес, технические параметры обращения | Поиск по документации | | Мессенджер Telegram | Данные, добровольно направленные Пользователем в чат поддержки | Оказание технической поддержки | 7.2. Все привлекаемые получатели обрабатывают данные исключительно в объёме, необходимом для указанных целей, и связаны обязательствами по обеспечению конфиденциальности. 7.3. Оператор не продаёт персональные данные, не передаёт их для целей рекламы третьих лиц и не раскрывает их иным лицам, кроме указанных в настоящем разделе. 7.4. При рассмотрении жалобы на злоупотребление Оператор вправе передать пострадавшей стороне, интернет-провайдеру или иному компетентному лицу минимально необходимую техническую информацию (в частности, IP-адрес и время сессий) без раскрытия персональных данных Заказчика, за исключением случаев, предусмотренных законом. 7.5. Раскрытие данных уполномоченным органам осуществляется только на основании их официального запроса, оформленного в соответствии с законодательством, и только в объёме, необходимом для исполнения требований закона. 7.6. При реорганизации деятельности Оператора либо отчуждении прав на платформу Tuna данные могут быть переданы правопреемнику с сохранением условий настоящей Политики; Пользователи уведомляются об этом заблаговременно. #### 8. Место хранения и трансграничная передача 8.1. Данные размещаются на серверах Оператора и привлекаемых им провайдеров инфраструктуры в Российской Федерации, Германии и Нидерландах. Перечень стран изменяется по мере появления новых регионов; актуальный перечень регионов, доступных для туннелей и проверок мониторинга, публикуется в разделе [Регионы](https://tuna.am/docs/tunnels/guides/locations.md). Регион Пользователь выбирает самостоятельно. 8.2. Использование сервисов, указанных в разделе 7, влечёт передачу отдельных категорий данных за пределы Республики Армения, в том числе: * в Российскую Федерацию — инфраструктура регионов, размещённых в этой стране, сервис ЮKassa при оплате рублёвой картой, агент по приёму платежей при оплате по счёту, сервис веб-аналитики Яндекс.Метрика; * в Германию и Нидерланды — инфраструктура регионов, размещённых в этих странах; * в Соединённые Штаты Америки, Канаду и Европейский союз — PayPro Global при оплате в долларах США; * в Соединённые Штаты Америки — сервис мониторинга ошибок Sentry и сервис поиска по документации Algolia. 8.3. Правовым основанием такой передачи являются: * законный интерес Оператора — для статистики посещаемости, согласие Пользователя — для записи действий на странице; * необходимость исполнения договора, стороной которого является Пользователь, — для платёжных данных и данных, размещаемых на серверах провайдеров инфраструктуры. 8.4. В отношении субъектов данных, находящихся в Европейской экономической зоне, передача в государства, не признанные Европейской комиссией обеспечивающими адекватный уровень защиты, осуществляется на основании стандартных договорных условий либо явного согласия субъекта данных. #### 9. Сроки хранения | Данные | Срок хранения | | -------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | | Учётная запись личного кабинета | В течение всего срока существования учётной записи; после её удаления — до 30 дней в резервных копиях | | Данные Заказчика, размещённые в сервисах | В течение срока действия договора; после его прекращения — до 30 календарных дней (раздел 8 [Условий обработки данных Заказчика](https://tuna.am/dpa.md)) | | Данные о платежах и закрывающие документы | В течение срока, установленного законодательством Республики Армения о бухгалтерском учёте и налогообложении | | Технические журналы подключений и события безопасности | 90 дней | | Обезличенные и агрегированные производные технических журналов | Бессрочно; персональными данными не являются | | События аудита организации, отображаемые в личном кабинете | В течение срока существования организации | | Обращения в техническую поддержку | 3 года с даты последнего сообщения | | Материалы по жалобам на злоупотребления | 3 года с даты рассмотрения | | Данные веб-аналитики | В соответствии с политикой сервиса Яндекс.Метрика | | Адрес электронной почты в базе рассылки | До отзыва согласия | 9.1. По истечении срока хранения данные удаляются либо обезличиваются. Если данные необходимы для защиты прав Оператора в рамках заявленного или возможного спора, они сохраняются до истечения соответствующего срока исковой давности. #### 10. Права Пользователя 10.1. Пользователь вправе: * получить подтверждение факта обработки его данных и копию обрабатываемых данных; * требовать уточнения, исправления неточных или неполных данных; * требовать удаления данных, если отсутствуют законные основания для их дальнейшей обработки; * требовать ограничения обработки; * возражать против обработки, осуществляемой на основании законного интереса, а также против получения маркетинговых сообщений; * получить свои данные в структурированном, машиночитаемом формате и потребовать их передачи другому оператору (право на переносимость данных); * отозвать ранее данное согласие — отзыв не влияет на правомерность обработки, осуществлённой до его получения; * обжаловать действия Оператора в надзорном органе или в суде. 10.2. Для реализации любого из указанных прав достаточно направить сообщение на адрес с адреса электронной почты, указанного в личном кабинете. Специальные пометки в теме письма не требуются. Оператор отвечает в срок не более 30 календарных дней и вправе запросить дополнительные сведения для подтверждения личности заявителя. 10.3. Если запрос касается данных, обрабатываемых Оператором по поручению Заказчика (п. 3.2), Оператор перенаправляет его соответствующему Заказчику, который выступает оператором таких данных. 10.4. Отказаться от маркетинговых рассылок можно также по ссылке отписки в любом письме. 10.5. Удаление аккаунта влечёт прекращение доступа к сервисам и удаление размещённых в них данных в сроки, указанные в разделе 9. Данные, подлежащие хранению в силу требований законодательства, сохраняются в течение установленных сроков. 10.6. Надзорным органом является Агентство по защите персональных данных Министерства юстиции Республики Армения. Пользователи, находящиеся в Европейской экономической зоне, вправе также обратиться в надзорный орган по месту своего жительства. #### 11. Безопасность 11.1. Оператор реализует организационные и технические меры защиты данных, включая шифрование трафика (TLS), хранение паролей исключительно в виде необратимых хешей, шифрование чувствительных данных при хранении, модель нулевого знания в менеджере паролей, разграничение прав доступа, ведение журналов доступа и резервное копирование. 11.2. Абсолютная безопасность передачи и хранения данных в сети Интернет не может быть гарантирована. Пользователь обязан обеспечивать конфиденциальность своего пароля, мастер-ключа менеджера паролей и токенов доступа. Распределение ответственности в отношении чувствительных данных установлено разделом 14 [Договора-оферты](https://tuna.am/tos.md). 11.3. При выявлении нарушения безопасности, создающего высокий риск для прав и свобод субъектов данных, Оператор уведомляет затронутых Пользователей и уполномоченный орган в сроки, установленные применимым законодательством. #### 12. Несовершеннолетние 12.1. Сайт, личный кабинет и сервисы платформы Tuna не предназначены для лиц младше 16 лет. Оператор не осуществляет целенаправленный сбор данных таких лиц. При обнаружении факта регистрации лица младше 16 лет соответствующие данные подлежат удалению. #### 13. Изменения Политики 13.1. Оператор вправе вносить изменения в настоящую Политику. Актуальная редакция с указанием даты публикуется по адресу [/policy/](https://tuna.am/policy.md). 13.2. О существенных изменениях, затрагивающих цели обработки или состав передаваемых третьим лицам данных, зарегистрированные Пользователи уведомляются по электронной почте либо через личный кабинет не менее чем за 7 календарных дней до вступления изменений в силу. #### 14. Контакты По любым вопросам, связанным с обработкой персональных данных, а также для реализации прав, предусмотренных разделом 10: Индивидуальный предприниматель Аминов Лев Александрович
Адрес: 3901, Республика Армения, Тавушская область, г. Дилижан
Учётный номер налогоплательщика (ՀՎՀՀ/TIN): 71062923
Электронная почта: --- ## Tos ### Условия использования **Договор-оферта**
Редакция от: 13 августа 2026 г. #### 1. Общие положения 1.1. Настоящий документ является публичной офертой Индивидуального предпринимателя Аминова Льва Александровича, учётный номер налогоплательщика (ՀՎՀՀ/TIN): 71062923, Республика Армения (далее — «Исполнитель»), адресованной любому лицу, желающему использовать платформу Tuna (далее — «Заказчик»). 1.2. Исполнитель является обладателем исключительных прав на платформу Tuna, входящее в неё программное обеспечение и связанные с ними товарные знаки и бренды. 1.3. Актуальный текст настоящего Договора публикуется по адресу [https://tuna.am/tos/](https://tuna.am/tos.md). В случае акцепта Оферты Договор считается заключённым на условиях, изложенных в её действующей редакции на момент акцепта. 1.4. Неотъемлемой частью настоящего Договора являются: * страница тарифов и лимитов на Сайте и в Личном кабинете; * [Правила допустимого использования](https://tuna.am/aup.md); * [Условия обработки данных Заказчика](https://tuna.am/dpa.md); * [Условия технической поддержки](https://tuna.am/docs/support.md); * [Политика конфиденциальности](https://tuna.am/policy.md); * описание функциональных возможностей Сервисов в [документации](https://tuna.am/docs.md) и в Личном кабинете. 1.5. Настоящий Договор регулируется правом Республики Армения (раздел 23). #### 2. Термины и определения 2.1. **Платформа Tuna (Платформа)** — совокупность программ для ЭВМ, сервисов и инфраструктуры Исполнителя, включающая Личный кабинет, API, серверную инфраструктуру Исполнителя и Клиентское ПО. 2.2. **Сервисы** — функциональные возможности Платформы, предоставляемые Заказчику по настоящему Договору. Состав Сервисов определяется в порядке п. 6.1. 2.3. **Облачные сервисы** — Сервисы, работающие на инфраструктуре Исполнителя и не требующие установки программного обеспечения на оборудование Заказчика. 2.4. **Клиентское ПО** — программы для ЭВМ, устанавливаемые на оборудование Заказчика: клиент командной строки `tuna`, приложение для рабочего стола `tuna-desktop`, серверные компоненты, распространяемые Исполнителем для установки на стороне Заказчика, и иные подобные компоненты. 2.5. **Сайт** — информационно-телекоммуникационный ресурс Исполнителя по адресу , включая поддомены. 2.6. **Личный кабинет** — совокупность страниц по адресу , доступ к которым осуществляется по логину и паролю Заказчика либо через поддерживаемого провайдера OpenID/SSO. 2.7. **Аккаунт** — учётная запись Заказчика в Личном кабинете. 2.8. **Организация (Команда)** — объединение нескольких Аккаунтов с общими ресурсами, тарифом и ролевой моделью доступа. Заказчиком в отношении Организации является лицо, от имени которого Организация создана и на которое оформлена Подписка. 2.9. **Тариф** — набор Сервисов, функций и лимитов, предоставляемых за определённую плату либо на безвозмездной основе. Тарифы публикуются на Сайте и в Личном кабинете. 2.10. **Дополнительные лицензии** — платные опции, расширяющие лимиты Тарифа или добавляющие отдельные функции. 2.11. **Подписка** — право использования Сервисов в объёме выбранного Тарифа в течение оплаченного периода. 2.12. **Данные Заказчика** — любые данные, которые Заказчик или его Конечные пользователи передают, размещают, хранят или пропускают через Сервисы: трафик туннелей и шлюзов, содержимое запросов, файлы, секреты, пароли, записи встреч, отчёты, конфигурации и иные данные. 2.13. **Служебные данные** — данные, формируемые системами Исполнителя в связи с работой Платформы и использованием Сервисов: метаданные соединений (IP-адреса, время, объём и длительность, адреса назначения, коды ответов, показатели задержек), сведения о потреблении ресурсов и лимитов, диагностические и отладочные записи, события безопасности, технические журналы инфраструктуры. Служебные данные не включают содержимое Данных Заказчика, а равно журналы и записи, которые Сервис ведёт для Заказчика как часть своей функциональности, в частности журналы доступа Приложений и журналы сессий Бастиона. 2.14. **Конечный пользователь** — участник Организации Заказчика, а равно любое лицо, которому Заказчик предоставил доступ к Сервисам или к результатам их работы. 2.15. **Потребитель** — физическое лицо, приобретающее или использующее Сервисы для личных, семейных, домашних и иных нужд, не связанных с осуществлением предпринимательской деятельности. 2.16. **Реселлер** — авторизованный реселлер Исполнителя, выступающий продавцом в отношениях с Заказчиком при оплате через соответствующий канал (п. 10.2). 2.17. **Агент** — лицо, принимающее оплату в пользу Исполнителя на основании агентского договора (п. 10.3). 2.18. **Оферта** — настоящее предложение Исполнителя, адресованное неопределённому кругу лиц. 2.19. **Акцепт Оферты** — полное и безоговорочное принятие Заказчиком условий Оферты путём совершения действий, указанных в разделе 3. Термины и определения используются в настоящем Договоре исключительно в значениях, указанных в настоящем разделе. #### 3. Заключение Договора (Акцепт Оферты) 3.1. Акцептом Оферты признаётся совершение Заказчиком любого из следующих действий: * регистрация Аккаунта в Личном кабинете; * вход в Личный кабинет через провайдера OpenID/SSO; * использование любого из Сервисов, в том числе через Клиентское ПО или API; * оплата любого платного Тарифа или Дополнительной лицензии. 3.2. Совершая любое из действий, указанных в п. 3.1, Заказчик подтверждает, что ознакомился с условиями настоящего Договора и документами, указанными в п. 1.4, полностью их понимает и принимает без оговорок. 3.3. Договор считается заключённым с момента совершения первого из указанных действий и действует в порядке, предусмотренном разделом 22. 3.4. Если Заказчик не согласен с условиями настоящего Договора, он обязан прекратить использование Платформы и удалить Клиентское ПО со своего оборудования. 3.5. Заказчик — юридическое лицо или индивидуальный предприниматель подтверждает, что лицо, совершающее Акцепт, обладает необходимыми полномочиями. 3.6. Регистрация Аккаунта лицами младше 16 лет не допускается. #### 4. Предмет Договора 4.1. По настоящему Договору Исполнитель обязуется предоставить Заказчику доступ к Сервисам в объёме выбранного Тарифа, а Заказчик обязуется соблюдать условия Договора и оплачивать Подписку, если выбранный Тариф является платным. 4.2. В части Клиентского ПО Исполнитель предоставляет Заказчику право использования на условиях простой (неисключительной) безвозмездной лицензии на срок действия настоящего Договора, на территории всех стран мира, с учётом ограничений раздела 20. Вознаграждение за использование Клиентского ПО включено в стоимость Подписки и отдельно не взимается. 4.3. Клиентское ПО распространяется в виде исполняемых (двоичных) файлов и в иных форматах, публикуемых Исполнителем. Исходный код Заказчику не передаётся, если иное прямо не указано для конкретного компонента. Настоящий Договор не является договором об отчуждении исключительного права. 4.4. Отдельные компоненты Платформы могут распространяться на условиях лицензий открытого исходного кода. К таким компонентам применяются условия соответствующих лицензий, и положения настоящего Договора не ограничивают прав, предоставляемых Заказчику этими лицензиями. 4.5. Настоящий Договор не является договором об оказании услуг связи и не предполагает предоставления Заказчику доступа к сети Интернет. #### 5. Аккаунт и доступ 5.1. Заказчик обязан предоставить достоверные данные при регистрации и поддерживать их в актуальном состоянии, в том числе адрес электронной почты, используемый для юридически значимых сообщений (п. 24.6). 5.2. Заказчик самостоятельно обеспечивает конфиденциальность пароля, ключей доступа, сервисных токенов и иных учётных данных. Действия, совершённые с использованием учётных данных Заказчика, считаются совершёнными Заказчиком. 5.3. Заказчик обязан незамедлительно уведомить Исполнителя по адресу о любом известном ему факте несанкционированного доступа к Аккаунту. 5.4. Исполнитель предоставляет средства защиты Аккаунта, включая многофакторную аутентификацию. Отказ Заказчика от их использования относится к зоне его ответственности. 5.5. Заказчик, создавший Организацию, самостоятельно определяет состав её участников и их роли, обеспечивает соблюдение ими условий настоящего Договора и отвечает за их действия как за свои собственные. 5.6. Один Аккаунт предназначен для использования одним лицом. Передача учётных данных третьим лицам не допускается; для совместной работы используется Организация. #### 6. Состав Сервисов и порядок их предоставления 6.1. Актуальный состав Сервисов, их функциональные возможности и лимиты определяются [документацией](https://tuna.am/docs.md) и Личным кабинетом на момент использования. Перечень Сервисов не является закрытым: Исполнитель вправе вводить новые Сервисы и функции, и с момента их предоставления Заказчику они являются частью Платформы и регулируются настоящим Договором без внесения в него изменений. 6.2. Для отдельных Сервисов Исполнитель вправе устанавливать специальные условия использования, публикуемые в документации соответствующего Сервиса. Такие специальные условия являются частью настоящего Договора и в случае противоречия имеют приоритет перед общими положениями Договора применительно к соответствующему Сервису. 6.3. Облачные сервисы предоставляются на инфраструктуре Исполнителя. Исполнитель самостоятельно определяет техническую архитектуру, состав используемых подрядчиков и провайдеров инфраструктуры, а также состав и расположение центров обработки данных, если для конкретного Сервиса не предусмотрен выбор региона. 6.4. Клиентское ПО устанавливается и запускается Заказчиком самостоятельно. Заказчик за свой счёт обеспечивает оборудование, каналы связи, электропитание, актуальность версий Клиентского ПО и информационную безопасность собственной инфраструктуры. 6.5. Исполнитель вправе изменять функциональные возможности Сервисов, выпускать новые версии Клиентского ПО, добавлять и удалять функции. В течение уже оплаченного периода Подписки функциональные возможности, заявленные для соответствующего Тарифа на момент оплаты, существенно не сокращаются, за исключением случаев, когда это вызвано требованиями законодательства, требованиями безопасности, прекращением поддержки со стороны третьих лиц или иными не зависящими от Исполнителя обстоятельствами. 6.6. О прекращении предоставления отдельного платного Сервиса или существенном сокращении его функциональности Исполнитель уведомляет затронутых Заказчиков по электронной почте или через Личный кабинет не менее чем за 30 календарных дней. Если такое прекращение приходится на оплаченный период и Заказчик не согласен продолжать пользоваться Подпиской, Исполнитель по требованию Заказчика возвращает неиспользованную часть оплаты пропорционально оставшемуся периоду. 6.7. Функции, обозначенные как экспериментальные, бета- или предварительные, предоставляются «как есть», без гарантий доступности и сохранности данных, и могут быть изменены или прекращены в любой момент без предварительного уведомления и без компенсации. 6.8. Исполнитель не осуществляет резервное копирование Данных Заказчика в интересах Заказчика, если такая функция прямо не заявлена для конкретного Сервиса. Организация резервного копирования данных, критичных для деятельности Заказчика, относится к зоне его ответственности. #### 7. Тарифы, лимиты и справедливое использование 7.1. Тарифы, состав включённых функций и количественные лимиты (в том числе ограничения по числу ресурсов, скорости, количеству запросов и объёму хранимых данных) публикуются на Сайте, в Личном кабинете и в [документации](https://tuna.am/docs/restrictions.md). 7.2. Исполнитель вправе изменять состав и величину лимитов. Изменения, ухудшающие положение Заказчика в рамках уже оплаченного периода Подписки, применяются к нему не ранее окончания этого периода, за исключением случаев, предусмотренных п. 6.5 и п. 7.4. 7.3. Сервисы предоставляются на условиях разделяемых ресурсов и справедливого использования. Исполнитель вправе применять технические ограничения к нагрузке, создаваемой Заказчиком, если она существенно превышает типичную для выбранного Тарифа и препятствует нормальной работе других пользователей. 7.4. Исполнитель вправе временно ограничить или приостановить работу отдельных Сервисов Заказчика без предварительного уведомления, если это необходимо для устранения угрозы работоспособности или безопасности Платформы. О таком ограничении Заказчик уведомляется в разумный срок. 7.5. Бесплатный Тариф предоставляется «как есть», без гарантий доступности и сохранности данных. Исполнитель вправе изменять условия бесплатного Тарифа, ограничивать его функциональность и прекращать его предоставление, уведомив Заказчиков по электронной почте или через Личный кабинет не менее чем за 14 календарных дней. 7.6. Исполнитель вправе удалять ресурсы и данные Аккаунтов на бесплатном Тарифе, не использовавшихся более 6 месяцев подряд, предварительно уведомив Заказчика по электронной почте не менее чем за 14 календарных дней. #### 8. Стоимость и порядок расчётов 8.1. Стоимость Подписки и Дополнительных лицензий определяется тарифами, действующими на момент оплаты. Оплата осуществляется на условиях 100% предоплаты. 8.2. Валюта оплаты и доступные способы оплаты отображаются в Личном кабинете. Стоимость одного и того же Тарифа в разных валютах и для разных регионов устанавливается Исполнителем независимо, может различаться и не является результатом конвертации по курсу. Регион определяется по данным Заказчика, указанным при регистрации и при оформлении платежа, включая страну плательщика. Заказчик оплачивает стоимость, отображённую при оформлении заказа на момент оплаты; последующее изменение курсов валют, а равно стоимости, установленной для иных валют и регионов, не влечёт перерасчёта, и Заказчик не вправе требовать применения к нему стоимости, установленной для другой валюты или другого региона. 8.3. Обязательство Заказчика по оплате считается исполненным с момента поступления денежных средств в полном объёме Исполнителю, его Реселлеру (п. 10.2) либо его Агенту (п. 10.3). При неполной оплате Сервисы в объёме платного Тарифа не предоставляются. 8.4. Комиссии и сборы платёжных систем, банков и иных посредников оплачиваются Заказчиком самостоятельно сверх стоимости Подписки. 8.5. При оплате непосредственно Исполнителю либо через Агента стоимость не облагается налогом на добавленную стоимость в соответствии с применяемым Исполнителем налоговым режимом Республики Армения. 8.6. При оплате через Реселлера (п. 10.2) расчёт, взимание и уплата применимых косвенных налогов (налога на добавленную стоимость, налога с продаж и аналогичных) осуществляются Реселлером в соответствии с законодательством страны Заказчика. Итоговая сумма к оплате, отображаемая при оформлении заказа, может превышать базовую стоимость Тарифа на сумму таких налогов. 8.7. За пределами случаев, предусмотренных п. 8.6, все налоги, сборы и пошлины, подлежащие уплате в юрисдикции Заказчика в связи с приобретением Подписки, включая налоги, удерживаемые у источника выплаты, уплачиваются Заказчиком самостоятельно и в стоимость Подписки не включены. Если законодательство юрисдикции Заказчика обязывает его удержать какой-либо налог из суммы платежа, сумма платежа подлежит увеличению таким образом, чтобы Исполнитель получил сумму, равную той, которую он получил бы при отсутствии такого удержания. 8.8. Закрывающие документы предоставляются по запросу Заказчика на адрес электронной почты, указанный в разделе 25. При оплате через Реселлера счета и иные документы об оплате формирует Реселлер. 8.9. При отсутствии мотивированных письменных возражений Заказчика в течение 5 (пяти) рабочих дней с даты предоставления доступа к оплаченному Тарифу услуги за соответствующий период считаются оказанными надлежащим образом и принятыми Заказчиком в полном объёме. Указанное не лишает Заказчика права предъявлять претензии к качеству Сервисов в течение всего срока действия Договора в порядке раздела 23. 8.10. Плата за Подписку является абонентской: она вносится за предоставление доступа к Сервисам в объёме выбранного Тарифа в течение оплаченного периода и не зависит от того, в каком объёме Заказчик фактически воспользовался Сервисами в этом периоде. Неиспользование Сервисов полностью или частично, в том числе неиспользование доступных по Тарифу лимитов и функциональных возможностей, не является основанием для перерасчёта или возврата платы; неиспользованный объём на следующий период не переносится. #### 9. Подписка, автопродление и изменение тарифов 9.1. Подписка оформляется на месячный или годовой период в соответствии с выбранным Тарифом. 9.2. **Подписка на месяц** означает предоставление Сервисов до соответствующего календарного числа следующего месяца. Если в следующем месяце соответствующее число отсутствует, срок Подписки истекает в последний день этого месяца. 9.3. **Подписка на год** означает предоставление Сервисов до соответствующего календарного числа того же месяца следующего года. Если такое число отсутствует, срок Подписки истекает в последний день соответствующего месяца. 9.4. При оплате платной Подписки используемое платёжное средство сохраняется, и автоматическое продление Подписки включается по умолчанию. 9.5. Списание при автоматическом продлении производится не ранее чем за 24 (двадцать четыре) часа до окончания текущего оплаченного периода по тарифу, действующему на момент списания. 9.6. Исполнитель уведомляет Заказчика по электронной почте о предстоящем списании не позднее чем за 3 (три) календарных дня до даты списания. После получения уведомления Заказчик вправе отказаться от продления либо сохранить Подписку. 9.7. Заказчик вправе в любой момент отменить Подписку и удалить сохранённое платёжное средство в Личном кабинете. Отмена прекращает автоматическое продление, при этом текущий оплаченный период сохраняется до его окончания. Если оплата производилась через Реселлера (п. 10.2), платёжное средство хранится у Реселлера, и отмена Подписки может дополнительно осуществляться через его интерфейс управления заказом. 9.8. При отсутствии или недостаточности денежных средств на сохранённом платёжном средстве, а равно при невозможности списания по иным причинам, автоматическое продление не осуществляется, и по окончании оплаченного периода Аккаунт переводится на бесплатный Тариф с ограниченным функционалом и лимитами. Ресурсы и данные, превышающие лимиты бесплатного Тарифа, могут стать недоступными или быть удалены в порядке п. 13.6. 9.9. Исполнитель вправе изменять тарифы. Изменение тарифов не влияет на стоимость уже оплаченных периодов. Для Заказчиков-Потребителей изменение тарифа вступает в силу не ранее чем через 7 календарных дней после уведомления по электронной почте или через Личный кабинет; до вступления изменений в силу Заказчик-Потребитель вправе отменить Подписку в порядке п. 9.7. 9.10. При переходе на более дорогой Тариф в течение оплаченного периода стоимость нового Тарифа рассчитывается с учётом неиспользованной части ранее оплаченного периода в порядке, отображаемом в Личном кабинете. #### 10. Каналы оплаты 10.1. Оплата может производиться: * **непосредственно Исполнителю** — способами, доступными в Личном кабинете, включая оплату банковской картой через платёжный сервис ЮKassa; * **через Реселлера** — в порядке п. 10.2; * **через Агента** — при оплате по счёту юридическими лицами и индивидуальными предпринимателями, находящимися на территории Российской Федерации, в порядке п. 10.3. Независимо от выбранного канала Сервисы предоставляются Исполнителем на условиях настоящего Договора. 10.2. **Оплата через Реселлера.** Приём оплаты может осуществляться компанией PayPro Global (PayPro Global Inc. и её аффилированные лица, далее — «Реселлер»), выступающей авторизованным реселлером (merchant of record). В этом случае Реселлер является продавцом в отношениях с Заказчиком: он оформляет заказ, выставляет счёт, принимает платёж, начисляет и уплачивает применимые налоги (п. 8.6), обеспечивает автоматическое продление и обрабатывает возвраты. К оформлению заказа дополнительно применяются условия и политики Реселлера, размещённые по адресу . 10.3. **Оплата по счёту через Агента.** Для юридических лиц и индивидуальных предпринимателей, находящихся на территории Российской Федерации, оплата по счёту принимается агентом Исполнителя — Индивидуальным предпринимателем Медведевым Евгением Сергеевичем, ИНН 661219749774 (далее — «Агент»). Агент действует на основании агентского договора с Исполнителем и принимает денежные средства в пользу Исполнителя. Обязательство Заказчика по оплате считается исполненным с момента поступления денежных средств Агенту. Иные каналы оплаты Агентом не обслуживаются. 10.4. Ни Реселлер, ни Агент не приобретают прав на Платформу. Стороной, предоставляющей Сервисы, во всех случаях остаётся Исполнитель. 10.5. Все требования, связанные с предоставлением Сервисов, их качеством и технической поддержкой, предъявляются Исполнителю в порядке раздела 23. Требования, связанные с оформлением платежа, выставленными документами и начисленными налогами, при оплате через Реселлера предъявляются Реселлеру. #### 11. Возврат средств 11.1. Заказчик-Потребитель вправе запросить возврат средств за впервые приобретённую платную Подписку в течение 7 (семи) календарных дней с момента оплаты, если его не устраивает функциональность или качество Сервисов. 11.2. Возврат средств за продление Подписки (автоматическое или ручное), а также за приобретение Подписки на Тариф, аналогичный ранее приобретённому, не производится, за исключением случаев, предусмотренных п. 6.6 и п. 11.3. 11.3. Для Заказчиков-Потребителей право на возврат в течение 7 календарных дней с момента оплаты новой Подписки сохраняется независимо от ранее приобретённых Подписок. 11.4. Заказчикам, не являющимся Потребителями (юридическим лицам, индивидуальным предпринимателям, а равно физическим лицам, приобретающим Сервисы для целей предпринимательской деятельности), возврат уплаченных сумм не производится ни по одному из оснований настоящего раздела, за исключением случаев, предусмотренных п. 6.6 и п. 22.8, и случаев, когда возврат производится по правилам Реселлера (п. 11.8). До приобретения платной Подписки такой Заказчик имеет возможность оценить функциональность и качество Сервисов на бесплатном Тарифе (п. 11.10). 11.5. Возврат не производится в случае расторжения Договора или блокировки Аккаунта по основаниям, предусмотренным разделом 12 и разделом 20. 11.6. С учётом абонентского характера платы (п. 8.10) при отказе Заказчика от Договора, отмене Подписки, удалении Аккаунта или прекращении использования Сервисов до окончания оплаченного периода уплаченная за этот период сумма не возвращается и не пересчитывается пропорционально; доступ к Сервисам сохраняется до окончания оплаченного периода. Настоящий пункт не применяется к случаям, предусмотренным п. 6.6, 11.1, 11.3 и 22.4. 11.7. Запрос на возврат направляется на адрес электронной почты, указанный в разделе 25, с указанием идентификатора платежа. Возврат осуществляется тем же способом, которым была произведена оплата, в срок не более 14 календарных дней с момента подтверждения запроса. При возврате Аккаунт переводится на бесплатный Тариф. 11.8. При оплате через Реселлера (п. 10.2) возврат осуществляется по правилам Реселлера, которые предусматривают собственный срок обращения и порядок рассмотрения запроса. Запрос направляется через форму поддержки Реселлера; Исполнителю предоставляется возможность урегулировать обращение самостоятельно, а при отсутствии урегулирования решение принимает Реселлер. Условия настоящего раздела применяются к таким платежам в части, не противоречащей правилам Реселлера. 11.9. Положения настоящего раздела не ограничивают прав Потребителей, предусмотренных императивными нормами применимого к ним законодательства (п. 23.4). 11.10. До приобретения платной Подписки Заказчик имеет возможность бесплатно оценить работу Платформы на бесплатном Тарифе. #### 12. Правила использования, злоупотребления и блокировка 12.1. Заказчик обязуется использовать Сервисы в соответствии с [Правилами допустимого использования](https://tuna.am/aup.md), являющимися неотъемлемой частью настоящего Договора. 12.2. Заказчик обязуется: * использовать Сервисы по их функциональному назначению и в пределах выбранного Тарифа; * не использовать Сервисы для незаконной деятельности, распространения вредоносного программного обеспечения, фишинга, спуфинга, спама и иных атак; * не размещать через Сервисы контент, распространение которого нарушает права третьих лиц, включая авторские и смежные права; * воздерживаться от действий, способных воспрепятствовать нормальной работе Платформы, инфраструктуры Исполнителя и других пользователей; * не осуществлять обход технических ограничений, лимитов и механизмов тарификации, в том числе путём регистрации нескольких Аккаунтов; * не декомпилировать, не дизассемблировать и не модифицировать Клиентское ПО, за исключением случаев, прямо разрешённых императивными нормами применимого законодательства; * сообщать Исполнителю об обнаруженных уязвимостях и не эксплуатировать их; * не проводить нагрузочное тестирование, сканирование и тестирование на проникновение в отношении инфраструктуры Исполнителя без его предварительного письменного согласия. 12.3. Заказчик самостоятельно отвечает за правомерность Данных Заказчика и за соблюдение прав третьих лиц при их обработке через Сервисы, а также за действия своих Конечных пользователей. 12.4. Исполнитель не осуществляет предварительный контроль Данных Заказчика и не обязан осуществлять их мониторинг. 12.5. Порядок приёма и рассмотрения жалоб на злоупотребления описан в разделе [Злоупотребления и жалобы](https://tuna.am/docs/abuse.md). Обращения направляются на адрес . 12.6. При нарушении Заказчиком настоящего раздела или Правил допустимого использования Исполнитель вправе, соразмерно характеру нарушения: * потребовать устранения нарушения в установленный срок; * ограничить или приостановить работу отдельного ресурса, Сервиса или Аккаунта; * удалить размещённый с нарушением контент; * расторгнуть настоящий Договор в одностороннем внесудебном порядке и заблокировать Аккаунт. 12.7. Приостановление или блокировка без предварительного уведомления допускаются, если нарушение создаёт непосредственную угрозу безопасности Платформы, третьим лицам либо влечёт риск ответственности Исполнителя, в частности при фишинге, распространении вредоносного программного обеспечения, спаме и распространении материалов, оборот которых запрещён. В остальных случаях Исполнитель предварительно уведомляет Заказчика и предоставляет разумный срок для устранения нарушения. 12.8. Об ограничении, приостановлении или блокировке Заказчик уведомляется по электронной почте с указанием основания, за исключением случаев, когда уведомление запрещено законом. Заказчик вправе направить возражение на адрес ; Исполнитель рассматривает его в течение 10 рабочих дней и восстанавливает доступ, если нарушение не подтвердилось. 12.9. При расторжении Договора по основаниям настоящего раздела уплаченные суммы возврату не подлежат, а убытки Заказчика не компенсируются. #### 13. Данные Заказчика 13.1. Данные Заказчика принадлежат Заказчику. Исполнитель не приобретает на них прав, за исключением ограниченного права, указанного в п. 13.2. 13.2. Заказчик предоставляет Исполнителю право обрабатывать Данные Заказчика (хранить, передавать, отображать, воспроизводить) исключительно в объёме, необходимом для предоставления Сервисов, обеспечения их работоспособности и безопасности, а также для исполнения требований законодательства. 13.3. Исполнитель не использует Данные Заказчика для обучения моделей машинного обучения, для рекламы и для иных целей, не связанных с предоставлением Сервисов. Настоящий пункт не распространяется на Служебные данные, порядок использования которых установлен п. 13.8. 13.4. Трафик, передаваемый через туннели и шлюзы, обрабатывается транзитом. Исполнитель не осуществляет анализ содержимого такого трафика, за исключением технически необходимой обработки для маршрутизации, применения настроенных Заказчиком политик обработки трафика, обеспечения безопасности и рассмотрения жалоб на злоупотребления. Ограничение настоящего пункта касается содержимого трафика; метаданные соединений относятся к Служебным данным (п. 2.13). Отдельные Сервисы по своей природе предполагают хранение содержимого запросов, файлов и иных данных на инфраструктуре Исполнителя; порядок такой обработки описан в документации соответствующего Сервиса и в [Условиях обработки данных Заказчика](https://tuna.am/dpa.md). 13.5. Заказчик самостоятельно определяет, какие данные он передаёт и размещает в Сервисах, и обязан не размещать в них данные, обработка которых запрещена применимым к нему законодательством либо требует специальных мер защиты, не предусмотренных настоящим Договором и документацией. 13.6. После прекращения действия Договора либо удаления Аккаунта Данные Заказчика удаляются в срок не более 30 календарных дней, за исключением данных, подлежащих хранению в силу требований законодательства. Заказчик обязан самостоятельно выгрузить необходимые ему данные до прекращения Договора; средства экспорта, предусмотренные документацией, доступны в течение срока действия Договора. 13.7. При переводе Аккаунта на бесплатный Тариф ресурсы и данные, превышающие лимиты бесплатного Тарифа, могут стать недоступными или быть удалены по истечении 30 календарных дней с даты перевода. Уведомление направляется по электронной почте не менее чем за 14 календарных дней до удаления. 13.8. Служебные данные Исполнитель обрабатывает как самостоятельный оператор (п. 15.1) исключительно для следующих целей: * эксплуатация Платформы, диагностика неисправностей и восстановление работоспособности Сервисов; * обеспечение безопасности, выявление и расследование атак, злоупотреблений и уязвимостей, рассмотрение жалоб; * контроль соблюдения лимитов Тарифа, тарификация и планирование мощностей; * формирование статистики, улучшение существующих и разработка новых Сервисов, включая обучение моделей машинного обучения для перечисленных целей. Для целей, выходящих за пределы эксплуатации, обеспечения безопасности и рассмотрения жалоб, в том числе для статистики, разработки Сервисов и обучения моделей, Исполнитель использует Служебные данные исключительно в агрегированном или обезличенном виде, не допускающем соотнесения с конкретным Заказчиком или физическим лицом. Результаты такой обработки, включая агрегированные показатели и обученные модели, принадлежат Исполнителю и Данных Заказчика не содержат. #### 14. Пароли, Секреты и иные чувствительные данные 14.1. Настоящий раздел применяется к Сервисам, предназначенным для хранения чувствительных данных Заказчика, в том числе к менеджеру паролей и к сервису секретов, и имеет приоритет перед общими положениями Договора применительно к таким Сервисам. 14.2. Менеджер паролей построен по модели нулевого знания: ключи шифрования формируются на стороне Заказчика, мастер-ключ Исполнителю не передаётся и им не хранится. Исполнитель технически не имеет возможности расшифровать содержимое хранилища паролей, восстановить утраченный мастер-ключ или предоставить доступ к данным иным способом. 14.3. **Утрата мастер-ключа означает безвозвратную потерю доступа к соответствующим данным.** Заказчик самостоятельно обеспечивает надёжное хранение мастер-ключа и его резервной копии. Исполнитель не несёт ответственности за утрату доступа к данным вследствие утраты мастер-ключа Заказчиком. 14.4. Секреты хранятся в зашифрованном виде, при этом модель нулевого знания к ним не применяется, что предусмотрено их назначением и описано в [документации](https://tuna.am/docs/secrets.md). Заказчик учитывает это при выборе состава размещаемых данных. 14.5. Заказчик самостоятельно определяет состав данных, размещаемых в указанных Сервисах, и несёт риск такого решения. **Заказчику не следует размещать в Сервисах данные, компрометация или утрата которых способна причинить ему или третьим лицам ущерб, несопоставимый со стоимостью Подписки**, в том числе данные, для которых применимое к Заказчику законодательство устанавливает специальные требования к хранению (сведения, составляющие банковскую, врачебную или иную охраняемую законом тайну, биометрические и специальные категории персональных данных, сведения, отнесённые к государственной тайне). 14.6. Заказчик обязан: * обеспечивать конфиденциальность учётных данных, мастер-ключа, сервисных токенов и ключей доступа; * ограничивать доступ участников своей Организации к чувствительным данным в соответствии с ролевой моделью; * своевременно отзывать доступ у выбывших участников и ротировать скомпрометированные секреты. 14.7. Исполнитель применяет меры защиты, описанные в п. 19.2 и в [Политике конфиденциальности](https://tuna.am/policy.md), однако не гарантирует абсолютную защищённость данных: ни одна система передачи и хранения данных не может считаться абсолютно защищённой. Исполнитель не принимает на себя риски Заказчика, связанные с утечкой, компрометацией или утратой данных, размещённых в Сервисах, за исключением случаев, когда такая утечка вызвана умыслом или грубой неосторожностью Исполнителя. 14.8. Ответственность Исполнителя, связанная с утратой, недоступностью, повреждением или несанкционированным раскрытием Данных Заказчика, во всех случаях ограничена пределами, установленными разделом 19, и не включает возмещения косвенных убытков и упущенной выгоды. 14.9. При выявлении нарушения безопасности, затронувшего Данные Заказчика, Исполнитель уведомляет затронутых Заказчиков в разумный срок и принимает меры по устранению нарушения и минимизации его последствий. #### 15. Персональные данные и распределение ролей 15.1. В отношении данных Аккаунта, платёжных данных, технических журналов и иных данных, которые Исполнитель обрабатывает для собственных целей, Исполнитель выступает оператором (контролёром) персональных данных. Порядок обработки определяется [Политикой конфиденциальности](https://tuna.am/policy.md). 15.2. В отношении персональных данных, содержащихся в Данных Заказчика, оператором (контролёром) выступает Заказчик, а Исполнитель — обработчиком (процессором), действующим по поручению Заказчика. Условия такой обработки определяются [Условиями обработки данных Заказчика](https://tuna.am/dpa.md), являющимися неотъемлемой частью настоящего Договора. 15.3. Заказчик гарантирует наличие правового основания для обработки персональных данных, передаваемых им в Сервисы, включая получение необходимых согласий субъектов данных и их уведомление, и самостоятельно обеспечивает реализацию прав субъектов данных. 15.4. Заказчик обязуется возместить Исполнителю документально подтверждённые убытки, штрафы и разумные расходы, возникшие вследствие требований третьих лиц или уполномоченных органов, связанных с нарушением Заказчиком п. 12.3, 13.5 или 15.3. 15.5. Раскрытие информации уполномоченным органам осуществляется только на основании официального запроса, оформленного в соответствии с законодательством, и в объёме, необходимом для исполнения требований закона. 15.6. При рассмотрении жалобы на злоупотребление Исполнитель вправе передать пострадавшей стороне, интернет-провайдеру или иному компетентному лицу минимально необходимую техническую информацию (в частности, IP-адрес и время сессий) без раскрытия персональных данных Заказчика, за исключением случаев, предусмотренных законом. #### 16. Конфиденциальность 16.1. Стороны обязуются не раскрывать третьим лицам информацию, полученную в ходе исполнения настоящего Договора и обозначенную передающей стороной как конфиденциальная, за исключением случаев, предусмотренных законом. 16.2. Обязательства по конфиденциальности сохраняют силу в течение 3 (трёх) лет после прекращения Договора. #### 17. Доступность Сервисов и техническая поддержка 17.1. Исполнитель принимает разумные меры для обеспечения непрерывной работы Сервисов, однако не гарантирует их бесперебойную и безошибочную работу, если для конкретного Тарифа не заключено отдельное соглашение об уровне обслуживания. 17.2. Плановые технические работы проводятся с уведомлением через Личный кабинет, сайт статуса или по электронной почте, за исключением аварийных работ, необходимых для устранения угрозы работоспособности или безопасности Платформы. 17.3. Условия и каналы технической поддержки, режим работы и сроки реакции по Тарифам описаны на странице [технической поддержки](https://tuna.am/docs/support.md), являющейся неотъемлемой частью настоящего Договора. 17.4. Сроки реакции не являются сроками устранения неисправности. Исполнитель не гарантирует устранение неисправности в конкретный срок. 17.5. Работы, выходящие за пределы технической поддержки (настройка инфраструктуры Заказчика, разработка, интеграции), выполняются по отдельному соглашению сторон. 17.6. Перерывы в работе Сервисов, вызванные обстоятельствами, не зависящими от Исполнителя, не являются нарушением Договора и не влекут перерасчёта стоимости Подписки, за исключением случаев, прямо предусмотренных отдельным соглашением об уровне обслуживания. К таким обстоятельствам относятся, в частности: * распределённые атаки на отказ в обслуживании (DDoS) и иные атаки третьих лиц на инфраструктуру Исполнителя; * аварии, сбои и работы у провайдеров хостинга, дата-центров, магистральных и региональных операторов связи, перебои электропитания; * ограничения доступа, блокировки, фильтрация трафика и иные меры со стороны государственных органов, операторов связи и третьих лиц, включая региональные ограничения и цензуру; * сбои в работе сетей, сервисов и программного обеспечения третьих лиц, к которым обращается Заказчик или которые используются для доставки трафика. 17.7. При наступлении обстоятельств, указанных в п. 17.6, Исполнитель принимает разумные меры для восстановления работоспособности Сервисов и информирует Заказчиков о ходе устранения доступными ему способами. #### 18. Интеллектуальная собственность 18.1. Исключительные права на Платформу, Клиентское ПО, документацию, дизайн, товарные знаки и иные результаты интеллектуальной деятельности принадлежат Исполнителю. Настоящий Договор не влечёт их передачи Заказчику. 18.2. Заказчик не вправе использовать товарные знаки и фирменный стиль Исполнителя без его предварительного письменного согласия, за исключением добросовестного указания на факт использования Сервисов. 18.3. Заказчик вправе направлять Исполнителю предложения по улучшению Сервисов. Исполнитель вправе использовать такие предложения без ограничений и без выплаты вознаграждения. 18.4. Использование Сервисов для оказания услуг третьим лицам допускается в пределах, предусмотренных выбранным Тарифом. Перепродажа доступа к Сервисам, а равно предоставление доступа к ним третьим лицам на возмездной основе вне рамок Организации Заказчика требует предварительного письменного согласования с Исполнителем. #### 19. Гарантии и ограничение ответственности 19.1. СЕРВИСЫ И КЛИЕНТСКОЕ ПО ПРЕДОСТАВЛЯЮТСЯ «КАК ЕСТЬ» (AS IS). В МАКСИМАЛЬНОЙ СТЕПЕНИ, ДОПУСКАЕМОЙ ПРИМЕНИМЫМ ПРАВОМ, ИСПОЛНИТЕЛЬ НЕ ПРЕДОСТАВЛЯЕТ КАКИХ-ЛИБО ГАРАНТИЙ, ЯВНЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ ГАРАНТИИ КОММЕРЧЕСКОЙ ПРИГОДНОСТИ, ПРИГОДНОСТИ ДЛЯ КОНКРЕТНОЙ ЦЕЛИ, БЕСПЕРЕБОЙНОЙ И БЕЗОШИБОЧНОЙ РАБОТЫ И НЕНАРУШЕНИЯ ПРАВ ТРЕТЬИХ ЛИЦ. 19.2. Исполнитель применяет организационные и технические меры защиты данных, включая шифрование трафика, хранение паролей в виде необратимых хешей, шифрование чувствительных данных при хранении, разграничение доступа и ведение журналов. 19.3. Исполнитель не несёт ответственности за: * невозможность использования Сервисов по причинам, не зависящим от Исполнителя, включая обстоятельства, перечисленные в п. 17.6, сбои оборудования и каналов связи Заказчика, действия провайдеров и операторов связи, ограничения в сетях третьих лиц и решения уполномоченных органов; * утрату или повреждение Данных Заказчика, вызванные действиями самого Заказчика, его Конечных пользователей или утратой учётных данных и ключей; * содержание Данных Заказчика и правомерность их обработки; * последствия настроек, выполненных Заказчиком, включая политики обработки трафика и правила доступа; * работу стороннего программного обеспечения и сервисов, к которым Заказчик подключается через Платформу. 19.4. Совокупная ответственность Исполнителя по настоящему Договору за любые требования ограничивается суммой, фактически уплаченной Заказчиком за Подписку в течение 12 (двенадцати) месяцев, предшествующих событию, послужившему основанием требования. В отношении бесплатного Тарифа и функций, указанных в п. 6.7, ответственность Исполнителя исключается в максимальной степени, допускаемой применимым правом. 19.5. Исполнитель ни при каких обстоятельствах не несёт ответственности за упущенную выгоду, косвенные, случайные и штрафные убытки, утрату деловой репутации, простой и расходы на замещающие решения. 19.6. Ограничения, установленные настоящим разделом, не применяются к ответственности за умышленное причинение вреда и грубую неосторожность, а также в иных случаях, когда ограничение ответственности не допускается императивными нормами применимого права. 19.7. Сервисы не предназначены для использования в системах, отказ которых может привести к гибели людей, причинению вреда здоровью или экологической катастрофе, а также в качестве единственного средства обеспечения безопасности объектов критической информационной инфраструктуры. #### 20. Правомерность использования, санкции и экспортные ограничения 20.1. Заказчик обязуется не использовать Сервисы для нарушения прав и свобод человека и для целей, запрещённых применимым законодательством. 20.2. Заказчик подтверждает, что он не включён в санкционные списки Республики Армения, Европейского союза, США и Организации Объединённых Наций, и обязуется не предоставлять доступ к Сервисам лицам, включённым в такие списки, а также не осуществлять реэкспорт Клиентского ПО в нарушение применимых экспортных ограничений. 20.3. При нарушении настоящего раздела Исполнитель вправе немедленно заблокировать Аккаунт и расторгнуть Договор без возмещения убытков и возврата уплаченных сумм. #### 21. Обстоятельства непреодолимой силы 21.1. Стороны освобождаются от ответственности за неисполнение или ненадлежащее исполнение обязательств, если оно вызвано обстоятельствами непреодолимой силы, определяемыми в соответствии с законодательством Республики Армения. 21.2. Сторона, для которой наступили такие обстоятельства, обязана уведомить об этом другую сторону в разумный срок. С момента прекращения указанных обстоятельств Договор действует в обычном порядке. #### 22. Срок действия, изменение и расторжение Договора 22.1. Договор вступает в силу с момента Акцепта Оферты и действует до удаления Аккаунта Заказчика либо до расторжения по основаниям, предусмотренным настоящим Договором. 22.2. Исполнитель вправе в одностороннем порядке вносить изменения в настоящий Договор и в документы, указанные в п. 1.4. Новая редакция публикуется на Сайте с указанием даты редакции. 22.3. Для Заказчиков — юридических лиц и индивидуальных предпринимателей изменения вступают в силу с момента публикации новой редакции на Сайте. 22.4. Для Заказчиков-Потребителей изменения вступают в силу не ранее чем через 7 календарных дней после уведомления по электронной почте или через Личный кабинет. В случае несогласия с изменениями Потребитель вправе отказаться от Договора; в этом случае Договор прекращается по истечении оплаченного периода, а неиспользованная часть оплаченной Подписки возвращается пропорционально. 22.5. Изменения Договора не применяются к уже оплаченным и действующим Подпискам в части их стоимости и заявленного при оплате объёма функциональности. 22.6. Заказчик вправе в любой момент отказаться от Договора, прекратив использование Сервисов и удалив Аккаунт. Уплаченные суммы при этом возврату не подлежат, за исключением случаев, предусмотренных разделом 11. 22.7. Исполнитель вправе отказаться от исполнения Договора в отношении Заказчика, использующего только бесплатный Тариф, уведомив его по электронной почте не менее чем за 14 календарных дней. 22.8. Исполнитель вправе отказаться от исполнения Договора в отношении Заказчика, не являющегося Потребителем, без указания причин, уведомив его по электронной почте не менее чем за 30 календарных дней. Договор прекращается по истечении срока уведомления, но не ранее окончания оплаченного периода Подписки; автоматическое продление с момента уведомления не производится, возврат уплаченных сумм не требуется. Исполнитель вправе прекратить предоставление Сервисов до окончания оплаченного периода, возвратив Заказчику неиспользованную часть оплаты пропорционально оставшемуся периоду; иные убытки Заказчика возмещению не подлежат. 22.9. Прекращение действия Договора не отменяет положений разделов 13, 14, 15, 16, 18, 19 и 23, которые сохраняют силу после его прекращения. #### 23. Применимое право и разрешение споров 23.1. Настоящий Договор, его заключение, толкование, исполнение и прекращение регулируются правом Республики Армения без учёта его коллизионных норм. 23.2. Все споры и разногласия стороны разрешают путём переговоров. Претензионный порядок является обязательным: претензия направляется в письменной форме на адрес электронной почты, указанный в разделе 25, и подлежит рассмотрению в течение 30 календарных дней с момента получения. 23.3. При недостижении согласия спор подлежит рассмотрению судом Республики Армения по месту нахождения Исполнителя. 23.4. Положения п. 23.1 и 23.3 не лишают Заказчика-Потребителя защиты, предоставляемой ему императивными нормами права страны его места жительства. Заказчик-Потребитель вправе обратиться в суд по месту своего жительства, если это предусмотрено императивными нормами применимого к нему законодательства. 23.5. Настоящий раздел регулирует споры между Заказчиком и Исполнителем. Споры, вытекающие из отношений Заказчика с Реселлером (п. 10.2) по поводу оформления заказа, платежа и налогов, регулируются условиями Реселлера и правом, применимым к его отношениям с покупателем. 23.6. К настоящему Договору не применяется Конвенция ООН о договорах международной купли-продажи товаров (Вена, 1980). #### 24. Прочие условия 24.1. Настоящий Договор публикуется на нескольких языках. В случае расхождений между версиями преимущественную силу имеет версия на русском языке. 24.2. Признание недействительным или неисполнимым любого положения настоящего Договора не влечёт недействительности остальных положений. 24.3. Заказчик не вправе уступать права и переводить обязанности по настоящему Договору без предварительного письменного согласия Исполнителя. Исполнитель вправе уступить права и обязанности по настоящему Договору правопреемнику при реорганизации или отчуждении прав на Платформу, уведомив Заказчика. 24.4. Настоящий Договор вместе с документами, указанными в п. 1.4, составляет полное соглашение сторон в отношении его предмета и заменяет все предшествующие договорённости. 24.5. Ненаправление Исполнителем требования об устранении нарушения не означает отказа от права требовать его устранения в дальнейшем. 24.6. Юридически значимые сообщения направляются сторонами по адресам электронной почты: Исполнителю — на адрес, указанный в разделе 25; Заказчику — на адрес, указанный им в Личном кабинете. Заказчик обязан поддерживать актуальность своего адреса электронной почты и считается получившим сообщение на следующий рабочий день после отправки. 24.7. Во всём, что не урегулировано настоящим Договором, стороны руководствуются законодательством Республики Армения. #### 25. Реквизиты Исполнителя Индивидуальный предприниматель Аминов Лев Александрович
Адрес: 3901, Республика Армения, Тавушская область, г. Дилижан
Учётный номер налогоплательщика (ՀՎՀՀ/TIN): 71062923
Электронная почта:
Жалобы на злоупотребления: **Авторизованный реселлер** (п. 10.2): PayPro Global Inc. и её аффилированные лица. **Агент по приёму оплаты по счёту на территории Российской Федерации** (п. 10.3): Индивидуальный предприниматель Медведев Евгений Сергеевич
ИНН: 661219749774 ---