Automatizar a verificação de imagem de contêiner

Concluído

Imagens de contêiner empacotam aplicações juntamente com todas as suas dependências, tornando-as artefatos de implantação convenientes. No entanto, essa conveniência apresenta desafios de segurança significativos: vulnerabilidades em imagens base, pacotes do sistema ou dependências de aplicativos podem comprometer contêineres implantados. Automatizar a verificação de imagens de contêiner em todo o ciclo de vida de desenvolvimento e implantação garante que apenas imagens seguras e compatíveis cheguem a ambientes de produção.

Noções básicas sobre os riscos de segurança do contêiner

As imagens de contêiner introduzem várias categorias de risco de segurança:

Vulnerabilidades de imagem base

Pacotes do sistema operacional:

  • Bibliotecas do sistema: As imagens base incluem bibliotecas do sistema operacional (glibc, OpenSSL, zlib) que podem conter vulnerabilidades.
  • Gerenciadores de pacotes: Os gerenciadores de pacotes do sistema (apt, yum, apk) e seus pacotes frequentemente têm problemas de segurança.
  • Utilitários de shell: Utilitários comuns (bash, curl, wget) em imagens base podem ter vulnerabilidades.
  • Atraso de atualização: Imagens base oficiais podem incluir pacotes desatualizados entre lançamentos.

Impacto na seleção de imagem base:

  • Alpine vs Debian: As imagens base do Linux alpino são menores, mas usam bibliotecas diferentes (musl em vez de glibc), afetando perfis de vulnerabilidade.
  • Imagens Sem Distribuição: As imagens sem distribuição do Google contêm apenas dependências de tempo de execução da aplicação, reduzindo drasticamente a superfície de ataque.
  • Variantes Slim: As variantes de imagem Slim excluem utilitários comuns, reduzindo o tamanho e a exposição a vulnerabilidades.
  • Atualização de versão: Usar latest tags pode introduzir mudanças inesperadas; tags de versão específicas fornecem estabilidade, mas requerem atualizações manuais.

Vulnerabilidades de dependência de aplicativo

Pacotes específicos do idioma:

  • Pacotes npm: Node.js aplicativos trazem centenas de dependências npm que podem ter vulnerabilidades.
  • Pacotes do Python: Os aplicativos Python incluem pacotes PyPI com possíveis problemas de segurança.
  • Dependências do Java: As dependências Maven e Gradle incluem transitivamente muitos arquivos JAR.
  • Pacotes do .NET: Pacotes NuGet em aplicativos .NET podem conter vulnerabilidades.

Dependências transitivas:

  • Árvores de dependência profunda: As dependências do aplicativo têm suas próprias dependências, criando árvores de dependência profunda.
  • Vulnerabilidades ocultas: Vulnerabilidades em dependências transitivas são fáceis de ignorar sem verificação automatizada.
  • Atualizar complexidade: A atualização de dependências transitivas requer a compreensão da compatibilidade em toda a cadeia de dependências.

Acúmulo de camada de imagem

Sistema de arquivos em camadas:

  • Herança de camada: Cada instrução do Dockerfile cria uma nova camada e as vulnerabilidades em qualquer camada afetam a imagem final.
  • Os arquivos excluídos persistem: Os arquivos excluídos em camadas posteriores ainda existem em camadas anteriores e contribuem para o tamanho da imagem e o perfil de segurança.
  • Segredos na história: Segredos acidentalmente confirmados em camadas iniciais permanecem no histórico de imagens, mesmo se removidos em camadas posteriores.
  • Dependências de tempo de compilação: As dependências necessárias somente durante a compilação (compiladores, ferramentas de construção) não devem aparecer em imagens finais de tempo de execução.

Vulnerabilidades de configuração

Configurações incorretas do Dockerfile:

  • Executando como raiz: Contêineres executados como usuário raiz possuem privilégios desnecessários.
  • Portas expostas: Portas expostas desnecessariamente expandem a superfície de ataque.
  • Binários SUID: Binários SUID/SGID permitem ataques de escalonamento de privilégios.
  • Padrões inseguros: As configurações padrão podem não seguir as práticas recomendadas de segurança.

Abordagens de verificação de contêiner

A segurança efetiva do contêiner requer a verificação em vários pontos do ciclo de vida:

Verificação do Registro

Monitoramento contínuo do registro: Os registros de contêiner fornecem locais centralizados para verificação e imposição de políticas.

Verificação do Registro de Contêiner do Azure com o Microsoft Defender:

  • Verificação automática: O Microsoft Defender para Contêineres verifica automaticamente as imagens enviadas por push para o Registro de Contêiner do Azure.
  • Varredura baseada em gatilho: As varreduras são acionadas em operações de push, importação e pull.
  • Verificação contínua: As imagens são verificadas periodicamente em busca de vulnerabilidades recentemente divulgadas.
  • Recomendações: A Central de Segurança fornece recomendações de correção para vulnerabilidades descobertas.

Gatilhos de varredura do registro:

  • Gatilhos de push: Novas imagens são automaticamente varridas quando enviadas para o registro.
  • Gatilhos de importação: As imagens importadas de registros externos são verificadas.
  • Gatilhos de pull: Imagens são varridas dentro de 24 horas após serem puxadas.
  • Verificação periódica: As imagens digitalizadas anteriormente são verificadas diariamente (últimos 90 dias para imagens enviadas por push, últimos 30 dias para imagens extraídas).

Escaneamento durante o tempo de compilação

Integração com pipeline CI/CD: A varredura durante a compilação de imagens detecta vulnerabilidades antes que as imagens cheguem aos registros.

Verificação de contêiner do Azure Pipelines:

trigger:
  branches:
    include:
      - main

pool:
  vmImage: "ubuntu-latest"

variables:
  imageName: "myapp"
  dockerfilePath: "$(Build.SourcesDirectory)/Dockerfile"

steps:
  - task: Docker@2
    displayName: "Build container image"
    inputs:
      command: "build"
      repository: "$(imageName)"
      dockerfile: "$(dockerfilePath)"
      tags: "$(Build.BuildNumber)"

  - task: AquaScannerCLI@4
    displayName: "Scan image with Aqua Security"
    inputs:
      image: "$(imageName):$(Build.BuildNumber)"
      scanType: "local"
      register: false
      hideBase: false
      showNegligible: false

  - script: |
      docker run --rm \
        -v /var/run/docker.sock:/var/run/docker.sock \
        -v $(Build.SourcesDirectory):/src \
        aquasec/trivy image \
        --severity HIGH,CRITICAL \
        --exit-code 1 \
        $(imageName):$(Build.BuildNumber)
    displayName: "Scan with Trivy (fail on high/critical)"

  - task: Docker@2
    displayName: "Push image to registry"
    condition: succeeded()
    inputs:
      command: "push"
      repository: "$(imageName)"
      tags: "$(Build.BuildNumber)"

Verificação de contêiner do GitHub Actions:

name: Container Build and Scan

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

env:
  IMAGE_NAME: myapp
  REGISTRY: ghcr.io

jobs:
  build-and-scan:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
      security-events: write

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2

      - name: Build container image
        uses: docker/build-push-action@v4
        with:
          context: .
          load: true
          tags: ${{ env.IMAGE_NAME }}:${{ github.sha }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

      - name: Scan image with Trivy
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: "${{ env.IMAGE_NAME }}:${{ github.sha }}"
          format: "sarif"
          output: "trivy-results.sarif"
          severity: "CRITICAL,HIGH"

      - name: Upload Trivy results to GitHub Security
        uses: github/codeql-action/upload-sarif@v2
        if: always()
        with:
          sarif_file: "trivy-results.sarif"

      - name: Scan with Snyk
        uses: snyk/actions/docker@master
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
        with:
          image: ${{ env.IMAGE_NAME }}:${{ github.sha }}
          args: --severity-threshold=high --file=Dockerfile

      - name: Log in to GitHub Container Registry
        if: github.event_name == 'push'
        uses: docker/login-action@v2
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Push image to registry
        if: github.event_name == 'push'
        run: |
          docker tag ${{ env.IMAGE_NAME }}:${{ github.sha }} \
            ${{ env.REGISTRY }}/${{ github.repository }}:${{ github.sha }}
          docker push ${{ env.REGISTRY }}/${{ github.repository }}:${{ github.sha }}

Verificação de contêiner com Segurança Avançada do GitHub: A Segurança Avançada do GitHub fornece recursos adicionais de segurança para contêineres por meio do CodeQL e da verificação de dependências.

name: Container Security with GitHub Advanced Security

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  schedule:
    - cron: "0 0 * * 0" # Weekly scheduled scan

env:
  IMAGE_NAME: myapp
  REGISTRY: ghcr.io

jobs:
  build-and-scan:
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write
      packages: write

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Initialize CodeQL
        uses: github/codeql-action/init@v2
        with:
          languages: "javascript" # Adjust based on your language

      - name: Build container image
        run: |
          docker build -t ${{ env.IMAGE_NAME }}:${{ github.sha }} .

      - name: Perform CodeQL Analysis
        uses: github/codeql-action/analyze@v2
        with:
          category: "/language:javascript"

      - name: Run CodeQL container scanning
        uses: github/codeql-action/analyze@v2
        with:
          category: "/language:dockerfile"

      - name: Scan container dependencies
        uses: anchore/scan-action@v3
        with:
          image: ${{ env.IMAGE_NAME }}:${{ github.sha }}
          fail-build: true
          severity-cutoff: high

      - name: Upload Anchore scan SARIF report
        uses: github/codeql-action/upload-sarif@v2
        if: always()
        with:
          sarif_file: results.sarif

      - name: Push image to registry
        if: github.event_name == 'push'
        run: |
          echo ${{ secrets.GITHUB_TOKEN }} | docker login ${{ env.REGISTRY }} -u ${{ github.actor }} --password-stdin
          docker tag ${{ env.IMAGE_NAME }}:${{ github.sha }} ${{ env.REGISTRY }}/${{ github.repository }}:${{ github.sha }}
          docker push ${{ env.REGISTRY }}/${{ github.repository }}:${{ github.sha }}

Benefícios da varredura em tempo de compilação:

  • Falha rápida: Evita que imagens vulneráveis sejam compiladas e enviadas para os registros.
  • Comentários do desenvolvedor: Forneça comentários imediatos aos desenvolvedores durante o processo de build.
  • Aplicação de política: Aplique políticas de segurança antes que as imagens atinjam registros ou produção.
  • Validação de artefatos de compilação: Garante que apenas imagens em conformidade avancem pelo pipeline de implantação.

Verificação em tempo de execução

Monitoramento de contêiner implantado: A verificação de runtime detecta vulnerabilidades em contêineres realmente implantados.

Controladores de admissão do Kubernetes: Os controladores de admissão impõem políticas antes que os contêineres sejam implantados nos clusters do Kubernetes.

Exemplo de política do OPA Gatekeeper:

apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
  name: k8srequiredscanstatus
spec:
  crd:
    spec:
      names:
        kind: K8sRequiredScanStatus
      validation:
        openAPIV3Schema:
          type: object
          properties:
            maxSeverity:
              type: string
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8srequiredscanstatus

        violation[{"msg": msg}] {
          container := input.review.object.spec.containers[_]
          not scan_clean(container.image)
          msg := sprintf("Image %v has not been scanned or has vulnerabilities", [container.image])
        }

        scan_clean(image) {
          # Query registry for scan status
          # This is simplified; actual implementation queries scan results
          scan_result := data.scans[image]
          scan_result.status == "passed"
        }

Proteção de runtime do Serviço de Kubernetes do Azure: O Microsoft Defender para Contêineres fornece detecção de ameaças em tempo de execução:

  • Análise comportamental: Monitora o comportamento do contêiner para detectar atividades anômalas.
  • Inteligência contra ameaças: Compara comportamentos observados com padrões de ataque conhecidos.
  • Mapeamento MITRE ATT&CK: Mapas detectaram ameaças à estrutura MITRE ATT&CK.
  • Geração de alertas: Gera alertas de segurança para atividades suspeitas de contêiner.

Ferramentas de verificação de contêiner

Trivy (Aqua Security)

O Trivy é um verificador de vulnerabilidade de contêiner de software livre abrangente.

Principais recursos:

  • Verificação abrangente: Verifica os pacotes do sistema operacional, as dependências do aplicativo, as configurações de IaC e os segredos.
  • Suporte a vários formatos: Verifica imagens de contêiner, sistemas de arquivos, repositórios git e clusters do Kubernetes.
  • Verificação offline: Pode operar em ambientes isolados sem conexão à rede com bancos de dados de vulnerabilidade offline.
  • Desempenho rápido: Scanner leve com tempos de verificação rápidos.
  • Geração de SBOM: Gera a lista de materiais de software CycloneDX e SPDX.

Integração do Azure Pipelines Trivy:

- script: |
    wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -
    echo "deb 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

    trivy image \
      --severity HIGH,CRITICAL \
      --exit-code 1 \
      --no-progress \
      --format json \
      --output trivy-results.json \
      $(imageName):$(Build.BuildNumber)
  displayName: "Scan image with Trivy"

Contêiner Snyk

O Snyk Container oferece scanner de imagens de contêiner integrado à plataforma focada no desenvolvedor do Snyk.

Principais recursos:

  • Recomendações de imagem base: Sugere imagens de base alternativas com menos vulnerabilidades.
  • Priorização: Prioriza vulnerabilidades com base na exploração e no impacto nos negócios.
  • Diretrizes de correção: Fornece etapas específicas de remediação para vulnerabilidades descobertas.
  • Integração do Kubernetes: Verifica as imagens implantadas nos clusters do Kubernetes.

Segurança do Aqua

O Aqua Security oferece segurança de contêiner de nível empresarial em todo o ciclo de vida.

Principais recursos:

  • Garantia de imagem: Verificação abrangente de imagens com políticas personalizáveis.
  • Proteção de runtime: Monitora a execução de contêineres para comportamento suspeito.
  • Verificação de conformidade: Valida as imagens em relação ao CIS Docker Benchmark e às políticas personalizadas.
  • Segurança da cadeia de suprimentos: Verifica a procedência da imagem e detecta ataques da cadeia de suprimentos.

Mecanismo de Ancoragem

Anchore Engine é um scanner de imagem de contêiner de código aberto com análise baseada em política.

Principais recursos:

  • Orientado por políticas: Mecanismo de política flexível para definir regras de segurança e conformidade.
  • Inspeção profunda: Analisa camadas de imagem, pacotes e configuração.
  • Políticas personalizadas: Defina políticas de segurança e conformidade específicas da organização.
  • Controlado por API: A API REST para integração com ferramentas personalizadas.

GitHub Advanced Security

O GitHub Advanced Security fornece recursos de segurança de nível empresarial para repositórios, incluindo recursos de verificação de contêiner.

Recursos de segurança de container:

  • Verificação de dependência: Detecta automaticamente dependências vulneráveis em imagens de contêiner.
  • Verificação secreta: Identifica segredos expostos (chaves de API, tokens, credenciais) em camadas de contêiner e Dockerfiles.
  • Aplicação de políticas: Regras de proteção de ramificação podem exigir a aprovação de verificações de segurança.
  • Avisos de segurança: Integração com o Banco de Dados de Consultoria do GitHub para inteligência de vulnerabilidade.
  • Segurança da cadeia de suprimentos: Grafo de dependências e integração do Dependabot para dependências de contêiner.

Executando o CodeQL em contêineres: A Segurança Avançada do GitHub dá suporte à execução da verificação de código CodeQL em ambientes de contêiner para análise abrangente:

Fluxo de trabalho de verificação de contêiner do CodeQL:

name: CodeQL Container Analysis

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  analyze-container:
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write

    strategy:
      fail-fast: false
      matrix:
        language: ["javascript", "python"]

    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Initialize CodeQL
        uses: github/codeql-action/init@v2
        with:
          languages: ${{ matrix.language }}
          queries: security-extended,security-and-quality

      - name: Build application in container
        run: |
          docker build -t app:latest .
          docker create --name temp-container app:latest
          docker cp temp-container:/app/built-artifacts ./artifacts
          docker rm temp-container

      - name: Perform CodeQL Analysis
        uses: github/codeql-action/analyze@v2
        with:
          category: "/language:${{ matrix.language }}"

      - name: Scan Dockerfile
        uses: github/codeql-action/analyze@v2
        with:
          category: "/language:dockerfile"

Verificação secreta de contêineres:

name: Container Secret Scanning

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  scan-secrets:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      security-events: write

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Build container image
        run: docker build -t myapp:${{ github.sha }} .

      - name: Scan image for secrets
        uses: trufflesecurity/trufflehog@main
        with:
          path: ./
          base: ${{ github.event.repository.default_branch }}
          head: HEAD

      - name: Scan container layers for secrets
        run: |
          docker save myapp:${{ github.sha }} -o image.tar
          docker run --rm -v $(pwd):/scan \
            trufflesecurity/trufflehog:latest \
            filesystem /scan/image.tar \
            --json > secrets-report.json

      - name: Upload secret scan results
        uses: github/codeql-action/upload-sarif@v2
        if: always()
        with:
          sarif_file: secrets-report.sarif

Benefícios da Segurança Avançada do GitHub:

  • Integração nativa: Profundamente integrado com fluxos de trabalho e recursos de segurança do GitHub.
  • Painel unificado: Visão geral de segurança centralizada na guia Segurança do GitHub.
  • Aplicação de políticas: Regras de proteção de ramificação podem exigir a aprovação em verificações de segurança.
  • Relatórios de conformidade: Relatórios de conformidade internos para SOC 2, ISO 27001 e outras estruturas.
  • Colaboração em equipe: Descobertas de segurança integradas às revisões de solicitação de pull e ao acompanhamento de problemas.

Habilitando a Segurança Avançada do GitHub:

Para organizações:

  1. Navegue até as configurações da organização → a segurança e a análise de código.
  2. Habilite a Segurança Avançada do GitHub para todos ou repositórios selecionados.
  3. Configure alertas do Dependabot, varredura de segredos e verificação de código.
  4. Configure políticas de segurança e avisos de segurança.

Para repositórios:

  1. Vá para configurações de repositório → análise e segurança de código.
  2. Habilitar grafo de dependência (gratuito para repositórios públicos).
  3. Habilite alertas dependabot e atualizações de segurança dependabot.
  4. Habilite a verificação secreta (requer a licença de Segurança Avançada do GitHub para repositórios privados).
  5. Habilite a verificação de código com o CodeQL ou ferramentas de terceiros.

Segurança Avançada para registros de contêiner:

name: Registry Security Monitoring

on:
  schedule:
    - cron: "0 */6 * * *" # Every 6 hours
  workflow_dispatch:

jobs:
  scan-registry:
    runs-on: ubuntu-latest
    permissions:
      packages: read
      security-events: write

    steps:
      - name: Login to GitHub Container Registry
        uses: docker/login-action@v2
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Pull images from registry
        run: |
          docker pull ghcr.io/${{ github.repository }}/app:latest
          docker pull ghcr.io/${{ github.repository }}/app:staging

      - name: Scan registry images
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: "ghcr.io/${{ github.repository }}/app:latest"
          format: "sarif"
          output: "trivy-registry.sarif"

      - name: Upload scan results
        uses: github/codeql-action/upload-sarif@v2
        with:
          sarif_file: trivy-registry.sarif
          category: "registry-scan"

      - name: Check for critical vulnerabilities
        run: |
          CRITICAL_COUNT=$(docker run --rm \
            -v /var/run/docker.sock:/var/run/docker.sock \
            aquasec/trivy image \
            --severity CRITICAL \
            --format json \
            ghcr.io/${{ github.repository }}/app:latest | \
            jq '.Results[].Vulnerabilities | length')

          if [ "$CRITICAL_COUNT" -gt 0 ]; then
            echo "::error::Found $CRITICAL_COUNT critical vulnerabilities"
            exit 1
          fi

Integração com os recursos de segurança do GitHub:

  • Visão geral de segurança: Painel de segurança em toda a organização mostrando vulnerabilidades de contêiner.
  • Alertas de segurança: Alertas automatizados para dependências de contêiner vulneráveis.
  • Atualizações do Dependabot: Solicitações de pull automatizadas para atualizar imagens e dependências base vulneráveis.
  • Integração de proprietários de código: Encaminhe as descobertas de segurança para as equipes apropriadas por meio do arquivo CODEOWNERS.
  • Logs de auditoria: Trilha completa de auditoria de eventos de segurança e ações de correção.

Práticas recomendadas para verificação de contêiner

Implemente compilações em múltiplos estágios

Dependências de build e runtime separadas:

# Build stage
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Runtime stage
FROM node:18-slim
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package*.json ./
USER node
EXPOSE 3000
CMD ["node", "dist/server.js"]

Benefits:

  • Imagens menores: As imagens de runtime não incluem ferramentas de build e artefatos intermediários.
  • Menos vulnerabilidades: Dependências de build (compiladores, SDKs) não aparecem em imagens finais.
  • Melhor desempenho: Imagens menores pressionam, puxam e iniciam mais rapidamente.

Utilizar imagens mínimas de base

Escolha as imagens base apropriadas:

  • Alpino: Imagem base pequena (aproximadamente 5 MB) com superfície de ataque mínima.
  • Sem distribuição: Contém apenas dependências de aplicativo e runtime, nenhum shell ou gerenciador de pacotes.
  • Variantes finas: As variantes oficiais *-slim excluem utilitários desnecessários.
  • Versões específicas: Use tags de versão específicas em vez de latest para reprodutibilidade.

Exemplo de imagem distroless:

FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 go build -o myapp .

FROM gcr.io/distroless/static-debian11
COPY --from=builder /app/myapp /
USER nonroot:nonroot
CMD ["/myapp"]

Verificar cedo e com frequência

Frequência de verificação:

  • Estação de trabalho do desenvolvedor: Verifique as imagens localmente antes de confirmar.
  • Validação de solicitação de pull: Varredura em pipelines CI a cada solicitação de pull.
  • Compilações da ramificação principal: Varreduras abrangentes em mesclagens na ramificação principal.
  • Admissão em Registros: Escaneie as imagens antes de aceitá-las nos registros.
  • Verificação agendada: Reanalise periodicamente imagens armazenadas para identificar vulnerabilidades recém-divulgadas.
  • Pré-implantação: Validação final antes da implantação em produção.

Implementar portões de segurança

Pontos de imposição de política:

- task: Trivy@1
  inputs:
    image: "$(imageName):$(Build.BuildNumber)"
    severityThreshold: "HIGH"
    exitCode: 1
  displayName: "Security gate: block high/critical vulnerabilities"

Exemplos de portão:

  • Severidade de vulnerabilidade: Interrompa compilações com vulnerabilidades críticas ou de alta severidade.
  • Conformidade de licença: Bloquear imagens com licenças proibidas.
  • Problemas de configuração: Evite a implantação de imagens executadas como raiz.
  • Detecção de segredo: Falhará se forem detectados segredos em camadas de imagem.

Automatizar a correção

Atualizações automatizadas:

  • Dependabot para Dockerfiles: Habilite o Dependabot para atualizar as versões de imagem base e as dependências no Dockerfiles.
  • Reconstruções automatizadas: Implemente pipelines para reconstruir imagens automaticamente quando as imagens base forem atualizadas.
  • Automação de patch: Use ferramentas para aplicar patches automaticamente em imagens de base ou dependências.
  • Pipelines de teste: Assegure-se de que as atualizações automatizadas ativam testes abrangentes.

Configuração do GitHub Dependabot para Docker:

version: 2
updates:
  - package-ecosystem: "docker"
    directory: "/"
    schedule:
      interval: "weekly"
    open-pull-requests-limit: 5

Manter o histórico de resultados do escaneamento

Acompanhamento e tendências:

  • Relatórios centralizados: A verificação agregada resulta em painéis centralizados.
  • Análise de tendência: Acompanhe as contagens de vulnerabilidades ao longo do tempo para medir a postura de segurança.
  • Auditorias de conformidade: Manter o histórico de resultados da verificação para obter evidências de conformidade.
  • Arquivamento de SBOM: Arquive a lista de materiais de software para imagens implantadas.

Implementar assinatura de imagem

Verificar a procedência da imagem:

- task: Docker@2
  inputs:
    command: "sign"
    arguments: "--key $(signingKey) $(imageName):$(Build.BuildNumber)"
  displayName: "Sign container image"

- script: |
    docker trust inspect --pretty $(imageName):$(Build.BuildNumber)
  displayName: "Verify image signature"

Benefícios de assinatura de imagem:

  • Verificação de procedência: Confirme as imagens originadas de fontes confiáveis.
  • Detecção de adulteração: Detecte se as imagens foram modificadas após a assinatura.
  • Imposição de política: Implante apenas imagens assinadas em ambientes de produção.

Automatizar a verificação de imagens de contêiner em todo o ciclo de vida de desenvolvimento e implantação garante a detecção abrangente de vulnerabilidades e a imposição de políticas. Examinando antecipadamente, verificando com frequência e implementando a correção automatizada, as organizações podem manter implantações de contêiner seguras sem sacrificar a velocidade de desenvolvimento. A próxima unidade examina como interpretar e priorizar alertas de ferramentas de verificador de segurança.