Skip to content

Services, Wiki-Artikel, Blog-Beiträge und Glossar-Einträge durchsuchen

↑↓NavigierenEnterÖffnenESCSchließen
Cloud & DevSecOps Glossary

Container Security

Security measures for containerized applications (Docker, Kubernetes). Containers share the host kernel—a compromised container can put other containers or the host at risk. Container security includes image hardening, runtime protection, network segmentation, and supply chain security.

Container Security protects containerized applications throughout their entire lifecycle: from image creation through the registry to runtime. Unlike VMs, containers share the host operating system’s kernel—which offers performance benefits but also creates specific security risks.

The Container Threat Model

LayerCountermeasure
Application (code vulnerabilities)SAST/DAST
Container Image (base image)Image scanning
Container Runtime (Docker)Runtime Security
Kubernetes / OrchestrationK8s Hardening
Host OS (Linux Kernel)gVisor / Kata
Infrastructure (Cloud/On-Prem)IaC Security

Phase 1: Building Secure Images

Dockerfile Best Practices

# BAD: fat image, root user
FROM ubuntu:latest
RUN apt-get update && apt-get install -y python3 pip curl wget
COPY . /app
CMD ["python3", "/app/app.py"]

# GOOD: minimal image, non-root, pinned versions
FROM python:3.12.2-slim@sha256:abc123...  # Pin digest instead of tag!

# Dependencies as a separate layer (cache)
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# App code
COPY --chown=appuser:appuser . .

# Non-root user
RUN useradd --uid 10001 --no-create-home appuser
USER appuser

# Expose only the health port
EXPOSE 8080

# No shell entry point (prevents shell injection)
ENTRYPOINT ["python3", "-m", "uvicorn", "main:app"]

Image Scanning

# Trivy - free, CNCF project
trivy image --severity HIGH,CRITICAL myapp:latest

# Output:
# myapp:latest (debian 12.4)
# Total: 3 (HIGH: 2, CRITICAL: 1)
# ┌──────────────┬────────────────┬──────────┬──────────────────────────┐
# │   Library    │ Vulnerability  │ Severity │ Installed Version        │
# ├──────────────┼────────────────┼──────────┼──────────────────────────┤
# │ libssl3      │ CVE-2024-5535  │ CRITICAL │ 3.0.11-1~deb12u2        │
# └──────────────┴────────────────┴──────────┴──────────────────────────┘

# In CI/CD (GitHub Actions)
- name: Scan image
  uses: aquasecurity/trivy-action@master
  with:
    image-ref: 'myapp:${{ github.sha }}'
    exit-code: '1'         # Pipeline aborts on CRITICAL
    severity: 'CRITICAL'

Supply Chain Security (SLSA)

# Cosign - Image signing
cosign sign --key cosign.key myregistry.io/myapp:1.0.0

# Verification before deployment
cosign verify --key cosign.pub myregistry.io/myapp:1.0.0

# Generate SBOM (Software Bill of Materials)
syft myapp:latest -o spdx-json > sbom.json

# Scan SBOM for vulnerabilities
grype sbom:sbom.json

Phase 2: Registry Security

Registry Security:

  • Use a private registry: Harbor, ECR, ACR (no public registry!)
  • Image scanning before push (Admission Policy)
  • Deploy only signed images (Policy Engine: Kyverno, OPA Gatekeeper)
  • Immutable tags: :1.2.3 instead of :latest
  • Registry credentials as secrets (not in Dockerfile!)

Harbor Sample Policy:

  • Allow: Images with CRITICAL: 0
  • Allow: Images with Cosign signature
  • Deny: Images older than 90 days without a re-scan

Phase 3: Kubernetes Cluster Hardening

Pod Security Standards

# Restrictive PodSecurityContext
apiVersion: v1
kind: Pod
spec:
  securityContext:
    runAsNonRoot: true          # No root!
    runAsUser: 10001
    fsGroup: 10001
    seccompProfile:
      type: RuntimeDefault      # seccomp profile enabled
  containers:
  - name: app
    securityContext:
      allowPrivilegeEscalation: false   # No sudo in container!
      readOnlyRootFilesystem: true      # Read-only root
      capabilities:
        drop:
          - ALL                         # Drop all Linux capabilities
        add:
          - NET_BIND_SERVICE            # Add only necessary ones
    resources:
      limits:
        memory: "256Mi"
        cpu: "500m"
      requests:
        memory: "128Mi"
        cpu: "100m"

NetworkPolicy (Kubernetes Firewall)

# Micro-segmentation: Frontend may only communicate with backend, not directly with DB
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: backend-isolation
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - port: 8080
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: database
    ports:
    - port: 5432

Secrets Management

# WRONG: Secret hardcoded in YAML
env:
  - name: DB_PASSWORD
    value: "super-secret-password"  # → in git history, etcd, logs!

# BETTER: Kubernetes Secret (base64-encoded, not encrypted by default!)
kubectl create secret generic db-secret \
  --from-literal=password="super-secret-password"

# BEST PRACTICE: External Secrets Operator + HashiCorp Vault
# secrets.yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
spec:
  secretStoreRef:
    name: vault-backend
  target:
    name: db-secret
  data:
  - secretKey: password
    remoteRef:
      key: prod/database
      property: password

Phase 4: Runtime Security

Falco - Runtime Threat Detection

# Falco Rule: Shell in Container (common sign of compromise)
- rule: Terminal Shell in Container
  desc: A shell was used as the entrypoint/exec point into a container
  condition: >
    spawned_process and container
    and shell_procs and proc.tty != 0
    and container_entrypoint
  output: >
    A shell was spawned in a container with an attached terminal
    (user=%user.name container=%container.name image=%container.image.repository)
  priority: NOTICE

Additional Falco Rules:

  • Privileged container started
  • /etc/passwd or /etc/shadow read
  • Network connection to unknown IP
  • Crypto-miner activity detected
  • Kubectl executed in container

OWASP Top 10 Container Security Risks

RiskCountermeasure
C1: Insecure Supply ChainImage Signing, SBOM, SCA
C2: Authorization FlawsRBAC, NetworkPolicy, OPA
C3: Overly Permissive ContainerRead-only FS, Drop ALL Caps
C4: Improper Network AccessNetworkPolicy, Service Mesh (Istio)
C5: Inadequate LoggingFalco, CloudTrail, Audit Logs
C6: Insecure SecretsVault, External Secrets Operator
C7: Vulnerable ComponentsTrivy, Grype, SBOM
C8: Runtime ThreatsFalco, Tetragon, Sysdig
C9: Misconfigured Orchestrationkube-bench (CIS Benchmark)
C10: Exposed DashboardNever make the Kubernetes Dashboard public!

kube-bench: CIS Benchmark Check

# Automatic check against the CIS Kubernetes Benchmark
kubectl apply -f https://raw.githubusercontent.com/aquasecurity/kube-bench/main/job.yaml
kubectl logs job/kube-bench

# Sample output:
# [FAIL] 1.2.1 Ensure that the --anonymous-auth argument is set to false
# [PASS] 1.2.6 Ensure that the --kubelet-https argument is set to true
# [FAIL] 4.2.1 Ensure that the --anonymous-auth argument is set to false
#
# == Summary ==
# 42 checks PASS
# 7 checks FAIL
# 11 checks WARN

Service Mesh (Istio/Linkerd)

Service Mesh enhances container security:

  • mTLS between all services (automatic)
  • Fine-grained authorization policies
  • Traffic encryption without changing app code
  • Observability: traces, metrics per service

Istio AuthorizationPolicy:

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
spec:
  action: ALLOW
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/prod/sa/frontend"]
    to:
    - operation:
        methods: ["GET", "POST"]
        paths: ["/api/*"]