Přeskočit na obsah
_CORE
AI & Agentic Systems Core Informační Systémy Cloud & Platform Engineering Data Platforma & Integrace Security & Compliance QA, Testing & Observability IoT, Automatizace & Robotika Mobile & Digital Banky & Finance Pojišťovnictví Veřejná správa Obrana & Bezpečnost Zdravotnictví Energetika & Utility Telco & Média Průmysl & Výroba Logistika & E-commerce Retail & Loyalty
Reference Technologie Blog Knowledge Base O nás Spolupráce Kariéra
Pojďme to probrat

Container Security — best practices pro produkci

08. 05. 2017 4 min čtení CORE SYSTEMSai

„Kontejnery jsou izolované, takže jsou bezpečné.” Tohle jsme si mysleli, než nám penetrační tester během půl hodiny eskaloval z kontejneru na root hosta. Kontejnery nejsou VM a bezpečnostní model je zásadně odlišný.

Kontejner není sandbox

Docker kontejner sdílí jádro s hostem. Namespace a cgroups poskytují izolaci procesů, síťového stacku a souborového systému — ale není to hardwarová virtualizace. Kernel exploit v kontejneru = kernel exploit na hostu. Tohle je fundamentální rozdíl oproti VM a musí se s ním počítat.

To neznamená, že kontejnery jsou nebezpečné. Znamená to, že bezpečnost musíte řešit na všech vrstvách — od base image přes build pipeline až po runtime konfiguraci.

Base image — minimalizujte útočnou plochu

Každý balíček v image je potenciální zranitelnost. Ubuntu base image má stovky balíčků, které vaše aplikace nepotřebuje — a každý z nich může mít CVE. Pravidlo číslo jedna: použijte minimální base image.

# ❌ Špatně — plný Ubuntu, 188 MB, stovky balíčků
FROM ubuntu:16.04

# ✅ Lépe — Alpine, 5 MB, minimální balíčky
FROM alpine:3.6

# ✅ Nejlépe — distroless, jen runtime
FROM gcr.io/distroless/java:latest

Alpine Linux je dobrý kompromis — 5 MB, musl libc, apk package manager. Pro maximální bezpečnost zvažte distroless images od Googlu: žádný shell, žádný package manager, žádné utility. Útočník, který se dostane do kontejneru, nemá k dispozici ani ls.

Multi-stage builds — oddělte build a runtime

Build nástroje (gcc, npm, maven) nemají co dělat v produkčním image. Multi-stage build oddělí kompilaci od finálního image.

FROM golang:1.9 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 go build -o server .

FROM alpine:3.6
RUN adduser -D -u 1001 appuser
COPY --from=builder /app/server /server
USER appuser
EXPOSE 8080
CMD ["/server"]

Výsledný image obsahuje jen binárku a Alpine. Žádný Go toolchain, žádné zdrojové kódy, žádné build závislosti. Menší image = menší útočná plocha = rychlejší deploy.

Neběžte jako root

Překvapivě mnoho Docker images běží jako root. Pokud aplikace nepotřebuje privilegovaný port nebo přístup k systémovým resources, vždy přidejte USER directive. Root v kontejneru může za určitých okolností eskalovat na root hosta.

V Kubernetes použijte securityContext na úrovni podu:

securityContext:
  runAsNonRoot: true
  runAsUser: 1001
  readOnlyRootFilesystem: true
  allowPrivilegeEscalation: false
  capabilities:
    drop: ["ALL"]

readOnlyRootFilesystem zabrání zápisu do souborového systému kontejneru — útočník nemůže persistovat malware. drop ALL capabilities odebere Linux capabilities, které aplikace nepotřebuje.

Image scanning — najděte CVE dřív než útočník

Každý image by měl projít vulnerability scannerem před nasazením do produkce. Nástroje jako Clair, Trivy nebo Anchore analyzují vrstvy image a porovnávají balíčky s CVE databázemi.

My skenujeme na dvou místech: v CI pipeline (build time) a v registry (continuous scan). Build time scan zastaví deploy s kritickými CVE. Continuous scan odhalí nově objevené zranitelnosti v images, které už běží v produkci.

Klíčové je nastavit policy: co je akceptovatelné a co ne. Nulová tolerance na kritické CVE v base image. Medium severity s plánem opravy do 30 dní. Low severity sledovat, ale neblokovat deploy.

Supply chain — důvěřuj, ale prověřuj

docker pull node:latest — víte, co přesně stahujete? Kdo ten image vytvořil? Byl modifikován? Docker Content Trust (Notary) umožňuje podepisování images. Povolte ho a akceptujte jen podepsané images.

Používejte konkrétní tagy, ne :latest. Ještě lépe: pinujte na digest. Tag může být přepsán, digest je immutable hash. A provozujte vlastní registry (Harbor, GitLab Registry) místo přímého stahování z Docker Hub.

Runtime ochrana

Build-time bezpečnost nestačí. V runtime potřebujete detekci anomálií. Seccomp profily omezují systémová volání — kontejner, který normálně dělá HTTP requesty, nemá důvod volat ptrace nebo mount. AppArmor nebo SELinux profily přidávají další vrstvu mandatory access control.

Network policies v Kubernetes fungují jako firewall mezi pody. Default deny — žádný pod nekomunikuje s jiným, pokud to explicitně nepovolíte. Mikroslužba pro platby nemá důvod komunikovat s CMS.

Secrets management

Nikdy nepečte secrets do image. Ani jako environment variable v Dockerfile, ani jako soubor v build kontextu. Secrets patří do Kubernetes Secrets (ideálně s externím backendem jako HashiCorp Vault), mountované jako volumes, rotované automaticky.

Skenujte historii image vrstev — docker history ukáže všechny vrstvy včetně smazaných souborů. Secret přidaný a pak smazaný v dalším RUN příkazu je stále v předchozí vrstvě.

Security jako continuous process

Container security není jednorázový audit. Je to kontinuální proces integrovaný do celého životního cyklu — od Dockerfile přes CI pipeline až po runtime monitoring. Začněte základy: non-root, minimální image, scanning v CI. Postupně přidávejte seccomp, network policies, runtime detekci. Každá vrstva ztěžuje útočníkovi práci.

dockersecuritycontainersdevsecops