Segurança em Containers
Aula 6 de 7
Princípios de Segurança
Non-root User
FROM node:20-alpine
# Criar usuário não-root
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
WORKDIR /app
COPY --chown=appuser:appgroup . .
CMD ["node", "app.js"]
# Verificar: o processo roda como appuser, não root
docker run --rm my-app id
# uid=1000(appuser) gid=1000(appgroup)
Read-only Filesystem
# Container com filesystem read-only
docker run --read-only --tmpfs /tmp --tmpfs /var/run nginx:alpine
# Equivalente no Compose
services:
app:
image: nginx:alpine
read_only: true
tmpfs:
- /tmp
- /var/run
Image Scanning
# Docker Scout (built-in)
docker scout quickview nginx:alpine
docker scout cves nginx:alpine
docker scout recommendations nginx:alpine
# Trivy (open source)
trivy image nginx:alpine
trivy image --severity CRITICAL, HIGH nginx:alpine
# CI/CD scan
trivy image --exit-code 1 --severity CRITICAL minha-app:latest
Capabilities
# Mínimo de capacidades Linux
docker run --cap-drop ALL --cap-add NET_BIND_SERVICE nginx:alpine
# Sem privilégios
docker run --security-opt no-new-privileges:true nginx:alpine
# Docker Compose
services:
app:
image: nginx:alpine
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
security_opt:
- no-new-privileges:true
Docker Bench Security
# Auditoria de segurança Docker
docker run --rm --net host \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /etc:/etc:ro \
docker/docker-bench-security
Content Trust
# Assinar imagens (Notary)
export DOCKER_CONTENT_TRUST=1
docker push minha-app:latest # exige assinatura
docker pull minha-app:latest # verifica assinatura
# Verificar assinatura
docker trust inspect --pretty minha-app:latest
Falhas Comuns
# ❌ RUIM: root rodando
docker run ubuntu:latest
# ✅ BOM: usuário não-root no Dockerfile
docker run --user 1000:1000 ubuntu:latest
# ❌ RUIM: privilégios totais
docker run --privileged app
# ✅ BOM: capabilities mínimas
docker run --cap-drop ALL --cap-add NET_BIND_SERVICE app
# ❌ RUIM: secrets em variáveis de ambiente
docker run -e DB_PASSWORD=secret app
# ✅ BOM: secrets em /run/secrets
docker run --secret db_password app
Seccomp e AppArmor
# Perfil seccomp personalizado
docker run --security-opt seccomp=custom.json nginx:alpine
# AppArmor profile
docker run --security-opt apparmor=my-profile nginx:alpine
# Docker padrão: seccomp restrito, sem AppArmor
Container security = Non-root user + Read-only FS + Drop all capabilities + Image scanning + No privileged mode + Secrets montados (não env vars).