MDstable
NoteSnippetChecklistPlaybook

Docker — Hardening & Sécurité

Checklist et commandes pour sécuriser un environnement Docker

checklistintermediate 2025-05-10 3 min read
dockerhardeningsecuriteconteneursdevsecops

Audit de sécurité Docker

bash
Variables
{{IMAGE}}
{{CONTAINER}}
# Audit avec Docker Bench Security
docker run --rm --net host --pid host --userns host --cap-add audit_control
-e DOCKER_CONTENT_TRUST$DOCKER_CONTENT_TRUST
-v /etc/etcro
-v /usr/bin/containerd/usr/bin/containerdro
-v /usr/bin/runc/usr/bin/runcro
-v /usr/lib/systemd/usr/lib/systemdro
-v /var/lib/var/libro
-v /var/run/docker.sock/var/run/docker.sockro
docker/docker-bench-security
# Audit image avec Trivy
trivy image {{IMAGE}}
# Audit image avec Grype
grype {{IMAGE}}
# Inspect container
docker inspect {{CONTAINER}}
docker stats {{CONTAINER}} --no-stream

Dockerfile sécurisé

dockerfile
# ✅ Bon exemple — image minimale + non-root
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
FROM node:20-alpine AS runner
# Créer user non-root
RUN addgroup -g 1001 -S appgroup && \
adduser -S -u 1001 -G appgroup appuser
WORKDIR /app
COPY --from=builder --chown=appuser:appgroup /app/node_modules ./node_modules
COPY --chown=appuser:appgroup . .
# Basculer sur user non-root
USER appuser
# Ne pas exposer port root (<1024)
EXPOSE 3000
# Health check
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD node -e "require('http').get('http://localhost:3000/health', r => process.exit(r.statusCode === 200 ? 0 : 1))"
CMD ["node", "server.js"]

docker-compose.yml sécurisé

yaml
Variables
{{SERVICE}}
version: '3.8'
services:
{{SERVICE}}:
image: myapp:latest
# Limites ressources
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
# Sécurité
security_opt:
- no-new-privileges:true
read_only: true
# Tmpfs pour /tmp
tmpfs:
- /tmp:noexec,nosuid,size=64m
# Capabilities minimales
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE # Seulement si nécessaire
# User non-root
user: "1001:1001"
# Variables env depuis fichier
env_file:
- .env
# Réseau isolé
networks:
- internal
# Pas de port host sauf nécessaire
expose:
- "3000"
networks:
internal:
driver: bridge
internal: true # Pas d'accès internet sauf via proxy
Checklist hardening Docker0/12

Commandes d'audit

bash
Variables
{{CONTAINER}}
{{IMAGE}}
# Processus dans le container
docker exec {{CONTAINER}} ps aux
# User courant
docker exec {{CONTAINER}} whoami
docker exec {{CONTAINER}} id
# Fichiers SUID/SGID dans l'image
docker run --rm --entrypoint sh {{IMAGE}} -c "find / -perm /6000 -type f 2>/dev/null"
# Réseaux Docker
docker network ls
docker network inspect bridge
# Volumes montés
docker inspect {{CONTAINER}} | jq '.[].HostConfig.Binds'
# Variables d'environnement (attention aux secrets !)
docker inspect {{CONTAINER}} | jq '.[].Config.Env'
OPS·BRAIN v1.03 notes · DevOpslocal