A segurança de containers é um tema crítico na área de segurança da informação, especialmente com a ampla adoção de tecnologias como Docker e Kubernetes. Containers oferecem isolamento em nível de processo, mas não são tão seguros quanto máquinas virtuais, exigindo cuidados específicos para evitar que vulnerabilidades na imagem ou no ambiente run-time comprometam o sistema como um todo.

Nesta aula, exploraremos os quatro pilares fundamentais para garantir a segurança de containers: a escolha e construção de imagens seguras, as práticas de run-time, a identificação de vulnerabilidades e o uso de ferramentas de image scanning. Ao final, você será capaz de implementar uma estratégia de segurança robusta para seus containers.

Imagens

As imagens de container são a base sobre a qual os containers são executados. Elas contêm o sistema operacional, bibliotecas, dependências e o código da aplicação. Uma imagem insegura pode introduzir vulnerabilidades desde o início. Por isso, é essencial adotar boas práticas na escolha e criação de imagens.

Primeiramente, utilize imagens oficiais e de fontes confiáveis, como o Docker Hub oficial ou registries privados. Evite imagens de terceiros não verificadas, pois podem conter malware ou configurações inseguras. Prefira versões minimalistas, como Alpine Linux, que reduzem a superfície de ataque por terem menos pacotes. Além disso, evite usar a tag latest, que pode mudar sem aviso; sempre especifique uma versão exata.

Ao construir sua própria imagem com um Dockerfile, siga o princípio de um processo por container. Não execute processos como root dentro do container; crie um usuário não privilegiado. Remova pacotes desnecessários e limpe caches após a instalação de dependências para reduzir o tamanho da imagem e possíveis vetores de ataque. Exemplo de Dockerfile seguro:

FROM alpine:3.18
RUN adduser -D myuser
USER myuser
COPY --chown=myuser:myuser app /app
CMD ["/app/start.sh"]

Esse Dockerfile cria um usuário não root, copia os arquivos com permissões corretas e executa o container com esse usuário. Nunca utilize sudo ou comandos que exijam privilégios elevados no container.

Run-time

A segurança no run-time envolve as configurações e práticas adotadas durante a execução do container. Mesmo com uma imagem segura, um container mal configurado pode ser explorado. É crucial aplicar restrições de capacidade, limitar recursos e isolar o container adequadamente.

O Docker oferece diversas opções de segurança, como --cap-drop=ALL e --cap-add para controlar capacidades do kernel. Por padrão, containers têm um conjunto limitado de capacidades, mas é recomendado remover todas e adicionar apenas as necessárias. Além disso, utilize o modo somente leitura no sistema de arquivos com --read-only para evitar alterações não autorizadas. Configure limites de memória e CPU com --memory e --cpus para mitigar ataques de negação de serviço.

Outra prática importante é usar namespaces de usuário (--userns-remap) para mapear o usuário root do container para um usuário não privilegiado no host. Isso impede que, mesmo que o container seja comprometido, o atacante não tenha acesso root no host. Exemplo de execução segura:

docker run --rm -d \
  --cap-drop=ALL \
  --cap-add=NET_BIND_SERVICE \
  --read-only \
  --memory=256m \
  --cpus=0.5 \
  --security-opt=no-new-privileges:true \
  myapp:1.0

Essas opções garantem que o container tenha privilégios mínimos, não possa escrever no sistema de arquivos (a menos que volumes sejam montados explicitamente), e tenha recursos limitados.

Vulnerabilidades

Vulnerabilidades em containers podem surgir de diversas fontes: bibliotecas desatualizadas, configurações incorretas, ou até mesmo o kernel do host. É fundamental entender os tipos comuns de vulnerabilidades e como mitigá-las.

Uma vulnerabilidade frequente é a execução de processos como root, que pode levar ao comprometimento total do host se houver uma falha de escalonamento de privilégios. Outra é o uso de imagens com pacotes vulneráveis, como versões antigas do OpenSSL ou do bash. Além disso, containers que compartilham o mesmo namespace de rede podem ser alvo de ataques de interceptação. Para mitigar, mantenha as imagens atualizadas, utilize ferramentas de scanning e aplique o princípio do menor privilégio.

Também é importante considerar vulnerabilidades no runtime do container, como o CVE-2019-5736, que afetou o runc e permitia que um container malicioso sobrescrevesse o binário do host. Para se proteger, mantenha o Docker e o kernel atualizados, e use namespaces de usuário e seccomp para restringir chamadas de sistema. Exemplo de perfil seccomp personalizado:

{
  "defaultAction": "SCMP_ACT_ERRNO",
  "architectures": ["SCMP_ARCH_X86_64"],
  "syscalls": [
    {
      "names": ["read", "write", "exit", "exit_group"],
      "action": "SCMP_ACT_ALLOW"
    }
  ]
}

Esse perfil bloqueia todas as chamadas de sistema, exceto as essenciais, reduzindo drasticamente a superfície de ataque.

Image scanning

O image scanning é o processo de analisar imagens de container em busca de vulnerabilidades conhecidas, configurações incorretas e segredos expostos. Ferramentas como Trivy, Clair, Anchore e Docker Scout automatizam essa verificação, integrando-se ao pipeline de CI/CD.

O scanning deve ser realizado em todas as imagens antes de serem implantadas, e periodicamente nas imagens em execução. A ferramenta compara os pacotes instalados com bancos de dados de CVEs (Common Vulnerabilities and Exposures) e gera relatórios de risco. Por exemplo, com Trivy:

trivy image alpine:3.18

Esse comando escaneia a imagem Alpine 3.18 e exibe as vulnerabilidades encontradas, com severidade e recomendações. É possível integrar o Trivy em pipelines Jenkins, GitLab CI ou GitHub Actions para bloquear builds que contenham vulnerabilidades críticas.

Além de vulnerabilidades, ferramentas de scanning podem detectar segredos como senhas e chaves SSH que foram acidentalmente incluídos na imagem. Por isso, é importante usar arquivos .dockerignore e limpar o histórico de camadas. Exemplo de saída do Trivy:

Total: 2 (UNKNOWN: 0, LOW: 1, MEDIUM: 1, HIGH: 0, CRITICAL: 0)

Essa saída indica que a imagem tem duas vulnerabilidades de baixa e média gravidade. Com base nisso, o desenvolvedor pode decidir se atualiza a imagem ou aceita o risco.

Boas práticas e observações finais

Além dos tópicos abordados, algumas práticas adicionais fortalecem a segurança de containers: use redes segregadas para isolar containers entre si, evite montar o socket do Docker dentro de containers (a menos que seja estritamente necessário), e implemente políticas de segurança com ferramentas como o AppArmor ou SELinux. Em ambientes orquestrados como Kubernetes, utilize Pod Security Policies ou OPA/Gatekeeper para aplicar regras de segurança de forma centralizada.

Lembre-se de que a segurança é um processo contínuo. Mantenha-se atualizado sobre novas vulnerabilidades e atualize regularmente suas imagens e ferramentas. A combinação de imagens seguras, run-time restrito, monitoramento de vulnerabilidades e scanning automatizado forma uma defesa em profundidade eficaz para containers.

Referências

Exercícios

  1. Explique por que é importante evitar o uso da tag latest em imagens de container e qual prática recomendada deve ser adotada.

    ✓ Resposta: A tag latest é mutável e pode apontar para versões diferentes ao longo do tempo, o que quebra a reprodutibilidade e pode introduzir alterações inesperadas. A prática recomendada é usar tags de versão específicas, como 1.0.0 ou sha256, para garantir que a mesma imagem seja usada em todos os ambientes.
  2. Descreva duas opções de segurança que podem ser usadas no comando docker run para limitar privilégios de um container.

    ✓ Resposta: Duas opções são: --cap-drop=ALL seguido de --cap-add para adicionar apenas capacidades necessárias; e --security-opt=no-new-privileges:true para impedir que processos dentro do container ganhem privilégios adicionais.
  3. Qual é a finalidade de um perfil seccomp em containers e como ele ajuda na segurança?

    ✓ Resposta: O seccomp (Secure Computing Mode) restringe as chamadas de sistema que um processo pode fazer. Ao definir um perfil personalizado, é possível bloquear chamadas potencialmente perigosas, reduzindo a superfície de ataque e dificultando a exploração de vulnerabilidades no kernel.
  4. Cite duas ferramentas de image scanning e explique como elas podem ser integradas a um pipeline de CI/CD.

    ✓ Resposta: Duas ferramentas são Trivy e Clair. Elas podem ser integradas em pipelines como GitHub Actions ou Jenkins: após a construção da imagem, executa-se o scanner; se vulnerabilidades críticas forem encontradas, o pipeline falha, evitando que a imagem insegura seja publicada.
  5. Qual é o risco de montar o socket do Docker (/var/run/docker.sock) dentro de um container e como mitigá-lo?

    ✓ Resposta: Montar o socket do Docker dá ao container acesso à API do Docker, permitindo que ele controle o daemon e execute containers privilegiados, o que pode comprometer todo o host. Para mitigar, evite essa montagem; se necessário, use alternativas como o Docker-in-Docker com segurança adicional ou ferramentas específicas com permissões limitadas.