Обе команды публикуют локальный сервис через HTTPS-имя Tailscale, и с машины, которая их выполняет, они выглядят почти одинаково. Разница в том, кто после этого может добраться до URL, и эта разница определяет, какие средства контроля вашей программе ещё нужны. Serve держит аудиторию внутри tailnet, а Funnel переносит её в открытый интернет. Сначала выберите аудиторию, затем команду, которая ей соответствует.

Serve отвечает на вопрос внутри вашего tailnet

Serve проксирует локальный порт или отдаёт локальное содержимое устройствам в вашем tailnet, и правила доступа tailnet по-прежнему действуют для каждого запроса. Панель на порту 3000 становится доступной по HTTPS-имени, которое могут разрешить и к которому могут подключиться только ваши устройства. Это правильное значение по умолчанию для внутренних инструментов, потому что аудитория уже аутентифицирована tailnet и вы не добавляете публичную поверхность. URL выглядит как обычный сайт, и именно поэтому люди принимают его за таковой.

Serve также может прикреплять к пересылаемым запросам заголовки идентичности, описывающие пользователя tailnet. Если ваше приложение доверяет этим заголовкам как аутентификации, привяжите backend к localhost, чтобы ничто другое не могло добраться до него напрямую; backend, слушающий на маршрутизируемом адресе, может получать запросы, которые никогда не проходили через прокси.

Funnel меняет аудиторию на открытый интернет

Funnel публикует выбранный сервис для любого, у кого есть URL, и посетителям не нужны клиент, учётная запись или членство в вашем tailnet. Поэтому ресурсу нужны аутентификация, ограничение скорости и обновления, которые вы применили бы к любому публичному сервису. Публичные запросы не несут заголовки идентичности tailnet от Serve, поэтому приложение, которое на них полагалось, под Funnel вообще не имеет идентичности пользователя. Выбор другой команды публикации не отвечает за вас на вопрос об аутентификации.

У Funnel есть и ограничения, о которых руководство из старой версии может не упоминать. Он завершает TLS сертификатом, который Tailscale получает для имени, и поддерживает только определённые порты прослушивания, как описывает документация Funnel. Если ваш сервис ожидает на одном из этих портов протокол, отличный от HTTPS, Funnel — неподходящий инструмент, а не головоломка с настройками.

Читайте режим из клиента, а не из порта

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

tailscale serve status
tailscale funnel status
tailscale status --json | head -40

Синтаксис команд менялся между версиями клиента, поэтому скопированный вызов может выбрать не тот режим, который вы задумали. Предпочитайте документированную форму для вашей версии и читайте подтверждение, которое печатает клиент, вместо того чтобы предполагать. Если существуют и конфигурация Serve, и конфигурация Funnel, для экспозиции важна публичная. Сбросьте конфигурацию, которую вы не имели в виду, вместо того чтобы накладывать ещё одну сверху.

Остановитесь и перечитайте состояние, если вывод не называет аудиторию. Опубликованный URL без указанной аудитории — это догадка, а догадки — это то, как внутренние панели оказываются в открытом интернете.

Тестируйте с той аудиторией, которую действительно имели в виду

Тестируйте снаружи tailnet, а не с машины, которая опубликовала сервис. Запрос с устройства в tailnet доказывает, что прокси работает; он не доказывает, что посторонний исключён. Используйте сеть без клиента Tailscale и без маршрута в tailnet.

curl -sI https://host.tailnet-name.ts.net
curl -sI https://host.tailnet-name.ts.net --resolve host.tailnet-name.ts.net:443:203.0.113.10

Для внутренней панели внешний запрос должен не суметь подключиться или не пройти авторизацию, а внутренний запрос должен успешно выполниться с ожидаемой идентичностью. Для публичного сервиса внешний запрос должен успешно выполниться, а приложение должно запросить собственные учётные данные. Запишите, какой из этих двух результатов вы наблюдали, потому что один только URL этого не скажет. Если результат противоположен замыслу, сначала удалите публичную конфигурацию, а затем разбирайтесь.

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

Похожие статьи