Images Docker sécurisées
Bonnes pratiques Dockerfile
# Utiliser une image minimale
FROM node:22-alpine AS builder
# Ne pas tourner en root
RUN addgroup -S app && adduser -S app -G app
# Copier uniquement le nécessaire
COPY --chown=app:app package.json pnpm-lock.yaml ./
RUN corepack enable && pnpm install --frozen-lockfile --prod
COPY --chown=app:app . .
RUN pnpm build
# Image finale minimale
FROM gcr.io/distroless/nodejs22-debian12
COPY --from=builder /app/dist /app
USER 1000
EXPOSE 3000
CMD ["app/server.js"]Règles d'or
- Images minimales : Alpine ou Distroless
- Multi-stage builds : pas d'outils de build en production
- Pas de root :
USER 1000ou utilisateur non-root - COPY spécifique : pas de
COPY . .sans.dockerignore - Versions fixées :
node:22.0.0-alpinepasnode:latest
Scan d'images
$trivy image mon-app:latest
Scanner les vulnérabilités d'une image Docker
$trivy image --severity HIGH,CRITICAL mon-app:latest
Uniquement les vulnérabilités hautes et critiques
$docker scout cves mon-app:latest
Docker Scout — analyse de vulnérabilités
$grype mon-app:latest
Grype — scanner open source d'Anchore
Intégration CI
# GitHub Actions
- name: Scan image
uses: aquasecurity/trivy-action@master
with:
image-ref: mon-app:latest
severity: HIGH,CRITICAL
exit-code: 1Runtime Docker sécurisé
Docker daemon
{
"icc": false,
"userns-remap": "default",
"no-new-privileges": true,
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}Exécution sécurisée
$docker run --read-only --tmpfs /tmp mon-app
Filesystem en lecture seule
$docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE mon-app
Capabilities minimales
$docker run --security-opt=no-new-privileges mon-app
Empêcher l'escalade de privilèges
$docker run --memory=256m --cpus=0.5 mon-app
Limiter les ressources
Checklist Docker
- Pas de conteneur en root
- Capabilities droppées
- Filesystem read-only quand possible
- Limites de ressources définies
- Images scannées dans le pipeline CI
- Pas de secrets dans les variables d'environnement de
docker run - Réseau Docker isolé par application
Kubernetes Security
Pod Security Standards
apiVersion: v1
kind: Pod
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: app
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
resources:
limits:
cpu: 500m
memory: 256Mi
requests:
cpu: 100m
memory: 128MiNetwork Policies
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
spec:
podSelector: {}
policyTypes:
- Ingress
- EgressapiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-api-to-db
spec:
podSelector:
matchLabels:
app: db
ingress:
- from:
- podSelector:
matchLabels:
app: api
ports:
- port: 5432RBAC
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
subjects:
- kind: ServiceAccount
name: monitoring
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.ioOutils K8s Security
| Outil | Usage |
|---|---|
| kube-bench | Audit CIS Benchmark |
| Falco | Runtime security monitoring |
| OPA/Gatekeeper | Policy enforcement |
| kubescape | Scan de sécurité complet |
$kube-bench run --targets node
Audit CIS Benchmark du node
$kubescape scan framework nsa
Scan NSA/CISA Kubernetes Hardening