Merhaba
Seri: SOC Analistleri İçin Log İzleme Rehberi (Ödeme Kuruluşları)
- Log İzleme Temelleri
- Mevzuat, Retention ve Silme Yasağı
- Windows/AD ve Linux Hardening
- Uygulama ve Veritabanı Katmanı
- Ağ Katmanı (Firewall/IDS-IPS/WAF/DDoS)
- Container ve Kubernetes (Bu Yazı)
- Bulut (AWS/Azure/GCP)
- XDR/EDR ve Bütünsel Korelasyon
Ön Not – Kapsam ve Amaç
Bu seri, kritik logları izlemeyi ve anlamayı öğretmek amacıyla yazılmıştır. Odak noktası tek tek ürünler değil, sürecin kendisidir: hangi olayın neden önemli olduğu, nasıl toplandığı, korele edildiği ve korunduğu.
Metindeki donanım, yazılım ve uygulama örnekleri (ürün adları, Event ID’ler, konfigürasyon parametreleri, komutlar) versiyona, sürüme ve yıllara göre değişiklik gösterebilir. Bir ayarın adı değişebilir, bir ürün yaşam döngüsünü tamamlayabilir, yeni bir alternatif ortaya çıkabilir. Bu nedenle örnekleri birebir kopyalanacak reçeteler olarak değil, mantığı kavramak için birer illüstrasyon olarak okuyun; kendi ortamınıza uygularken ilgili üreticinin güncel dokümantasyonunu esas alın.
Aynı şekilde, “Ödeme Kuruluşları İçin PCI DSS, HIPAA ve Türkiye Mevzuatı Bağlamında” hazırlanan bölümler de yürürlükteki düzenlemelere dayanır ve mevzuat değiştikçe güncellenmesi gerekir. PCI DSS sürümleri, TCMB tebliğleri, KVKK/MASAK düzenlemeleri ve retention süreleri zaman içinde değişebilir. Bu rehber hukuki veya denetim danışmanlığı yerine geçmez; nihai uygulama için kurumunuzun uyumluluk ekibine, QSA’sına ve güncel resmi mevzuata başvurun.
Kısacası: amaç, süreci ve mantığı anlamaktır. Örnekler bugünün fotoğrafıdır; ilke ise kalıcıdır.
Serinin altıncı bölümü. Konteyner ortamı geleneksel sunucudan farklı kurallara sahiptir: Kubernetes API audit ≠ pod stdout. RKE2 audit policy, Kyverno/OPA admission control (Riskli İşlemleri loglamak değil ENGELLEMEK), etcd encryption, Fluent Bit log toplama, CDE cluster ayrımı ve container’a özgü silme yasağı.
4.50. Container / Kubernetes – Log Katmanları
RKE2/Rancher gibi bir Kubernetes ortamında log yönetimi, geleneksel sunucudan farklı katmanlara sahiptir. En kritik yanılgı Bölüm 4.18’de belirttiğimizdir: pod stdout ≠ Kubernetes API audit log. Aşağıdaki tablo katmanları ve regülatif ağırlıklarını gösteriyor.
| Katman | Kaynak | PCI DSS | Retention | Kritiklik |
|---|---|---|---|---|
| Kubernetes API Audit | kube-apiserver audit log | 🔴 10.2 tümü – en kritik | 10 yıl | 🔴🔴 |
| Container/Pod stdout | Uygulama logu | 10.2.1.x | 10 yıl (audit) / 90 gün (debug) | 🔴 |
| Container Runtime | containerd, CRI-O, Docker daemon | 10.2.1.7 | 1 yıl | 🟠 |
| Node/Host (Linux) | auditd, journald | 10.2.1.2 | 10 yıl | 🔴 |
| etcd | Cluster state DB | 🔴 Secret’lar burada! | 1 yıl | 🔴 |
| Admission Controller | OPA/Gatekeeper, Kyverno | 6.5.1 (policy enforcement) | 10 yıl | 🔴 |
| Image Registry | Harbor, ECR, Quay | 6.3.2 (SBOM), 11.3 | 10 yıl | 🟠 |
| CNI / Network Policy | Calico, Cilium | 1.2, 1.3 (segmentasyon) | 1 yıl | 🔴 |
| Secrets Management | Vault, Sealed Secrets | 3.5, 3.6, 8.6 | 10 yıl | 🔴 |
| CI/CD Pipeline | GitLab CI, ArgoCD, Jenkins | 6.5.1, 6.5.4 | 10 yıl | 🔴 |
4.51. Windows Event ID ↔ Kubernetes Karşılığı
| Windows | Anlam | Kubernetes Karşılığı |
|---|---|---|
| 4624 | Başarılı login | API audit: responseStatus.code=200/201 |
| 4625 | Başarısız login | API audit: responseStatus.code=401 (Unauthorized) |
| 4672 | Special privileges | 🔴 cluster-admin ClusterRoleBinding · privileged: true pod |
| 4688 | Process oluşturuldu | 🔴 pods/exec (kubectl exec) · Node’da auditd execve |
| 4720 | Kullanıcı oluşturuldu | create serviceaccounts |
| 4728/4732/4756 | ⭐ Gruba üye eklendi | 🔴🔴 create/update clusterrolebindings → cluster-admin verilmesi |
| 4670 | İzin (ACL) değişti | 🔴 create/update clusterroles, roles (RBAC rule değişimi) |
| 4719 | ⚠️ Audit policy değişti | 🔴🔴 audit-policy.yaml değişimi · apiserver flag değişimi |
| 1102 | ⚠️ Log temizlendi | 🔴🔴 Audit log dosyası silme · Fluent Bit/Filebeat durdurma |
| 1100 | Log servisi durdu | Fluent Bit / Filebeat DaemonSet silinmesi |
Kubernetes’e özgü – Windows’ta Karşılığı Olmayan Kritik Olaylar:
| Olay | Neden Kritik |
|---|---|
🔴 pods/exec |
Container’a shell açma = production’da doğrudan komut. CDE’de neredeyse hiç olmamalı |
🔴 privileged: true pod |
Container escape → node root |
🔴 hostPath volume mount |
Node dosya sistemine erişim (/ , /var/run/docker.sock) |
🔴 secrets GET/LIST |
Vault/Secret içeriği okunması |
🔴 hostNetwork/hostPID/hostIPC |
Node namespace’ine erişim |
🔴 nodes/proxy |
Kubelet API’ye doğrudan erişim = tüm pod’lara komut |
| 🔴 CronJob oluşturma | Persistence mekanizması |
| 🔴 etcd erişimi | Tüm secret’lar düz metin (encryption at rest yoksa) |
4.52. RKE2 – Kubernetes API Audit Policy
/etc/rancher/rke2/audit-policy.yaml (Kritik Kurallar):
apiVersion: audit.k8s.io/v1
kind: Policy
omitStages: ["RequestReceived"]
omitManagedFields: true
rules:
# RBAC DEĞİŞİKLİKLERİ - Windows 4728/4729/4670 karşılığı
- level: RequestResponse
verbs: ["create", "update", "patch", "delete", "deletecollection"]
resources:
- group: "rbac.authorization.k8s.io"
resources: ["roles", "rolebindings", "clusterroles", "clusterrolebindings"]
# 🔴 EXEC / ATTACH / PORT-FORWARD - Windows 4688 karşılığı (CDE'de neredeyse hiç olmamalı)
- level: RequestResponse
resources:
- group: ""
resources: ["pods/exec", "pods/attach", "pods/portforward", "pods/proxy"]
# 🔴 SECRETS - içerik loglanmaz ama ERİŞİM loglanır
- level: Metadata # 🔴 RequestResponse DEĞİL! Secret içeriği log'a düşer!
resources:
- group: ""
resources: ["secrets", "configmaps"]
# 🔴 Node erişimi (kubelet API bypass)
- level: RequestResponse
resources:
- group: ""
resources: ["nodes", "nodes/proxy", "nodes/status"]
# 🔴 Admission controller / policy değişimi
- level: RequestResponse
resources:
- group: "admissionregistration.k8s.io"
resources: ["validatingwebhookconfigurations", "mutatingwebhookconfigurations"]
- group: "kyverno.io"
resources: ["clusterpolicies", "policies"]
# 🔴 Network Policy (segmentasyon - PCI 1.2/1.3)
- level: RequestResponse
resources:
- group: "networking.k8s.io"
resources: ["networkpolicies", "ingresses"]
# 🔴 CDE namespace'lerinde TÜM yazma işlemleri
- level: RequestResponse
namespaces: ["payment-prod", "cde", "payment-db"]
verbs: ["create", "update", "patch", "delete"]
# 🔴 SİLME İŞLEMLERİ - TÜMÜ
- level: RequestResponse
verbs: ["delete", "deletecollection"]
# Sağlık kontrolleri (gürültü filtresi)
- level: None
nonResourceURLs: ["/healthz*", "/readyz*", "/livez*", "/metrics"]
🔴 KRİTİK:
secretsiçinlevel: Metadataolmalı,RequestResponsedeğil. Aksi halde secret’ın base64 içeriği (veritabanı parolası, API key, sertifika) audit log’a düz metin düşer – PCI DSS 3.5/8.6 ihlali ve ciddi QSA bulgusu.
⚠️ Geniş
level: Nonekuralları tehlikelidir.users: ["system:serviceaccount:*"]gibi bir muafiyet asla konulmamalı saldırgan tam da bir ServiceAccount kullanır.
/etc/rancher/rke2/config.yaml (Audit + Hardening):
kube-apiserver-arg:
- "audit-policy-file=/etc/rancher/rke2/audit-policy.yaml"
- "audit-log-path=/var/lib/rancher/rke2/server/logs/audit.log"
- "audit-log-maxage=365" # 🔴 Yerel: 1 yıl (arşiv 10 yıl WORM'da)
- "audit-log-maxbackup=100"
- "audit-log-mode=blocking-strict" # 🔴🔴 LOG YAZILAMAZSA API İSTEĞİ REDDEDİLİR
- "encryption-provider-config=/etc/rancher/rke2/encryption-config.yaml" # 🔴 etcd şifreleme
- "anonymous-auth=false"
- "profiling=false"
- "enable-admission-plugins=NodeRestriction,PodSecurity,ServiceAccount,AlwaysPullImages"
kubelet-arg:
- "read-only-port=0" # 🔴 Kimlik doğrulamasız kubelet portu KAPALI
- "anonymous-auth=false"
- "protect-kernel-defaults=true"
profile: "cis" # 🔴 CIS Kubernetes Benchmark
secrets-encryption: true # 🔴 RKE2 native secret encryption
etcd encryption at rest (PCI DSS 3.5) – encryption-config.yaml:
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources: ["secrets", "configmaps"]
providers:
- kms: # 🔴 KMS (Vault) - anahtar dışarıda
apiVersion: v2
name: vault-kms
endpoint: unix:///opt/vault-kms/socket.sock
- aescbc:
keys:
- name: key1
secret:
- identity: {} # 🔴 EN SONA! (identity = şifresiz)
🔴
identity: {}en sonda olmalı. Başta olursa hiçbir şey şifrelenmez (sessiz fail). etcd snapshot’ı çalınırsa tüm DB parolaları ve API key’ler açık gider.
4.53. Kubernetes Audit Log – Örnek Kayıtlar
🔴🔴 cluster-admin Verildi (Windows 4728 Muadili):
{
"level": "RequestResponse",
"verb": "create",
"requestURI": "/apis/rbac.authorization.k8s.io/v1/clusterrolebindings",
"user": { "username": "baki@example.com", "groups": ["platform-admins"] },
"sourceIPs": ["10.20.5.44"],
"objectRef": { "resource": "clusterrolebindings", "name": "backdoor-admin" },
"requestObject": {
"roleRef": { "kind": "ClusterRole", "name": "cluster-admin" },
"subjects": [{ "kind": "ServiceAccount", "name": "svc-backdoor", "namespace": "default" }]
},
"responseStatus": { "code": 201 }
}
🔴 kubectl exec (Windows 4688 Muadili – CDE’de Olmamalı!):
{
"level": "RequestResponse",
"verb": "create",
"requestURI": ".../namespaces/payment-prod/pods/payment-api-7d9f/exec?command=%2Fbin%2Fsh...",
"user": { "username": "baki@example.com" },
"objectRef": { "resource": "pods", "subresource": "exec",
"namespace": "payment-prod", "name": "payment-api-7d9f" },
"responseStatus": { "code": 101 }
}
🔴 subresource: exec + namespace: payment-prod (CDE) = P1 alarm. Change Ticket ve CyberArk PAM oturumu ile eşleşmeli. Container içindeki komutlar audit log’da GÖRÜNMEZ bu yüzden node auditd + sudo I/O recording ile tamamlanmalıdır.
🔴 Privileged pod (Container Escape Riski):
{
"level": "Request", "verb": "create",
"user": { "username": "system:serviceaccount:default:svc-backdoor" },
"requestObject": { "spec": {
"hostPID": true, "hostNetwork": true,
"containers": [{ "securityContext": { "privileged": true },
"command": ["nsenter", "--target", "1", "--mount", "--", "/bin/bash"] }],
"volumes": [{ "hostPath": { "path": "/" } }]
}},
"responseStatus": { "code": 201 }
}
🔴 Bu pod başarıyla oluştuysa (201), admission controller (OPA/Kyverno/PSA) yok demektir. Engellenmiş (403) olmalıydı sadece loglanmamalıydı.
4.54. Admission Control – Riskli İşlemleri Engelleme (Kyverno)
Audit log loglar ama engellemez. Ödeme kuruluşunda riskli işlemler admission controller ile engellenmelidir.
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: pci-dss-baseline
spec:
validationFailureAction: Enforce # 🔴 Audit değil, ENFORCE (blokla)
rules:
# 🔴 Privileged / host namespace / hostPath YASAK (PCI 2.2.6)
- name: disallow-privileged-and-host
match: { any: [{ resources: { kinds: ["Pod"] } }] }
validate:
message: "PCI DSS 2.2.6: privileged/hostNetwork/hostPID/hostPath yasak"
pattern:
spec:
=(hostNetwork): "false"
=(hostPID): "false"
containers:
- =(securityContext):
=(privileged): "false"
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities: { drop: ["ALL"] }
securityContext: { runAsNonRoot: true }
# 🔴 Sadece onaylı registry + imza (PCI 6.3.2)
- name: allowed-registries
match: { any: [{ resources: { kinds: ["Pod"] } }] }
validate:
message: "PCI DSS 6.3.2: Sadece harbor.example.local"
pattern:
spec:
containers:
- image: "harbor.example.local/*"
# 🔴 :latest tag YASAK (izlenebilirlik - PCI 6.5.3)
- name: disallow-latest
match: { any: [{ resources: { kinds: ["Pod"] } }] }
validate:
message: "':latest' yasak - versiyon/digest belirtilmeli"
pattern:
spec:
containers:
- image: "!*:latest"
Silme Yasağı – Admission Webhook:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: prevent-deletion-compliance
spec:
validationFailureAction: Enforce
rules:
# 🔴 CDE'de PVC/StatefulSet silme YASAK
- name: prevent-pvc-deletion
match:
any:
- resources:
kinds: ["PersistentVolumeClaim", "PersistentVolume", "StatefulSet"]
namespaces: ["payment-prod", "payment-db", "cde", "logging"]
preconditions:
all: [{ key: "{{ request.operation }}", operator: Equals, value: DELETE }]
validate:
message: "SILME YASAK - 6493/TCMB 10 yil saklama zorunlu. Imha Komisyonu karari gerekir."
deny: {}
# 🔴 Log toplama altyapısı silinemez (PCI 10.7)
- name: prevent-logging-deletion
match:
any:
- resources:
kinds: ["DaemonSet", "Deployment", "ConfigMap"]
namespaces: ["logging", "cattle-logging-system"]
preconditions:
all: [{ key: "{{ request.operation }}", operator: Equals, value: DELETE }]
validate:
message: "PCI DSS 10.7: Log toplama altyapisi silinemez/durdurulamaz."
deny: {}
OPA/Gatekeeper Alternatifi Aynı Mantığı Rego ile İfade Eder:
package k8spcicompliance
violation[{"msg": msg}] {
input.review.operation == "DELETE"
input.review.kind.kind == "PersistentVolumeClaim"
{"payment-prod", "payment-db", "cde"}[input.review.namespace]
msg := sprintf("SILME YASAK: PVC %v/%v - 6493/TCMB 10 yil", [input.review.namespace, input.review.name])
}
4.55. Container Log Toplama – Fluent Bit DaemonSet
Container’ların ephemeral doğası (pod silinince /var/log/containers/*.log kaybolur) log toplamayı kritik kılar. Kritik gereksinimler: pod/node çökse de log kaybolmamalı, anında SIEM’e forward, 3. maskeleme katmanı, shipper silinemez/durdurulamaz.
fluent-bit.conf (Kritik Kısımlar):
[SERVICE]
Health_Check On # 🔴 Heartbeat (PCI 10.7)
storage.path /var/log/flb-storage/ # 🔴 Disk-backed buffer
storage.checksum on # 🔴 Bütünlük
# 🔴 Kubernetes API Audit Log (EN KRİTİK)
[INPUT]
Name tail
Tag k8s.audit
Path /var/lib/rancher/rke2/server/logs/audit.log
DB /var/log/flb_audit.db
Skip_Long_Lines Off # 🔴 UZUN SATIRI ATLAMA! (log kaybı)
storage.type filesystem # 🔴 RAM değil, disk
# Container stdout + Node auditd inputs benzer şekilde tanımlanır...
[FILTER]
Name kubernetes
Match kube.*
Merge_Log On
K8S-Logging.Exclude Off # 🔴 Pod annotation ile log HARİÇ TUTMA YASAK!
# 🔴 PCI DSS MASKELEME (3. katman)
[FILTER]
Name lua
Match *
script /fluent-bit/scripts/pci_mask.lua
call mask_sensitive
# 🔴 Hassas alanları tamamen kaldır
[FILTER]
Name record_modifier
Match *
Remove_key password
Remove_key token
Remove_key cvv
Remove_key pan
# 🔴 SIEM'e gönderim (mTLS)
[OUTPUT]
Name es
Match *
Host elasticsearch.example.local
tls On # 🔴 TLS zorunlu
tls.crt_file /certs/client.crt # 🔴 mTLS
Retry_Limit False # 🔴 SONSUZ RETRY (log kaybolmasın!)
storage.total_limit_size 10G
🔴
K8S-Logging.Exclude Offkritiktir.Onolursa, bir pod kendi annotation’ıyla (fluentbit.io/exclude: "true") loglanmamayı seçebilir saldırgan izlerini böyle gizler.
🔴
Retry_Limit False– SIEM geçici erişilemezse log düşürülmez, disk queue’da bekler.Retry_Limit 5olsa log kaybolur = PCI 10.2 ihlali.
4.56. Docker (Standalone) – Kısa Not
Kubernetes dışında Docker kullanılıyorsa: daemon.json‘da icc: false , no-new-privileges: true , userns-remap , live-restore , log rotation. En kritik nokta 🔴🔴 /var/run/docker.sock – bir container’a mount edilirse tam node kontrolü sağlar (K8s’teki privileged: true ile aynı tehlike). auditd ile izlenmeli:
# /etc/audit/rules.d/docker-pci.rules
-w /var/run/docker.sock -p rwa -k docker_socket_CRITICAL
-w /run/containerd/containerd.sock -p rwa -k containerd_socket_CRITICAL
-w /etc/docker/daemon.json -p wa -k docker_config
PCI Uyumlu Container Çalıştırma:
--read-only , --cap-drop=ALL , --security-opt=no-new-privileges:true , --user 10001 , --memory/--cpus limit, digest ile (@sha256:...) – asla --privileged , -v /var/run/docker.sock , --net=host , --pid=host , image:latest.
4.57. Container / Kubernetes – SIEM Korelasyon Kuralları
🔴 P1 – Anında Alarm
Kural K1 – cluster-admin Yetkisi Verildi 🔴🔴 (Windows 4728 Muadili)
k8s_audit: verb IN ("create","update","patch")
AND objectRef.resource = "clusterrolebindings"
AND requestObject.roleRef.name IN ("cluster-admin","admin","edit")
AND responseStatus.code IN (200,201)
→ P1: Change Ticket + CyberArk oturumu ile eşleştir
→ MITRE: T1098
Kural K2 – Privileged Pod / Container Escape 🔴🔴
k8s_audit: verb="create" AND resource="pods"
AND (securityContext.privileged=true OR hostPID=true OR hostNetwork=true
OR volumes[*].hostPath EXISTS)
AND responseStatus.code = 201 # 🔴 BAŞARILI = admission controller YOK!
→ P1 KRİTİK: Container escape mümkün. Kyverno/OPA eksik!
→ MITRE: T1611 (Escape to Host)
Kural K3 – CDE Namespace’inde kubectl exec 🔴
k8s_audit: objectRef.subresource IN ("exec","attach")
AND objectRef.namespace IN ("payment-prod","cde","payment-db")
→ P1: CyberArk PAM oturumu + Change Ticket zorunlu
→ ⚠️ Container İÇİNDEKİ komutlar audit'te GÖRÜNMEZ → node auditd ile tamamla
→ MITRE: T1609
Kural K4 – Kubernetes Audit Log Kesildi / Silindi 🔴🔴 (Windows 1102 Muadili)
Fluent Bit/Filebeat heartbeat kesildi > 5 dk
OR k8s_audit: verb="delete" AND resource="daemonsets" AND namespace="logging"
OR auditd: key="pci_log_tamper" AND path CONTAINS "audit.log"
→ P1 KRİTİK: PCI DSS 10.7
→ MITRE: T1562.008 (Disable Cloud Logs)
Kural K5 – Secret Toplu Erişim / Exfiltration 🔴
k8s_audit: verb IN ("get","list") AND resource="secrets"
AND COUNT > 10 in 5 dakika BY same user.username
AND user NOT IN (approved_controllers)
→ MITRE: T1552.007
Kural K8 – Silme Girişimi (CDE Kaynağı) 🔴🔴
k8s_audit: verb IN ("delete","deletecollection")
AND namespace IN ("payment-prod","payment-db","cde","logging")
AND resource IN ("persistentvolumeclaims","statefulsets","daemonsets","secrets")
→ P1: 6493/TCMB SİLME YASAĞI. Engellenmiş mi (403)? Değilse admission controller eksik!
→ MITRE: T1485
Kural K10 – Admission Controller Devre Dışı 🔴🔴
k8s_audit: verb IN ("delete","update")
AND resource IN ("validatingwebhookconfigurations","clusterpolicies","constrainttemplates")
→ P1: Güvenlik politikaları kaldırılıyor
→ MITRE: T1562.001
🟠 P2 – Aynı Gün
Kural K13 – RBAC Keşfi (Recon)
k8s_audit: verb IN ("list","get")
AND resource IN ("clusterroles","clusterrolebindings","roles","rolebindings")
COUNT > 20 in 5 dk BY same user
→ kubectl-who-can / rakkess = saldırı hazırlığı
→ MITRE: T1069
Kural K11 – Container İçinde Şüpheli Process (node auditd Korelasyonu)
[node auditd] key="pci_exec"
AND process IN ("nsenter","chroot","crictl","kubectl")
OR cmdline MATCHES "/var/run/docker.sock|/proc/1/ns"
→ Container escape (audit log'da görünmez, node'da görünür!)
→ MITRE: T1611
Kural K15 – CronJob / Job Oluşturuldu (Persistence)
k8s_audit: verb="create" AND resource IN ("cronjobs","jobs")
AND namespace NOT IN (approved_batch_namespaces) AND NO change_ticket
→ MITRE: T1053.007
4.58. CDE Cluster Ayrımı – Kritik Mimari Kararı
PCI DSS scope’unu küçültmek için en önemli mimari karar: CDE’yi ayrı bir cluster’da çalıştırmak.
SEÇENEK A (önerilen): Ayrı cluster
┌──────────────────┐ ┌──────────────────┐
│ CDE Cluster │ │ Non-CDE Cluster │
│ payment-api │ │ crm, hr, portal │
│ payment-db │ │ │
│ 🔴 PCI scope │ │ ✅ scope dışı │
└──────────────────┘ └──────────────────┘
SEÇENEK B: Tek cluster + katı izolasyon
⚠️ Control plane (apiserver, etcd) PAYLAŞILDIĞI için
TÜM CLUSTER PCI SCOPE'A GİRER
🔴 QSA’nın bakış açısı: Tek cluster’da CDE ve non-CDE varsa, control plane paylaşıldığı için tüm cluster scope’a girer. Namespace izolasyonu segmentasyon sayılmaz (VLAN/firewall gibi değildir). Ödeme kuruluşu için ayrı cluster çok daha savunulabilir bir mimaridir.
4.59. Container’a Özgü Kritik Riskler
| Risk | Neden Kritik | Kontrol |
|---|---|---|
| 🔴 Ephemeral pod = kaybolan log | Pod silinince log dosyası silinir | Fluent Bit anında forward + disk queue |
| 🔴 Secret env var’da | kubectl describe pod kubectl describe pod ile görünür |
Vault Agent / CSI Secret Store, volume mount |
| 🔴 etcd’de secret düz metin | Snapshot çalınırsa tüm parolalar | secrets-encryption: true + KMS (Vault) |
| 🔴 Container image’da hardcoded secret | Registry’den çıkarılabilir | Trivy/Grype scan + Cosign imza |
| 🔴 Container escape | Node root = tüm cluster | Kyverno: privileged/hostPath/hostPID yasak |
| 🔴 Docker socket mount | Anında node kontrolü | auditd + Kyverno engelleme |
🔴 :latest tag |
Hangi kod çalışıyor bilinmez | Digest (@sha256:...) zorunlu |
| 🔴 Multi-tenancy | CDE ve non-CDE aynı cluster’da | Ayrı cluster önerilir |
4.60. Container Saldırı Zinciri – Bütünsel Görünüm
SALDIRI ZİNCİRİ - Tüm log katmanları:
1. [Ingress/WAF] Uygulama zafiyeti (Log4Shell) exploit → T1190
2. [Pod stdout] Uygulama exception + anormal davranış → 🟡 tek başına düşük
3. [Node auditd] Container içinde reverse shell (execve) → T1059
4. [K8s Audit] SA token ile API'ye erişim (pod'dan) → T1552.007
5. [K8s Audit] 403 yoğunluğu - yetki testi → T1613
6. [K8s Audit] 🔴 secrets LIST → DB credentials okundu → T1552
7. [K8s Audit] 🔴 privileged pod create (hostPath: /) → T1611 ESCAPE
8. [Node auditd] 🔴 nsenter → node root → T1611
9. [K8s Audit] 🔴🔴 clusterrolebinding → cluster-admin → T1098
10. [pgaudit] payment.cardholder_data toplu SELECT → T1213
11. [FortiGate] CDE → internete DNS tunneling → T1071.004
12. [K8s Audit] 🔴 Fluent Bit DaemonSet DELETE (iz silme) → T1562.008
13. [Node auditd] 🔴 /var/log/audit/audit.log unlink → T1070.002
- adımda admission controller engelleseydi zincir kırılırdı. 12–13. adımda silme yasağı (Kyverno +
chattr +a+ auditd-e 2) engellemeliydi. Her katman ayrı log kaynağıdır – WAF + Pod + Node auditd + K8s Audit + DB + Firewall ve XDR/SIEM bunları tek storyline olarak birleştirir.
4.61. Container / Kubernetes – Denetim Kanıtları ve Sık Bulgular
Denetim Kanıt Listesi (Özet)
kube-apiserver --audit-policy-fileayarlı +--audit-log-mode=blocking-strict- Audit policy’de
secrets → level: Metadata(RequestResponse değil) 🔴 - Geniş
level: Nonekuralı yok (bypass riski) - Audit log SIEM’de + retention (yerel 1 yıl + WORM 10 yıl)
cluster-adminyetkisine sahip kullanıcı/SA listesi (≤5, named)- Default SA’larda
automountServiceAccountToken: false - Kyverno/Gatekeeper Enforce modda 🔴
- Negatif test: privileged pod deploy → 403 reddedildi kanıtı
- Silme yasağı policy’si + test (PVC delete → 403)
secrets-encryption: true+identity: {}en sonda 🔴- Fluent Bit
Retry_Limit False+K8S-Logging.Exclude Off🔴 - Pod restart testi: log kaybolmuyor kanıtı
- CDE namespace’lerinde NetworkPolicy (default deny)
- Sadece onaylı registry + Cosign imza doğrulama
- Node’larda auditd (
-e 2) + docker.sock izleniyor - CDE cluster ayrımı veya tek cluster ise tüm cluster PCI scope kabulü
En Sık Denetim Bulguları
| Bulgu | Sonuç |
|---|---|
| 🔴 K8s API audit log YOK (sadece pod stdout) | PCI DSS 10.2 FAIL – kim ne yaptı bilinmiyor |
🔴 Audit policy’de secrets: RequestResponse |
Secret içeriği düz metin log’da – PCI 3.5/8.6 FAIL |
🔴 audit-log-mode=batch (blocking değil) |
Log yazılamazsa API çalışmaya devam eder |
| 🔴 Admission controller yok / Audit modda | Privileged pod deploy edilebiliyor |
🔴 privileged: true pod’lar production’da |
Container escape mümkün |
🔴 hostPath: / veya docker.sock mount |
Node tam kontrolü |
| 🔴 Default SA’da cluster-admin | Her pod cluster admin |
🔴 secrets-encryption kapalı |
etcd’de parolalar düz metin |
🔴 identity: {} config’de başta |
Hiçbir şey şifrelenmiyor (sessiz fail!) |
| 🔴 Pod restart’ta log kayboluyor | Log bütünlüğü yok |
🔴 K8S-Logging.Exclude On |
Pod kendini log’dan gizleyebiliyor |
| 🔴 CDE ve non-CDE aynı cluster, “segmente” deniyor | QSA kabul etmez – tüm cluster scope’a girer |
🔴 kubectl exec production CDE’de serbest |
10.2.1.2 – izlenemeyen ayrıcalıklı erişim |
| 🔴 PVC/StatefulSet silinebiliyor | 6493 – silme yasağı ihlali |
| 🟠 NetworkPolicy yok (default allow) | Segmentasyon yok |
| 🟠 Node’larda auditd yok | Container escape sonrası kör nokta |
Container/K8s – Sekiz Maddelik Ana İlke:
- Pod stdout ≠ Kubernetes Audit Log. K8s API audit = Windows Security Event Log muadili, zorunludur.
secretsaudit level = Metadata asla RequestResponse (içerik log’a düşer).audit-log-mode=blocking-strictlog yazılamıyorsa API isteği reddedilir.- Admission controller (Kyverno/OPA) Enforce modda riskli işlemler loglanmaz, ENGELLENİR.
- CDE için ayrı cluster tek cluster’da namespace izolasyonu QSA’ya segmentasyon olarak satılamaz.
kubectl execCDE’de yasak break-glass hariç; yapılırsa node auditd ile içerideki komutlar da yakalanmalı.- Log shipper silinemez/durdurulamaz – Kyverno policy + PCI DSS 10.7 alarmı.
- Ephemeral doğa = anında forward pod silinince log kaybolmamalı (disk-backed queue, sonsuz retry).
Bu yazıda container ve Kubernetes ortamında log güvenliğini; Kubernetes API audit ile pod stdout ayrımını, RKE2 audit policy’yi, Kyverno/OPA admission control’ü, etcd encryption’ı, Fluent Bit ile log toplamayı ve CDE cluster ayrımını ele aldık. Container ve Kubernetes – Bölüm 6 böylece tamamlandı.
Serinin bir sonraki yazısında “Bulut Loglama: AWS, Azure, GCP ve Veri Lokasyonu” konularına giriyoruz: CloudTrail/Activity Log/Cloud Audit kurgusu, data event’ler ve immutable storage.
Başka bir yazıda görüşmek dileğiyle…

