A varredura de segurança de contêineres com Trivy tornou-se o padrão de facto para detectar vulnerabilidades em imagens Docker antes que cheguem à produção. Se você já se perguntou como atacantes exploram CVEs conhecidos em imagens base como ubuntu:20.04 ou node:18, ou se seu Dockerfile expõe segredos, o Trivy fornece a resposta em segundos. Este guia cobre instalação, estratégias de varredura, integração CI/CD e como interpretar e agir sobre as descobertas do Trivy sem se afogar em falsos positivos.
Pré-requisitos
- Docker instalado e em execução (Docker 20.10+)
- Estação de trabalho Linux, macOS ou Windows (WSL2)
- Familiaridade básica com imagens Docker e Dockerfiles
- Uma plataforma CI/CD (GitHub Actions, GitLab CI ou Jenkins) para integração de pipelines
- Acesso root ou sudo para instalação do Trivy em nível de sistema (ou use a instalação do binário)
Instalando o Trivy
O Trivy é distribuído como um único binário estático sem dependências externas. O caminho mais rápido no Linux:
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin
trivy --version
No Ubuntu/Debian você pode adicionar o repositório apt da Aqua Security para atualizações gerenciadas:
sudo apt-get install wget apt-transport-https gnupg lsb-release -y
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/trivy.list
sudo apt-get update && sudo apt-get install trivy -y
No macOS com Homebrew: brew install trivy
O Trivy baixa seu banco de dados de vulnerabilidades na primeira execução. Force uma atualização do banco de dados a qualquer momento com trivy image --download-db-only.
Varrendo Imagens Docker em Busca de Vulnerabilidades
O comando principal é direto:
trivy image nginx:latest
O Trivy baixa a imagem se não estiver em cache local, descompacta as camadas e verifica cada pacote do SO instalado e dependência de linguagem em seu banco de dados de vulnerabilidades (NVD, GitHub Advisory, Alpine secdb e outros). A saída mostra IDs de CVE, severidade, versão instalada e a versão corrigida quando disponível.
Filtrando por Severidade
Por padrão, o Trivy mostra todas as severidades de UNKNOWN a CRITICAL. Na prática, você quer focar em descobertas acionáveis:
trivy image --severity HIGH,CRITICAL nginx:latest
Ignorando Vulnerabilidades Sem Correção
Muitos CVEs ainda não têm correção disponível. Use --ignore-unfixed para ignorá-los e focar no que você pode realmente remediar:
trivy image --severity HIGH,CRITICAL --ignore-unfixed nginx:latest
Formatos de Saída
O Trivy suporta múltiplos formatos de saída para diferentes consumidores:
# Tabela legível por humanos (padrão)
trivy image nginx:latest
# JSON para processamento programático
trivy image --format json --output results.json nginx:latest
# SARIF para integração com a aba de Segurança do GitHub
trivy image --format sarif --output results.sarif nginx:latest
# SBOM CycloneDX
trivy image --format cyclonedx --output sbom.json nginx:latest
O formato SARIF integra-se diretamente com a aba de Segurança do GitHub, exibindo anotações de vulnerabilidades inline em pull requests.
Varrendo Dockerfiles e Erros de Configuração IaC
O scanner config do Trivy verifica Dockerfiles, manifestos Kubernetes, Terraform e Helm charts em busca de erros de configuração de segurança antes que sejam implantados:
# Varrer um Dockerfile
trivy config ./Dockerfile
# Varrer um diretório completo (manifestos Kubernetes, Terraform)
trivy config ./k8s/
# Varrer charts do Helm
trivy config --helm-values values.yaml ./charts/myapp
Descobertas comuns em Dockerfiles incluem: execução como root, uso de ADD em vez de COPY, ausência de HEALTHCHECK, exposição de portas sensíveis e não fixar digests de imagem base.
Detectando Segredos e Dados Sensíveis
O Trivy pode varrer camadas de imagem e sistemas de arquivos em busca de segredos acidentalmente incorporados:
# Habilitar varredura de segredos em uma imagem
trivy image --scanners secret nginx:latest
# Varrer um diretório local em busca de segredos
trivy fs --scanners secret ./src/
O Trivy detecta chaves AWS, tokens do GitHub, chaves SSH privadas, strings de conexão de banco de dados e centenas de outros padrões de segredos. Isso é particularmente valioso para capturar segredos comprometidos no código-fonte que acabaram em uma camada do Docker.
Comparação com Alternativas
| Recurso | Trivy | Grype | Snyk | Clair |
|---|---|---|---|---|
| CVEs de pacotes do SO | Sim | Sim | Sim | Sim |
| Dependências de linguagem | Sim | Sim | Sim | Não |
| Erros de configuração IaC | Sim | Não | Sim | Não |
| Varredura de segredos | Sim | Não | Sim | Não |
| Geração de SBOM | Sim | Sim | Sim | Não |
| Licença | Apache 2.0 | Apache 2.0 | Proprietária | Apache 2.0 |
| Integração CI/CD | Nativa | Nativa | Nativa | Limitada |
| Modo offline | Sim | Sim | Não | Parcial |
A vantagem do Trivy é a amplitude — combina varredura de vulnerabilidades, detecção de erros de configuração, varredura de segredos e geração de SBOM em um único binário sem exigir um servidor em execução ou banco de dados.
Integrando o Trivy em Pipelines CI/CD
GitHub Actions
name: Varredura de Segurança de Contêineres
on:
push:
branches: [main]
pull_request:
jobs:
trivy-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Construir imagem Docker
run: docker build -t myapp:${{ github.sha }} .
- name: Executar scanner de vulnerabilidades Trivy
uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:${{ github.sha }}
format: sarif
output: trivy-results.sarif
severity: HIGH,CRITICAL
exit-code: 1
ignore-unfixed: true
- name: Enviar resultados do Trivy para a aba de Segurança do GitHub
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: trivy-results.sarif
A configuração exit-code: 1 reprovará o pipeline quando CVEs críticos ou altos forem encontrados. if: always() no upload do SARIF garante que os resultados sejam visíveis mesmo quando a etapa de varredura falha.
GitLab CI
trivy-scan:
image: aquasec/trivy:latest
stage: test
script:
- trivy image --exit-code 1 --severity CRITICAL --ignore-unfixed $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
allow_failure: false
Cenário Real
Você tem uma aplicação em produção executando node:16 como imagem base. Sua equipe de segurança sinaliza que o pipeline CI/CD nunca valida imagens de contêiner antes da implantação. Você tem 48 horas para implementar um portão de varredura.
Etapa 1 — Auditar a imagem atual:
trivy image node:16 --severity HIGH,CRITICAL --ignore-unfixed
Isso revela 47 CVEs HIGH e 12 CRITICAL na imagem base — a maioria corrigida atualizando para node:18-alpine.
Etapa 2 — Atualizar o Dockerfile:
# Antes
FROM node:16
# Depois
FROM node:18-alpine
Etapa 3 — Revarrer para confirmar a correção:
trivy image node:18-alpine --severity HIGH,CRITICAL --ignore-unfixed
A variante alpine reduz a contagem de CVEs de 59 para 3 (todos sem correção).
Etapa 4 — Adicionar o portão CI:
Adicione o workflow do GitHub Actions acima. Todos os PRs futuros serão bloqueados se CVEs CRITICAL forem introduzidos.
Etapa 5 — Varrer também IaC:
trivy config ./k8s/ --severity HIGH,CRITICAL
Isso revela dois problemas: um deployment executando como root e uma configuração de contexto de segurança readOnlyRootFilesystem ausente.
Armadilhas e Casos Especiais
Desatualização do banco de dados de vulnerabilidades: O Trivy armazena seu banco de dados em cache localmente. Em ambientes CI, execute trivy image --download-db-only como uma etapa de cache separada para evitar downloads redundantes.
Autenticação em registros privados: Exporte credenciais como variáveis de ambiente antes de varrer:
export TRIVY_USERNAME=meuusuario
export TRIVY_PASSWORD=minhasenha
trivy image meuregistro.exemplo.com/minhaapp:latest
Falsos positivos: Alguns CVEs são sinalizados em bibliotecas que sua aplicação nunca chama. Use .trivyignore para suprimir falsos positivos conhecidos:
# .trivyignore
CVE-2022-12345 # Não explorável — biblioteca não chamada em tempo de execução
Alpine musl vs glibc: Imagens baseadas em Alpine relatam menos CVEs porque o Alpine usa musl libc e a equipe de segurança do Alpine aplica patches agressivamente. Isso não é cobertura “ausente” — reflete diferenças genuínas no ecossistema de bibliotecas.
Imagens multi-arquitetura: Sempre especifique a plataforma ao varrer imagens multi-arch para obter resultados corretos: trivy image --platform linux/amd64 myapp:latest.
Trivy vs segurança em tempo de execução: O Trivy encontra vulnerabilidades em tempo de compilação. Ele não substitui ferramentas de segurança em tempo de execução como o Falco que detectam comportamento inesperado em contêineres em execução.
Solução de Problemas
Erro “No such image”: O Trivy não consegue encontrar a imagem localmente e não consegue baixá-la. Confirme o nome da imagem, a tag e as credenciais do registro.
Falhas de download do banco de dados em ambientes isolados: Baixe o pacote do banco de dados em uma máquina conectada à internet com trivy image --download-db-only, depois transfira o diretório ~/.cache/trivy/ para o host isolado.
Alto uso de memória em imagens grandes: Use --parallel 1 para reduzir o processamento simultâneo de camadas: trivy image --parallel 1 myapp:latest.
Código de saída 1 mas sem CVEs críticos exibidos: Verifique se --ignore-unfixed está omitido — CVEs críticos sem correção podem acionar o código de saída mesmo que você esperasse ver apenas problemas corrigíveis.
Timeout de varredura no CI: Defina TRIVY_TIMEOUT=10m para estender o timeout padrão de 5 minutos para imagens grandes.
Resumo
- O Trivy é um scanner de binário único cobrindo CVEs, erros de configuração, segredos e geração de SBOM
- Execute
trivy image --severity HIGH,CRITICAL --ignore-unfixed myapp:latestcomo varredura base - Use
--exit-code 1no CI/CD para bloquear implantações com vulnerabilidades críticas - Combine
trivy image(runtime) comtrivy config(Dockerfile/IaC) para cobertura completa - Imagens baseadas em Alpine reduzem dramaticamente a superfície de CVEs
- Use
.trivyignorepara suprimir falsos positivos confirmados e reduzir a fadiga de alertas - Envie resultados SARIF para a aba de Segurança do GitHub para anotações inline em PRs
- O Trivy não substitui a segurança em tempo de execução — combine-o com Falco para defesa em profundidade