Você pode executar o Docker em produção por meses sem problemas visíveis. Os contêineres são iniciados, os aplicativos respondem, nada quebra. Então, uma porta exposta ou uma permissão mal configurada cria uma posição que um invasor não precisava conquistar. A maioria dos erros de segurança do Docker não parecem erros até que algo dê errado.
Este artigo aborda as configurações específicas que colocam os ambientes de contêiner em risco, o que cada uma delas permite a um invasor e termina com uma lista de verificação que você pode executar em sua própria configuração hoje.
Por que a segurança do Docker é mais difícil do que parece
Os contêineres parecem isolados. Você inicia um, ele executa seu próprio espaço de processo e, dentro dele, o próximo contêiner não existe. Você consegue isolamento, mas é apenas parcial. Os contêineres compartilham o kernel do host, o que significa que um processo dentro de um contêiner pode, sob condições específicas, atingir inteiramente o sistema host.
Os navios Docker são configurados para conveniência do desenvolvedor, não para proteção de produção. Acesso root ativado. Todas as portas podem ser vinculadas a todas as interfaces. Sem monitoramento de tempo de execução. A maioria dos desenvolvedores aceita essas configurações, envia o contêiner e segue em frente. Essa é uma abordagem razoável para começar; não é uma postura de segurança acabada.
De acordo com Relatório de segurança do estado do Kubernetes de 2024 da Red Hat, 67% das organizações atrasaram ou retardaram a implantação de aplicativos devido a preocupações com a segurança do contêiner ou do Kubernetes. Esse atrito geralmente não vem de ataques. É das equipes que descobrem que suas configurações de contêiner precisavam de proteção que não haviam sido incorporadas.
Freqüentemente vemos contêineres rodando em produção com a mesma configuração que tinham na máquina local do desenvolvedor. É aí que os erros de segurança do Docker tendem a se agravar silenciosamente, sem sintomas visíveis até que algo seja auditado ou falhe.
Os erros que criam essas lacunas são específicos, previsíveis e, em sua maioria, evitáveis, começando no nível da configuração.
Erros comuns de configuração do Docker
A maioria das violações de contêineres não começa com uma exploração de dia zero. Eles começam com uma configuração definida no primeiro dia, sem pensar muito na exposição da rede ou no escopo de privilégios.
As configurações padrão do Docker foram criadas para funcionar. A lacuna entre funcional e seguro é onde os riscos de segurança dos contêineres Docker se acumulam, especialmente em configurações auto-hospedadas que são implantadas e nunca revisitadas.
Vemos esse padrão com frequência: contêineres em servidores IP públicos com ligações de portas, configurações de usuário e configurações de rede exatamente como estavam na implantação inicial.
Executando contêineres como root
Quando você inicia um contêiner Docker sem especificar um usuário, ele é executado como root. Isso significa que qualquer processo dentro do contêiner, incluindo seu aplicativo, possui privilégios de nível raiz no namespace do contêiner.

Root dentro de um contêiner não é o mesmo que root no host, mas a separação não é absoluta. Explorações de escalonamento de privilégios direcionadas ao tempo de execução, como o bem documentado runc CVE-2019-5736 e falhas de tempo de execução semelhantes, frequentemente exigem um processo de contêiner raiz para serem bem-sucedidos.
Os contêineres não-raiz removem o requisito do processo raiz do qual essas explorações dependem, estreitando significativamente a superfície de ataque para essa classe de vulnerabilidade, embora não eliminem totalmente o risco de escape do contêiner.
Adicionar uma diretiva USER ao seu Dockerfile resolve isso. Algumas imagens oficiais são fornecidas com um usuário sem privilégios que você pode ativar com uma diretiva USER, mas muitas ainda usam o root como padrão sem nenhum usuário de aplicativo pronto. Nesses casos, você cria o usuário no Dockerfile antes de mudar para ele. Para a maioria das configurações auto-hospedadas, esta única alteração remove uma categoria inteira de risco de escalonamento.
Expondo muitas portas à Internet pública
Quando você publica uma porta com o Docker, o Docker escreve suas próprias regras de iptables diretamente. Essas regras são executadas antes das regras de firewall no nível do host. Este é um comportamento bem conhecido relatado pela comunidade e documentado no guia de filtragem de pacotes do Docker, não é uma configuração incorreta e significa que o UFW e ferramentas semelhantes não bloqueiam o que o Docker já abriu.

O Docker grava diretamente no iptables, ignorando os padrões UFW e firewalld em muitos hosts Linux. Isso significa que uma porta vinculada a 0.0.0.0 pode ser acessível publicamente mesmo quando seu firewall parece configurado. Grupos de segurança em nuvem e regras de cadeia DOCKER-USER ainda podem bloquear esse tráfego, portanto, a exposição real depende da configuração específica da sua rede.
Vincule serviços a 127.0.0.1 sempre que possível, roteie o tráfego público por meio de um proxy reverso e publique apenas o que realmente requer acesso externo. Um proxy reverso é a maneira mais confiável de controlar o que é exposto fora do host.
Ignorando o isolamento de rede entre contêineres
Qualquer contêiner nessa rede pode alcançar qualquer outro contêiner sem restrições. A ponte padrão não aplica filtragem de tráfego entre contêineres que a compartilham, e a maioria das configurações nunca altera essa configuração.

Se um contêiner for comprometido, essa comunicação aberta se tornará uma via de movimento lateral. Um contêiner de front-end pode acessar um banco de dados, uma API interna ou qualquer outra coisa na mesma rede de ponte padrão, mesmo quando esse acesso nunca foi pretendido.
As redes definidas pelo usuário oferecem controle explícito sobre quais contêineres podem se comunicar, mas uma única rede personalizada compartilhada por todos os seus serviços ainda permite tráfego gratuito entre contêineres. O isolamento real requer a colocação de serviços que não deveriam se comunicar entre si em redes separadas. Desligar a ponte padrão é o ponto de partida, não a linha de chegada.
Com vista para o soquete Docker
O soquete Docker em /var/run/docker.sock é a interface de controle para todo o mecanismo Docker. Montá-lo em um contêiner fornece a esse contêiner acesso direto da API ao daemon em execução no host.

Com esse acesso, um contêiner pode iniciar novos contêineres, montar diretórios de host, inspecionar e modificar contêineres em execução e controlar efetivamente a máquina host. A superfície de ataque é equivalente ao root no host, e é por isso que qualquer ferramenta que requeira acesso a soquete merece uma avaliação cuidadosa.
Para a maioria dos casos de uso, existem alternativas mais seguras: APIs com escopo ou Ferramentas de gerenciamento Docker que não requerem acesso ao soquete. O Docker-in-Docker traz suas próprias compensações operacionais e de segurança e não é um substituto direto.
Erros de configuração criam a exposição inicial. As escolhas de imagem e dependência determinam como essa exposição se agrava ao longo do tempo.
Erros de imagem e segredos que duram mais que o contêiner
Quando você para um contêiner, os erros de configuração dentro dele param com ele. Ao reconstruir a partir de uma imagem que contém uma vulnerabilidade ou uma credencial codificada, o problema reinicia com o contêiner. Erros no nível da imagem não são redefinidos entre implantações.
Eles viajam com a imagem para todos os ambientes que a extraem, todos os registros que a armazenam e todos os membros da equipe que a executam. Essa persistência torna o gerenciamento de imagens e segredos uma categoria distinta de risco, que vale a pena auditar separadamente da configuração.
Vemos esse padrão com frequência: uma imagem escolhida cuidadosamente no início do projeto e nunca reconstruída desde então, desviando-se lentamente da linha de base de segurança que representava inicialmente.
Usando imagens não confiáveis ou desatualizadas
Os registros públicos estão abertos a qualquer pessoa. Imagens maliciosas foram distribuídas por meio do Docker Hub, transportando mineradores de criptografia e backdoors incorporados no histórico da camada que persistem durante as reinicializações do contêiner. Verificação antes de retirar assuntos, principalmente para imagens de editores não oficiais ou desconhecidos.

O problema separado é a obsolescência. Uma imagem oficial que você extraiu há seis meses e nunca mais reconstruiu desde então vem acumulando vulnerabilidades não corrigidas do Docker com cada CVE divulgado em seus pacotes. A imagem não está quebrada. Simplesmente não é mais atual.
Relatório sobre o estado da cadeia de fornecimento de software de 2024 da Sonatype descobriram que 95% das vezes um componente vulnerável é consumido, uma versão corrigida já está disponível e 80% das dependências do aplicativo permanecem sem atualização por mais de um ano. Esse padrão também é relevante para imagens base do Docker, uma vez que elas dependem dos mesmos pacotes de código aberto.
Use imagens oficiais de editores verificados e fixe tags de versões específicas em vez de confiar nas “mais recentes”. Crie uma cadência de reconstrução regular para manter suas imagens atualizadas.
Segredos de codificação em Dockerfiles e arquivos Compose
As credenciais gravadas em uma instrução Dockerfile ENV ou ARG, codificadas em um bloco de ambiente Compose, passadas como argumentos de construção ou armazenadas em um arquivo .env confirmado para controle de versão não desaparecem quando você interrompe o contêiner. Eles permanecem no histórico da camada de imagem ou no controle de origem, acessíveis a qualquer pessoa que possa acessá-los.

Este é um dos erros de segurança mais negligenciados do Docker porque não causa problemas visíveis durante o desenvolvimento. Uma chave API em uma instrução ENV funciona corretamente. Ele também está no seu repositório, incorporado à sua imagem e distribuído por onde quer que a imagem viaje.
O Docker Compose moderno oferece suporte a um mecanismo de segredos nativo que monta credenciais em tempo de execução sem incorporá-las na imagem. A API de segredos do Docker e os gerenciadores de segredos externos seguem o mesmo princípio. Estas são as opções que mantêm as credenciais totalmente fora dos artefatos de construção e dos arquivos confirmados.
Variáveis de ambiente de tempo de execução são uma melhoria em relação às credenciais codificadas, mas ainda são expostas por meio da inspeção de saída, logs e despejos de memória do Docker. Eles são um avanço em relação aos segredos embutidos, não uma solução acabada.
Não atualizar imagens de contêiner regularmente
Manter a mesma imagem durante meses é um hábito comum. Cada dia que passa após uma nova vulnerabilidade ser divulgada, mas antes da reconstrução, seus contêineres carregam uma janela de exposição que cresce sem qualquer alteração visível.
Crie um cronograma de reconstrução consistente. Automatize esse processo sempre que possível e execute um scanner de vulnerabilidade periodicamente em suas imagens atuais. O objetivo não é a perfeição. Está diminuindo o tempo entre o lançamento de um patch e sua implantação.
O controle de acesso e o monitoramento podem perder a prioridade em implantações rápidas. São também as categorias onde os incidentes passam despercebidos por mais tempo.
Controle de acesso e lacunas de visibilidade
Depois que um contêiner estiver em execução com uma configuração sólida e imagens atuais, duas categorias de falha permanecerão. Ambos são invisíveis por natureza: você não notará um problema de controle de acesso fraco até que alguém o use e não notará uma lacuna no monitoramento até precisar investigar atividades que nunca foram registradas.
O mesmo Pesquisa Red Hat 2024 descobriram que 42% das equipes não tinham capacidades suficientes para lidar com a segurança dos contêineres e ameaças relacionadas.
Descobrimos que as lacunas de monitorização normalmente surgem durante as investigações de incidentes, e não antes. Quando a visibilidade se torna uma prioridade, muitas vezes ela está respondendo a algo em vez de impedi-lo.
Autenticação fraca e painéis de gerenciamento expostos
Um painel de gerenciamento de contêineres em um IP público sem autenticação não requer um invasor sofisticado. Exige que eles saibam o endereço. Esse é um nível mais baixo do que a maioria das equipes imagina.

Ferramentas de monitoramento e gerenciamento auto-hospedadas normalmente vêm com uma interface web acessível em todas as interfaces de rede. Deixá-los em um IP público sem autenticação na frente deles é o equivalente a deixar um painel de administração desbloqueado.
Autenticação, proxy reverso e posicionamento de rede privada são a linha de base. O controle de acesso é uma etapa de configuração que você adiciona a qualquer interface de gerenciamento, e não algo que vem habilitado.
O mesmo princípio se aplica a Gerenciamento Docker CLI e GUI; o acesso de nível de administrador ao daemon acarreta o mesmo risco, independentemente da interface.
Não monitorar o que seus contêineres estão fazendo
Se um contêiner for comprometido, a atividade do invasor cria um rastro: alterações no comportamento do processo, conexões de rede incomuns e modificações inesperadas nos arquivos. Sem a coleta de logs implementada, essa trilha não existe em uma forma na qual você possa agir.
A coleta centralizada de registros, o registro de auditoria de contêineres e as ferramentas de monitoramento de tempo de execução fornecem os dados para detectar atividades anormais antes que elas se agravem. O objetivo não é analisar todas as linhas. É ter os dados disponíveis quando você precisar investigar.
As configurações de contêiner que são executadas silenciosamente na produção, sem pipeline de log e sem alertas, não exigem pouca manutenção. Eles não são inspecionados. Esses são dois estados operacionais diferentes.
Por que o ambiente de infraestrutura também é importante
A segurança do contêiner começa com a configuração, mas a configuração é executada na infraestrutura. Um host com rede mal configurada, recursos compartilhados ou nenhuma filtragem no nível da rede cria condições que afetam todos os contêineres acima dele. Acertar a configuração do contêiner e a configuração correta do servidor são duas tarefas distintas.
Muitas lacunas de segurança do Docker são amplificadas pelas condições que os próprios contêineres herdam:
- Um servidor de locação compartilhada sem isolamento de hardware entre locatários
- Um kernel host rodando sem patch
- Um host sem filtragem integrada em nível de rede
Isso não elimina a necessidade das etapas de configuração acima, uma vez que a proteção adequada do contêiner é importante, independentemente da camada de infraestrutura. Começar com uma infraestrutura isolada elimina uma camada de preocupação da equação.
Na Cloudzy, oferecemos dois caminhos dependendo do que sua configuração exige:
- VPS Linux: um ambiente limpo para implantar o Docker você mesmo e aplicar as etapas de proteção deste artigo
- Portainer VPS: uma opção de um clique com o Portainer pré-instalado; o servidor inicializa e você já está no painel
Ambas as opções são executadas na mesma infraestrutura: virtualização KVM, CPUs AMD Ryzen 9 com clock boost de até 5,7 GHz, memória DDR5, armazenamento SSD NVMe, rede de até 40 Gbps e proteção DDoS gratuita por meio de filtragem BuyVM, em 12 locais globais com um SLA de tempo de atividade de 99,95%.
Para uma análise mais aprofundada da execução do Portainer em um VPS, abordamos isso em um artigo dedicado.
Uma lista de verificação prática de segurança para implantações do Docker
Os erros de segurança do Docker acima vêm principalmente de decisões de configuração únicas tomadas uma vez e nunca revisadas. A execução desta lista de verificação em uma configuração existente detecta essas lacunas. Funciona como uma auditoria, não como um guia de implantação.
Estas práticas recomendadas de segurança do Docker abordam como proteger os contêineres do Docker contra as falhas de configuração mais comuns descritas acima.
Referência rápida: todos os 9 erros
| Erro | Categoria | Correção de uma linha |
| Executando como root | Configuração | Adicionar USUÁRIO diretiva para o seu Dockerfile |
| Portas vinculadas a 0.0.0.0 | Configuração | Vincular a 127.0.0.1 e rotear por meio de um proxy reverso |
| Sem isolamento de rede | Configuração | Divida os serviços em redes separadas definidas pelo usuário com base nas necessidades de acesso. |
| Soquete Docker montado | Configuração | Remova o suporte; use APIs ou alternativas com escopo definido |
| Imagens não confiáveis ou desatualizadas | Imagem | Use imagens oficiais com tags de versão fixadas |
| Segredos codificados | Imagem | Mova credenciais para ambientes de tempo de execução ou um gerenciador de segredos |
| Nenhuma programação de reconstrução de imagem | Imagem | Defina uma cadência de reconstrução mensal; automatizar sempre que possível |
| Painéis não autenticados | Acesso | Adicione autenticação e mova UIs de gerenciamento para redes privadas |
| Nenhuma coleção de logs de contêiner | Acesso | Configure o registro centralizado e o monitoramento de tempo de execução |
Recomendamos executá-lo primeiro nas configurações existentes, pois é aí que as lacunas provavelmente já estão presentes.
Contêineres executados como não-root: Verifique seus Dockerfiles para uma diretiva USER. Se não existir, o contêiner será executado como root.
Vinculações de porta limitadas a localhost ou proxy: Execute docker ps e revise as ligações das portas. Uma entrada 0.0.0.0:PORT pode ser acessível publicamente em hosts onde nenhum grupo de segurança upstream, firewall externo ou regra de cadeia DOCKER-USER a bloqueia.
Redes de pontes personalizadas em uso: Os contêineres na ponte padrão do Docker podem se comunicar livremente. Os contêineres na mesma ponte definida pelo usuário ainda podem se comunicar entre si, portanto, divida os serviços em redes separadas por limite de confiança para isolamento real.
Soquete Docker não montado em contêineres: Marque Compor arquivos e executar argumentos. Se /var/run/docker.sock aparecer como um volume, confirme se é obrigatório e intencional.
Imagens base de editores verificados com versões fixadas: Um FROM ubuntu:latest extrai uma versão não especificada e potencialmente desatualizada. Fixe em uma versão específica.
Não há segredos em Dockerfiles, arquivos Compose ou argumentos de construção: O histórico da camada de imagem persiste nas credenciais após a exclusão do contêiner. Use segredos do Compose, segredos do Swarm, construa montagens secretas ou um gerenciador de segredos externo. Variáveis de ambiente de tempo de execução são melhores que valores codificados, mas ainda aparecem na saída e nos logs da inspeção.
Cronograma de reconstrução de imagem definido: Imagens antigas acumulam vulnerabilidades. Uma cadência de reconstrução mensal mantém a janela de exposição gerenciável para a maioria das configurações.
Interfaces de gerenciamento por trás da autenticação: Qualquer painel em um IP público sem autenticação é um ponto de entrada aberto. A colocação em rede privada é preferível sempre que possível.
Logs de contêiner sendo coletados: Sem um pipeline de log, a detecção de incidentes depende do impacto visível no sistema. Esse é um sinal tardio para agir.
Conclusão
A configuração padrão do Docker é criada para conveniência, não para segurança. A maioria dos erros abordados neste artigo remonta a configurações que nunca foram alteradas após a implantação inicial, e não a ataques sofisticados.
As correções são principalmente decisões de configuração únicas: uma diretiva USER, uma alteração de ligação de porta, uma rede personalizada, um cronograma de reconstrução. Nenhum deles requer novas ferramentas para a maioria das configurações.
Acertar a configuração do contêiner é a primeira tarefa. A infraestrutura em que funciona é a segunda. Ambos são importantes e nenhum substitui o outro.