Skip to main content

performing-container-image-hardening

Harden container images by minimizing attack surface, stripping unnecessary packages, implementing multi-stage builds, configuring non-root users, and applying CIS Docker Benchmark recommendations to produce secure, production-ready images. Use when building production container images, when compliance requires CIS Docker Benchmark adherence, or when shrinking image size to reduce vulnerability exposure from unused packages.

الانتقال إلى التثبيت

معلومات المصدر

المستودع
mukul975/Anthropic-Cybersecurity-Skills
آخر نشاط في المصدر
٢ أغسطس ٢٠٢٦ في ١٦:٣٢
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٣٣٬١٢٩
التفرعات
٤٬٠١٦

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

مستكشف الملفات
8 ملفات

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
performing-container-image-hardening
description
Harden container images by minimizing attack surface, stripping unnecessary packages, implementing multi-stage builds, configuring non-root users, and applying CIS Docker Benchmark recommendations to produce secure, production-ready images. Use when building production container images, when compliance requires CIS Docker Benchmark adherence, or when shrinking image size to reduce vulnerability exposure from unused packages.
domain
cybersecurity
subdomain
devsecops
tags
["devsecops","cicd","container-hardening","docker","cis-benchmark","secure-sdlc"]
version
1.0.0
author
mahipal
license
Apache-2.0
nist_csf
["PR.PS-01","GV.SC-07","ID.IM-04","PR.PS-04"]
mitre_attack
["T1195","T1554","T1059.004","T1610","T1611"]
# Performing Container Image Hardening ## When to Use - When building production container images that need minimal attack surface - When compliance requires CIS Docker Benchmark adherence for container configurations - When reducing image size to minimize vulnerability exposure from unused packages - When implementing defense-in-depth for containerized workloads - When migrating from fat base images to distroless or minimal images **Do not use** for runtime container security monitoring (use Falco), for host-level Docker daemon hardening (use CIS Docker Benchmark host checks), or for container orchestration security (use Kubernetes security scanning). ## Prerequisites - Docker or BuildKit for multi-stage builds - Base image options: distroless, Alpine, slim, or scratch - Container scanning tool (Trivy) for validation - CIS Docker Benchmark reference ## Workflow ### Step 1: Use Multi-Stage Builds to Minimize Image Size ```dockerfile # Build stage with all dependencies FROM python:3.12-bookworm AS builder WORKDIR /build COPY requirements.txt . RUN pip install --no-cache-dir --prefix=/install -r requirements.txt COPY src/ ./src/ RUN python -m compileall src/ # Production stage with minimal base FROM python:3.12-slim-bookworm AS production RUN apt-get update && \ apt-get install -y --no-install-recommends libpq5 && \ rm -rf /var/lib/apt/lists/* && \ apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false COPY --from=builder /install /usr/local COPY --from=builder /build/src /app/src RUN groupadd -r appuser && useradd -r -g appuser -d /app -s /sbin/nologin appuser RUN chown -R appuser:appuser /app USER appuser WORKDIR /app HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8080/health')" || exit 1 EXPOSE 8080 ENTRYPOINT ["python", "-m", "src.main"] ``` ### Step 2: Use Distroless Base Images ```dockerfile # Go application with distroless FROM golang:1.22 AS builder WORKDIR /app COPY go.* ./ RUN go mod download COPY . . RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o /server . FROM gcr.io/distroless/static-debian12:nonroot COPY --from=builder /server /server USER nonroot:nonroot ENTRYPOINT ["/server"] ``` ### Step 3: Remove Unnecessary Components ```dockerfile # Hardened image checklist FROM ubuntu:24.04 AS base RUN apt-get update && \ apt-get install -y --no-install-recommends \ ca-certificates \ libssl3 && \ # Remove package manager to prevent runtime package installation apt-get purge -y --auto-remove apt dpkg && \ rm -rf /var/lib/apt/lists/* \ /var/cache/apt/* \ /tmp/* \ /var/tmp/* \ /usr/share/doc/* \ /usr/share/man/* \ /usr/share/info/* \ /root/.cache # Remove shells if not needed RUN rm -f /bin/sh /bin/bash /usr/bin/sh 2>/dev/null || true # Remove setuid/setgid binaries RUN find / -perm /6000 -type f -exec chmod a-s {} + 2>/dev/null || true ``` ### Step 4: Configure Read-Only Filesystem ```yaml # Kubernetes deployment with read-only root filesystem apiVersion: apps/v1 kind: Deployment metadata: name: hardened-app spec: template: spec: securityContext: runAsNonRoot: true runAsUser: 65534 fsGroup: 65534 seccompProfile: type: RuntimeDefault containers: - name: app image: app:hardened securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: ["ALL"] volumeMounts: - name: tmp mountPath: /tmp - name: cache mountPath: /app/cache volumes: - name: tmp emptyDir: sizeLimit: 100Mi - name: cache emptyDir: sizeLimit: 50Mi ``` ### Step 5: Pin Base Image by Digest ```dockerfile # Pin to exact image digest for reproducibility FROM python:3.12-slim-bookworm@sha256:abcdef1234567890 AS production # This ensures the exact same base image is used every time ``` ### Step 6: Validate Hardening with Automated Scanning ```bash # Scan hardened image with Trivy trivy image --severity HIGH,CRITICAL hardened-app:latest # Check CIS Docker Benchmark compliance docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \ aquasec/docker-bench-security # Verify no root processes docker run --rm hardened-app:latest whoami # Expected: appuser (NOT root) # Verify read-only filesystem docker run --rm hardened-app:latest touch /test 2>&1 # Expected: Read-only file system error ``` ## Key Concepts | Term | Definition | |------|------------| | Multi-Stage Build | Docker build technique using multiple FROM stages to separate build and runtime, reducing final image size | | Distroless | Google-maintained minimal container images containing only the application and runtime dependencies | | Non-Root User | Running container processes as unprivileged user to limit impact of container escape exploits | | Read-Only Root | Mounting the container root filesystem as read-only to prevent runtime modification | | Image Digest | SHA256 hash uniquely identifying an exact image version, more precise than mutable tags | | Scratch Image | Empty Docker base image used for statically compiled binaries requiring no OS | | Security Context | Kubernetes pod/container-level security settings controlling privileges, filesystem, and capabilities | ## Tools & Systems - **Docker BuildKit**: Advanced Docker build engine supporting multi-stage builds and build secrets - **Distroless Images**: Google's minimal container base images (static, base, java, python, nodejs) - **docker-bench-security**: Script checking CIS Docker Benchmark compliance - **Trivy**: Container image vulnerability and misconfiguration scanner - **Hadolint**: Dockerfile linter enforcing best practices ## Common Scenarios ### Scenario: Reducing a 1.2GB Python Image to Under 150MB **Context**: A data science team uses `python:3.12` as base image (1.2GB) with scientific computing packages. The image has 200+ known CVEs from unnecessary system packages. **Approach**: 1. Switch to `python:3.12-slim-bookworm` as base (150MB) and install only required system libraries 2. Use multi-stage build: compile C extensions in builder stage, copy wheels to production 3. Pin numpy, pandas, and scipy to pre-built wheels to avoid build dependencies in production 4. Remove pip, setuptools, and wheel from the final image 5. Create non-root user and set filesystem permissions 6. Validate with Trivy: expect CVE count to drop from 200+ to under 20 **Pitfalls**: Some Python packages require shared libraries at runtime (libgomp, libstdc++). Test the application thoroughly after removing system packages. Alpine-based images use musl libc which can cause compatibility issues with numpy and pandas. ## Output Format ``` Container Image Hardening Report ================================== Image: app:hardened Base: python:3.12-slim-bookworm Date: 2026-02-23 SIZE COMPARISON: Before hardening: 1,247 MB (python:3.12) After hardening: 143 MB (python:3.12-slim + multi-stage) Reduction: 88.5% SECURITY CHECKS: [PASS] Non-root user configured (appuser:1000) [PASS] HEALTHCHECK instruction present [PASS] No setuid/setgid binaries found [PASS] Package manager removed [PASS] Base image pinned by digest [PASS] No shell access (/bin/sh removed) [WARN] /tmp writable (emptyDir mounted) VULNERABILITY COMPARISON: Before: 234 CVEs (12 Critical, 45 High) After: 18 CVEs (0 Critical, 3 High) Reduction: 92.3% ```
عرض على GitHub