Blog
Defendendo Contra Fuga de Contêineres: Um Guia Prático de Isolamento Docker para Hospedagem Multi-Tenant
Aprenda a proteger contêineres Docker contra vulnerabilidades de fuga e falhas de isolamento em ambientes multi-tenant com passos concretos e exemplos.

Resumo
Contêineres Docker compartilham o kernel do host, tornando o isolamento crítico—especialmente em hospedagem multi-tenant, onde uma única fuga de contêiner pode comprometer todos os tenants. Muitos desenvolvedores assumem que contêineres são máquinas virtuais perfeitamente isoladas, mas a realidade é diferente. Este artigo explica os recursos do kernel Linux por trás do isolamento Docker (namespaces, cgroups) e os vetores de ataque que os ameaçam. Você aprenderá passos práticos para fortalecer sua configuração Docker: limitando privilégios, usando runtime seguro, escaneando imagens e implementando segmentação de rede. Seguindo um exemplo do mundo real de um provedor de hospedagem WordPress multi-tenant, você verá como aplicar essas defesas. Também abordamos ressalvas como trade-offs de desempenho e o uso de seccomp/AppArmor. O objetivo é fornecer uma estratégia de isolamento robusta que previna fugas de contêineres e mantenha seus tenants seguros.
Introdução
Se você gerencia uma plataforma de hospedagem multi-tenant—seja hospedagem compartilhada WordPress, uma aplicação SaaS ou um serviço de ambiente de desenvolvimento—a fuga de contêineres é o cenário de pesadelo. Uma vulnerabilidade no kernel ou uma configuração incorreta pode permitir que um tenant escape de seu contêiner e acesse os dados de outros tenants ou o próprio host. O isolamento do Docker depende de recursos do kernel Linux como namespaces e cgroups, mas as configurações padrão muitas vezes são insuficientes para uma segurança robusta. Este artigo irá guiá-lo pelos vetores de ataque e fornecer passos acionáveis para travar seus contêineres Docker, ilustrado com um exemplo real de WordPress multi-tenant. Para uma visão mais ampla de orquestração de produção, veja nosso guia sobre Orquestrando Aplicações Containerizadas Prontas para Produção.
Entendendo o Isolamento Docker
Contêineres Docker usam namespaces Linux para fornecer isolamento em nível de processo: namespaces PID isolam árvores de processos, namespaces de rede separam interfaces de rede, namespaces de montagem isolam montagens do sistema de arquivos e namespaces de usuário permitem o mapeamento do root do contêiner para um usuário host não privilegiado. Grupos de controle (cgroups) limitam o uso de recursos como CPU, memória e I/O de disco. Esses recursos juntos criam uma "sandbox" ao redor de cada contêiner. No entanto, ao contrário de uma máquina virtual que executa um kernel separado, os contêineres compartilham o kernel do host. Isso significa que uma vulnerabilidade no kernel (por exemplo, CVE-2022-0492) pode ser explorada para escapar do isolamento de namespace do contêiner. Adicionalmente, configurações incorretas como executar contêineres como root dentro do contêiner, conceder ao contêiner todas as capacidades, ou não descartar capacidades Linux desnecessárias podem ampliar a superfície de ataque.
Vetores de Ataque
Vetores de ataque comuns incluem:
- Exploits de Kernel: Explorar um bug no kernel do host para obter acesso ao host.
- Contêineres Privilegiados: Executar com
--privilegedconcede todas as capacidades e contorna a maioria do isolamento. - Abuso de Capacidades: Mesmo sem modo privilegiado completo, um contêiner com capacidades perigosas como
CAP_SYS_ADMINouCAP_NET_ADMINpode montar sistemas de arquivos ou manipular configurações de rede. - Práticas Inseguras de Imagem: Usar imagens base com vulnerabilidades conhecidas ou incluir ferramentas desnecessárias como compiladores ou interpretadores de shell.
- Namespaces de Montagem Compartilhados: Montar diretórios do host em contêineres pode permitir fuga se não forem somente leitura.
Passos Práticos de Segurança
1. Execute Contêineres como Usuário Não-Root
Por padrão, o Docker executa contêineres como root dentro do contêiner. Se um atacante obtiver acesso root dentro do contêiner, ele terá mais alavancagem. Crie um usuário em seu Dockerfile e use a diretiva USER. Além disso, evite usar a flag --user no Docker Compose para mapear para um usuário host arbitrário, se possível.
2. Descarte Todas as Capacidades e Adicione Apenas as Necessárias
Capacidades Linux dividem privilégios de superusuário em unidades menores. No Docker Compose, use cap_drop: ALL e depois cap_add apenas as necessárias (por exemplo, NET_BIND_SERVICE). Evite capacidades perigosas como SYS_ADMIN, NET_ADMIN, SYS_PTRACE.
3. Use Sistema de Arquivos Root Somente Leitura
Defina read_only: true na sua definição de contêiner. Isso impede que atacantes escrevam no sistema de arquivos do contêiner. Se seu aplicativo precisar escrever arquivos temporários, monte um volume tmpfs nesse local.
4. Habilite o Re-mapeamento de Namespace de Usuário
O re-mapeamento de namespace de usuário mapeia o usuário root do contêiner para um usuário host não privilegiado. Isso adiciona uma camada de isolamento, pois mesmo que um root de contêiner escape, ele terá os privilégios do usuário remapeado. Habilite-o em /etc/docker/daemon.json com "userns-remap": "default". Esteja ciente de que isso pode complicar as permissões de volume. Para mais detalhes, veja Dominando o Isolamento Docker para Hospedagem Web Segura e Eficiente.
5. Aplique Perfis Seccomp e AppArmor/AppArmor
Seccomp restringe as chamadas de sistema que um contêiner pode fazer. O Docker fornece um perfil seccomp padrão que bloqueia chamadas de sistema perigosas. Você também pode criar perfis personalizados. Da mesma forma, AppArmor (ou SELinux) fornece controle de acesso obrigatório. Use AppArmor para confinar seu contêiner a um conjunto mínimo de operações permitidas. O perfil de segurança pode ser definido via security_opt no Docker Compose.
6. Use Imagens Base Mínimas e Escaneie Vulnerabilidades
Escolha imagens pequenas como Alpine ou Distroless que tenham uma superfície de ataque menor. Escaneie regularmente imagens com ferramentas como Docker Scout, Trivy ou Clair. Integre a varredura em seu pipeline CI/CD para evitar que imagens vulneráveis sejam implantadas.
7. Segmentação de Rede com Redes Bridge Personalizadas
Crie redes bridge separadas para cada tenant ou camada de aplicação. Isso limita o tráfego leste-oeste. No Docker Compose, defina redes e isole serviços. Use internal: true se um serviço não precisar de acesso à Internet de saída. Regras de firewall no host restringem ainda mais o tráfego inter-contêineres.
8. Limite Recursos com Cgroups
Defina limites de CPU e memória no Docker Compose usando deploy.resources.limits. Isso impede que um contêiner comprometido inicie um ataque de exaustão de recursos. Adicionalmente, defina kernel_memory e memory_reservation para um controle mais fino.
Exemplo do Mundo Real: Hospedagem WordPress Multi-Tenant com Docker Compose
Considere um cenário onde você hospeda vários sites WordPress para diferentes clientes, cada um em seu próprio contêiner Docker. Uma configuração insegura pode parecer:
version: '3'
services:
wordpress:
image: wordpress:latest
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: exampleuser
WORDPRESS_DB_PASSWORD: examplepass
WORDPRESS_DB_NAME: exampledb
volumes:
- ./wp-content:/var/www/html/wp-content
db:
image: mysql:5.7
environment:
MYSQL_DATABASE: exampledb
MYSQL_USER: exampleuser
MYSQL_PASSWORD: examplepass
MYSQL_ROOT_PASSWORD: somewordpress
volumes:
- db_data:/var/lib/mysql
volumes:
db_data:
Esta configuração é vulnerável: o contêiner WordPress roda como root por dentro, tem todas as capacidades (já que nenhuma é descartada), monta um diretório do host com acesso de escrita e tem acesso de rede irrestrito.
Agora vamos fortalecê-la:
version: '3'
services:
wordpress:
image: wordpress:latest
user: www-data
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
read_only: true
tmpfs:
- /var/www/html/wp-content/plugins
security_opt:
- seccomp=seccomp-profile.json
- apparmor=wordpress-profile
networks:
- frontend
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: exampleuser
WORDPRESS_DB_PASSWORD: examplepass
WORDPRESS_DB_NAME: exampledb
volumes:
- wp-uploads:/var/www/html/wp-content/uploads
deploy:
resources:
limits:
cpus: '0.5'
memory: 256M
db:
image: mysql:5.7
user: mysql
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
networks:
- backend
environment:
MYSQL_DATABASE: exampledb
MYSQL_USER: exampleuser
MYSQL_PASSWORD: examplepass
MYSQL_ROOT_PASSWORD: somewordpress
volumes:
- db_data:/var/lib/mysql
deploy:
resources:
limits:
cpus: '0.25'
memory: 128M
networks:
frontend:
driver: bridge
internal: false
backend:
driver: bridge
internal: true
volumes:
wp-uploads:
db_data:
Melhorias chave:
- Ambos os contêineres rodam como usuários não-root (
www-dataemysql). - Todas as capacidades descartadas, apenas
NET_BIND_SERVICEadicionada. - O sistema de arquivos do WordPress é somente leitura, exceto por um volume tmpfs e um volume de uploads.
- Perfis Seccomp e AppArmor aplicados (você precisaria fornecer perfis personalizados).
- Redes separadas isolam a web do banco de dados, com a rede do banco de dados interna.
- Limites de recursos previnem exaustão de recursos.
Para mais informações sobre hardening Docker específico para WordPress, veja Docker para WordPress: Por que Contêineres Isolados Mudam Tudo.
Ressalvas
- Re-mapeamento de Namespace de Usuário: Embora poderoso, ele quebra o mapeamento de volumes porque o UID do host remapeado não é o mesmo que o UID do contêiner. Você pode precisar pré-criar diretórios com as permissões corretas ou usar volumes Docker com suporte a remapeamento.
- Perfis Seccomp/AppArmor: Perfis personalizados exigem o entendimento dos padrões de chamadas de sistema e acesso a arquivos de sua aplicação. Perfis excessivamente restritivos podem quebrar a funcionalidade. Teste completamente.
- Desempenho: Camadas de segurança adicionais como seccomp e AppArmor têm sobrecarga mínima, mas limites de recursos e sistemas de arquivos somente leitura podem afetar aplicações com muitas escritas.
- Complexidade de Orquestração: Em um ambiente multi-tenant, gerenciar arquivos Docker Compose por tenant pode se tornar complicado. Considere usar uma ferramenta de orquestração de nível superior como Kubernetes, mas isso introduz suas próprias considerações de segurança.
Conclusão
A fuga de contêineres é uma ameaça real em hospedagem Docker multi-tenant, mas é prevenível. Ao entender os mecanismos de isolamento e aplicar defesa em profundidade—descartando capacidades, executando como não-root, habilitando namespaces de usuário, seccomp, AppArmor, segmentação de rede e varredura regular de imagens—você pode reduzir drasticamente o risco. Lembre-se que as configurações padrão do Docker não são prontas para produção para cargas de trabalho multi-tenant. Implemente estes passos hoje para proteger seus tenants e sua infraestrutura. Para uma visão geral abrangente das melhores práticas de segurança Docker, consulte Protegendo Suas Aplicações Web com Docker: Um Guia Prático de Isolamento e Melhores Práticas.
Sources (5)
- Docker and Container Isolation - Medium
- What is container isolation? Mechanisms, limitations, and secure runtimes | Blog - Northflank
- Container Isolation Explained for Kubernetes and Beyond - Edera
- Docker Security: 5 Risks and 12 Best Practices for Securing Your Containers - Tigera.io
- 9 Security Best Practices for Docker Containers - Kinsta®

