
Um auditor de segurança para configurações do Tailscale. Escaneia sua tailnet em busca de configurações incorretas, controles de acesso excessivamente permissivos e violações de boas práticas de segurança.
Um auditor de segurança para configurações do Tailscale. O Tailsnitch verifica sua tailnet em busca de 57 configurações incorretas, controles de acesso excessivamente permissivos e violações de boas práticas de segurança.
# 1. Defina suas credenciais da API do Tailscale
export TS_API_KEY="tskey-api-..."
# 2. Execute a auditoria
tailsnitch
# 3. Veja apenas descobertas de alta gravidade
tailsnitch --severity high
# 4. Corrija alguns problemas ~interativamente~ modo yolo
tailsnitch --fix
Baixe a versão mais recente em GitHub Releases.
Usuários de macOS: Remova o atributo de quarentena após o download:
sudo xattr -rd com.apple.quarantine tailsnitch
go install github.com/Adversis/tailsnitch@latest
git clone https://github.com/Adversis/tailsnitch.git
cd tailsnitch
go build -o tailsnitch .
O Tailsnitch suporta dois métodos de autenticação. OAuth é preferido quando ambos estão configurados.
Clientes OAuth fornecem acesso com escopo e auditável que não expira quando funcionários saem da empresa.
export TS_OAUTH_CLIENT_ID="..."
export TS_OAUTH_CLIENT_SECRET="tskey-client-..."
Crie um cliente OAuth em: https://login.tailscale.com/admin/settings/oauth
Escopos necessários para auditoria somente leitura:
all:read cobre tudo. Concedendo escopos individualmente:
| Escopo | Usado para |
|---|---|
policy_file:read | Arquivo de política da tailnet — ACL-, NET-, SSH-* |
devices:core:read | Lista de dispositivos — DEV-, NET-, ACL-011 |
dns:read | Configuração de DNS — DNS-001, DEV-007 |
auth_keys:read | Chaves de autenticação de máquina — AUTH-*, ACL-011 |
feature_settings:read | Configurações da tailnet — DEV-008, DEV-009, DEV-014 |
logs:network:read | Configuração de registro de fluxo de rede — LOG-001 |
networking_settings:read | Configuração de certificado HTTPS — NET-004 |
log_streaming:read | Destinos de streaming de logs — LOG-002 |
webhooks:read | Endpoints de webhook — LOG-005, LOG-012 |
oauth_keys:read | Clientes OAuth — LOG-006 |
users:read | Funções e status de usuários — USER-001, LOG-006 |
account_settings:read | Contato de segurança — LOG-011 |
devices:posture_attributes:read | Integrações de postura — DEV-014 |
Qualquer escopo que você omitir afeta apenas as verificações que precisam dele: essas verificações relatam que não conseguiram ler a configuração em vez de passar.
AUTH-005 e AUTH-006 leem as identidades federadas da tailnet, que o console
de administração chama de credenciais de confiança. Elas chegam da mesma listagem de chaves que as
chaves de autenticação, então espera-se que auth_keys:read as cubra. Isso não foi confirmado
contra uma tailnet ativa. Se a listagem de chaves não puder ser lida, ambas as verificações relatam
"não avaliado" em vez de passar. Se um escopo ausente retorna um erro ou em vez disso
retorna a listagem com as identidades filtradas não foi confirmado; se
filtrar silenciosamente, AUTH-005 relataria que nenhuma credencial de confiança existe e
AUTH-006 não encontraria nada para verificar.
Escopos adicionais para o modo de correção:
devices:core - Excluir dispositivos, modificar tags (requer seleção de tag)auth_keys - Excluir chaves de autenticaçãoDEV-010 e DEV-012 relatam sobre Tailnet Lock, que a API do Tailscale não
expõe como uma configuração da tailnet. Dispositivos bloqueados por ele são visíveis através da
API, mas determinar se o lock está habilitado precisa do CLI local tailscale,
que lê o daemon na máquina que executa o tailsnitch. Ao auditar outra
tailnet com --tailnet, trate essa parte do resultado de acordo. Use
--tailscale-path se o binário estiver em um local não padrão.
Chaves de API operam como o usuário que as criou e herdam as permissões desse usuário.
export TS_API_KEY="tskey-api-..."
Crie uma chave de API em: https://login.tailscale.com/admin/settings/keys
# Executar auditoria completa
tailsnitch
# Mostrar também verificações aprovadas (verboso)
tailsnitch --verbose
# Saída como JSON para processamento
tailsnitch --json
# Auditar uma tailnet específica (quando o cliente OAuth tem acesso a várias)
tailsnitch --tailnet mycompany.com
# Mostrar apenas problemas críticos e de alta gravidade
tailsnitch --severity high
# Filtrar por categoria
tailsnitch --category access # Problemas de ACL
tailsnitch --category auth # Autenticação e chaves
tailsnitch --category device # Segurança de dispositivos
tailsnitch --category network # Exposição de rede
tailsnitch --category ssh # Regras de SSH
tailsnitch --category log # Registros e administração
# Executar apenas verificações específicas
tailsnitch --checks ACL-001,AUTH-001,DEV-010
tailsnitch --checks stale-devices,tailnet-lock-not-enabled
# Listar todas as verificações disponíveis
tailsnitch --list-checks
O modo de correção permite remediar problemas diretamente via API do Tailscale:
# Modo de correção interativo
tailsnitch --fix
# Pré-visualizar o que seria corrigido (execução de teste)
tailsnitch --fix --dry-run
# Auto-selecionar correções seguras (ainda requer confirmação)
tailsnitch --fix --auto
# Desabilitar registro de auditoria das ações de correção
tailsnitch --fix --no-audit-log
Itens corrigíveis via API:
| Verificação | Ação |
|---|---|
| AUTH-001, AUTH-002, AUTH-003 | Excluir chaves de autenticação |
| DEV-002 | Remover tags de dispositivos de usuários |
| DEV-004 | Excluir dispositivos obsoletos |
| DEV-005 | Autorizar dispositivos pendentes |
O modo de correção também fornece links diretos para o console de administração para problemas que exigem intervenção manual.
Gere relatórios de evidências para auditorias SOC 2 com mapeamentos de controles de Critérios Comuns (CC):
# Exportar como JSON
tailsnitch --soc2 json > soc2-evidence.json
# Exportar como CSV (para planilhas)
tailsnitch --soc2 csv > soc2-evidence.csv
O relatório SOC 2 inclui:
Exemplo de saída 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
Crie um arquivo .tailsnitch-ignore para suprimir descobertas de riscos conhecidos e aceitos:
# .tailsnitch-ignore
# Ignorar verificações informativas
ACL-008 # Não usamos grupos intencionalmente
ACL-009 # ACLs legadas são suficientes para nosso caso de uso
# Ignorar verificações médias específicas com justificativa
DEV-006 # Dispositivos externos são contratados aprovados
LOG-001 # Logs de fluxo exigem plano Enterprise
# Ignorar um item dentro de uma verificação, em vez de silenciar a verificação inteira
ACL-011:tag:monitoring # amplo por design; todas as outras tags ainda são verificadas
AUTH-001:tskey-auth-xxxx # rotaciona automaticamente via CI, rastreado em TICKET-123
Uma linha nomeia uma verificação inteira (ACL-011) ou um item dentro dela
(CHECK-ID:item, dividido no primeiro dois-pontos - o item em si pode conter
dois-pontos). Uma regra por item suprime apenas esse item: a verificação ainda é executada e
ainda relata tudo o mais que encontrar. Suprimir cada item sinalizado nunca
transforma uma verificação reprovada em uma aprovada - a descoberta permanece, rebaixada para
Informativa, então uma descoberta suprimida nunca é lida como um controle satisfeito.
Locais do arquivo de ignorados (verificados em ordem):
.tailsnitch-ignore no diretório atual~/.tailsnitch-ignore no diretório pessoalComo o primeiro local é o diretório de trabalho, um arquivo de ignorados pode vir
de um repositório em vez de você. Cada execução relata qual arquivo usou
e quantas descobertas e itens suprimiu, e --json registra isso nos
campos ignore_file e ignored (CHECK-ID para uma verificação inteira,
CHECK-ID:item para um item suprimido). Use --no-ignore para pular o arquivo.
# Usar um arquivo de ignorados específico
tailsnitch --ignore-file /path/to/ignore
# Desabilitar completamente o processamento do arquivo de ignorados
tailsnitch --no-ignore
# Exportar relatório completo
tailsnitch --json > audit.json
# Extrair verificações reprovadas como TSV
tailsnitch --json | jq -r '
.suggestions
| map(select(.pass == false))
| .[]
| [.id, .title, .severity, .remediation]
| @tsv
' > findings.tsv
# Resumo por gravidade
tailsnitch --json | jq '
.suggestions
| map(select(.pass == false))
| group_by(.severity)
| map({severity: .[0].severity, count: length})
'
# Listar problemas críticos/altos com links de administração
tailsnitch --json | jq -r '
.suggestions
| map(select(.pass == false and (.severity == "CRITICAL" or .severity == "HIGH")))
| .[]
| "\(.id): \(.title)\n Fix: \(.fix.admin_url // "manual")\n"
'
| Flag | Descrição |
|---|---|
--json | Saída como JSON |
--severity | Filtrar por gravidade mínima: critical, high, medium, low, info |
--category | Filtrar por categoria: access, auth, network, ssh, log, device, dns |
--checks | Executar verificações específicas (IDs ou slugs separados por vírgula) |
--list-checks | Listar todas as verificações disponíveis e sair |
--tailnet | Especificar tailnet a auditar (padrão: da chave de API) |
--verbose | Mostrar também verificações aprovadas |
--fix | Habilitar modo de correção interativo |
--auto | Auto-selecionar correções seguras (requer --fix) |
--dry-run | Pré-visualizar ações de correção sem executar (requer --fix) |
--no-audit-log | Desabilitar registro de auditoria das ações de correção |
--soc2 | Exportar evidências SOC 2: json ou csv |
--tailscale-path | Caminho para o CLI tailscale (para verificações de Tailnet Lock) |
--timeout | Orçamento de tempo total para a auditoria (padrão 2m) |
--ignore-file | Caminho para o arquivo de ignorados |
--no-ignore | Desabilitar processamento do arquivo de ignorados |
--version | Mostrar informações de versão |
O Tailsnitch executa 57 verificações de segurança em 7 categorias. Consulte docs/CHECKS.md para documentação detalhada de cada verificação.
| ID | Verificação | Risco |
|---|---|---|
| ACL-001 | Política padrão 'permitir tudo' | Todos os dispositivos têm acesso irrestrito |
| ACL-002 | Configuração incorreta de SSH autogroup:nonroot | SSH como qualquer usuário não root |
| ACL-006 | tagOwners muito amplo | Escalação de privilégios via tags |
| ACL-007 | Uso de autogroup:danger-all | Acesso concedido a usuários externos |
| ID | Verificação | Risco |
|---|---|---|
| ACL-011 | Alcance de tag cruza uma fronteira de confiança | Uma chave reutilizável roubada cria uma tag que alcança tudo |
| AUTH-001 | Chaves de autenticação reutilizáveis | Adições ilimitadas de dispositivos se roubadas |
| AUTH-002 | Chaves de autenticação com expiração longa | Janela de exposição estendida |
| AUTH-003 | Chaves pré-autorizadas | Ignoram aprovação de dispositivos |
| AUTH-006 | Assunto de identidade federada muito amplo | Qualquer principal que o emissor garanta pode criar a tag |
| DEV-001 | Dispositivos com tag sem expiração de chave | Acesso indefinido |
| DEV-002 | Dispositivos de usuários com tag | Persistem após remoção do usuário |
| DEV-010 | Tailnet Lock desabilitado | Sem proteção contra chaves roubadas |
| DEV-012 | Assinaturas pendentes de Tailnet Lock | Nós não assinados precisam de revisão |
| NET-001 | Exposição Funnel | Acesso pela internet pública |
| NET-003 | Fronteira de confiança do roteador de sub-rede | Tráfego não criptografado na rede local |
| SSH-002 | SSH root sem modo de verificação | Nenhuma reautenticação necessária |
| ID | Verificação | Risco |
|---|---|---|
| ACL-004 | Uso de autogroup:member | Usuários externos incluídos |
| ACL-005 | AutoApprovers configurado | Ignoram aprovação de rotas |
| AUTH-004 | Chaves CI/CD não efêmeras | Dispositivos obsoletos se acumulam |
| AUTH-005 | Federação de identidade de carga de trabalho não em uso | Chaves de longa duração permanecem roubáveis |
| DEV-003 | Clientes desatualizados | Vulnerabilidades potenciais |
| DEV-004 | Dispositivos obsoletos | Superfície de ataque não utilizada |
| DEV-005 | Dispositivos não autorizados | Fila de aprovação pendente |
| DEV-007 | Nomes de máquina sensíveis | Exposição em log CT |
| DEV-009 | Configuração de aprovação de dispositivos | Pode não estar habilitada |
| NET-004 | Exposição em log CT HTTPS | Nomes de máquina públicos |
| NET-005 | Visibilidade do tráfego do nó de saída | Operador vê todo o tráfego |
| NET-006 | Exposição Serve | Serviços locais na tailnet |
| SSH-003 | Exposição da interface do gravador | Sessões visíveis na rede |
Verificações de configuração de registros, configurações de DNS, funções de usuário e itens de verificação manual.
Várias verificações classificam o que encontram em vez de carregar uma gravidade fixa. Três merecem destaque aqui:
+=====================================================================+
| TAILSNITCH SECURITY AUDIT |
| Tailnet: example.com |
| Version: 1.0.0 (build: abc123) |
+=====================================================================+
Usando arquivo de ignorados: .tailsnitch-ignore (3 regras)
=== CONTROLES DE ACESSO ===============================================
[CRITICAL] ACL-001: Política padrão 'permitir tudo' ativa
Sua política de ACL omite o campo 'acls'. O Tailscale aplica uma
política padrão 'permitir tudo', concedendo acesso total a todos os dispositivos.
Remediação:
Defina regras de ACL explícitas seguindo o princípio do menor privilégio.
Fonte: https://tailscale.com/docs/reference/examples/acls
----------------------------------------------------------------------
=== AUTENTICAÇÃO E CHAVES =============================================
[HIGH] AUTH-001: Chaves de autenticação reutilizáveis existem
Encontrada(s) 2 chave(s) de autenticação reutilizável(is). Elas podem ser reutilizadas para adicionar
múltiplos dispositivos se comprometidas.
Detalhes:
- Chave tskey-auth-xxx (expira em 45 dias)
- Chave tskey-auth-yyy (expira em 89 dias)
Remediação:
Armazene chaves reutilizáveis em um gerenciador de segredos. Prefira chaves de uso único.
Fonte: https://tailscale.com/docs/features/access-control/auth-keys
----------------------------------------------------------------------
RESUMO
======================================================================
Críticas: 1 Altas: 3 Médias: 5 Baixas: 2 Info: 8
Total de descobertas: 19 | Aprovadas: 33
As verificações de Tailnet Lock (DEV-010, DEV-012) exigem o CLI local tailscale e são executadas contra o daemon da máquina local. Ao auditar uma tailnet remota via --tailnet, essas verificações refletem o status local, não o da tailnet auditada.
# Especificar caminho personalizado do binário tailscale se necessário
tailsnitch --tailscale-path /opt/tailscale/bin/tailscale
Execute o Tailsnitch em pipelines CI/CD para detectar regressões de segurança:
# Exemplo de GitHub Actions
- name: Auditar Segurança do Tailscale
env:
TS_OAUTH_CLIENT_ID: ${{ secrets.TS_OAUTH_CLIENT_ID }}
TS_OAUTH_CLIENT_SECRET: ${{ secrets.TS_OAUTH_CLIENT_SECRET }}
run: |
tailsnitch --json > audit.json
# Falhar se existirem problemas críticos ou de alta gravidade
if tailsnitch --severity high --json | jq -e '.summary.critical + .summary.high > 0' > /dev/null; then
echo "Problemas críticos ou de alta gravidade encontrados!"
tailsnitch --severity high
exit 1
fi
MIT
Consulte CONTRIBUTING.md para diretrizes.