Os contêineres revolucionaram como o software é empacotado e implantado, e o Docker é sua encarnação mais popular. Praticamente toda infraestrutura moderna usa contêineres, então entender sua segurança — como são isolados e como esse isolamento pode ser rompido — é essencial para o pentest de ambientes atuais. Esta aula cobre os fundamentos de segurança de contêineres, o conceito crítico de "escape de contêiner", e as configurações inseguras que os comprometem. Laboratório com Docker, sempre.

Contêiner compartilha o kernel

Comece entendendo o que é um contêiner e como difere de uma máquina virtual, porque isso define seu modelo de segurança. Uma máquina virtual (aula Montando seu laboratório: o campo de treino legal) virtualiza hardware — cada VM tem seu próprio sistema operacional completo, fortemente isolado. Um contêiner é mais leve: ele compartilha o kernel do sistema operacional hospedeiro, isolando apenas o espaço da aplicação (processos, arquivos, rede) usando recursos do próprio kernel Linux (namespaces e cgroups). Isso torna contêineres muito mais eficientes que VMs (iniciam em segundos, consomem menos recursos), mas tem uma implicação de segurança fundamental: o isolamento do contêiner é mais fraco que o da VM, porque todos os contêineres compartilham o mesmo kernel. Se um atacante consegue explorar o kernel a partir de dentro de um contêiner, ele pode afetar o hospedeiro e outros contêineres — algo muito mais difícil com VMs. Essa diferença de isolamento é o cerne da segurança de contêineres.

O escape de contêiner

O conceito ofensivo central é o escape de contêiner (container escape): romper o isolamento para sair do contêiner e alcançar o sistema hospedeiro. Como o hospedeiro executa todos os contêineres, escapar para ele frequentemente significa comprometer todos os contêineres naquela máquina — uma escalação devastadora. Os escapes exploram tipicamente configurações inseguras (mais comum) ou vulnerabilidades no runtime de contêiner ou no kernel (mais raro). A causa mais frequente de escape não é uma falha sofisticada — é configuração perigosa, o que torna a segurança de contêineres, como tantas coisas no curso, majoritariamente uma questão de configuração correta.

As configurações que levam ao escape

As configurações inseguras que levam a escape são conhecidas e vale entendê-las. O contêiner privilegiado (--privileged) é a mais grave: rodar um contêiner em modo privilegiado remove a maior parte do isolamento, dando a ele acesso quase total ao hospedeiro — é praticamente entregar o hospedeiro se o contêiner for comprometido. A montagem do Docker socket dentro do contêiner: o socket do Docker controla o daemon do Docker; se um contêiner tem acesso a ele, pode criar outros contêineres (inclusive privilegiados) e assim controlar o hospedeiro. Montagens de volumes sensíveis (montar diretórios do hospedeiro, especialmente o sistema de arquivos raiz, dentro do contêiner) dão ao contêiner acesso a arquivos do hospedeiro. Capabilities excessivas concedidas ao contêiner. Cada uma dessas configurações enfraquece o isolamento, e o pentester de contêineres procura justamente por elas ao pisar dentro de um contêiner comprometido — a enumeração local (aula Escalação de privilégios em Linux: de usuário comum a root) adaptada ao contexto de contêiner ("estou num contêiner? é privilegiado? tenho acesso ao Docker socket? que volumes estão montados?").

Imagens vulneráveis e o Docker socket

Além do escape, há outras preocupações de segurança de contêineres. As imagens vulneráveis: contêineres são criados a partir de imagens, que podem conter software desatualizado com vulnerabilidades conhecidas, ou — pior — imagens maliciosas de fontes não confiáveis (o problema da cadeia de suprimentos, Bloco XVII, aplicado a imagens). Os segredos em imagens: credenciais, chaves e tokens hardcoded nas imagens de contêiner (a lição recorrente do Bloco IV — segredos embutidos são extraíveis por qualquer um com a imagem). E a superfície do próprio Docker (o daemon e sua API, que se expostos, permitem controle total). Escanear imagens em busca de vulnerabilidades e segredos é uma prática de segurança essencial (o "shift left" — segurança no início do desenvolvimento).

Trocar isolamento por eficiência

O ponto conceitual: os contêineres trocam isolamento por eficiência, e essa troca tem consequências de segurança que precisam ser gerenciadas com configuração correta. O contêiner não é uma fronteira de segurança tão forte quanto uma VM — tratá-lo como se fosse é um erro perigoso. A segurança de contêineres é, em grande parte, sobre reforçar um isolamento inerentemente mais fraco através de configuração cuidadosa, imagens confiáveis, e menor privilégio. É a defesa em profundidade (aula Por que o hacking ético existe e o que ele quer de você) aplicada a uma abstração que, por design, prioriza velocidade e eficiência sobre isolamento máximo.

Nunca privilegiado sem necessidade

Do lado defensivo, as práticas de segurança de contêineres são claras: nunca rodar contêineres privilegiados sem necessidade absoluta (e questionar sempre essa necessidade); nunca montar o Docker socket dentro de contêineres não confiáveis; aplicar menor privilégio (rodar contêineres como usuário não-root, remover capabilities desnecessárias, usar perfis de segurança como seccomp e AppArmor que restringem o que o contêiner pode fazer); usar imagens confiáveis e mínimas (de fontes verificadas, com o mínimo de software para reduzir a superfície); escanear imagens em busca de vulnerabilidades e segredos antes de usá-las; não embutir segredos em imagens (usar mecanismos de gestão de segredos); e manter o Docker e o kernel atualizados. A lição: contêineres são poderosos e onipresentes, mas seu isolamento mais fraco exige disciplina de configuração — a maioria dos comprometimentos de contêiner vem de configurações inseguras evitáveis, não de falhas exóticas.

Fontes e leituras recomendadas

Exercícios

  1. Qual a diferença fundamental de isolamento entre um contêiner e uma máquina virtual, e por que isso importa para a segurança?

    ✓ Resposta:

    A VM virtualiza hardware e tem seu próprio SO completo, com isolamento forte; o contêiner compartilha o kernel do hospedeiro, isolando só o espaço da aplicação via recursos do kernel. Importa para a segurança porque o isolamento do contêiner é mais fraco — como todos compartilham o mesmo kernel, explorá-lo a partir de um contêiner pode afetar o hospedeiro e os demais contêineres.

  2. O que é um "escape de contêiner" e por que ele é uma escalação tão devastadora?

    ✓ Resposta:

    É romper o isolamento do contêiner para alcançar o sistema hospedeiro. É devastador porque o hospedeiro executa todos os contêineres — escapar para ele frequentemente significa comprometer todos os contêineres daquela máquina, uma escalação de um contêiner para o controle de toda a máquina.

  3. Cite três configurações inseguras que podem levar a escape de contêiner.

    ✓ Resposta:

    Contêiner privilegiado (--privileged), montagem do Docker socket dentro do contêiner, montagem de volumes sensíveis do hospedeiro (ex.: sistema de arquivos raiz), capabilities excessivas. (Três quaisquer.)

  4. Por que segredos hardcoded em imagens de contêiner são um problema, e a que lição recorrente do curso isso se liga?

    ✓ Resposta:

    Porque qualquer um com acesso à imagem pode extrair os segredos embutidos (credenciais, chaves, tokens), comprometendo o que eles protegem. Liga-se à lição recorrente do Bloco IV de que segredos hardcoded (em código, firmware, imagens) são sempre extraíveis e nunca devem ser embutidos.

  5. Cite três contramedidas de segurança de contêineres, incluindo a mais importante contra escapes por configuração.

    ✓ Resposta:

    Não rodar contêineres privilegiados (a mais importante contra escapes por configuração), não montar o Docker socket, aplicar menor privilégio (usuário não-root, seccomp/AppArmor), usar imagens confiáveis e mínimas, escanear imagens, não embutir segredos, manter Docker/kernel atualizados. (Três quaisquer.)