Назад

2026/10/27

Ответ на Tailworm: как мы усилили защиту сети Tailscale, не останавливая продакшн

Как мы проверили свою сеть Tailscale по находкам Tailworm, устранили уязвимое место в виде Tailscale SSH и сохранили работу всех производственных задач.

Кратко

25 октября 2026 года исследователь в области безопасности опубликовал «Tailworm» — 11 находок в Tailscale и headscale, раскрытых без скоординированного раскрытия (coordinated disclosure). На момент написания статьи Tailscale не выпустила исправлений. В тот же вечер мы проверили собственную сеть Tailscale по каждой из находок. Мы устранили единственную уязвимость, которая нас касалась, ужесточили доступ, и всё это время все производственные задачи продолжали работать.

В этой статье мы рассказываем, что проверили, что изменили, как избежали простоя и какие выводы сделали. Это не независимая проверка отчёта.

Что сообщил Tailworm — коротко

11 находок делятся на несколько групп:

  • Tailscale SSH (самое серьёзное). Авторизованную SSH-сессию можно было повысить до прав root на целевой машине. В лаборатории исследователя атака затем распространялась с машины на машину.
  • App connectors. Адреса назначения (destination) не проверяются.
  • Исчерпание памяти — на управляющем сервере и на клиентах.
  • Пограничные случаи в Serve и Funnel.

Каждая находка требует, чтобы у атакующего уже был плацдарм в системе. Ни одна из них не является удалённой атакой из интернета. Некоторые специалисты по безопасности считают, что подача преувеличивает риск, но главная уязвимость — Tailscale SSH — реальна, и её легко устранить.

Шаг 1. Сначала проверить, потом менять

Мы начали с проверок только на чтение и зафиксировали результаты, прежде чем что-либо трогать:

  • используемые версии клиента Tailscale
  • какие функции на самом деле включены
  • журналы SSH-сессий за 60 дней — чтобы увидеть, кто и откуда подключался и использовал ли кто-то проброс портов или сокетов
  • список устройств, включая те, что не появлялись в сети месяцами

Результаты:

  • Tailscale SSH был включён в части нашей среды, поэтому находки F1–F3 и F5 касались нас.
  • Функции, от которых зависят остальные находки, не использовались, так что большинство из них к нам не относилось.
  • В журналах SSH не оказалось неожиданных источников подключений и запросов на проброс.

Шаг 2. Устранить уязвимость без простоя

Очевидным решением было отключить Tailscale SSH и перейти на стандартную аутентификацию по ключу в OpenSSH. Но предварительная проверка выявила ловушку.

Tailscale SSH аутентифицирует по идентификатору в tailnet, а не по SSH-ключу. Наши скрипты автоматизации передавали SSH-ключ в командной строке, но этот ключ был защищён парольной фразой и никогда не смог бы работать в автоматическом режиме. Задачи выполнялись только потому, что Tailscale SSH вообще не смотрел на ключ. Если бы мы просто отключили Tailscale SSH, все автоматические задачи остановились бы.

Поэтому мы выполнили переключение в таком порядке:

  1. Создали отдельный ключ для автоматизации, ограниченный одной исходной машиной, с отключённым пробросом.
  2. Проверили новый путь до переключения. Мы открыли временный порт OpenSSH, доступный только внутри tailnet, и подключились из среды, аналогичной той, где выполняются наши задачи (без SSH-агента, без терминала), всеми способами, которыми наши скрипты вызывают SSH.
  3. Провели негативные тесты. Новый ключ отклонялся при использовании вне разрешённого источника, а запросы на проброс отклонялись.
  4. Заранее подготовили автоматический откат. Перед отключением Tailscale SSH мы запланировали таймер, который включил бы его обратно сам. Этот путь восстановления не зависел от работоспособности SSH.
  5. Переключились и проверили каждую автоматическую задачу на новых подключениях. Каждая задача отработала реальный запуск. Уже открытую сессию мы доказательством не считали.
  6. Удалили временные элементы — дополнительный порт, правило межсетевого экрана и таймер отката — и проверили всё ещё раз.

Шаг 3. Ужесточить остальное

  • Очистили политику Tailscale SSH. Политика по умолчанию позволяла любому устройству пользователя открывать SSH-сессии на других его устройствах, в том числе от имени root, при условии еженедельного повторного подтверждения в браузере. Мы её очистили, так что случайное повторное включение Tailscale SSH больше не даёт доступа.
  • Закрыли SSH из интернета. Перед этим мы убедились, что вход через внеполосную (out-of-band) консоль работает, чтобы не отрезать себе доступ. После этого проверили из внешней сети, что SSH больше не отвечает.
  • Включили обязательное одобрение устройств. Новые устройства могут подключиться только после одобрения администратором.
  • Проверили ключи регистрации. Отзывать было нечего.
  • Убедились, что для учётной записи администратора включена MFA. Сетевые меры защиты может отменить любой, кто завладеет входом администратора.
  • Начали наблюдать за реальным трафиком между устройствами, чтобы следующий шаг — ограничение того, какие устройства могут обращаться к каким сервисам, — опирался на факты, а не на догадки.

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

Шаг 4. Исправить runbook, а не только сервер

Наша старая процедура восстановления предписывала переподключать сервер с включённым Tailscale SSH. Если бы ей последовали после этого изменения, рискованная функция незаметно вернулась бы. Мы переписали процедуру:

  • Сначала диагностика. Пропало сетевое подключение или проблема в самом SSH (ключи, конфигурация, межсетевой экран)? Эти случаи исправляются по-разному.
  • Переподключаться без изменения настроек. Не использовать дополнительные флаги, сохранить настройки узла перед переподключением и сравнить их после.
  • Открывать аварийный доступ только с таймером. Сначала получить одобрение, до открытия запланировать автоматическое закрытие, ограничить источник и проверить IPv4 и IPv6.
  • Не включать Tailscale SSH снова даже в экстренной ситуации. Необходимое для этого изменение политики доступа нельзя откатить автоматически.

Что мы вынесли из этого

  1. Прежде чем убирать функцию безопасности, выясните, что именно она аутентифицирует. Ключ, указанный в наших скриптах, ни разу не использовался.
  2. Проверяйте именно тот путь, на который переходите, в той же среде, где работают ваши задачи, до переключения.
  3. Готовьте откат, который не зависит от того, что вы меняете. Таймер, а не «зайдём по SSH и починим».
  4. Проверьте резервный доступ, прежде чем закрывать дверь. Мы убедились в доступе через консоль до того, как закрыли SSH из интернета.
  5. Обновляйте runbook в рамках того же изменения. Старый шаг восстановления может через несколько месяцев свести на нет исправление безопасности.
  6. Читайте политики по умолчанию. «Разрешить собственные устройства, включая root» — именно с такой настройки по умолчанию мы начинали.
  7. Разделяйте «изменение сработало» и «уязвимость устранена». Находки, связанные с Tailscale SSH, нас больше не затрагивают, но Tailworm в целом не закрыт, пока не выйдут исправления upstream. Когда они выйдут, мы обновим клиенты.
  8. Сначала измерить, потом ограничить. Наблюдаемый трафик и список реальных зависимостей должны появиться раньше более строгих правил доступа, чтобы усиление защиты не мешало бизнесу.

Что дальше

Мы сужаем сетевой доступ между устройствами до минимума, необходимого каждому сервису, на основе наблюдаемого трафика. Исправления Tailscale мы установим сразу после их выхода.

Источники: отчёт Tailworm (tailworm.com) и документация Tailscale о Tailnet Lock.