Răspuns scurt
- Securizezi containerele Docker rulând procesele ca utilizator fără privilegii, fără flagul privileged, cu toate capabilitățile eliminate și adăugate doar cele strict necesare.
- Nu monta niciodată /var/run/docker.sock într-un container: cine controlează socketul controlează serverul.
- Folosește imagini minimale, fixate pe digest, scanate de vulnerabilități înainte de fiecare deploy.
- Pune sistemul de fișiere în read-only, limitează memoria și procesorul și separă containerele în rețele dedicate.
- Rulează periodic un audit după CIS Docker Benchmark și tratează rezultatele ca listă de lucru.
- Utilizator în container
- USER non-root în Dockerfile; niciodată root
- Capabilități
- --cap-drop ALL, apoi --cap-add doar ce trebuie
- Socketul Docker
- nu se montează în containere
- Referința de audit
- CIS Docker Benchmark, automatizat cu docker-bench-security
Containerul nu este o mașină virtuală
O mașină virtuală are kernel propriu; containerul folosește kernelul serverului și este izolat doar prin namespace-uri și cgroups. Un proces root în container este root pentru kernel, limitat de capabilități și de profilul seccomp. Dacă adaugi --privileged, limitele dispar. Dacă montezi socketul Docker, procesul poate porni un container nou cu discul serverului montat. De aceea prima regulă este utilizatorul non-root din Dockerfile, iar a doua lista de capabilități redusă la zero și completată explicit, de exemplu NET_BIND_SERVICE pentru portul 443.
Imagini: mici, fixate, scanate
O imagine bazată pe o distribuție completă aduce sute de pachete pe care aplicația nu le folosește, fiecare cu propriile vulnerabilități. Alege variante slim, alpine sau distroless și construiește multi-stage, ca uneltele de build să nu ajungă în runtime. Fixează imaginea de bază pe digest, nu pe eticheta latest. Scanează cu Trivy sau Grype în CI și blochează deploy-ul la vulnerabilități critice cu remediere disponibilă. Reconstruiește periodic chiar fără schimbări de cod, ca patch-urile din imaginea de bază să ajungă în producție.
Ce arată un audit CIS și ce cer clienții din UE
docker-bench-security parcurge recomandările CIS Docker Benchmark și marchează ce nu corespunde: daemon configurat nesigur, containere fără limite de resurse, socket expus, imagini fără utilizator definit. Raportul este un limbaj comun cu auditorii clienților din UE, care cer frecvent dovada unui standard recunoscut pentru containere, alături de acordul de prelucrare conform articolului 28 GDPR. Pentru furnizorii din sectoarele acoperite de Legea nr. 48/2023, același raport documentează gestionarea riscurilor tehnice. Rulează-l lunar și păstrează diferențele.
Setări Docker: implicit față de recomandat în producție| Setare | Implicit | Recomandat | Ce previne |
|---|
| Utilizator | root | USER non-root în Dockerfile | escaladare la root pe host |
|---|
| Capabilități | set implicit larg | --cap-drop ALL, --cap-add minim | manipulare rețea, montări, module |
|---|
| Sistem de fișiere | scriere liberă | --read-only cu tmpfs pentru /tmp | persistența unui shell web |
|---|
| Porturi publicate | 0.0.0.0 | 127.0.0.1 sau rețea privată | ocolirea firewall-ului |
|---|
| Resurse | nelimitate | --memory, --cpus, --pids-limit | oprirea vecinilor |
|---|
Comenzi și configurări
Dockerfile cu utilizator non-rootFROM node:22-alpine@sha256:<digest>
WORKDIR /app
COPY --chown=node:node dist/ ./dist/
COPY --chown=node:node node_modules/ ./node_modules/
USER node
EXPOSE 3000
CMD ["node", "dist/server.js"]
Rulare cu privilegii minimedocker run -d --name app \
--read-only --tmpfs /tmp \
--cap-drop ALL \
--security-opt no-new-privileges \
--memory 512m --cpus 1 --pids-limit 200 \
-p 127.0.0.1:3000:3000 \
exemplu.md/app:1.4.0
Scanare și audit CIStrivy image --severity HIGH,CRITICAL --ignore-unfixed exemplu.md/app:1.4.0
# Excepție conștientă de la regula „nu monta socketul": auditul rulează o dată,
# manual. Fără montările de mai jos secțiunile CIS 1-3 dau rezultate false.
docker run --rm --net host --pid host --userns host --cap-add audit_control \
-v /var/lib:/var/lib:ro -v /etc:/etc:ro \
-v /usr/bin/containerd:/usr/bin/containerd:ro -v /usr/bin/runc:/usr/bin/runc:ro \
-v /usr/lib/systemd:/usr/lib/systemd:ro \
-v /var/run/docker.sock:/var/run/docker.sock docker/docker-bench-security
Exemple din practică
Echipă de outsourcing din Chișinău cu servere pentru mai mulți clienți
Un container de CI avea socketul Docker montat pentru a construi imagini. O dependență compromisă din pipeline a folosit socketul pentru a citi volumele altor clienți de pe același server. Build-urile au trecut pe runner-e izolate, fără socket.
Fintech din Chișinău cu API în containere
Auditorul băncii partenere a cerut raportul CIS. Prima rulare a arătat 23 de avertismente, majoritatea despre limite de resurse și utilizator root. După două săptămâni de ajustări, raportul a intrat în dosarul de conformitate cu trei observații minore.
Greșeli frecvente
- Crezi că containerul este izolat implicit, deși rulează ca root cu capabilități complete.
- Montezi /var/run/docker.sock „pentru monitorizare” și oferi oricărui proces din container control asupra serverului.
- Folosești eticheta latest și nu știi ce versiune rulează de fapt în producție.
- Publici porturile containerelor pe 0.0.0.0 și ocolești firewall-ul serverului fără să observi.
Cum te ajută 4hosting
- Serviciul Docker & Kubernetes proiectează arhitectura de containere pe VPS-urile și serverele dedicate 4hosting, cu rețele separate și limite de resurse.
- Hardening & Compliance include hardening-ul containerelor și raportul CIS pe care îl poți anexa la contractul cu clientul din UE.
- Orele de DevOps incluse acoperă scanarea imaginilor în CI și reconstrucția periodică; le ceri din panoul de client.
- Factură în euro, cu TVA 20 % defalcat și factură electronică SFS; suport în română și rusă.
Întrebări conexe
Merită Docker rootless în producție?
Da, unde aplicația nu are nevoie de porturi sub 1024 sau de funcții de rețea speciale. Daemonul rulează ca utilizator obișnuit, deci o evadare din container nu dă root pe server. Costul este configurare suplimentară pentru rețea și volume. CIS îl recomandă unde este posibil.
Cum monitorizez containerele fără să montez socketul Docker?
Folosește un exportator de metrici care citește cgroups direct, precum cAdvisor în mod restricționat, sau un agent care rulează pe server, nu în container. Dacă un instrument insistă pe socket, montează-l read-only printr-un proxy de socket care permite doar apelurile de citire.