Audit Logging #

Setiap aksi terhadap Kubernetes API — buat Pod, baca Secret, hapus Deployment — bisa dicatat dalam audit log. Ini adalah rekaman jejak yang memungkinkan kamu menjawab pertanyaan kritis saat insiden: siapa yang akses Secret database jam 3 pagi? Kapan Deployment ini diubah? Apakah ada akses tidak normal yang mendahului serangan? Tanpa audit log, investigasi insiden berjalan hampir buta.

Cara Kerja Audit Logging #

Audit logging dikonfigurasi di API Server. Setiap request ke API Server dicatat dalam beberapa tahap:

Stages dalam audit log:
  RequestReceived  — saat request diterima API Server, sebelum diproses
  ResponseStarted  — saat header response mulai dikirim (untuk long-running requests)
  ResponseComplete — saat response selesai dikirim
  Panic            — saat API Server mengalami panic saat memproses request

Audit Policy #

Audit policy menentukan request mana yang dicatat dan seberapa detail:

# /etc/kubernetes/audit-policy.yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
# Jangan catat request ke endpoint yang tidak informatif
- level: None
  users: ["system:kube-proxy"]
  verbs: ["watch"]
  resources:
  - group: ""
    resources: ["endpoints", "services", "services/status"]

- level: None
  userGroups: ["system:nodes"]
  verbs: ["get"]
  resources:
  - group: ""
    resources: ["nodes", "nodes/status"]

# Catat semua akses ke Secret dengan detail request
- level: Metadata          # catat metadata saja, bukan isi Secret
  resources:
  - group: ""
    resources: ["secrets", "configmaps"]
    # Tidak mencatat nilai Secret (untuk keamanan)
    # Tapi mencatat siapa, kapan, dari mana

# Catat perubahan ke Deployment, StatefulSet, DaemonSet
- level: RequestResponse   # catat request dan response body
  verbs: ["create", "update", "patch", "delete"]
  resources:
  - group: "apps"
    resources: ["deployments", "statefulsets", "daemonsets"]
  - group: ""
    resources: ["pods"]

# Catat semua akses dari user manusia (bukan system components)
- level: Request
  userGroups: ["system:authenticated"]
  omitStages: ["RequestReceived"]

# Default: catat metadata untuk semua request yang tersisa
- level: Metadata
  omitStages: ["RequestReceived"]

Level Audit #

None:
  → Jangan catat sama sekali
  → Untuk request yang sangat frekuen dan tidak informatif

Metadata:
  → Catat metadata request: user, waktu, resource, verb
  → Tidak catat isi request atau response body
  → Baik untuk Secret (aman) dan request volume tinggi

Request:
  → Catat metadata + request body
  → Tidak catat response body
  → Baik untuk operasi create/update/delete

RequestResponse:
  → Catat metadata + request body + response body
  → Paling lengkap tapi paling banyak storage
  → Gunakan untuk aksi yang butuh audit penuh (delete, critical changes)

Mengaktifkan Audit Logging di API Server #

# kube-apiserver manifest (untuk cluster self-managed)
# /etc/kubernetes/manifests/kube-apiserver.yaml
spec:
  containers:
  - command:
    - kube-apiserver
    - --audit-policy-file=/etc/kubernetes/audit-policy.yaml
    - --audit-log-path=/var/log/kubernetes/audit.log
    - --audit-log-maxage=30          # simpan 30 hari
    - --audit-log-maxbackup=10       # simpan 10 file backup
    - --audit-log-maxsize=100        # max 100MB per file
    # Atau kirim ke webhook (lebih baik untuk produksi):
    - --audit-webhook-config-file=/etc/kubernetes/audit-webhook.yaml
    - --audit-webhook-batch-max-size=400
    - --audit-webhook-batch-max-wait=30s
    volumeMounts:
    - mountPath: /etc/kubernetes/audit-policy.yaml
      name: audit-policy
      readOnly: true
    - mountPath: /var/log/kubernetes
      name: audit-log

Format Audit Log #

Setiap entry audit log adalah JSON:

{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "Metadata",
  "auditID": "a4d2b0c3-...",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/production/secrets/db-credentials",
  "verb": "get",
  "user": {
    "username": "[email protected]",
    "groups": ["engineering", "system:authenticated"]
  },
  "sourceIPs": ["203.0.113.42"],
  "userAgent": "kubectl/v1.28.0",
  "objectRef": {
    "resource": "secrets",
    "namespace": "production",
    "name": "db-credentials",
    "apiVersion": "v1"
  },
  "responseStatus": {
    "code": 200
  },
  "requestReceivedTimestamp": "2024-01-15T03:27:14.123456Z",
  "stageTimestamp": "2024-01-15T03:27:14.156789Z"
}

Query dan Investigasi Audit Log #

# Cari semua akses ke Secret tertentu
grep '"name":"db-credentials"' /var/log/kubernetes/audit.log | \
  jq '{time: .requestReceivedTimestamp, user: .user.username, verb: .verb, source: .sourceIPs}'

# Cari akses diluar jam kerja (contoh: setelah jam 20:00 atau sebelum 08:00)
grep '"stage":"ResponseComplete"' /var/log/kubernetes/audit.log | \
  jq 'select(.requestReceivedTimestamp | test("T(20|21|22|23|00|01|02|03|04|05|06|07):"))' | \
  jq '{time: .requestReceivedTimestamp, user: .user.username, action: .verb, resource: .objectRef.resource}'

# Cari operasi delete di production
grep '"verb":"delete"' /var/log/kubernetes/audit.log | \
  grep '"namespace":"production"' | \
  jq '{time: .requestReceivedTimestamp, user: .user.username, resource: .objectRef.resource, name: .objectRef.name}'

# Lihat semua aksi dari user tertentu
grep '"username":"[email protected]"' /var/log/kubernetes/audit.log | \
  jq '{time: .requestReceivedTimestamp, verb: .verb, resource: .objectRef.resource, name: .objectRef.name}'

Integrasi dengan SIEM #

Untuk produksi, jangan simpan audit log di file lokal — kirim ke sistem yang bisa dianalisis:

# audit-webhook.yaml — kirim ke log aggregation (Elasticsearch, Splunk, dll)
apiVersion: v1
kind: Config
clusters:
- name: audit-backend
  cluster:
    server: https://elasticsearch.monitoring:9200/_bulk
    certificate-authority: /etc/ssl/certs/ca.crt
users:
- name: audit-user
  user:
    token: <elasticsearch-token>
contexts:
- name: audit-context
  context:
    cluster: audit-backend
    user: audit-user
current-context: audit-context

Untuk cloud managed Kubernetes, audit log biasanya tersedia di platform log management:

# GKE: lihat di Cloud Logging
gcloud logging read 'resource.type="k8s_cluster" AND logName=~"cloudaudit"' \
  --project=my-project --limit=100

# EKS: aktifkan control plane logging ke CloudWatch
aws eks update-cluster-config --name my-cluster \
  --logging '{"clusterLogging":[{"types":["api","audit","authenticator"],"enabled":true}]}'

Deteksi Anomali: Sinyal yang Perlu Dipantau #

Aksi mencurigakan yang harus di-alert:

1. Akses Secret di luar jam kerja atau dari IP tidak dikenal
   → Mungkin credential breach

2. kubectl exec ke Pod production
   → Siapa yang masuk ke container dan kenapa?
   → Verb: create, Resource: pods/exec

3. Buat ClusterRoleBinding dengan cluster-admin
   → Privilege escalation attempt

4. List semua Secret di namespace
   → Verb: list, Resource: secrets

5. Hapus resource secara massal
   → deletecollection verb

6. Akses dari ServiceAccount yang biasanya tidak manusia
   → system:serviceaccount:namespace:name dari source IP eksternal

7. API error rate yang tinggi dari satu user/service
   → Mungkin brute force atau misconfigured automation

Ringkasan #

  • Audit policy dengan level yang tepat per resource — Secret cukup level Metadata (jangan log isinya); Deployment changes perlu RequestResponse; request frekuen dari system component bisa None.
  • Kirim ke SIEM, bukan file lokal — file lokal tidak bisa di-query dengan efisien dan bisa hilang jika node bermasalah; gunakan Elasticsearch, Splunk, atau platform cloud logging.
  • Alert untuk aksi kritis — akses Secret di luar jam kerja, kubectl exec ke production, buat ClusterRoleBinding baru, dan list secrets adalah sinyal yang harus memicu alert.
  • Cloud managed Kubernetes sudah sediakan infrastruktur — GKE ke Cloud Logging, EKS ke CloudWatch; aktifkan dan konfigurasikan retention policy yang sesuai compliance.
  • Audit log untuk investigasi pasca-insiden — “siapa yang deploy ini?”, “kapan Secret ini diakses?”, “dari mana traffic ini berasal?” semua bisa dijawab dari audit log.
  • Jangan log response body Secret — level Metadata untuk Secret sudah cukup untuk audit trail tanpa mengekspos nilai sensitif ke log infrastructure.

← Sebelumnya: Supply Chain Security   Berikutnya: Cluster Hardening →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact