DevOps & Cloud

Docker Security Best Practices: Rootless, Scanning, Secrets & Hardening

TOKEN

Panduan komprehensif keamanan Docker — rootless mode, image vulnerability scanning, secrets management, container hardening, network security, dan compliance untuk production environment

1. Pengenalan Docker Security

Container Docker menawarkan isolasi yang lebih ringan dibanding VM, tetapi tetap memiliki permukaan serangan (attack surface) yang perlu dijaga. Keamanan container bukan hanya tentang mengamankan aplikasi di dalamnya, tetapi juga tentang mengamankan seluruh supply chain — dari base image, build process, runtime, hingga orchestration.

Dalam tutorial Docker Dasar dan Docker Compose Advanced, kita telah mempelajari cara membuat dan mengelola container. Kali ini kita fokus pada aspek keamanan yang kritis untuk production deployment.

Defense in Depth

Konsep defense in depth berarti menerapkan beberapa lapisan keamanan, sehingga jika satu lapisan gagal, lapisan lain tetap melindungi sistem:

Diagram: Docker Security Layers
┌─────────────────────────────────────────────────────────┐
│                  DOCKER SECURITY LAYERS                  │
│                                                          │
│  ┌───────────────────────────────────────────────────┐  │
│  │ LAYER 1: Host Security                            │  │
│  │ - OS hardening, kernel updates, firewall          │  │
│  │ ┌───────────────────────────────────────────────┐ │  │
│  │ │ LAYER 2: Docker Daemon Security               │ │  │
│  │ │ - Rootless mode, TLS, audit logging           │ │  │
│  │ │ ┌───────────────────────────────────────────┐ │ │  │
│  │ │ │ LAYER 3: Image Security                   │ │ │  │
│  │ │ │ - Trusted base, scanning, minimal images  │ │ │  │
│  │ │ │ ┌───────────────────────────────────────┐ │ │ │  │
│  │ │ │ │ LAYER 4: Container Runtime Security   │ │ │ │  │
│  │ │ │ │ - Non-root, capabilities, read-only   │ │ │ │  │
│  │ │ │ │ ┌───────────────────────────────────┐ │ │ │ │  │
│  │ │ │ │ │ LAYER 5: Application Security     │ │ │ │ │  │
│  │ │ │ │ │ - Secrets, env vars, auth          │ │ │ │ │  │
│  │ │ │ │ └───────────────────────────────────┘ │ │ │ │  │
│  │ │ │ └───────────────────────────────────────┘ │ │ │  │
│  │ │ └───────────────────────────────────────────┘ │ │  │
│  │ └───────────────────────────────────────────────┘ │  │
│  └───────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────┘

Anatomy of a Container Attack

Vektor Serangan Risiko Mitigasi
Vulnerable base imageCVE exploit dari library lamaImage scanning, update berkala
Container running as rootPrivilege escalation ke hostNon-root user, rootless Docker
Secrets in environment varsBocor via inspect/logsDocker secrets, external vault
Privileged containerFull access ke host kernelHindari --privileged, drop capabilities
Unrestricted networkContainer bisa ke mana sajaNetwork policies, internal networks
Mutable filesystemMalware bisa menulis ke diskRead-only root filesystem
Docker socket exposureFull control atas Docker daemonJangan mount socket, gunakan proxy
⚠️ Peringatan

Docker socket (/var/run/docker.sock) adalah root access ke host. Jangan pernah mount socket ke dalam container kecuali benar-benar diperlukan (misalnya monitoring agent). Siapapun yang bisa mengakses socket memiliki kontrol penuh atas semua container dan host.

2. Threat Model Container

Sebelum menerapkan keamanan, kita perlu memahami apa yang perlu dilindungi. Docker container memiliki beberapa komponen yang masing-masing memiliki risiko keamanan tersendiri.

Komponen Keamanan Docker

Text
# ===========================
# DOCKER ATTACK SURFACE
# ===========================

# 1. DOCKER DAEMON (dockerd)
#    - Berjalan sebagai root secara default
#    - Mengelola semua container, images, networks
#    - Akses ke Docker daemon = akses ke semua container

# 2. DOCKER IMAGES
#    - Base image bisa mengandung vulnerabilities
#    - Malicious images dari untrusted registry
#    - Supply chain attack via compromised dependencies

# 3. DOCKER CONTAINERS
#    - Running as root = root di host (jika escape)
#    - Shared kernel = kernel exploit berdampak semua container
#    - Excessive capabilities

# 4. DOCKER NETWORK
#    - Default bridge: semua container bisa saling akses
#    - Exposed ports ke host
#    - Unencrypted communication antar container

# 5. DOCKER SECRETS & CONFIG
#    - Secrets di environment variables terlihat di docker inspect
#    - Config files bisa bocor via image layers
#    - Hardcoded credentials di Dockerfile

# 6. HOST INTERACTION
#    - Volume mounts = akses ke host filesystem
#    - Docker socket = full host control
#    - Host networking = bypass isolation

Security Checklist Awal

Area Checklist Prioritas
ImagesGunakan official images, scan vulnerabilities, pin versi🔴 Kritis
RuntimeNon-root user, drop capabilities, read-only FS🔴 Kritis
SecretsJangan pakai ENV, gunakan Docker secrets atau vault🔴 Kritis
NetworkInternal networks, firewall rules, encrypted traffic🟡 Tinggi
ResourcesLimit CPU, memory, PID, ulimit🟡 Tinggi
LoggingAudit logging, centralized logs, alert🟡 Tinggi
UpdatesPatch OS, Docker engine, dan base images berkala🟡 Tinggi

3. Rootless Docker Mode

Secara default, Docker daemon (dockerd) berjalan sebagai root. Ini berarti jika ada vulnerability di Docker daemon atau container runtime, attacker bisa mendapatkan akses root ke host. Rootless mode menjalankan Docker daemon sebagai user biasa, sehingga bahkan jika terjadi container escape, attacker hanya mendapatkan akses sebagai user tersebut.

Perbandingan Root vs Rootless

Aspek Root Mode (Default) Rootless Mode
Daemon User🔴 root🟢 regular user
Container Escape Impact🔴 Full root access🟢 Limited user access
Port Binding (<1024)🟢 Langsung bisa🟡 Butuh sysctl atau port mapping
Cgroup Management🟢 Penuh🟡 Terbatas (butuh cgroup v2)
Overlay Network🟢 Penuh🟡 Terbatas
AppArmor/SELinux🟢 Didukung🟡 Terbatas
Performance🟢 Native🟡 Slight overhead

Instalasi Rootless Docker

Bash
# ===========================
# INSTALL ROOTLESS DOCKER
# ===========================

# 1. Install dependencies
sudo apt-get install -y uidmap dbus-user-session fuse-overlayfs slirp4netns

# 2. Pastikan user memiliki subuid/subgid mapping
grep $(whoami) /etc/subuid || sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $(whoami)

# 3. Install rootless Docker (sebagai user, BUKAN root)
dockerd-rootless-setuptool.sh install

# 4. Set environment variables (tambahkan ke ~/.bashrc)
export PATH=/home/$(whoami)/bin:$PATH
export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock

# 5. Verifikasi
docker info | grep -i "root dir"
# Output: Docker Root Dir: /home/user/.local/share/docker

# 6. Cek Docker daemon berjalan sebagai user
ps aux | grep dockerd
# Output: user  12345  dockerd --rootless

# 7. Test container
docker run --rm hello-world

User Namespace Remapping

Alternatif lain adalah menggunakan user namespace remapping pada Docker daemon biasa:

Bash — /etc/docker/daemon.json
# /etc/docker/daemon.json
{
  "userns-remap": "default",
  "storage-driver": "overlay2",
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}

# Setelah edit, restart Docker daemon
sudo systemctl restart docker

# Verifikasi user namespace remapping
docker run --rm alpine cat /proc/1/uid_map
# Output: 0     100000      65536
# Artinya: root(0) di container = UID 100000 di host
💡 Tips

Rootless mode memerlukan beberapa konfigurasi tambahan untuk fitur tertentu seperti AppArmor dan port di bawah 1024. Untuk production, kombinasikan rootless mode dengan user namespace remapping untuk keamanan berlapis.

4. Image Vulnerability Scanning

Image scanning adalah proses menganalisis Docker image untuk menemukan known vulnerabilities (CVE) pada packages dan library yang digunakan. Ini adalah langkah pertama dalam mengamankan supply chain container.

Tools Image Scanning

Tool Tipe Kelebihan
TrivyOpen-source CLICepat, mudah, scan image/filesystem/repo
GrypeOpen-source CLIRingan, integrasi SBOM dengan Syft
Docker ScoutIntegrated (Docker)Terintegrasi langsung di Docker Desktop/CLI
Snyk ContainerCommercial + Free tierFix suggestions, CI/CD integration
ClairOpen-source serverRegistry integration, API-based

Menggunakan Trivy

Bash
# ===========================
# INSTALL TRIVY
# ===========================

# Ubuntu/Debian
sudo apt-get install -y wget apt-transport-https gnupg
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb generic main" | sudo tee /etc/apt/sources.list.d/trivy.list
sudo apt-get update && sudo apt-get install trivy

# macOS
brew install trivy

# ===========================
# SCAN DOCKER IMAGES
# ===========================

# Scan image untuk vulnerabilities
trivy image node:20-alpine
# Output: tabel vulnerabilities dengan severity (CRITICAL, HIGH, MEDIUM, LOW)

# Scan dengan severity filter
trivy image --severity CRITICAL,HIGH nginx:latest

# Scan dan output JSON (untuk CI/CD)
trivy image --format json --output result.json node:20-alpine

# Scan image lokal yang baru di-build
trivy image myapp:v1.0

# Scan dengan exit code (CI/CD pipeline)
# Exit code 1 jika ditemukan CRITICAL vulnerability
trivy image --exit-code 1 --severity CRITICAL myapp:v1.0

# Scan Dockerfile untuk best practices
trivy config --policy-bundle-repository ghcr.io/aquasecurity/trivy-policies Dockerfile

# Scan filesystem (dependencies)
trivy fs --scanners vuln ./my-project/

Docker Scout

Bash
# Docker Scout (terintegrasi di Docker CLI)

# Login ke Docker Scout
docker scout login

# Quick view vulnerabilities
docker scout quickview node:20-alpine

# Detail CVE list
docker scout cves node:20-alpine

# Hanya CVE yang bisa di-fix
docker scout cves --only-fixed node:20-alpine

# Rekomendasi base image yang lebih aman
docker scout recommendations node:20-alpine

# Compare image versions
docker scout compare --to node:18-alpine node:20-alpine

Secure Dockerfile Patterns

Dockerfile — Secure Base Images
# ===========================
# SECURE DOCKERFILE BEST PRACTICES
# ===========================

# 1. Gunakan specific version tags (BUKAN latest)
FROM node:20.11-alpine3.19

# 2. Gunakan slim/distroless images untuk mengurangi attack surface
FROM gcr.io/distroless/nodejs20-debian12

# 3. Multi-stage build untuk mengurangi ukuran image
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

FROM gcr.io/distroless/nodejs20-debian12
COPY --from=builder /app/dist /app/dist
COPY --from=builder /app/node_modules /app/node_modules
WORKDIR /app
CMD ["dist/server.js"]

# 4. Buat user non-root
RUN addgroup -g 1001 appgroup && \
    adduser -u 1001 -G appgroup -s /bin/sh -D appuser
USER appuser

# 5. Copy file dengan permission yang tepat
COPY --chown=appuser:appgroup . .

# 6. Jangan install package yang tidak perlu
RUN apk add --no-cache curl && \
    rm -rf /var/cache/apk/*

# 7. Scan image setelah build
# trivy image --exit-code 1 --severity CRITICAL myapp:v1.0

5. Secrets Management

Secrets seperti password, API keys, dan certificates harus dikelola dengan aman. Docker menyediakan beberapa mekanisme untuk ini, masing-masing cocok untuk skenario berbeda.

❌ Cara yang SALAH (Jangan Lakukan)

Dockerfile — JANGAN INI!
# ❌ JANGAN hardcode secrets di Dockerfile
ENV DB_PASSWORD=supersecret123
ENV API_KEY=ak_1234567890abcdef

# ❌ JANGAN copy file secrets ke image
COPY .env /app/.env
COPY secrets/ /app/secrets/

# ❌ JANGAN kirim secrets via build args (masih terlihat di history)
ARG DB_PASSWORD
RUN echo "Setting up with $DB_PASSWORD"

✅ Docker Secrets (Swarm Mode)

YAML — Docker Secrets
# docker-compose.yml dengan secrets
# Secrets di-mount sebagai file di /run/secrets/

services:
  api:
    image: myapp/api
    secrets:
      - db_password
      - jwt_secret
      - tls_cert
      - tls_key
    environment:
      # Baca secret dari file (bukan dari ENV langsung)
      - DB_PASSWORD_FILE=/run/s...rd
      - JWT_SECRET_FILE=/run/secrets/jwt_secret
    volumes:
      - tls-cert:/tls:ro

  postgres:
    image: postgres:16
    secrets:
      - db_password
    environment:
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password

secrets:
  # Dari file di host
  db_password:
    file: ./secrets/db_password.txt
  jwt_secret:
    file: ./secrets/jwt_secret.txt
  # External (sudah ada di Swarm)
  tls_cert:
    external: true
  tls_key:
    external: true

✅ Build-Time Secrets dengan BuildKit

Dockerfile — BuildKit Secrets
# Dockerfile — BuildKit secrets (TIDAK tersimpan di image)
# Secrets hanya tersedia selama build, hilang setelahnya

# Install private dependencies
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc \
    npm ci --only=production

# Clone dari private repo
RUN --mount=type=secret,id=ssh_key,target=/root/.ssh/id_rsa \
    git clone git@github.com:private/repo.git /app

# Set certificate
RUN --mount=type=secret,id=ca_cert,target=/usr/local/share/ca-certificates/custom.crt \
    update-ca-certificates
Bash — Build dengan BuildKit Secrets
# Build dengan BuildKit secrets
DOCKER_BUILDKIT=1 docker build \
  --secret id=npmrc,src=$HOME/.npmrc \
  --secret id=ssh_key,src=$HOME/.ssh/id_rsa \
  -t myapp:v1.0 .

# Pastikan .dockerignore exclude secrets
echo "secrets/" >> .dockerignore
echo ".env" >> .dockerignore
echo ".npmrc" >> .dockerignore
echo "*.pem" >> .dockerignore
echo "*.key" >> .dockerignore

✅ External Secrets Manager

Text — Secrets Manager Integration
# ===========================
# SECRETS MANAGEMENT OPTIONS
# ===========================

# 1. Docker Swarm Secrets (built-in)
#    - Cocok untuk Docker Swarm deployment
#    - Encrypted at rest and in transit
#    - Mounted sebagai file di /run/secrets/

# 2. HashiCorp Vault
#    - Enterprise-grade secrets management
#    - Dynamic secrets (rotating credentials)
#    - Audit logging lengkap
#    - Integration dengan Kubernetes, Docker, CI/CD

# 3. AWS Secrets Manager / SSM Parameter Store
#    - Managed service, tidak perlu operasi infrastruktur
#    - Automatic rotation
#    - IAM-based access control

# 4. Azure Key Vault / Google Secret Manager
#    - Cloud-native solutions
#    - Integration dengan respective CI/CD tools

# 5. SOPS (Secrets OPerationS) oleh Mozilla
#    - Encrypted files yang aman untuk git
#    - Support AWS KMS, GCP KMS, Azure Key Vault
#    - Bisa di-decrypt saat CI/CD pipeline
⚠️ Peringatan

Hindari mengirim secrets melalui docker run -e SECRET=value karena secret akan terlihat di docker inspect, ps aux, dan process listing. Gunakan Docker secrets atau external vault untuk production.

6. Container Hardening

Container hardening berarti membatasi apa yang bisa dilakukan container di runtime. Semakin sedikit akses yang dimiliki container, semakin kecil dampak jika terjadi kompromi.

Complete Security-Hardened Dockerfile

Dockerfile — Production Hardened
# ===========================
# SECURITY-HARDENED DOCKERFILE
# BeebaneLabs Production Template
# ===========================

# Multi-stage build untuk minimal image
FROM node:20-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force

FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Final stage - distroless-like
FROM node:20-alpine AS production

# Install security updates
RUN apk update && apk upgrade && apk add --no-cache \
    dumb-init \
    && rm -rf /var/cache/apk/*

# Create non-root user
RUN addgroup -g 1001 -S appgroup && \
    adduser -u 1001 -S appuser -G appgroup -s /sbin/nologin

WORKDIR /app

# Copy only production dependencies
COPY --from=deps --chown=appuser:appgroup /app/node_modules ./node_modules
COPY --from=build --chown=appuser:appgroup /app/dist ./dist
COPY --from=build --chown=appuser:appgroup /app/package.json ./

# Set environment
ENV NODE_ENV=production
ENV PORT=3000

# Expose port
EXPOSE 3000

# Switch to non-root user
USER 1001:1001

# Health check
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
    CMD node -e "require('http').get('http://localhost:3000/health', (r) => { process.exit(r.statusCode === 200 ? 0 : 1) })"

# Use dumb-init as PID 1 (proper signal handling)
ENTRYPOINT ["dumb-init", "--"]
CMD ["node", "dist/server.js"]

Docker Compose Security Hardening

YAML — Hardened docker-compose.yml
services:
  api:
    build: ./backend
    # Non-root user
    user: "1001:1001"
    # Read-only root filesystem
    read_only: true
    # tmpfs untuk directory yang perlu write
    tmpfs:
      - /tmp:noexec,nosuid,size=100m
      - /app/.cache:noexec,nosuid,size=50m
    # Drop ALL capabilities, add only what's needed
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE    # Hanya jika bind port < 1024
    # Prevent privilege escalation
    security_opt:
      - no-new-privileges:true
    # Limit PIDs (prevent fork bomb)
    pids_limit: 100
    # Resource limits
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 128M
    # Logging
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "5"
    restart: unless-stopped

  postgres:
    image: postgres:16-alpine
    user: "70:70"    # postgres user in alpine
    read_only: true
    tmpfs:
      - /tmp:noexec,nosuid
      - /run/postgresql:noexec,nosuid
    cap_drop:
      - ALL
    cap_add:
      - CHOWN
      - DAC_OVERRIDE
      - FOWNER
      - SETGID
      - SETUID
    security_opt:
      - no-new-privileges:true
    pids_limit: 100
    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 1G
    # JANGAN expose port ke host di production
    # ports:
    #   - "5432:5432"    ← JANGAN
    expose:
      - "5432"           ← Hanya internal network
    networks:
      - data

Kernel Security Parameters

Bash — Host Kernel Hardening
# /etc/sysctl.d/99-docker-security.conf
# Terapkan di host untuk meningkatkan keamanan container

# Prevent IP spoofing
net.ipv4.conf.all.rp_filter = 1

# Disable IP forwarding (kecuali diperlukan)
net.ipv4.ip_forward = 0

# Disable ICMP redirects
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0

# Enable SYN cookies (protect against SYN flood)
net.ipv4.tcp_syncookies = 1

# Limit kernel pointer exposure
kernel.kptr_restrict = 2

# Disable core dumps
fs.suid_dumpable = 0

# Apply
sudo sysctl --system

7. Network Security

Network security di Docker melibatkan segmentasi traffic, pembatasan akses, dan enkripsi komunikasi antar container.

Network Security Best Practices

YAML — Network Security
services:
  api:
    networks:
      frontend:        # Hanya frontend dan backend
      backend:
    # JANGAN gunakan host networking
    # network_mode: host    ← JANGAN

  postgres:
    networks:
      data:            # Hanya data network
    # JANGAN expose port ke host
    expose:
      - "5432"         # Internal only

  redis:
    networks:
      data:
    expose:
      - "6379"
    # Password-protect Redis
    command: redis-server --requirepass ${REDIS_PASSWORD}

networks:
  # Frontend network - bisa akses internet
  frontend:
    driver: bridge
    internal: false

  # Backend network - internal only
  backend:
    driver: bridge
    internal: true

  # Data network - paling terisolasi
  data:
    driver: bridge
    internal: true    # Tidak bisa akses internet
    driver_opts:
      com.docker.network.bridge.enable_icc: "true"
      com.docker.network.bridge.enable_ip_masquerade: "false"

TLS untuk Docker Daemon

Bash — Docker Daemon TLS
# Generate CA certificate
openssl genrsa -aes256 -out ca-key.pem 4096
openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem

# Generate server certificate
openssl genrsa -out server-key.pem 4096
openssl req -subj "/CN=docker-host" -sha256 -new -key server-key.pem -out server.csr
echo "subjectAltName=DNS:docker-host,IP:192.168.1.10,IP:127.0.0.1" > extfile.cnf
echo "extendedKeyUsage = serverAuth" >> extfile.cnf
openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem \
  -CAcreateserial -out server-cert.pem -extfile extfile.cnf

# Configure Docker daemon untuk TLS
cat > /etc/docker/daemon.json <<'EOF'
{
  "tls": true,
  "tlscacert": "/etc/docker/certs/ca.pem",
  "tlscert": "/etc/docker/certs/server-cert.pem",
  "tlskey": "/etc/docker/certs/server-key.pem",
  "tlsverify": true
}
EOF

sudo systemctl restart docker

8. Runtime Security & Monitoring

Setelah container berjalan, kita perlu memonitor aktivitas yang mencurigakan dan mendeteksi anomali.

Runtime Security Tools

Tool Fungsi Tipe
FalcoRuntime threat detection berdasarkan system callsOpen-source
sysdigSystem exploration dan troubleshootingOpen-source
Aqua SecurityFull lifecycle container securityCommercial
Twistlock/PrismaContainer security platformCommercial
Docker BenchCIS Docker Benchmark compliance checkerOpen-source

Docker Bench for Security

Bash
# Jalankan Docker Bench Security (CIS Benchmark)
docker run --rm --net host --pid host --userns host --cap-add audit_control \
    -e DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST \
    -v /var/lib:/var/lib:ro \
    -v /var/run/docker.sock:/var/run/docker.sock:ro \
    -v /usr/lib/systemd:/usr/lib/systemd:ro \
    -v /etc:/etc:ro \
    --label docker_bench_security \
    docker/docker-bench-security

# Output berisi rekomendasi terorganisir:
# [WARN] 1.1.1 - Ensure Docker is up to date
# [PASS] 1.1.2 - Ensure only trusted users are in docker group
# [WARN] 2.1 - Ensure network traffic is restricted between containers
# ...

Falco Runtime Monitoring

Bash — Falco Installation
# Install Falco di host
curl -fsSL https://falco.org/repo/falcosecurity-packages.asc | sudo gpg --dearmor -o /usr/share/keyrings/falco-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/falco-archive-keyring.gpg] https://download.falco.org/packages/deb stable main" | sudo tee /etc/apt/sources.list.d/falcosecurity.list
sudo apt-get update && sudo apt-get install -y falco

# Jalankan Falco
sudo systemctl start falco

# Contoh rules yang terdeteksi:
# - Container melakukan shell exec
# - File sensitive diakses (/etc/shadow, /etc/passwd)
# - Network connection ke suspicious IP
# - K8s API call dari container
# - Binary baru dijalankan di container

Audit Logging

Bash — Docker Audit Logging
# Enable Docker daemon audit logging
# /etc/docker/daemon.json
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "5",
    "labels": "service,environment",
    "tag": "{{.ImageName}}/{{.Name}}/{{.ID}}"
  }
}

# Linux audit rules untuk Docker
sudo auditctl -w /usr/bin/docker -p rwxa -k docker
sudo auditctl -w /var/lib/docker -p rwxa -k docker
sudo auditctl -w /etc/docker -p rwxa -k docker
sudo auditctl -w /var/run/docker.sock -p rwxa -k docker
sudo auditctl -w /usr/bin/dockerd -p rwxa -k docker

# Cek audit logs
sudo ausearch -k docker --interpret

# Docker events untuk monitoring real-time
docker events --since '1h' --filter 'type=container'
docker events --filter 'event=start' --filter 'event=stop'

9. Compliance & Benchmarking

CIS Docker Benchmark adalah standar keamanan yang diakui secara luas untuk Docker deployment. Benchmark ini mencakup 6 bagian utama:

CIS Docker Benchmark Overview

Section Topik Contoh Rekomendasi
1. Host ConfigurationKeamanan host OSPartisi terpisah, update OS, audit logging
2. Docker DaemonKonfigurasi daemonTLS, userns-remap, content trust
3. Docker FilesDockerfile best practicesNon-root user, minimal packages, HEALTHCHECK
4. Container ImagesImage securityTrusted base, scan vulnerabilities, pin version
5. Container RuntimeRuntime hardeningRead-only FS, no-privileged, resource limits
6. Security OperationsOperational securityImage signing, content trust, audit

Automated Compliance Check

Bash
# Docker Content Trust (image signing)
export DOCKER_CONTENT_TRUST=1

# Pull hanya signed images
docker pull nginx:latest  # Akan verifikasi signature

# Docker Scout compliance
docker scout recommendations myapp:v1.0

# Manual security checklist
echo "=== Docker Security Audit ==="

# 1. Cek Docker daemon running as root?
ps -eo user,comm | grep dockerd

# 2. Cek containers running as root?
docker ps --format '{{.Names}}' | while read name; do
    echo -n "$name: running as "
    docker exec $name whoami 2>/dev/null || echo "N/A"
done

# 3. Cek containers dengan --privileged?
docker inspect --format='{{.HostConfig.Privileged}}' $(docker ps -q)

# 4. Cek containers dengan host network?
docker inspect --format='{{.HostConfig.NetworkMode}}' $(docker ps -q)

# 5. Cek exposed ports
docker ps --format "table {{.Names}}\t{{.Ports}}"

# 6. Cek volume mounts dari host
docker inspect --format='{{.Mounts}}' $(docker ps -q)

# 7. Cek resource limits
docker inspect --format='{{.HostConfig.Memory}} {{.HostConfig.CpuQuota}}' $(docker ps -q)

10. Security di CI/CD Pipeline

Integrasikan security scanning ke dalam CI/CD pipeline untuk mendeteksi vulnerabilities sebelum deployment. Lihat juga tutorial GitLab CI/CD dan Jenkins untuk panduan CI/CD lengkap.

GitLab CI Security Stage

YAML — .gitlab-ci.yml Security
# .gitlab-ci.yml - Security scanning stages
stages:
  - build
  - test
  - security
  - deploy

build-image:
  stage: build
  script:
    - docker build -t myapp:$CI_COMMIT_SHA .

image-scan:
  stage: security
  image:
    name: aquasec/trivy:latest
    entrypoint: [""]
  script:
    # Scan image untuk vulnerabilities
    - trivy image --exit-code 1 --severity CRITICAL,HIGH myapp:$CI_COMMIT_SHA
    # Generate report
    - trivy image --format json --output trivy-report.json myapp:$CI_COMMIT_SHA
  artifacts:
    paths:
      - trivy-report.json
    when: always

dockerfile-lint:
  stage: security
  image:
    name: hadolint/hadolint:latest-debian
    entrypoint: [""]
  script:
    - hadolint Dockerfile --strict

dependency-check:
  stage: security
  script:
    - npm audit --audit-level=high
    - trivy fs --exit-code 1 --severity CRITICAL ./node_modules/

Security Pipeline Checklist

Text
# ===========================
# CI/CD SECURITY PIPELINE
# ===========================

# PRE-BUILD:
# ✓ Lint Dockerfile (hadolint)
# ✓ Scan dependencies (npm audit, trivy fs)
# ✓ Check for secrets in code (gitleaks, trufflehog)

# BUILD:
# ✓ Use multi-stage build
# ✓ Don't include secrets in build context
# ✓ Use BuildKit secret mounts
# ✓ Pin base image versions

# POST-BUILD:
# ✓ Scan image for CVEs (trivy, grype)
# ✓ Sign image (cosign, Docker Content Trust)
# ✓ Push to secure registry

# PRE-DEPLOY:
# ✓ Verify image signature
# ✓ Check compliance (CIS benchmark)
# ✓ Run integration tests

# POST-DEPLOY:
# ✓ Runtime monitoring (Falco)
# ✓ Audit logging
# ✓ Periodic re-scan of running containers

11. Quiz Pemahaman

Uji pemahaman Anda tentang Docker Security:

1. Mengapa menjalankan container sebagai root berbahaya?

2. Apa fungsi cap_drop: ALL di Docker Compose?

3. Mengapa Docker socket tidak boleh di-mount ke container?

4. Apa keuntungan multi-stage build dari sisi keamanan?

5. Apa itu Docker Content Trust?

🔍 Zoom
100%
🎨 Tema