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

RecursoTrivyGrypeSnykClair
CVEs de pacotes do SOSimSimSimSim
Dependências de linguagemSimSimSimNão
Erros de configuração IaCSimNãoSimNão
Varredura de segredosSimNãoSimNão
Geração de SBOMSimSimSimNão
LicençaApache 2.0Apache 2.0ProprietáriaApache 2.0
Integração CI/CDNativaNativaNativaLimitada
Modo offlineSimSimNãoParcial

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:latest como varredura base
  • Use --exit-code 1 no CI/CD para bloquear implantações com vulnerabilidades críticas
  • Combine trivy image (runtime) com trivy config (Dockerfile/IaC) para cobertura completa
  • Imagens baseadas em Alpine reduzem dramaticamente a superfície de CVEs
  • Use .trivyignore para 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

Artigos Relacionados