🐳 Container & Kubernetes Security Deep Dive

Panduan komprehensif β€” dari container runtime hardening hingga Kubernetes cluster defense. Mencakup attack surface, image security, runtime monitoring, RBAC, network policies, supply chain SLSA, admission control, secrets management, studi kasus nyata, dan tooling audit.

Navigasi Vault

Topik ini terkait erat dengan cicd-shiftleft-shiftright (DevSecOps pipeline), ebpf-kernel-security (eBPF-based runtime defense), comprehensive-threat-directory (threat taxonomy), web-hacking-exploitation (web-layer attacks yang kerap menjadi entry point ke K8s), dan it-domain-hierarchy (domain trust model).


πŸ“‹ Daftar Isi

  1. Container Attack Surface & Kernel Isolation
  2. Seccomp, AppArmor & SELinux
  3. Image Security & Multi-Stage Builds
  4. Distroless & Minimal Base Images
  5. Image Scanning & Vulnerability Management
  6. Runtime Security: Falco
  7. Runtime Security: Tracee
  8. Runtime Security: Tetragon & eBPF
  9. Kubernetes RBAC Deep Dive
  10. Pod Security Standards (PSS) & Pod Security Admission (PSA)
  11. OPA / Gatekeeper
  12. Kyverno Policy Engine
  13. Cilium & NetworkPolicy
  14. Service Mesh Security (Istio, mTLS)
  15. Supply Chain SLSA untuk OCI Images
  16. Cosign & Image Signing
  17. Admission Control & Mutating Webhooks
  18. Secrets Management
  19. Case Study: Tesla Kubernetes Compromise
  20. Case Study: Log4j di Kubernetes
  21. Tooling Audit: kube-bench, kube-hunter, Popeye, Kubescape
  22. Kesimpulan & Best Practices

Container Attack Surface & Kernel Isolation

Container tidak menyediakan hypervisor-level isolation. Sebuah container berbagi kernel host dengan container lain dan host itu sendiri. Attack surface utama meliputi:

Attack VectorDeskripsiDampak
Namespace escapeExploit kernel bug untuk break out dari namespaceRoot on host
Capability abuseContainer dengan CAP_SYS_ADMIN, CAP_NET_RAWPrivilege escalation
Shared /proc, /sysWrite ke /proc/sys/kernel/core_patternHost code execution
Container breakout via mountMount host filesystem dari containerFull host access
User namespace mappingMisconfigured UID/GID mappingBypass permission
cgroupfsWrite ke cgroup notify_on_releaseHost code execution
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Host Kernel                    β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       β”‚
β”‚  β”‚  ctr-1   β”‚  β”‚  ctr-2   β”‚  β”‚  ctr-3   β”‚       β”‚
β”‚  β”‚ (pid ns) β”‚  β”‚ (pid ns) β”‚  β”‚ (pid ns) β”‚       β”‚
β”‚  β”‚ net ns   β”‚  β”‚ net ns   β”‚  β”‚ net ns   β”‚       β”‚
β”‚  β”‚ mnt ns   β”‚  β”‚ mnt ns   β”‚  β”‚ mnt ns   β”‚       β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β”‚
β”‚  Linux Kernel (shared by ALL containers)          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Mitigasi:

  • Jalankan container dengan --security-opt no-new-privileges:true
  • Drop semua capabilities, add hanya yang diperlukan (--cap-drop=ALL --cap-add=NET_BIND_SERVICE)
  • Gunakan user namespace remapping (/etc/subuid, /etc/subgid)
  • Hindari --privileged flag dalam produksi

Seccomp, AppArmor & SELinux

Seccomp (Secure Computing Mode)

Membatasi syscall yang bisa digunakan container. Tiga mode:

ModeDeskripsiUse Case
defaultWhitelist ~300+ syscall amanDefault Docker
unconfinedSemua syscall diizinkanDebugging (tidak untuk produksi)
Custom JSONWhitelist spesifik per containerAplikasi dengan syscall khusus
{
  "defaultAction": "SCMP_ACT_ERRNO",
  "architectures": ["SCMP_ARCH_X86_64"],
  "syscalls": [
    { "names": ["accept4", "epoll_wait", "write", "read", "openat"], "action": "SCMP_ACT_ALLOW" }
  ]
}

AppArmor (Application Armor)

Leverage LSM (Linux Security Module) untuk membatasi file path, network, dan capability. Profile di-load ke kernel dan di-enforce per container.

# Load profile
apparmor_parser -r /etc/apparmor.d/container-profile
 
# Jalankan container dengan profile
docker run --security-opt apparmor=container-profile nginx

SELinux (Security-Enhanced Linux)

Label-based MAC yang lebih granular. Di RHEL/CoreOS, container mendapat tipe container_t dengan MCS level unik per pod. Konfigurasi Kubernetes:

securityContext:
  seLinuxOptions:
    level: "s0:c123,c456"
    type: "container_t"

Comparison matrix:

LSMScopePolicy LanguageOverheadUse in K8s
SeccompSyscallJSONMinimalGA v1.19+
AppArmorPath, net, capText profileLowBeta (PSA)
SELinuxLabel-based MACPolicy moduleMediumRHCOS/Flatcar

Image Security & Multi-Stage Builds

Setiap lapisan (layer) pada container image menambah attack surface β€” termasuk toolchains, debug symbols, dan package manager artifacts.

Golden image anti-pattern:

FROM ubuntu:22.04
RUN apt-get update && apt-get install -y curl wget git build-essential python3
COPY app /app
CMD ["/app/entrypoint"]

β†’ 1.2 GB image, ~120 CVEs, puluhan unused binaries.

Multi-stage build:

# Stage 1: builder
FROM golang:1.22-alpine AS builder
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /app/server .
 
# Stage 2: runtime
FROM gcr.io/distroless/static-debian12:nonroot
COPY --from=builder /app/server /server
EXPOSE 8080
USER 65532:65532
ENTRYPOINT ["/server"]

βœ… Final image: ~15 MB, 0 CVEs, hanya satu binary.


Distroless & Minimal Base Images

Base ImageSizeCVE Count (typical)Use Case
ubuntu:22.0477 MB30–80Dev, testing
alpine:3.207 MB0–5Lightweight prod
gcr.io/distroless/static2 MB0Go/rust static binary
chainguard/static2.5 MB0FIPS-compliant minimal
scratch0 B0Fully static binary only

Rekomendasi

Untuk production: pilih distroless atau Chainguard. Alpine memakai musl libc β€” uji kompatibilitas aplikasi terlebih dahulu. Untuk compliance (FIPS, SOC 2), Chainguard menyediakan base image with zero CVEs dan SBOM built-in.


Image Scanning & Vulnerability Management

Alat scanning terintegrasi di pipeline CI/CD untuk mencegah image dengan critical CVE masuk ke registry atau cluster.

# GitHub Actions β€” Trivy scan example
- name: Scan image
  uses: aquasecurity/trivy-action@master
  with:
    image-ref: myapp:latest
    format: sarif
    severity: CRITICAL,HIGH
    output: trivy-results.sarif
    exit-code: 1 # ganti pipeline jika temuan critical
ScannerFormatRegistry IntegrationPolicy EngineLicense
TrivySARIF, JSON, HTMLECR, GAR, ACR, Docker HubIaC + K8sApache 2.0
GrypeCycloneDX, JSONAny OCI registry+Syft SBOMApache 2.0
ClairJSONQuay, HarborVulnerability matcherApache 2.0
SnykSARIF, JSON, HTMLAll major registriesSeverity-based gateProprietary
AnchoreJSON, CycloneDXECR, Docker HubPolicy bundlesApache 2.0

Runtime Security: Falco

Falco β€” project CNCF β€” menggunakan driver kernel (eBPF atau kernel module) untuk memonitor syscall dan menghasilkan falco events berdasarkan rule engine.

Arsitektur:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚         Kubernetes Node              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚ Falco    β”‚   β”‚ Container    β”‚   β”‚
β”‚  β”‚ (driver) │──▢│ (syscall)    β”‚   β”‚
β”‚  β”‚ eBPF/KM  β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜                      β”‚
β”‚       β”‚                            β”‚
β”‚  β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”                      β”‚
β”‚  β”‚ Falco    β”‚                      β”‚
β”‚  β”‚ Userspaceβ”‚                      β”‚
β”‚  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜                      β”‚
β”‚       β”‚                            β”‚
β”‚  β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ Output   │───▢│ gRPC / Stdout β”‚  β”‚
β”‚  β”‚ Channel  β”‚    β”‚ Webhook      β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Contoh rule β€” detect shell masuk kontainer:

- rule: Terminal shell in container
  desc: A shell was spawned by a program in a container
  condition: >
    spawned_process and container
    and shell_procs
    and not user_expected_terminal_shell_in_container_conditions
  output: >
    Shell spawned in container
    (user=%user.name container_name=%container.name shell=%proc.name parent=%proc.pname)
  priority: WARNING
  tags: [container, process, shell]

Runtime Security: Tracee

Tracee β€” dari Aqua Security β€” menggunakan eBPF untuk deteksi threats dan forensik tanpa kernel module.

FeatureTraceeFalco
Signatures150+ built-in200+ rules
eBPF-nativeβœ… Standalone eBPFβœ… eBPF (alternatif)
Kernel module❌ Tidak perluβœ… Juga support
Container forensicsβœ… Capture file write❌ Terbatas
CO-RE (BTF)βœ…βœ…
Output formatJSON, table, gobJSON, gRPC
# Tracee β€” one-shot signature scan
tracee --signatures --scope pid=1
 
# Tracee β€” daemon mode dengan output JSON
tracee --remap --output json --capture exec --capture write=/tmp/dump

Runtime Security: Tetragon & eBPF

Tetragon β€” dari Isovalent (sekarang Cisco) β€” menawarkan enforcement berbasis eBPF di Cilium ecosystem.

# Tetragon TracingPolicy β€” block execution of /bin/sh
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
  name: "block-shell"
spec:
  kprobes:
    - call: "sys_execve"
      syscall: true
      args:
        - index: 0
          type: "string"
      selectors:
        - matchArgs:
            - index: 0
              operator: "Equal"
              values:
                - "/bin/sh"
          matchActions:
            - action: Sigkill

eBPF Security Landscape

eBPF memungkinkan observability dan enforcement tanpa mengubah kernel source. Tools seperti Falco (kernel module/eBPF), Tracee (pure eBPF), dan Tetragon (eBPF-based enforcement) membentuk lapisan runtime defense yang semakin mature. Lihat ebpf-kernel-security untuk technical deep dive.


Kubernetes RBAC Deep Dive

RBAC di Kubernetes menggunakan Role / ClusterRole (permissions) dan RoleBinding / ClusterRoleBinding (binding ke user/SA/group).

Privilege escalation via RBAC misconfig:

# ❌ JANGAN β€” binding cluster-admin ke service account
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: dangerous-binding
subjects:
  - kind: ServiceAccount
    name: myapp
    namespace: default
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin

Principle of Least Privilege (PoLP):

# βœ… Role minimal untuk pod reader
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: production
  name: pod-reader
rules:
  - apiGroups: [""]
    resources: ["pods", "pods/log"]
    verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: production
  name: myapp-pod-reader
subjects:
  - kind: ServiceAccount
    name: myapp
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: pod-reader

RBAC audit checklist:

  1. βœ… Apakah ada binding ke cluster-admin di namespace non-system?
  2. βœ… Apakah SA digunakan tanpa token mount?
  3. βœ… Apakah escalate / bind verb diberikan?
  4. βœ… Apakah * wildcard resources/verbs digunakan?
  5. βœ… Apakah get secrets dibatasi?

Pod Security Standards (PSS) & Pod Security Admission (PSA)

PSS menggantikan PSP (PodSecurityPolicy, deprecated di v1.25) dengan tiga policy level:

LevelDeskripsiKetatContoh Restriksi
privilegedunrestrictedLonggarTidak ada batasan
baselineminimal restrictionsSedangNo hostPID, no privileged, no hostPort
restrictedhardened by defaultKetatSeccomp=RuntimeDefault, drop ALL caps, readOnlyRootFilesystem

Implementasi via label namespace:

kubectl label ns production \
  pod-security.kubernetes.io/enforce=restricted \
  pod-security.kubernetes.io/audit=baseline \
  pod-security.kubernetes.io/warn=baseline
ModeBehavior
enforceTolak pod yang melanggar policy
auditLog pelanggaran ke audit log (pod tetap jalan)
warnTampilkan warning ke user (pod tetap jalan)

OPA / Gatekeeper

OPA Gatekeeper β€” admission controller berbasis Rego policy language β€” memungkinkan kebijakan deklaratif untuk resource Kubernetes.

Constraint template β€” blokir image dari registry tidak dikenal:

package k8sallowedrepos
 
violation[{"msg": msg}] {
  container := input.review.object.spec.containers[_]
  not startswith(container.image, "registry.internal.company.io/")
  msg := sprintf("Container %v menggunakan image dari registry eksternal", [container.name])
}

Install Gatekeeper:

kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/v3.16/deploy/gatekeeper.yaml

Constraint instance:

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sAllowedRepos
metadata:
  name: prod-allowed-repos
spec:
  match:
    namespaces: ["production"]
  parameters:
    repos:
      - "registry.internal.company.io/"

Kyverno Policy Engine

Kyverno β€” engine yang lebih Kubernetes-native β€” menulis policy dalam bentuk YAML, bukan Rego. Dapat melakukan mutate, validate, generate resource.

# Kyverno policy β€” require readOnlyRootFilesystem
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-readonly-rootfs
spec:
  validationFailureAction: Enforce
  rules:
    - name: check-readonly-rootfs
      match:
        any:
          - resources:
              kinds:
                - Pod
      validate:
        message: "Root filesystem harus read-only"
        pattern:
          spec:
            containers:
              - securityContext:
                  readOnlyRootFilesystem: true
FeatureOPA/GatekeeperKyverno
Policy languageRegoYAML (native)
Learning curveTinggiRendah
Mutation❌ (via webhook)βœ… Built-in
Generate resourcesβŒβœ…
Policy reportsβœ…βœ…
Background scanβŒβœ…
Ecosystem policiesGatekeeper LibraryKyverno Policies (200+)

Cilium & NetworkPolicy

Kubernetes NetworkPolicy default hanya bekerja di layer 3/4. Cilium β€” berbasis eBPF β€” memberikan L3-L7 network security dengan identitas service, bukan IP.

Kubernetes NetworkPolicy (native):

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-allow
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: api
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: frontend
      ports:
        - port: 3000

Cilium NetworkPolicy (L7 HTTP-aware):

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: l7-api-policy
spec:
  endpointSelector:
    matchLabels:
      app: api
  ingress:
    - fromEndpoints:
        - matchLabels:
            app: frontend
      toPorts:
        - ports:
            - port: "3000"
              protocol: TCP
          rules:
            http:
              - method: "GET"
                path: "/api/v1/public"
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Cilium Service Mesh     β”‚
β”‚                           β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”    β”‚
β”‚  β”‚     │────▢│     β”‚    β”‚
β”‚  β”‚ Svc β”‚     β”‚ Pod β”‚    β”‚
β”‚  β”‚ A   β”‚     β”‚ B   β”‚    β”‚
β”‚  β”‚(ID:1)β”‚     β”‚(ID:2)β”‚    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”˜    β”‚
β”‚       β”‚           β”‚      β”‚
β”‚  β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”  β”Œβ”€β–Όβ”€β”€β”€β”€β” β”‚
β”‚  β”‚ Hubble   β”‚  β”‚Enforceβ”‚ β”‚
β”‚  β”‚ Observ.  β”‚  β”‚ BPF   β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚      eBPF Programs        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Service Mesh Security (Istio, mTLS)

Service mesh menyediakan mTLS, fine-grained authorization, dan observability di layer aplikasi tanpa mengubah kode.

# Istio PeerAuthentication β€” strict mTLS untuk namespace production
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: production
spec:
  mtls:
    mode: STRICT # STRICT | PERMISSIVE | DISABLE
---
# Istio AuthorizationPolicy β€” allow only frontend ke api
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: api-authz
  namespace: production
spec:
  selector:
    matchLabels:
      app: api
  action: ALLOW
  rules:
    - from:
        - source:
            principals: ["cluster.local/ns/production/sa/frontend"]
      to:
        - operation:
            methods: ["GET"]
            paths: ["/api/*"]

Zero Trust Network untuk K8s

Kombinasi Cilium (eBPF NetworkPolicy) + Istio (mTLS + Authz) memberikan defense-in-depth. Cilium mengamankan traffic antar node, Istio mengamankan traffic antar pod di dalam node. Untuk implementasi lengkap, lihat web-hacking-exploitation untuk memahami web-layer threats yang service mesh cegah di L7.


Supply Chain SLSA untuk OCI Images

SLSA (Supply-chain Levels for Software Artifacts) β€” framework dari OpenSSF β€” mendefinisikan level keamanan supply chain dari L0 (no guarantees) hingga L3 (hermetic + reproducible).

LevelBuild as codeProvenanceIsolatedHermeticReproducible
SLSA L1βœ…βŒβŒβŒβŒ
SLSA L2βœ…βœ…βŒβŒβŒ
SLSA L3βœ…βœ…βœ…βœ…βŒ
SLSA L4βœ…βœ…βœ…βœ…βœ…

Praktik untuk mencapai SLSA L3 di OCI:

  1. Build as code β€” Dockerfile + CI pipeline (GitHub Actions, GitLab CI, Tekton)
  2. Signed provenance (DSSE) β€” attestation dari build platform
  3. Isolated build β€” no network during build, clean environment
  4. Hermetic build β€” semua dependensi dideklarasikan dan diverifikasi
# Generate provenance attestation dengan gitsign + cosign
steps:
  - uses: sigstore/cosign-installer@main
  - name: Sign image
    run: |
      cosign sign --yes "$IMAGE"
  - name: Generate provenance
    run: |
      cosign attest --yes --type slsa --predicate slsa.json "$IMAGE"

Cosign & Image Signing

Cosign β€” dari Sigstore project β€” memungkinkan signing, verifying, dan storing signatures untuk OCI container images.

Signing flow:

# Generate keyless signing
cosign sign myapp:latest
 
# Verify
cosign verify myapp:latest \
  --certificate-identity "someone@example.com" \
  --certificate-oidc-issuer "https://accounts.google.com"

Verifikasi admission β€” CUE policy dengan cosign:

# Gate admission dengan cosign verify
kubectl exec -it kube-apiserver -- \
  --admission-control-config-file=<(
    echo '
    plugins:
    - name: CosignImageVerification
      configuration:
        policies:
        - image: "registry.internal.company.io/*"
          key:
            kms: "gcpkms://projects/my-project/locations/global/keyRings/cosign/cryptoKeys/signer"
    '
  )
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Build   │────▢│  Sign    │────▢│  Verify on   β”‚
β”‚  Image   β”‚     β”‚  (Cosign)β”‚     β”‚  Admission   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
                                         β”‚
                                    β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”
                                    β”‚ Deploy  β”‚
                                    β”‚ βœ… Deny β”‚
                                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Admission Control & Mutating Webhooks

Admission controllers adalah gatekeeper kustom di kube-apiserver yang memvalidasi/memodifikasi object sebelum disimpan ke etcd.

Admission ControllerFungsi
MutatingAdmissionWebhookModify object (default values, sidecar injection)
ValidatingAdmissionWebhookValidate object (policy enforcement)
PodSecurityEnforce PSS (replaces PSP)
NamespaceLifecyclePrevent deletion of system namespaces
LimitRangerEnforce resource limits
ImagePolicyWebhookKontrol image registry

Mutating webhook β€” inject sidecar:

apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
  name: sidecar-injector
webhooks:
  - name: sidecar.mesh.io
    clientConfig:
      service:
        name: sidecar-injector
        namespace: mesh-system
        path: /mutate
      caBundle: <base64>
    rules:
      - operations: ["CREATE"]
        apiGroups: [""]
        apiVersions: ["v1"]
        resources: ["pods"]
    admissionReviewVersions: ["v1"]
    sideEffects: None

Secrets Management

Masalah dengan Kubernetes Secrets Native:

  • Base64-only encoding (bukan encryption by default)
  • etcd belum tentu terenkripsi
  • Rotasi secrets memerlukan rolling pods
  • Audit trail terbatas

Solusi Eksternal:

ToolEncryption at restDynamic rotationKMS IntegrationVault Provider
External Secrets Operatoretcd encryptβœ…AWS/GCP/Azureβœ…
Sealed SecretsController key❌❌❌
HashiCorp VaultVault transitβœ…All major KMSN/A
Secret Store CSI DriverN/A (provider-side)βœ…AWS/GCP/Azureβœ…

External Secrets Operator:

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: database-credentials
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: vault-backend
    kind: SecretStore
  target:
    name: db-creds
    creationPolicy: Owner
  data:
    - secretKey: DB_PASSWORD
      remoteRef:
        key: secret/data/database
        property: password

Sealed Secrets:

# Encrypt secret untuk disimpan di Git
kubeseal --format yaml < secret.yaml > sealed-secret.yaml
# Sealed secret aman disimpan di repo publik β€” hanya controller bisa decrypt

Case Study: Tesla Kubernetes Compromise

Timeline (2018):

  1. Entry point: Kubernetes admin console tanpa password (kubectl dashboard exposed ke internet)
  2. Lateral movement: Attacker menemukan credential AWS di sebuah pod environment variable
  3. Data exfiltration: Menggunakan kubelet credential untuk mencuri data mining pod
  4. Cryptocurrency mining: Deploy container mining di cluster Tesla menggunakan pods

Root cause analysis:

  • Kubectl dashboard tidak seharusnya terekspos publik tanpa auth
  • Service account dengan cluster-admin digunakan untuk dashboard
  • Credential AWS disimpan di env variable, bukan secrets management
  • NetworkPolicy tidak membatasi egress ke internet

Pelajaran:

πŸ“Œ ❌ JANGAN: expose Kubernetes Dashboard ke internet
πŸ“Œ βœ… WAJIB: RBAC dengan least privilege
πŸ“Œ βœ… WAJIB: External Secrets / Vault untuk credential
πŸ“Œ βœ… WAJIB: NetworkPolicy untuk blokir egress kecuali approved
πŸ“Œ βœ… WAJIB: Audit logging ke SIEM (Splunk, ELK)

Case Study: Log4j di Kubernetes

CVE-2021-44228 (Log4Shell) β€” Impact di K8s:

  • JNDI injection menyebabkan RCE pada ribuan aplikasi Java yang menggunakan Log4j
  • Service mesh (Istio/Linkerd) tidak bisa memblokir sepenuhnya karena exploit terjadi di layer aplikasi
  • Container image yang belum di-scan membawa vulnerable library

Mitigasi di K8s yang efektif:

  1. WAF + L7 Policy: Blokir header JNDI di ingress (Cilium HTTP policy, ModSecurity)
  2. Image scanning: Trivy/Grype scan β€” block image dengan Log4j < 2.17
  3. Runtime detection: Falco rule β€” detect proses spawn by JVM yang mencurigakan
  4. Network segmentation: Istio AuthorizationPolicy dengan deny-all default untuk egress
  5. Admission control: Kyverno β€” blokir pod tanpa annotation vulnerability scan
# Kyverno β€” require image scan attestation
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-image-scan
spec:
  validationFailureAction: Enforce
  rules:
    - name: check-sbom
      match:
        any:
          - resources:
              kinds:
                - Pod
      validate:
        message: "Image harus memiliki SBOM attestation"
        deny:
          conditions:
            all:
              - key: "{{ request.operation }}"
                operator: NotEquals
                value: DELETE

Tooling Audit: kube-bench, kube-hunter, Popeye, Kubescape

kube-bench

Benchmark keamanan Kubernetes berdasarkan CIS Benchmark for Kubernetes.

kube-bench run --targets node,master --version 1.29
# Output: PASS/FAIL per control β€” remediation untuk setiap failure

Sample output:

Control IDCheckStatus
1.1.1API server β€”anonymous-auth=falseβœ… PASS
1.2.6Controller Manager β€”address=127.0.0.1❌ FAIL
4.2.1kubelet β€”anonymous-auth=false❌ FAIL

kube-hunter

Penetration testing tool dari Aqua β€” mencari eksploit path aktif.

kube-hunter --cidr 10.0.0.0/16
kube-hunter --remote cluster.example.com

Popeye

Cluster sanitizer β€” memindai resource K8s dan memberikan score numerik.

popeye --context production --out html --output-file popeye-report.html
# Score < 70: perlu intervensi segera

Kubescape

Tool all-in-one dari ARMO β€” mencakup CIS benchmark, NSA CISA framework, MITRE ATT&CK.

kubescape scan --submit --format json framework nsa,mitre
kubescape scan framework nsa --format html -o report.html

Tool comparison:

ToolFocusFrameworkOutputScan Type
kube-benchNode/control plane CISCIS BenchmarkCLI, JSON, HTMLConfiguration audit
kube-hunterActive exploit pathN/ACLI, JSONPenetration test
PopeyeK8s resource hygieneCustom scoringCLI, HTML, JSONStatic analysis
KubescapeComprehensive securityNSA CISA + MITRE + CISCLI, JSON, HTML, PDFMulti-framework

Kesimpulan & Best Practices

Defense-in-Depth untuk K8s:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    LAYER 1: CODE                        β”‚
β”‚   Image scanning Β· SBOM generation Β· Multi-stage      β”‚
β”‚   Distroless base Β· Cosign signing Β· SLSA L3+         β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                    LAYER 2: ADMISSION                   β”‚
β”‚   Kyverno/OPA policy Β· Image verification             β”‚
β”‚   Mutating webhooks Β· Pod Security Standards          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                    LAYER 3: NETWORK                     β”‚
β”‚   Cilium NetworkPolicy Β· Istio mTLS Β· Egress control  β”‚
β”‚   Hubble observability Β· Service mesh authz           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                    LAYER 4: RUNTIME                     β”‚
β”‚   Falco/Tracee detection Β· Tetragon enforcement       β”‚
β”‚   eBPF syscall monitoring Β· Seccomp profile           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                    LAYER 5: AUDIT & COMPLIANCE          β”‚
β”‚   kube-bench CIS Β· Kubescape Β· SIEM integration       β”‚
β”‚   Audit logging Β· Policy reports Β· Metrics            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

10 Golden Rules:

  1. Least privilege RBAC β€” mulai dengan deny-all, add permission bertahap
  2. Immutable infrastructure β€” image immutable, rolling update, no exec into pods
  3. Image scanning wajib β€” gate pipeline dengan Trivy/Grype (exit-code 1 jika critical)
  4. NetworkPolicy deny-all default β€” allow only traffic yang diperlukan, blokir egress
  5. Secrets bukan env var β€” External Secrets Operator / Vault / CSI
  6. Pod Security Standards enforced β€” minimal baseline, prefer restricted
  7. Runtime detection 24/7 β€” Falco atau Tracee di setiap node
  8. Supply chain SLSA β€” signed provenance, hermetic build, Cosign verify
  9. Zero Trust networking β€” mTLS everywhere via service mesh atau Cilium
  10. Audit & scan terus-menerus β€” kube-bench mingguan, Kubescape di pipeline

Referensi & Bacaan Lanjutan

Dokumentasi resmi: