Назад к обновлениям
New releaseSep 4, 2026

tailsnitch v1.7

Инструмент аудита безопасности для конфигураций Tailscale. Сканирует ваш tailnet на наличие неправильных конфигураций, излишне разрешительных политик доступа и нарушений лучших практик безопасности.

Поделиться

Tailsnitch

Аудитор безопасности конфигураций Tailscale. Tailsnitch сканирует вашу tailnet-сеть на наличие 57 ошибок конфигурации, излишне разрешающих контролей доступа и нарушений лучших практик безопасности.

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

# 1. Укажите свои учётные данные API Tailscale
export TS_API_KEY="tskey-api-..."

# 2. Запустите аудит
tailsnitch

# 3. Покажите только находки высокой степени серьёзности
tailsnitch --severity high

# 4. Исправьте некоторые проблемы  ~интерактивно~ режим yolo
tailsnitch --fix

Установка

Загрузка готового бинарного файла

Загрузите последний релиз из GitHub Releases.

Пользователям macOS: Снимите атрибут quarantine после загрузки:

sudo xattr -rd com.apple.quarantine tailsnitch

Установка через Go

go install github.com/Adversis/tailsnitch@latest

Сборка из исходного кода

git clone https://github.com/Adversis/tailsnitch.git
cd tailsnitch
go build -o tailsnitch .

Аутентификация

Tailsnitch поддерживает два метода аутентификации. OAuth предпочтителен, если настроены оба.

Вариант 1: OAuth-клиент (рекомендуется)

OAuth-клиенты обеспечивают ограниченный, аудируемый доступ, который не истекает при увольнении сотрудников.

export TS_OAUTH_CLIENT_ID="..."
export TS_OAUTH_CLIENT_SECRET="tskey-client-..."

Создайте OAuth-клиент по адресу: https://login.tailscale.com/admin/settings/oauth

Необходимые области для аудита только на чтение:

all:read покрывает всё. Предоставление областей по отдельности:

ОбластьИспользуется для
policy_file:readФайл политики tailnet — ACL-, NET-, SSH-*
devices:core:readСписок устройств — DEV-, NET-, ACL-011
dns:readКонфигурация DNS — DNS-001, DEV-007
auth_keys:readКлючи аутентификации машин — AUTH-*, ACL-011
feature_settings:readНастройки tailnet — DEV-008, DEV-009, DEV-014
logs:network:readНастройка журналирования сетевого трафика — LOG-001
networking_settings:readНастройка сертификатов HTTPS — NET-004
log_streaming:readНазначения потоковой передачи журналов — LOG-002
webhooks:readКонечные точки webhook — LOG-005, LOG-012
oauth_keys:readOAuth-клиенты — LOG-006
users:readРоли и статусы пользователей — USER-001, LOG-006
account_settings:readКонтакт для безопасности — LOG-011
devices:posture_attributes:readИнтеграции posture — DEV-014

Любая область, которую вы пропустите, влияет только на проверки, которым она нужна: такие проверки сообщают, что не смогли прочитать настройку, а не проходят успешно.

AUTH-005 и AUTH-006 читают федеративные удостоверения tailnet, которые консоль администратора называет доверенными учётными данными. Они поступают из того же списка ключей, что и ключи аутентификации, поэтому ожидается, что auth_keys:read их покрывает. Это не было подтверждено на живой tailnet-сети. Если список ключей не может быть прочитан, обе проверки сообщают «не оценено», а не «пройдено». Подтверждено ли, что отсутствующая область возвращает ошибку или вместо этого возвращает список с отфильтрованными удостоверениями, не установлено; если она фильтрует молча, AUTH-005 сообщит, что доверенных учётных данных не существует, а AUTH-006 не найдёт, что проверять.

Дополнительные области для режима исправления:

  • devices:core — Удаление устройств, изменение тегов (требуется выбор тега)
  • auth_keys — Удаление ключей аутентификации

Tailnet Lock

DEV-010 и DEV-012 сообщают о Tailnet Lock, который API Tailscale не раскрывает как настройку tailnet. Устройства, заблокированные им, видны через API, но определение того, включён ли lock, требует локального CLI tailscale, который читает демон на машине, где запущен tailsnitch. При аудите другой tailnet-сети с помощью --tailnet учитывайте эту часть результата соответствующим образом. Используйте --tailscale-path, если бинарный файл находится в нестандартном месте.

Вариант 2: API-ключ

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

export TS_API_KEY="tskey-api-..."

Создайте API-ключ по адресу: https://login.tailscale.com/admin/settings/keys

Примеры использования

Базовый аудит

# Запуск полного аудита
tailsnitch

# Показ также проходящих проверок (подробный режим)
tailsnitch --verbose

# Вывод в формате JSON для обработки
tailsnitch --json

# Аудит конкретной tailnet-сети (когда OAuth-клиент имеет доступ к нескольким)
tailsnitch --tailnet mycompany.com

Фильтрация результатов

# Показ только критических проблем и проблем высокой серьёзности
tailsnitch --severity high

# Фильтрация по категории
tailsnitch --category access    # Проблемы ACL
tailsnitch --category auth      # Аутентификация и ключи
tailsnitch --category device    # Безопасность устройств
tailsnitch --category network   # Сетевая доступность
tailsnitch --category ssh       # Правила SSH
tailsnitch --category log       # Журналирование и администрирование

# Запуск только конкретных проверок
tailsnitch --checks ACL-001,AUTH-001,DEV-010
tailsnitch --checks stale-devices,tailnet-lock-not-enabled

# Список всех доступных проверок
tailsnitch --list-checks

Интерактивный режим исправления

Режим исправления позволяет устранять проблемы напрямую через API Tailscale:

# Интерактивный режим исправления
tailsnitch --fix

# Предпросмотр того, что будет исправлено (пробный запуск)
tailsnitch --fix --dry-run

# Автовыбор безопасных исправлений (всё равно требует подтверждения)
tailsnitch --fix --auto

# Отключение журналирования аудита действий по исправлению
tailsnitch --fix --no-audit-log

Элементы, исправляемые через API:

ПроверкаДействие
AUTH-001, AUTH-002, AUTH-003Удаление ключей аутентификации
DEV-002Удаление тегов с пользовательских устройств
DEV-004Удаление устаревших устройств
DEV-005Авторизация ожидающих устройств

Режим исправления также предоставляет прямые ссылки на консоль администратора для проблем, требующих ручного вмешательства.

Экспорт доказательств для SOC 2

Создание отчётов-доказательств для аудитов SOC 2 с сопоставлением общих критериев (CC):

# Экспорт в JSON
tailsnitch --soc2 json > soc2-evidence.json

# Экспорт в CSV (для электронных таблиц)
tailsnitch --soc2 csv > soc2-evidence.csv

Отчёт SOC 2 включает:

  • Результаты тестов по каждому ресурсу (каждое устройство, ключ, правило ACL тестируются индивидуально)
  • Сопоставления кодов CC (CC6.1, CC6.2, CC6.3, CC6.6, CC7.1, CC7.2 и т. д.)
  • Статус Pass/Fail/N/A для каждого контрольного теста
  • Временная метка для цепочки аудита

Пример вывода CSV:

resource_type,resource_id,resource_name,check_id,check_title,cc_codes,status,details,tested_at
device,node123,prod-server,DEV-001,Tagged devices with key expiry disabled,CC6.1;CC6.3,PASS,Tags: [tag:server] key expiry enabled,2025-01-05T10:30:00Z
key,tskey-auth-xxx,tskey-auth-xxx,AUTH-001,Reusable auth keys exist,CC6.1;CC6.2;CC6.3,FAIL,Reusable key expires in 45 days,2025-01-05T10:30:00Z

Игнорирование известных рисков

Создайте файл .tailsnitch-ignore, чтобы скрывать находки для известных принятых рисков:

# .tailsnitch-ignore
# Игнорирование информационных проверок
ACL-008  # Мы намеренно не используем группы
ACL-009  # Устаревшие ACL подходят для нашего случая использования

# Игнорирование конкретных проверок средней серьёзности с обоснованием
DEV-006  # Внешние устройства — одобренные подрядчики
LOG-001  # Журналы потоков требуют тарифного плана Enterprise

# Игнорирование одного элемента в проверке вместо отключения всей проверки
ACL-011:tag:monitoring  # широкий по замыслу; каждый другой тег всё равно проверяется
AUTH-001:tskey-auth-xxxx  # автоматически ротируется через CI, отслеживается в TICKET-123

Строка называет либо целую проверку (ACL-011), либо один элемент внутри неё (CHECK-ID:item, разделение по первому двоеточию — сам элемент может содержать двоеточия). Правило для отдельного элемента скрывает только этот элемент: проверка продолжает выполняться и по-прежнему сообщает обо всём остальном, что находит. Скрытие каждого отмеченного элемента никогда не превращает проваленную проверку в пройденную — находка остаётся, пониженная до информационной, поэтому скрытая находка никогда не читается как выполненный контроль.

Расположение файлов игнорирования (проверяются по порядку):

  1. .tailsnitch-ignore в текущем каталоге
  2. ~/.tailsnitch-ignore в домашнем каталоге

Поскольку первое расположение — это рабочий каталог, файл игнорирования может поступать из репозитория, а не от вас. Каждый запуск сообщает, какой файл он использовал и сколько находок и элементов он скрыл, а --json записывает это в поля ignore_file и ignored (CHECK-ID для целой проверки, CHECK-ID:item для одного скрытого элемента). Используйте --no-ignore, чтобы пропустить файл.

# Использование конкретного файла игнорирования
tailsnitch --ignore-file /path/to/ignore

# Полное отключение обработки файла игнорирования
tailsnitch --no-ignore

Экспорт в JSON и обработка

# Экспорт полного отчёта
tailsnitch --json > audit.json

# Извлечение проваленных проверок в TSV
tailsnitch --json | jq -r '
  .suggestions
  | map(select(.pass == false))
  | .[]
  | [.id, .title, .severity, .remediation]
  | @tsv
' > findings.tsv

# Сводка по серьёзности
tailsnitch --json | jq '
  .suggestions
  | map(select(.pass == false))
  | group_by(.severity)
  | map({severity: .[0].severity, count: length})
'

# Список критических/высоких проблем со ссылками для администратора
tailsnitch --json | jq -r '
  .suggestions
  | map(select(.pass == false and (.severity == "CRITICAL" or .severity == "HIGH")))
  | .[]
  | "\(.id): \(.title)\n  Fix: \(.fix.admin_url // "manual")\n"
'

Справочник команд

ФлагОписание
--jsonВывод в формате JSON
--severityФильтр по минимальной серьёзности: critical, high, medium, low, info
--categoryФильтр по категории: access, auth, network, ssh, log, device, dns
--checksЗапуск конкретных проверок (ID или слаги через запятую)
--list-checksСписок всех доступных проверок и выход
--tailnetУказание tailnet-сети для аудита (по умолчанию: из API-ключа)
--verboseПоказ также проходящих проверок
--fixВключение интерактивного режима исправления
--autoАвтовыбор безопасных исправлений (требует --fix)
--dry-runПредпросмотр действий по исправлению без выполнения (требует --fix)
--no-audit-logОтключение журналирования аудита действий по исправлению
--soc2Экспорт доказательств SOC 2: json или csv
--tailscale-pathПуть к CLI tailscale (для проверок Tailnet Lock)
--timeoutОбщий бюджет времени на аудит (по умолчанию 2m)
--ignore-fileПуть к файлу игнорирования
--no-ignoreОтключение обработки файла игнорирования
--versionПоказ информации о версии

Проверки безопасности

Tailsnitch выполняет 57 проверок безопасности в 7 категориях. См. docs/CHECKS.md для подробной документации по каждой проверке.

Критическая серьёзность

IDПроверкаРиск
ACL-001Политика «разрешить всё» по умолчаниюВсе устройства имеют неограниченный доступ
ACL-002Неправильная конфигурация SSH autogroup:nonrootSSH от имени любого пользователя, не являющегося root
ACL-006tagOwners слишком широкиеПовышение привилегий через теги
ACL-007Использование autogroup:danger-allДоступ предоставлен внешним пользователям

Высокая серьёзность

IDПроверкаРиск
ACL-011Достижимость тега пересекает границу доверияУкраденный многоразовый ключ создаёт тег, который достигает всего
AUTH-001Многоразовые ключи аутентификацииНеограниченное добавление устройств при краже
AUTH-002Ключи аутентификации с длительным сроком действияРасширенное окно воздействия
AUTH-003Предварительно авторизованные ключиОбход одобрения устройств
AUTH-006Субъект федеративного удостоверения слишком широкийЛюбой субъект, за которого поручился эмитент, может создать тег
DEV-001Устройства с тегами без истечения срока ключаНеограниченный доступ
DEV-002Пользовательские устройства с тегамиСохраняются после удаления пользователя
DEV-010Tailnet Lock отключёнНет защиты от украденных ключей
DEV-012Ожидающие подписи Tailnet LockНеподписанные узлы требуют проверки
NET-001Воздействие FunnelПубличный доступ в интернет
NET-003Граница доверия маршрутизатора подсетиНезашифрованный трафик в локальной сети
SSH-002Root SSH без режима проверкиНе требуется повторная аутентификация

Средняя серьёзность

IDПроверкаРиск
ACL-004Использование autogroup:memberВключены внешние пользователи
ACL-005Настроены AutoApproversОбход одобрения маршрутов
AUTH-004Неэфимерные ключи CI/CDНакопление устаревших устройств
AUTH-005Федерация удостоверений рабочих нагрузок не используетсяДолгоживущие ключи остаются похищаемыми
DEV-003Устаревшие клиентыПотенциальные уязвимости
DEV-004Устаревшие устройстваНеиспользуемая поверхность атаки
DEV-005Неавторизованные устройстваОчередь ожидающих одобрения
DEV-007Чувствительные имена машинРаскрытие в CT-журналах
DEV-009Конфигурация одобрения устройствМожет быть не включена
NET-004Раскрытие в CT-журналах HTTPSИмена машин публичны
NET-005Видимость трафика узла выходаОператор видит весь трафик
NET-006Воздействие ServeЛокальные сервисы в tailnet
SSH-003Воздействие интерфейса RecorderСеансы видны сети

Информационные

Проверки конфигурации журналирования, настроек DNS, ролей пользователей и элементов ручной проверки.

Серьёзность, зависящая от находки

Некоторые проверки оценивают то, что находят, а не несут одну фиксированную серьёзность. Три из них стоит выделить:

  • ACL-011 сообщает о достижимости каждого тега как об информационной. Проверка проваливается только тогда, когда тег, который может назначить ключ аутентификации, достигает подстановочного назначения, маршрутизируемой подсети или исходящего трафика узла выхода: Высокая серьёзность, если многоразовый ключ назначает этот тег, Средняя, если только одноразовый ключ. Количество устройств никогда не определяет серьёзность.
  • AUTH-005 сообщает о Средней серьёзности, когда в tailnet вообще нет доверенных учётных данных, и о Низкой, когда доверенные учётные данные существуют, но многоразовый ключ всё равно создаёт теги, которые ни одна из них не покрывает.
  • AUTH-006 сообщает о Высокой серьёзности для субъекта, который является не чем иным, как подстановочным знаком, и о Низкой для более узкого подстановочного знака или отсутствующей аудитории.

Пример вывода

+=====================================================================+
|                    TAILSNITCH SECURITY AUDIT                        |
|            Tailnet: example.com                                     |
|            Version: 1.0.0 (build: abc123)                           |
+=====================================================================+

  Используется файл игнорирования: .tailsnitch-ignore (3 правила)

=== ACCESS CONTROLS ===================================================

[CRITICAL] ACL-001: Активна политика «разрешить всё» по умолчанию
  В вашей политике ACL отсутствует поле 'acls'. Tailscale применяет
  политику «разрешить всё» по умолчанию, предоставляя всем устройствам полный доступ.

  Исправление:
  Определите явные правила ACL, следуя принципу наименьших привилегий.

  Источник: https://tailscale.com/docs/reference/examples/acls
----------------------------------------------------------------------

=== AUTHENTICATION & KEYS =============================================

[HIGH] AUTH-001: Существуют многоразовые ключи аутентификации
  Найдено 2 многоразовых ключа аутентификации. При компрометации
  их можно повторно использовать для добавления нескольких устройств.

  Детали:
    - Ключ tskey-auth-xxx (истекает через 45 дней)
    - Ключ tskey-auth-yyy (истекает через 89 дней)

  Исправление:
  Храните многоразовые ключи в менеджере секретов. Предпочитайте одноразовые ключи.

  Источник: https://tailscale.com/docs/features/access-control/auth-keys
----------------------------------------------------------------------

SUMMARY
======================================================================
  Critical: 1  High: 3  Medium: 5  Low: 2  Info: 8
  Всего находок: 19  |  Пройдено: 33

Проверки Tailnet Lock

Проверки Tailnet Lock (DEV-010, DEV-012) требуют локального CLI tailscale и выполняются против демона локальной машины. При аудите удалённой tailnet-сети через --tailnet эти проверки отражают локальный статус, а не аудируемую tailnet-сеть.

# Указание пользовательского пути к бинарному файлу tailscale при необходимости
tailsnitch --tailscale-path /opt/tailscale/bin/tailscale

Интеграция с CI/CD

Запускайте Tailsnitch в конвейерах CI/CD для обнаружения регрессий безопасности:

# Пример для GitHub Actions
- name: Audit Tailscale Security
  env:
    TS_OAUTH_CLIENT_ID: ${{ secrets.TS_OAUTH_CLIENT_ID }}
    TS_OAUTH_CLIENT_SECRET: ${{ secrets.TS_OAUTH_CLIENT_SECRET }}
  run: |
    tailsnitch --json > audit.json
    # Завершить с ошибкой, если существуют проблемы критической или высокой серьёзности
    if tailsnitch --severity high --json | jq -e '.summary.critical + .summary.high > 0' > /dev/null; then
      echo "Найдены проблемы критической или высокой серьёзности!"
      tailsnitch --severity high
      exit 1
    fi

Ссылки

Лицензия

MIT

Участие в разработке

См. CONTRIBUTING.md для получения рекомендаций.

Категории