Docker Security

Tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporte o HackTricks

Segurança Båsica do Docker Engine

O Docker engine utiliza os Namespaces e Cgroups do kernel Linux para isolar contĂȘineres, oferecendo uma camada bĂĄsica de segurança. Proteção adicional Ă© fornecida atravĂ©s da eliminação de Capacidades, Seccomp e SELinux/AppArmor, melhorando o isolamento dos contĂȘineres. Um plugin de autenticação pode restringir ainda mais as açÔes do usuĂĄrio.

Docker Security

Acesso Seguro ao Docker Engine

O Docker engine pode ser acessado localmente via um socket Unix ou remotamente usando HTTP. Para acesso remoto, é essencial empregar HTTPS e TLS para garantir confidencialidade, integridade e autenticação.

O Docker engine, por padrão, escuta no socket Unix em unix:///var/run/docker.sock. Em sistemas Ubuntu, as opçÔes de inicialização do Docker são definidas em /etc/default/docker. Para habilitar o acesso remoto à API e ao cliente do Docker, exponha o daemon do Docker através de um socket HTTP adicionando as seguintes configuraçÔes:

DOCKER_OPTS="-D -H unix:///var/run/docker.sock -H tcp://192.168.56.101:2376"
sudo service docker restart

No entanto, expor o daemon do Docker via HTTP nĂŁo Ă© recomendado devido a preocupaçÔes de segurança. É aconselhĂĄvel proteger as conexĂ”es usando HTTPS. Existem duas abordagens principais para garantir a conexĂŁo:

  1. O cliente verifica a identidade do servidor.
  2. Tanto o cliente quanto o servidor autenticam mutuamente a identidade um do outro.

Certificados são utilizados para confirmar a identidade de um servidor. Para exemplos detalhados de ambos os métodos, consulte este guia.

Segurança das Imagens de ContĂȘiner

As imagens de contĂȘiner podem ser armazenadas em repositĂłrios privados ou pĂșblicos. O Docker oferece vĂĄrias opçÔes de armazenamento para imagens de contĂȘiner:

  • Docker Hub: Um serviço de registro pĂșblico do Docker.
  • Docker Registry: Um projeto de cĂłdigo aberto que permite aos usuĂĄrios hospedar seu prĂłprio registro.
  • Docker Trusted Registry: A oferta comercial de registro do Docker, com autenticação de usuĂĄrio baseada em funçÔes e integração com serviços de diretĂłrio LDAP.

AnĂĄlise de Imagens

Os contĂȘineres podem ter vulnerabilidades de segurança tanto por causa da imagem base quanto pelo software instalado sobre a imagem base. O Docker estĂĄ trabalhando em um projeto chamado Nautilus que faz a anĂĄlise de segurança dos ContĂȘineres e lista as vulnerabilidades. O Nautilus funciona comparando cada camada da imagem do ContĂȘiner com o repositĂłrio de vulnerabilidades para identificar falhas de segurança.

Para mais informaçÔes leia isso.

  • docker scan

O comando docker scan permite que vocĂȘ escaneie imagens Docker existentes usando o nome ou ID da imagem. Por exemplo, execute o seguinte comando para escanear a imagem hello-world:

docker scan hello-world

Testing hello-world...

Organization:      docker-desktop-test
Package manager:   linux
Project name:      docker-image|hello-world
Docker image:      hello-world
Licenses:          enabled

✓ Tested 0 dependencies for known issues, no vulnerable paths found.

Note that we do not currently have vulnerability data for your image.
trivy -q -f json <container_name>:<tag>
snyk container test <image> --json-file-output=<output file> --severity-threshold=high
clair-scanner -w example-alpine.yaml --ip YOUR_LOCAL_IP alpine:3.5

Assinatura de Imagem Docker

A assinatura de imagem Docker garante a segurança e integridade das imagens usadas em contĂȘineres. Aqui estĂĄ uma explicação condensada:

  • Docker Content Trust utiliza o projeto Notary, baseado no The Update Framework (TUF), para gerenciar a assinatura de imagens. Para mais informaçÔes, veja Notary e TUF.
  • Para ativar a confiança de conteĂșdo do Docker, defina export DOCKER_CONTENT_TRUST=1. Este recurso estĂĄ desativado por padrĂŁo na versĂŁo 1.10 do Docker e posteriores.
  • Com este recurso ativado, apenas imagens assinadas podem ser baixadas. O envio inicial da imagem requer a definição de senhas para as chaves raiz e de tag, com o Docker tambĂ©m suportando Yubikey para segurança aprimorada. Mais detalhes podem ser encontrados aqui.
  • Tentar puxar uma imagem nĂŁo assinada com a confiança de conteĂșdo ativada resulta em um erro “No trust data for latest”.
  • Para envios de imagem apĂłs o primeiro, o Docker solicita a senha da chave do repositĂłrio para assinar a imagem.

Para fazer backup de suas chaves privadas, use o comando:

tar -zcvf private_keys_backup.tar.gz ~/.docker/trust/private

Ao mudar de hosts Docker, é necessårio mover as chaves de root e repositório para manter as operaçÔes.

Recursos de Segurança de ContĂȘineres

Resumo dos Recursos de Segurança de ContĂȘineres

Principais Recursos de Isolamento de Processos

Em ambientes containerizados, isolar projetos e seus processos é fundamental para a segurança e gerenciamento de recursos. Aqui estå uma explicação simplificada dos conceitos-chave:

Namespaces

  • PropĂłsito: Garantir o isolamento de recursos como processos, rede e sistemas de arquivos. Particularmente no Docker, os namespaces mantĂȘm os processos de um contĂȘiner separados do host e de outros contĂȘineres.
  • Uso do unshare: O comando unshare (ou a syscall subjacente) Ă© utilizado para criar novos namespaces, proporcionando uma camada adicional de isolamento. No entanto, enquanto o Kubernetes nĂŁo bloqueia isso inherentemente, o Docker o faz.
  • Limitação: Criar novos namespaces nĂŁo permite que um processo retorne aos namespaces padrĂŁo do host. Para penetrar nos namespaces do host, normalmente seria necessĂĄrio acesso ao diretĂłrio /proc do host, usando nsenter para entrada.

Grupos de Controle (CGroups)

  • Função: Usado principalmente para alocar recursos entre processos.
  • Aspecto de Segurança: Os CGroups em si nĂŁo oferecem segurança de isolamento, exceto pelo recurso release_agent, que, se mal configurado, pode ser potencialmente explorado para acesso nĂŁo autorizado.

Queda de Capacidades

  • ImportĂąncia: É um recurso de segurança crucial para o isolamento de processos.
  • Funcionalidade: Restringe as açÔes que um processo root pode realizar, eliminando certas capacidades. Mesmo que um processo seja executado com privilĂ©gios de root, a falta das capacidades necessĂĄrias impede que ele execute açÔes privilegiadas, pois as syscalls falharĂŁo devido a permissĂ”es insuficientes.

Estas sĂŁo as capacidades restantes apĂłs o processo descartar as outras:

Current: cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap=ep

Seccomp

EstĂĄ habilitado por padrĂŁo no Docker. Ajuda a limitar ainda mais as syscalls que o processo pode chamar.
O perfil padrĂŁo do Docker Seccomp pode ser encontrado em https://github.com/moby/moby/blob/master/profiles/seccomp/default.json

AppArmor

O Docker tem um template que vocĂȘ pode ativar: https://github.com/moby/moby/tree/master/profiles/apparmor

Isso permitirá reduzir capacidades, syscalls, acesso a arquivos e pastas


Namespaces

Namespaces sĂŁo um recurso do kernel Linux que particiona recursos do kernel de modo que um conjunto de processos vĂȘ um conjunto de recursos, enquanto outro conjunto de processos vĂȘ um conjunto diferente de recursos. O recurso funciona tendo o mesmo namespace para um conjunto de recursos e processos, mas esses namespaces se referem a recursos distintos. Os recursos podem existir em mĂșltiplos espaços.

O Docker faz uso dos seguintes Namespaces do kernel Linux para alcançar a isolação de Containers:

  • pid namespace
  • mount namespace
  • network namespace
  • ipc namespace
  • UTS namespace

Para mais informaçÔes sobre os namespaces consulte a seguinte pågina:

Namespaces

cgroups

O recurso do kernel Linux cgroups fornece a capacidade de restringir recursos como cpu, memĂłria, io, largura de banda de rede entre um conjunto de processos. O Docker permite criar Containers usando o recurso cgroup, que permite o controle de recursos para o Container especĂ­fico.
A seguir estĂĄ um Container criado com memĂłria de espaço de usuĂĄrio limitada a 500m, memĂłria do kernel limitada a 50m, compartilhamento de cpu a 512, blkioweight a 400. O compartilhamento de CPU Ă© uma proporção que controla o uso de CPU do Container. Tem um valor padrĂŁo de 1024 e uma faixa entre 0 e 1024. Se trĂȘs Containers tiverem o mesmo compartilhamento de CPU de 1024, cada Container pode usar atĂ© 33% da CPU em caso de contenção de recursos de CPU. blkio-weight Ă© uma proporção que controla o IO do Container. Tem um valor padrĂŁo de 500 e uma faixa entre 10 e 1000.

docker run -it -m 500M --kernel-memory 50M --cpu-shares 512 --blkio-weight 400 --name ubuntu1 ubuntu bash

Para obter o cgroup de um contĂȘiner, vocĂȘ pode fazer:

docker run -dt --rm denial sleep 1234 #Run a large sleep inside a Debian container
ps -ef | grep 1234 #Get info about the sleep process
ls -l /proc/<PID>/ns #Get the Group and the namespaces (some may be uniq to the hosts and some may be shred with it)

Para mais informaçÔes, consulte:

CGroups

Capacidades

As capacidades permitem um controle mais fino sobre as capacidades que podem ser permitidas para o usuårio root. O Docker usa o recurso de capacidade do kernel Linux para limitar as operaçÔes que podem ser realizadas dentro de um Container, independentemente do tipo de usuårio.

Quando um contĂȘiner docker Ă© executado, o processo descarta capacidades sensĂ­veis que o processo poderia usar para escapar do isolamento. Isso tenta garantir que o processo nĂŁo consiga realizar açÔes sensĂ­veis e escapar:

Linux Capabilities

Seccomp no Docker

Este Ă© um recurso de segurança que permite ao Docker limitar as syscalls que podem ser usadas dentro do contĂȘiner:

Seccomp

AppArmor no Docker

AppArmor Ă© uma melhoria do kernel para confinar contĂȘineres a um conjunto limitado de recursos com perfis por programa.:

AppArmor

SELinux no Docker

  • Sistema de Rotulagem: O SELinux atribui um rĂłtulo Ășnico a cada processo e objeto de sistema de arquivos.
  • Aplicação de PolĂ­ticas: Ele aplica polĂ­ticas de segurança que definem quais açÔes um rĂłtulo de processo pode realizar em outros rĂłtulos dentro do sistema.
  • RĂłtulos de Processos de ContĂȘiner: Quando os mecanismos de contĂȘiner iniciam processos de contĂȘiner, eles geralmente recebem um rĂłtulo SELinux confinado, comumente container_t.
  • Rotulagem de Arquivos dentro de ContĂȘineres: Arquivos dentro do contĂȘiner geralmente sĂŁo rotulados como container_file_t.
  • Regras de PolĂ­tica: A polĂ­tica do SELinux garante principalmente que processos com o rĂłtulo container_t sĂł possam interagir (ler, escrever, executar) com arquivos rotulados como container_file_t.

Esse mecanismo garante que, mesmo que um processo dentro de um contĂȘiner seja comprometido, ele esteja confinado a interagir apenas com objetos que tenham os rĂłtulos correspondentes, limitando significativamente o potencial de dano de tais compromissos.

SELinux

AuthZ & AuthN

No Docker, um plugin de autorização desempenha um papel crucial na segurança, decidindo se deve permitir ou bloquear solicitaçÔes ao daemon do Docker. Essa decisão é tomada examinando dois contextos principais:

  • Contexto de Autenticação: Isso inclui informaçÔes abrangentes sobre o usuĂĄrio, como quem ele Ă© e como se autenticou.
  • Contexto de Comando: Isso compreende todos os dados pertinentes relacionados Ă  solicitação sendo feita.

Esses contextos ajudam a garantir que apenas solicitaçÔes legítimas de usuårios autenticados sejam processadas, aumentando a segurança das operaçÔes do Docker.

AuthZ& AuthN - Docker Access Authorization Plugin

DoS de um contĂȘiner

Se vocĂȘ nĂŁo estiver limitando adequadamente os recursos que um contĂȘiner pode usar, um contĂȘiner comprometido poderia causar DoS no host onde estĂĄ sendo executado.

  • DoS de CPU
# stress-ng
sudo apt-get install -y stress-ng && stress-ng --vm 1 --vm-bytes 1G --verify -t 5m

# While loop
docker run -d --name malicious-container -c 512 busybox sh -c 'while true; do :; done'
  • Bandwidth DoS
nc -lvp 4444 >/dev/null & while true; do cat /dev/urandom | nc <target IP> 4444; done

Flags Interessantes do Docker

Flag –privileged

Na pĂĄgina a seguir, vocĂȘ pode aprender o que a flag --privileged implica:

Docker –privileged

–security-opt

no-new-privileges

Se vocĂȘ estiver executando um contĂȘiner onde um atacante consegue obter acesso como um usuĂĄrio de baixo privilĂ©gio. Se vocĂȘ tiver um binĂĄrio suid mal configurado, o atacante pode abusar dele e escalar privilĂ©gios dentro do contĂȘiner. O que pode permitir que ele escape dele.

Executar o contĂȘiner com a opção no-new-privileges habilitada irĂĄ prevenir esse tipo de escalonamento de privilĂ©gios.

docker run -it --security-opt=no-new-privileges:true nonewpriv

Outros

#You can manually add/drop capabilities with
--cap-add
--cap-drop

# You can manually disable seccomp in docker with
--security-opt seccomp=unconfined

# You can manually disable seccomp in docker with
--security-opt apparmor=unconfined

# You can manually disable selinux in docker with
--security-opt label:disable

Para mais opçÔes de --security-opt consulte: https://docs.docker.com/engine/reference/run/#security-configuration

Outras ConsideraçÔes de Segurança

Gerenciamento de Segredos: Melhores PrĂĄticas

É crucial evitar embutir segredos diretamente nas imagens do Docker ou usar variĂĄveis de ambiente, pois esses mĂ©todos expĂ”em suas informaçÔes sensĂ­veis a qualquer pessoa com acesso ao contĂȘiner atravĂ©s de comandos como docker inspect ou exec.

Volumes do Docker sĂŁo uma alternativa mais segura, recomendada para acessar informaçÔes sensĂ­veis. Eles podem ser utilizados como um sistema de arquivos temporĂĄrio na memĂłria, mitigando os riscos associados ao docker inspect e ao registro. No entanto, usuĂĄrios root e aqueles com acesso exec ao contĂȘiner ainda podem acessar os segredos.

Segredos do Docker oferecem um método ainda mais seguro para lidar com informaçÔes sensíveis. Para instùncias que requerem segredos durante a fase de construção da imagem, BuildKit apresenta uma solução eficiente com suporte para segredos em tempo de construção, aumentando a velocidade de construção e fornecendo recursos adicionais.

Para aproveitar o BuildKit, ele pode ser ativado de trĂȘs maneiras:

  1. Através de uma variåvel de ambiente: export DOCKER_BUILDKIT=1
  2. Prefixando comandos: DOCKER_BUILDKIT=1 docker build .
  3. Habilitando-o por padrão na configuração do Docker: { "features": { "buildkit": true } }, seguido de uma reinicialização do Docker.

BuildKit permite o uso de segredos em tempo de construção com a opção --secret, garantindo que esses segredos não sejam incluídos no cache de construção da imagem ou na imagem final, usando um comando como:

docker build --secret my_key=my_value ,src=path/to/my_secret_file .

Para segredos necessĂĄrios em um contĂȘiner em execução, Docker Compose e Kubernetes oferecem soluçÔes robustas. Docker Compose utiliza uma chave secrets na definição do serviço para especificar arquivos secretos, como mostrado em um exemplo de docker-compose.yml:

version: "3.7"
services:
my_service:
image: centos:7
entrypoint: "cat /run/secrets/my_secret"
secrets:
- my_secret
secrets:
my_secret:
file: ./my_secret_file.txt

Esta configuração permite o uso de segredos ao iniciar serviços com Docker Compose.

Em ambientes Kubernetes, segredos são suportados nativamente e podem ser gerenciados com ferramentas como Helm-Secrets. Os Controles de Acesso Baseados em Função (RBAC) do Kubernetes aumentam a segurança do gerenciamento de segredos, semelhante ao Docker Enterprise.

gVisor

gVisor Ă© um kernel de aplicativo, escrito em Go, que implementa uma parte substancial da superfĂ­cie do sistema Linux. Inclui um runtime da Open Container Initiative (OCI) chamado runsc que fornece uma fronteira de isolamento entre o aplicativo e o kernel do host. O runtime runsc se integra ao Docker e Kubernetes, facilitando a execução de contĂȘineres em sandbox.

GitHub - google/gvisor: Application Kernel for Containers

Kata Containers

Kata Containers Ă© uma comunidade de cĂłdigo aberto que trabalha para construir um runtime de contĂȘiner seguro com mĂĄquinas virtuais leves que se comportam e tĂȘm desempenho como contĂȘineres, mas fornecem isolamento de carga de trabalho mais forte usando tecnologia de virtualização de hardware como uma segunda camada de defesa.

Kata Containers - Open Source Container Runtime Software | Kata Containers

Dicas Resumidas

  • NĂŁo use a flag --privileged ou monte um socket Docker dentro do contĂȘiner. O socket docker permite a criação de contĂȘineres, entĂŁo Ă© uma maneira fĂĄcil de ter controle total do host, por exemplo, executando outro contĂȘiner com a flag --privileged.
  • NĂŁo execute como root dentro do contĂȘiner. Use um usuĂĄrio diferente e namespaces de usuĂĄrio. O root no contĂȘiner Ă© o mesmo que no host, a menos que seja remapeado com namespaces de usuĂĄrio. É apenas levemente restrito por, principalmente, namespaces do Linux, capacidades e cgroups.
  • Remova todas as capacidades (--cap-drop=all) e habilite apenas aquelas que sĂŁo necessĂĄrias (--cap-add=...). Muitas cargas de trabalho nĂŁo precisam de capacidades e adicionĂĄ-las aumenta o escopo de um ataque potencial.
  • Use a opção de segurança “no-new-privileges” para evitar que processos ganhem mais privilĂ©gios, por exemplo, atravĂ©s de binĂĄrios suid.
  • Limite os recursos disponĂ­veis para o contĂȘiner. Limites de recursos podem proteger a mĂĄquina contra ataques de negação de serviço.
  • Ajuste seccomp, AppArmor (ou SELinux) perfis para restringir as açÔes e syscalls disponĂ­veis para o contĂȘiner ao mĂ­nimo necessĂĄrio.
  • Use imagens docker oficiais e exija assinaturas ou construa suas prĂłprias com base nelas. NĂŁo herde ou use imagens backdoored. TambĂ©m armazene chaves root, senhas em um lugar seguro. O Docker tem planos para gerenciar chaves com UCP.
  • Reconstrua regularmente suas imagens para aplicar patches de segurança ao host e Ă s imagens.
  • Gerencie seus segredos com sabedoria para que seja difĂ­cil para o atacante acessĂĄ-los.
  • Se vocĂȘ expor o daemon docker, use HTTPS com autenticação de cliente e servidor.
  • Em seu Dockerfile, prefira COPY em vez de ADD. ADD extrai automaticamente arquivos compactados e pode copiar arquivos de URLs. COPY nĂŁo tem essas capacidades. Sempre que possĂ­vel, evite usar ADD para nĂŁo ficar suscetĂ­vel a ataques atravĂ©s de URLs remotas e arquivos Zip.
  • Tenha contĂȘineres separados para cada micro-serviço.
  • NĂŁo coloque ssh dentro do contĂȘiner, “docker exec” pode ser usado para ssh no ContĂȘiner.
  • Tenha imagens de contĂȘiner menores.

Docker Breakout / Escalada de Privilégios

Se vocĂȘ estĂĄ dentro de um contĂȘiner docker ou tem acesso a um usuĂĄrio no grupo docker, vocĂȘ pode tentar escapar e escalar privilĂ©gios:

Docker Breakout / Privilege Escalation

Bypass do Plugin de Autenticação do Docker

Se vocĂȘ tem acesso ao socket docker ou tem acesso a um usuĂĄrio no grupo docker, mas suas açÔes estĂŁo sendo limitadas por um plugin de autenticação do docker, verifique se vocĂȘ pode contornĂĄ-lo:

AuthZ& AuthN - Docker Access Authorization Plugin

Fortalecendo o Docker

ReferĂȘncias

Tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporte o HackTricks