Audit Logging #
Dalam arsitektur sistem terdistribusi seperti Kubernetes, setiap interaksi antara pengguna, aplikasi, dan komponen internal kluster dikelola oleh komponen tunggal: Kubernetes API Server (kube-apiserver). Ketika seorang developer menjalankan perintah kubectl, sebuah skrip otomatis melakukan pembaruan versi aplikasi, atau sebuah Pod meminta rahasia (Secret) dari etcd, semuanya mengirimkan request HTTP ke API Server. Di lingkungan produksi yang ketat, memiliki visibilitas penuh terhadap siapa yang melakukan apa, kapan hal tersebut dilakukan, dan dari mana request tersebut berasal adalah pilar utama dari keamanan sistem. Audit Logging menyediakan catatan jejak audit (audit trail) kriptografis dan terstruktur yang mencatat setiap peristiwa keamanan tersebut secara berurutan, memberikan kemampuan deteksi dini ancaman serta bahan analisis forensik yang tak ternilai saat terjadi insiden keamanan.
Arsitektur dan Alur Pemrosesan Audit #
Mekanisme audit di Kubernetes berjalan sebagai bagian terintegrasi dari pipeline pemrosesan request di dalam kube-apiserver. Setiap request yang masuk disaring melalui beberapa tahap evaluasi (autentikasi, otorisasi, admission control) sebelum akhirnya dieksekusi dan disimpan di etcd. Pemrosesan log audit terjadi di sepanjang siklus hidup request ini.
Tahapan Request (Audit Stages) #
Untuk memberikan visibilitas yang komprehensif tanpa membebani performa I/O secara konstan, Kubernetes API Server mendefinisikan empat tahap perekaman (audit stages):
Tahapan Siklus Hidup Request dalam Audit Log:
1. RequestReceived:
- Log dicatat segera setelah API Server menerima request, namun sebelum request tersebut diteruskan ke filter autentikasi, otorisasi, atau admission control.
- Berguna untuk mendeteksi serangan denial of service (DoS) atau pelacakan waktu masuk awal request.
2. ResponseStarted:
- Tahap ini hanya dipicu untuk request yang bertipe long-running (misalnya, `kubectl logs -f`, `kubectl port-forward`, atau koneksi WebSocket).
- Log dicatat tepat setelah header HTTP dikirimkan ke client, namun sebelum data payload diselesaikan.
3. ResponseComplete:
- Tahap akhir perekaman log setelah seluruh proses eksekusi selesai dan response body dikirimkan kembali ke client.
- Ini adalah tahap yang paling sering dicatat karena mengandung kode status HTTP final dan hasil eksekusi request.
4. Panic:
- Tahap khusus yang dipicu jika terjadi kegagalan sistem internal (panic) di dalam API Server saat memproses request.
- Membantu tim administrator menginvestigasi bug sistem atau anomali input yang menyebabkan crash.
Diagram Alir Pipeline Audit API Server #
flowchart TD
Client["Client Request (kubectl / ServiceAccount)"] --> K8sAPI["Kube-API Server"]
K8sAPI --> AuthN["Authentication & Authorization"]
subgraph AuditFilter["Audit Filter Engine"]
direction TB
RequestStage1["Stage: RequestReceived"] --> PolicyCheck{"Evaluasi Policy?"}
PolicyCheck -- "None" --> DropLog["Abaikan Log (Tidak Dicatat)"]
PolicyCheck -- "Metadata/Request/RequestResponse" --> WriteBackend["Kirim ke Log Backend"]
end
AuthN --> RequestStage1
subgraph Execution["Pemrosesan API & Mutasi"]
direction TB
MutatingAdmission["Admission Webhook (Mutating)"] --> ObjectStore["Simpan ke etcd / Jalankan Aksi"]
end
WriteBackend --> MutatingAdmission
ObjectStore --> RequestStage2["Stage: ResponseComplete / Panic"]
RequestStage2 --> WriteFinalLog["Kirim Response Log ke Backend"]
subgraph OutputBackends["Log Destinations"]
direction LR
LocalFile["File Lokal (/var/log/kubernetes/audit.log)"]
Webhook["SIEM Webhook (Elasticsearch/Splunk)"]
end
WriteFinalLog --> OutputBackends
Menentukan Level Detail Audit (Audit Levels) #
Tantangan terbesar dalam mengaktifkan audit logging adalah manajemen volume data. Jika kita mencatat setiap detail request dari seluruh komponen kluster, kita akan mengalami penurunan performa pada API Server dan lonjakan biaya penyimpanan log (storage cost) yang eksponensial. Oleh karena itu, kita harus memilih tingkat detail (audit levels) yang tepat untuk setiap jenis resource.
Perbandingan Karakteristik Level Audit #
| Level | Data yang Dicatat | Overhead Performa | Use Case Terbaik | Risiko Keamanan |
|---|---|---|---|---|
None |
Tidak ada catatan sama sekali | Nol | Request internal volume tinggi (kube-proxy watch, node status updates). | Kehilangan jejak aktivitas jika disusupi. |
Metadata |
Metadata request (User, IP, waktu, verb, namespace, resource nama, status code). | Sangat Rendah | Sumber daya sensitif (Secrets, ConfigMaps) untuk menghindari pencatatan isi payload rahasia. | Tidak mencatat data mutasi jika ada manipulasi nilai internal. |
Request |
Metadata + request body (JSON payload yang dikirim client). | Sedang | Operasi mutasi non-sensitif (Create/Update Pod, Ingress, Service). | Dapat mencatat informasi sensitif jika ditulis di env var non-Secret. |
RequestResponse |
Metadata + request body + response body (output kembalian API). | Tinggi | Audit kritis untuk perubahan izin (RBAC ClusterRoleBinding, ServiceAccounts). | Konsumsi I/O tinggi; rawan kebocoran data jika log tidak dienkripsi. |
Kebijakan Audit Tingkat Produksi (Production Audit Policy) #
Kebijakan audit (Audit Policy) didefinisikan dalam sebuah file konfigurasi deklaratif yang dievaluasi dari atas ke bawah. Aturan pertama yang cocok (first match) akan menentukan level audit untuk request tersebut.
Berikut adalah perbandingan antara konfigurasi policy yang salah (kebocoran data) dengan konfigurasi policy tingkat produksi (hardened production audit policy).
# ANTI-PATTERN: Menyamaratakan level audit ke RequestResponse untuk semua resource.
# Hal ini menyebabkan kebocoran nilai Secret ke file log lokal, serta membebani
# I/O API Server karena mencatat request status dari kubelet dan kube-proxy.
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: RequestResponse # JANGAN: Ini akan mencatat nilai aktual dari Secret di log!
resources:
- group: ""
resources: ["secrets"]
- level: RequestResponse # JANGAN: Ini mencatat event status node yang membanjiri storage
verbs: ["get", "list", "watch"]
# ==============================================================================
# BENAR: Kebijakan Audit Tingkat Produksi yang Aman, Efisien, dan Informatif.
# File: /etc/kubernetes/audit-policy.yaml
apiVersion: audit.k8s.io/v1
kind: Policy
omitStages:
- "RequestReceived" # Abaikan tahap awal untuk mengurangi ukuran log hingga 50%
rules:
# 1. Abaikan request sistem ber-frekuensi tinggi (Kebisingan Log)
- level: None
users: ["system:apiserver", "system:kube-scheduler", "system:kube-controller-manager"]
- level: None
users: ["system:kube-proxy"]
verbs: ["watch"]
resources:
- group: ""
resources: ["endpoints", "services", "services/status"]
- level: None
userGroups: ["system:nodes"]
verbs: ["get", "update", "patch"]
resources:
- group: ""
resources: ["nodes", "nodes/status"]
- level: None
namespaces: ["kube-system"]
resources:
- group: ""
resources: ["endpoints"]
# 2. Amankan Secret dan ConfigMap (Catat Metadata saja, hindari pencatatan nilai rahasia)
- level: Metadata
resources:
- group: ""
resources: ["secrets", "configmaps"]
namespaces: [] # Berlaku untuk semua namespace
# 3. Log Aksi Kritis RBAC dan Autentikasi dengan Detail Maksimal
- level: RequestResponse
verbs: ["create", "update", "patch", "delete"]
resources:
- group: "rbac.authorization.k8s.io"
resources: ["clusterroles", "clusterrolebindings", "roles", "rolebindings"]
- group: ""
resources: ["serviceaccounts"]
# 4. Log Operasi Mutasi Aplikasi
- level: Request
verbs: ["create", "update", "patch", "delete"]
resources:
- group: "apps"
resources: ["deployments", "statefulsets", "daemonsets"]
- group: ""
resources: ["pods"]
# 5. Kebijakan Default (Catch-All) untuk Request Pengguna
- level: Metadata
userGroups: ["system:authenticated"]
Mengaktifkan Audit Logging di Control Plane #
Setelah merancang file kebijakan audit, kita harus menerapkannya pada Kubernetes API Server. Untuk kluster berbasis control plane yang dikelola secara mandiri (misalnya menggunakan kubeadm), API Server berjalan sebagai Static Pod. Kita harus mengedit manifest konfigurasinya secara langsung di server control plane.
Langkah-Langkah Konfigurasi di Master Node #
- Letakkan file kebijakan audit di
/etc/kubernetes/audit-policy.yamlpada host master node. - Edit file manifest API Server
/etc/kubernetes/manifests/kube-apiserver.yaml. - Tambahkan flag command konfigurasi audit:
# Cuplikan manifest /etc/kubernetes/manifests/kube-apiserver.yaml
apiVersion: v1
kind: Pod
metadata:
name: kube-apiserver
namespace: kube-system
spec:
containers:
- command:
- kube-apiserver
# Flag konfigurasi audit
- --audit-policy-file=/etc/kubernetes/audit-policy.yaml
- --audit-log-path=/var/log/kubernetes/audit/audit.log
- --audit-log-maxage=30 # Rentang waktu penyimpanan log (hari)
- --audit-log-maxbackup=10 # Jumlah maksimum file cadangan yang disimpan
- --audit-log-maxsize=100 # Ukuran file log maksimum sebelum dirotasi (MB)
name: kube-apiserver
volumeMounts:
# Mount file kebijakan audit ke container API Server
- mountPath: /etc/kubernetes/audit-policy.yaml
name: audit-policy
readOnly: true
# Mount direktori penyimpanan log pada host
- mountPath: /var/log/kubernetes/audit
name: audit-log-dir
volumes:
- name: audit-policy
hostPath:
path: /etc/kubernetes/audit-policy.yaml
type: File
- name: audit-log-dir
hostPath:
path: /var/log/kubernetes/audit
type: DirectoryOrCreate
Setelah manifest disimpan, kubelet di master node akan mendeteksi perubahan konfigurasi dan secara otomatis me-restart Static Pod kube-apiserver. Pastikan untuk memeriksa apakah API Server kembali berjalan normal:
# Periksa status pod control plane
kubectl get pods -n kube-system -l component=kube-apiserver
# Periksa apakah file audit log mulai terisi data JSON
tail -n 5 /var/log/kubernetes/audit/audit.log
Struktur Log Audit (JSON Schema Analysis) #
Setiap entri di dalam audit log dicatat dalam format baris JSON tunggal (JSON Lines). Ini mempermudah integrasi dengan mesin parser log modern. Berikut adalah contoh entri audit log tingkat produksi saat seorang pengguna ([email protected]) mengeksekusi pod/exec:
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"level": "Request",
"auditID": "9c12b7a4-8b1c-4b67-827c-9b16ea9825b1",
"stage": "ResponseComplete",
"requestURI": "/api/v1/namespaces/production/pods/payment-gateway-8f8f/exec?command=%2Fbin%2Fsh&container=app&stdin=true&stdout=true&tty=true",
"verb": "create",
"user": {
"username": "[email protected]",
"groups": [
"engineering-team",
"system:authenticated"
]
},
"sourceIPs": [
"192.168.10.45"
],
"userAgent": "kubectl/v1.28.2 (darwin/arm64) kubernetes/89a41a3",
"objectRef": {
"resource": "pods",
"namespace": "production",
"name": "payment-gateway-8f8f",
"subresource": "exec",
"apiVersion": "v1"
},
"responseStatus": {
"metadata": {},
"code": 101
},
"requestReceivedTimestamp": "2026-06-17T07:45:12.103982Z",
"stageTimestamp": "2026-06-17T07:45:12.112489Z"
Penjelasan Field Kunci untuk Analisis Keamanan #
auditID: UUID unik yang dihasilkan oleh API Server untuk melacak siklus hidup request di seluruh stages.user.username: Identitas asli subjek pengirim request. Jika request berasal dari aplikasi internal, field ini berisisystem:serviceaccount:<namespace>:<name>.sourceIPs: Alamat IP publik atau privat client. Sangat krusial untuk melacak kebocoran token dari luar jaringan VPN kantor.objectRef.subresource: Deteksi aksi khusus sepertiexec,portforward, atauattach.
Integrasi Webhook dan SIEM (Security Information and Event Management) #
Menyimpan log audit di hard disk lokal node control plane tidak aman. Jika penyerang berhasil mendapatkan akses root ke master node, mereka dapat memodifikasi atau menghapus file /var/log/kubernetes/audit/audit.log untuk menghilangkan jejak (anti-forensics).
Untuk cluster tingkat produksi, kita harus mengirimkan log audit secara real-time ke log aggregator eksternal (seperti Elastic Stack, Splunk, Datadog) menggunakan mode webhook.
Konfigurasi Webhook Audit (audit-webhook.yaml)
#
Kita membuat file konfigurasi kubeconfig untuk server webhook audit:
# File: /etc/kubernetes/audit-webhook.yaml
apiVersion: v1
kind: Config
clusters:
- name: secure-siem-endpoint
cluster:
# URL dari endpoint pengumpul log (SIEM / Logstash / Fluentd)
server: https://siem-collector.internal.company.com/v1/audit-receiver
certificate-authority: /etc/ssl/certs/internal-ca.crt
users:
- name: apiserver-audit-client
user:
token: "secret-bearer-token-for-auth"
contexts:
- name: audit-context
context:
cluster: secure-siem-endpoint
user: apiserver-audit-client
current-context: audit-context
Tambahkan flag berikut ke manifest kube-apiserver.yaml untuk mengarahkan transmisi log ke webhook tersebut:
- --audit-webhook-config-file=/etc/kubernetes/audit-webhook.yaml
- --audit-webhook-batch-max-size=500 # Kirim log dalam batch berisi 500 baris
- --audit-webhook-batch-max-wait=10s # Jeda transmisi maksimum jika batch belum penuh
- --audit-webhook-batch-throttle-qps=10 # Batasi throughput transmisi ke SIEM
Skenario Forensik Nyata (Incident Investigation) #
Mari kita simulasikan bagaimana tim keamanan (Security Operations Center) menggunakan log audit untuk memecahkan insiden pelanggaran keamanan nyata menggunakan perkakas baris perintah (grep, jq).
Skenario A: Melacak Pengguna yang Melakukan kubectl exec ke Pod Produksi
#
Ketika ada aktivitas mencurigakan di dalam database kontainer, kita ingin tahu siapa saja yang pernah membuka terminal interaktif (kubectl exec) ke dalam kluster.
# Jalankan pencarian terhadap subresource 'exec' di file log audit
grep '"subresource":"exec"' /var/log/kubernetes/audit/audit.log | \
jq '{
Waktu: .requestReceivedTimestamp,
Pengguna: .user.username,
IP_Asal: .sourceIPs[0],
Namespace: .objectRef.namespace,
Pod: .objectRef.name,
Perintah: .requestURI
}'
# Output yang dihasilkan:
# {
# "Waktu": "2026-06-17T07:45:12.103982Z",
# "Pengguna": "[email protected]",
# "IP_Asal": "192.168.10.45",
# "Namespace": "production",
# "Pod": "payment-gateway-8f8f",
# "Perintah": "/api/v1/namespaces/production/pods/payment-gateway-8f8f/exec?command=%2Fbin%2Fsh..."
# }
Skenario B: Mendeteksi Eskalasi Hak Akses (Privilege Escalation) #
Seorang penyerang yang berhasil meretas ServiceAccount aplikasi mungkin mencoba membuat ClusterRoleBinding baru dengan hak akses cluster-admin agar menguasai seluruh kluster.
# Cari aksi create/update terhadap ClusterRoleBinding
grep -i "clusterrolebindings" /var/log/kubernetes/audit/audit.log | \
grep -E '"verb":"(create|update|patch)"' | \
jq '{
Waktu: .requestReceivedTimestamp,
Aktor: .user.username,
Aksi: .verb,
TargetBinding: .objectRef.name,
Status: .responseStatus.code
}'
Skenario C: Mendeteksi Pencurian Secret Massal (Credential Dumping) #
Kebocoran data rahasia biasanya didahului oleh aksi pembacaan (list) seluruh rahasia di dalam satu namespace secara tidak sah.
# Deteksi aksi 'list' atau 'watch' terhadap resource 'secrets'
grep '"resource":"secrets"' /var/log/kubernetes/audit/audit.log | \
grep '"verb":"list"' | \
jq 'select(.responseStatus.code == 200) | {
Waktu: .requestReceivedTimestamp,
Aktor: .user.username,
Namespace: .objectRef.namespace,
Client: .userAgent
}'
Anti-Pattern dalam Mengelola Audit Log #
Berikut adalah beberapa kesalahan implementasi (anti-pattern) yang harus kita hindari dalam konfigurasi audit logging Kubernetes:
1. Menyimpan Kunci Enkripsi etcd di Tingkat Log RequestResponse
#
Jika kluster kita dikonfigurasi untuk menulis enkripsi database atau kunci data sensitif ke Kubernetes API, menggunakan level RequestResponse untuk namespace rahasia akan mencatatkan payload plain-text tersebut ke dalam log. Pastikan aturan filter untuk Secrets selalu diatur ke level Metadata.
2. Mengabaikan Latensi Webhook Audit #
Jika server tujuan webhook SIEM mengalami penurunan performa, API Server dapat memblokir proses pemrosesan internal jika antrean log penuh.
# JANGAN: Mengabaikan fallback policy saat webhook gagal terhubung.
# Secara default, api-server bisa stuck jika antrean penuh.
# BENAR: Set konfigurasi antrean batch secara dinamis dengan buffer aman.
- --audit-webhook-batch-buffer-size=10000 # Buffer penyimpanan sementara
- --audit-webhook-mode=batch # Kirim asinkron (jangan sinkron/blocking)
3. Tidak Melakukan Korelasi Waktu (Clock Drift) #
Log audit tidak berguna jika waktu di master node berbeda dengan waktu di server SIEM. Pastikan seluruh server master node menjalankan protokol penyelarasan waktu Network Time Protocol (NTP) secara aktif.
Checklist Audit Logging Produksi #
Gunakan daftar checklist berikut untuk memastikan audit logging kluster Anda telah memenuhi standar kepatuhan industri:
KONFIGURASI POLICY & FILTER:
□ File audit-policy.yaml disaring secara berlapis dari atas ke bawah.
□ Kategori sistem (kubelet, kube-proxy) dikecualikan dengan level 'None'.
□ Data rahasia (secrets, configmaps) hanya dicatat pada level 'Metadata'.
□ Perubahan hak akses (RBAC, ServiceAccount) dicatat penuh pada level 'RequestResponse'.
□ Tahap 'RequestReceived' diabaikan untuk menekan kapasitas ukuran log.
PENGAMANAN & ROTASI FILE MASTER:
□ Kube-apiserver dikonfigurasi dengan flag limit maxage, maxbackup, dan maxsize.
□ Izin akses direktori log (/var/log/kubernetes/audit) dibatasi hanya untuk user root (chmod 700).
□ Rotasi file dikonfigurasi menggunakan logrotate bawaan OS master node untuk kompresi tambahan.
INTEGRASI SIEM & CLOUD:
□ Transmisi log dikirim ke SIEM eksternal secara asinkron (mode batch).
□ Kredensial webhook disimpan secara aman dengan otentikasi token atau TLS client certificates.
□ Sinkronisasi waktu NTP berjalan aktif di seluruh control plane kluster.
□ Pada layanan managed cloud (GKE/EKS), fitur audit logging telah diaktifkan di konsol provider.
Ringkasan #
- Audit Trail adalah Kotak Hitam Kluster — Log audit mencatat setiap aktivitas di Kubernetes API Server, memberikan visibilitas mutlak atas aksi user maupun ServiceAccount.
- Batasi Log Secret pada Level Metadata — Jangan mencatat isi body Secret; gunakan level
Metadatauntuk merekam siapa yang mengakses tanpa membocorkan data sensitif.- Kirim Log ke Luar Kluster (SIEM) — Jangan andalkan hard disk lokal; kirim log audit ke sistem analitik terpusat (Elasticsearch/Splunk) secara asinkron.
- Kurangi Kebisingan Log — Filter request sistem berfrekuensi tinggi (seperti status check dari kube-proxy atau scheduler) menggunakan level
None.- Eksplorasi dengan jq dan grep — Kemampuan parsing cepat menggunakan tools JSON CLI mempercepat tim respons insiden dalam melacak terminal interaktif
kubectl exec.- Manajemen Rotasi Log Wajib Dikonfigurasi — Batasi kapasitas file audit agar tidak membanjiri ruang penyimpanan di master node dengan mengatur parameter size dan max backup.
← Sebelumnya: Supply Chain Security Berikutnya: Cluster Hardening →