You are on page 1of 61

ÖZET

Güvenlik, geleneksel olarak, küçük veya büyük


ölçekli yazılım uygulamalarını çalıştırırken önemli
bir odak alanı olmuştur. Ancak, karmaşıklıktaki
çarpıcı artış ve yazılım geliştirme süreçlerindeki
dinamizm, Kubernetes güvenliğini daha da kritik
ve zor hale getirmektedir.

Container tabanlı uygulamaları gerçek ortamda


sorunsuz çalıştırmanın en önemli hususlarından
biri Kubernetes ortamının güvenliğinin
sağlanmasıdır. Bu nedenle, container tedarik
zincirinin güvenliğinden, denetim loglarının
tutulmasına, en az ayrıcalık ilkesine
uyulmasından, pod, container ve host
güvenliğinin sağlanmasını temin etmeye kadar
birçok bileşeni barındıran doğru bir Kubernetes
güvenlik metodolojisinin uygulanması ihtiyaçtan
öte zorunluluktur.
KUBERNETES
GÜVENLİĞİ Orhan Fikret DUMAN
MSc | CKA
Kubernetes Güvenliğine Yönelik Sıkılaştırma
Tedbirleri
İçindekiler
1. Giriş ........................................................................................................................................................ 2
2. Tehdit Modeli ........................................................................................................................................ 2
a. Tedarik Zinciri (Supply Chain) ........................................................................................................ 3
b. Kötü Amaçlı Tehdit Aktörü .............................................................................................................. 3
c. İç Tehdit. ............................................................................................................................................ 4
3. Pod Güvenliği........................................................................................................................................ 4
a. Non-root Container’lar ve Rootless Container Engine ............................................................... 4
b. Değiştirilemez (immutable-readonly) Container Dosya Sistemleri ........................................... 5
c. Güvenli Container İmajları Oluşturulması. ................................................................................... 6
ç. Pod Service Account Token’larının Korunması ......................................................................... 10
d. Container Ortamlarının Sıkılaştırılması....................................................................................... 10
4. Ağ Bölümleme ve Sıkılaştırma ......................................................................................................... 11
a. Namespace ..................................................................................................................................... 11
b. Temel Hususlar .............................................................................................................................. 12
(1) Kaynakların İzolasyonu için Network ve Resource Policy Kullanılması ........................ 12
(2) Controlplane’in Güvenliğinin Sağlanması .......................................................................... 15
(3) Hassas Verinin Kriptolanması .............................................................................................. 18
5. Kimlik Doğrulama ve Yetkilendirme (Authentication & Authorization) ........................................ 21
a. Kimlik Doğrulama (Authentication) .............................................................................................. 21
b. Role Based Access Control (RBAC) ........................................................................................... 22
6. Denetim Günlüğü ve Tehdit Algılama (Audit Logging & Threat Detection) ............................... 26
a. Logging ............................................................................................................................................ 26
(1) Kubernetes-native Denetim Günlüğü Yapılandırması ............................................................ 27
(2) Worker Node ve Container Logging .......................................................................................... 33
(3) Seccomp: audit mode .................................................................................................................. 34
(4) Syslog ............................................................................................................................................ 34
(5) SIEM Platformları ......................................................................................................................... 35
(6) Service Mesh ................................................................................................................................ 35
(7) Hata Toleransı (Fault Tolerance) ............................................................................................... 37
b. Tehdit Algılama (Threat Detection) ................................................................................................. 37
(1) Uyarılar (Alerting) ......................................................................................................................... 39
c. Araçlar (Tools) .................................................................................................................................... 40
7. Versiyon Yükseltme ve Uygulama Güvenliği Uygulamaları ......................................................... 41
8. Kubernetes Güvenliği Uygulama Adımları ..................................................................................... 42
Referanslar .................................................................................................................................................. 60

ORHAN FİKRET DUMAN 1 KUBERNETES GÜVENLİĞİ


KUBERNETES GÜVENLİĞİNE YÖNELİK
SIKILAŞTIRMA TEDBİRLERİ

1. Giriş:
Kubernetes, container tabanlı uygulamaları dağıtmayı (deployment), ölçeklendirmeyi
(scale) ve yönetmeyi (orchestration) otomatikleştirmek için kullanılan açık kaynaklı bir
container yönetim (Container Orchestration) platformudur. Aşağıdaki şekilde gösterildiği gibi,
bir uygulamadaki her bir mikroservisten, cluster’ın kendisine kadar, bir cluster’ı oluşturan tüm
bileşenleri yönetir. Container tabanlı uygulamaların mikroservisler olarak kullanılması,
monolitik yazılım platformlarına kıyasla daha fazla esneklik ve güvenlik avantajı sağlamakla
birlikte başka karmaşıklıkları da beraberinde getirebilmektedir.

Şekil 1: Kubernetes cluster bileşenlerinin üst düzey görünümü [1]


Dokümanın hazırlanmasında ağırlıklı olarak Mart/Ağustos 2022’de NSA ve CISA
tarafından yayımlanan “Kubernetes Hardening Guide”dan [1] faydalanılmış olmakla birlikte
farklı kaynaklardan yararlanılarak içerik zenginleştirilmiştir.
Bu dokümanda, container tabanlı uygulama altyapıları ve kubernetes platformlarındaki
güvenlik hususlarına odaklanılarak, bu hususlara yönelik güvenlik sıkılaştırma stratejileri
önerilmektedir. Aşağıda sunulan tedbirler, daha güvenli Kubernetes cluster’ları oluşturmaya
yardımcı olabilecek belirli güvenlik yapılandırmalarını ortaya koymaktadır.

2. Tehdit Modeli:
Kubernetes, kullanımının yaygınlaşmasıyla birlikte veri veya bilgi işlem gücü (compute
power) hırsızlığı için siber tehdit aktörleri arasında değerli bir hedef haline gelmektedir. Veri
hırsızlığı geleneksel olarak birincil motivasyon olsa da, hesaplama gücü (genellikle kripto para
madenciliği için) arayan siber aktörler de temel altyapıdan yararlanmak için Kubernetes
platformlarına saldırmaktadır. Kaynak hırsızlığına ek olarak, siber tehdit aktörleri Kubernetes'i
hedef alarak hizmet reddine (Denial of Service) neden olabilmektedir. Aşağıdaki tehditler, bir
Kubernetes cluster’ı için en olası hedeflerden bazılarını temsil etmektedir:

ORHAN FİKRET DUMAN 2 KUBERNETES GÜVENLİĞİ


a. Tedarik Zinciri (Supply Chain): Tedarik zincirine yönelik saldırı vektörleri
çeşitlidir ve hafifletilmesi zordur. Risk, düşmanın bir sistemi oluşturan herhangi bir unsuru
bozabilmesidir. Buna, ürünün elde edilmesine yardımcı olan ürün bileşenleri, hizmetler veya
personel dahildir. Ek tedarik zinciri riskleri, Kubernetes cluster’ını oluşturmak ve yönetmek için
kullanılan üçüncü taraf yazılımları ve satıcıları içerebilir. Tedarik zincirinin istismarı,
Kubernetes'i aşağıdakiler de dahil olmak üzere birden çok düzeyde etkileyebilir:
(1) Container/uygulama düzeyi: Kubernetes'te çalışan uygulamaların ve
üçüncü taraf bağımlılıklarının güvenliği, geliştiricilerin güvenilirliğine ve geliştirme altyapısının
savunmasına bağlıdır. Üçüncü bir taraftan gelen kötü amaçlı bir container veya uygulama,
siber aktörlere, cluster içerisinde bir dayanak noktası sağlayabilir.
(2) Container çalışma zamanı: Her node, depodan container imajlarını
indirmek için yüklenmiş bir container çalışma zamanına (container runtime) sahiptir. Bu
sayede, yerel sistem kaynaklarını izler, her bir container için sistem kaynaklarını yalıtır ve
container yaşam döngüsünü yönetir. Container çalışma zamanındaki bir güvenlik açığı,
containerlar arasında yetersiz bir izolasyona ve tehdidin yayılmasına neden olabilir.
(3) Altyapı: Kubernetes’i barındıran temel sistemlerin kendi yazılım ve
donanım bağımlılıkları vardır. Worker node’lar veya controlplane’in bir parçası olarak kullanılan
sistemlerin herhangi bir şekilde ele geçirilmesi, siber aktörlere cluster’da bir dayanak noktası
sağlayabilir.

Şekil 2: Cluster içerisine zararlı kodun giriş yaptığı Container tedarik zinciri örneği [1]
b. Kötü Amaçlı Tehdit Aktörü: Kötü niyetli aktörler, uzak bir konumdan erişim
elde etmek için genellikle güvenlik açıklarından veya sosyal mühendislikten çalınan kimlik
bilgilerinden yararlanır. Kubernetes mimarisi, siber aktörlerin uzaktan kullanım için potansiyel
olarak yararlanabilecekleri çeşitli API'ler sunar:
(1) Controlplane: Kubernetes controlplane, cluster’ı izlemek ve yönetmek
için iletişim kuran birçok bileşene sahiptir. Siber aktörler, uygun erişim kontrollerinden yoksun
açıktaki controlplane bileşenlerinden sıklıkla yararlanır.
(2) Worker Node: Bir container runtime engine’ini çalıştırmanın yanı sıra,
çalışan node’lar, siber aktörler tarafından potansiyel olarak yararlanılabilecek kubelet ve kube-
proxy hizmetini barındırır. Ek olarak, çalışan node’lar kapalı controlplane’in dışında bulunur ve
siber aktörler için daha erişilebilir olabilir.
(3) Container uygulamaları: Cluster içinde çalışan uygulamalar ortak
hedeflerdir. Cluster dışından sıklıkla erişilebilirler ve bu da onları uzaktaki siber aktörler
tarafından erişilebilir hale getirir. Bir aktör, daha sonra, güvenliği ihlal edilmiş bir Pod'dan
yararlanabilir veya dış erişime açık bir uygulamanın dahili olarak erişilebilir kaynaklarını
kullanarak cluster içindeki ayrıcalıkları yükseltebilir.

ORHAN FİKRET DUMAN 3 KUBERNETES GÜVENLİĞİ


c. İç Tehdit: Tehdit aktörleri, kurum personeline çalıştığı dönemde verilen özel
bilgi ve ayrıcalıkları istismar ederek cluster içindeki güvenlik açıklarından yararlanabilmekte
veya bireye verilen ayrıcalıkları istismar edebilmektedir.
(1) Yönetici (administrator): Kubernetes yöneticileri, container
ortamlarında komut yürütmek (command execution) de dahil olmak üzere, container’ların
çalıştırılması üzerinde denetime sahiptir. Kubernetes tarafından zorunlu kılınan rol tabanlı
erişim denetimi (RBAC) yetkilendirmesi, hassas yeteneklere erişimi kısıtlayarak riski azaltabilir.
Ancak, Kubernetes'te iki kişilik bütünlük denetimleri bulunmadığından, en az bir yönetici
hesabın cluster’ın denetimini yürütme yeteneğine sahip olması gerekir. Yöneticilerin genellikle
sistemlere veya hipervizörlere fiziksel erişimi vardır ve bunlar Kubernetes ortamının istismarı
için de kullanılabilir.
(2) Kullanıcı: Container tabanlı uygulama kullanıcıları, Kubernetes
cluster’ındaki container tabanlı hizmetlere erişmek için kimlik bilgilerine sahip olabilir. Bu erişim
düzeyi, uygulamanın kendisinden veya diğer cluster bileşenlerinden yararlanmak için yeterli
araçları sağlayabilir.
(3) Bulut hizmeti veya altyapı sağlayıcısı: Kubernetes node’larını
yöneten fiziksel sistemlere veya hipervizörlere erişim, bir Kubernetes ortamının istismarı için
kullanılabilir. Bulut Hizmet Sağlayıcıları (Cloud Service Provider - CSP), sistemleri ayrıcalıklı
yöneticilerden korumak için genellikle teknik ve idari denetim katmanlarına sahiptir.

3. Pod Güvenliği:
Pod'lar, yüklenebilen en küçük Kubernetes bileşenleridir ve Kubernetes ortamının yapı
taşıdır. Bir veya daha fazla container’dan oluşur. Pod’lar genellikle bir siber tehdit aktörünün
bir container’ın istismarından sonraki ilk yürütme ortamıdır. Bu nedenle, istismarı daha zor hale
getirmek ve başarılı bir istismarın etkisini sınırlamak için Pod'lar sıkılaştırılmalıdır. Aşağıdaki
şekilde, bir Pod'un bileşenleri ve olası saldırı yüzeyi gösterilmektedir:

Şekil 3: Pod Bileşenleri - (container + sidecar proxy  log container) [1]


a. Non-root Container’lar ve Rootless Container Engine: Uygulamaları “root”
yetkisinde çalıştırmak yerine “non-root” olarak çalıştıracak container’ların kullanılması
sağlanmalıdır. (USER parametresi ile)
Örnek Dockerfile:
FROM ubuntu:latest

ORHAN FİKRET DUMAN 4 KUBERNETES GÜVENLİĞİ


#Update and install the make utility
RUN apt update && apt install -y make
#Copy the source from a folder called “code” and build the application with
the make utility
COPY . /code
RUN make /code
#Create a new user (user1) and new group (group1); then switch into that
user’s context
RUN useradd user1 && groupadd group1
USER user1:group1
#Set the default entrypoint for the container
CMD /code/app

Container seviyesinde yapılan kullanıcı tanımı dışında Kubernetes ortamında


pod/container seviyesindeki aşağıdaki tanımlama ile “user” seviyesinde işlem yapılması
sağlanmalıdır.
“SecurityContext: runAsUser”
Yukarıdaki hususlar dışında (henüz geliştirilme aşamasında olması nedeniyle mümkün
olması durumunda) “rootless container engine” kullanımı da değerlendirilebilecektir.
b. Değiştirilemez (immutable-readonly) Container Dosya Sistemleri:
Uygulamaların çalışırlığını etkilemeyecek şekilde, container’ların değiştirilemez dosya
sistemleri (readonly - immutable file system) ile çalıştırılması sağlanmalıdır.
Varsayılan olarak, container’lara çoğunlukla kendi bünyelerinde sınırsız yürütmeye
(execution) izin verilmektedir. Bir container’da yürütme yetkisi kazanmış bir siber saldırgan,
dosyalar oluşturabilir, komut dosyaları indirebilir ve container içindeki uygulamayı değiştirebilir.
Kubernetes, bir container’ın dosya sistemini kilitleyebilir ve böylece birçok istismar sonrası
etkinliğini (post-exploitation activity) önleyebilir. Ancak, bu sınırlamalar gerçek container
uygulamalarını da etkileyebilmekte ve potansiyel olarak çökmelere veya anormal davranışlara
neden olabilmektedir
Kubernetes yöneticileri tarafından, meşru uygulamaların zarar görmesini önlemek için
uygulamaların yazma erişimi gerektirdiği belirli dizinler için “ikincil okuma/yazma dosya
sistemleri” tanımlanmalıdır.
Örnek “değiştirilemez” ve “ikincil” dosya sistemine sahip pod tanımı:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: web
name: web
spec:
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
name: web
spec:
containers:
- command: ["sleep"]
args: ["999"]
image: ubuntu:latest
name: web
securityContext: # ilave
readOnlyRootFilesystem: true # ilave
volumeMounts: # ilave

ORHAN FİKRET DUMAN 5 KUBERNETES GÜVENLİĞİ


- mountPath: /writeable/location/here # ilave
name: volName # ilave
volumes: # ilave
- emptyDir: {} # ilave
name: volName # ilave

c. Güvenli Container İmajları Oluşturulması: Container imajları genellikle ya


sıfırdan bir container oluşturularak ya da bir repo’dan alınan mevcut bir imajın üzerine inşa
edilerek oluşturulur. Geliştirici ortamındaki repository denetimleri, geliştiricilerin yalnızca
güvenilir repo’ları kullanmasını sağlayacak şekilde kısıtlamak için kullanılabilir. Belirli kontroller
ortama bağlı olarak değişir ancak hem kabul kontrolleri (admission controls) gibi platform
seviyesindeki kısıtlamaları hem de ağ seviyesindeki kısıtlamaları içerebilir. Kubernetes kabul
denetleyicileri (admission controllers), üçüncü taraf araçlar ve bazı bulut servis sağlayıcıları
(CSP) yerel çözümleri, cluster’da yalnızca dijital olarak imzalanmış imajların yürütülebilmesi
için girişi kısıtlayabilir.
Containerları oluşturmak için güvenilir depoları kullanmanın yanı sıra, imaj
tarama, dağıtılan containerların güvenli olmasını sağlamanın anahtarıdır. Container oluşturma
iş akışı boyunca, güncel olmayan kitaplıkları, bilinen güvenlik açıklarını veya güvenli olmayan
bağlantı noktaları veya izinler gibi yanlış yapılandırmaları belirlemek için imajlar taranmalıdır.
Bu maksatla kabul denetim araçları (admission controller) webhook olarak
tanımlanarak kullanılabilir. Bu araçlar ile organizasyonun güvenlik politikaları ile uyumlu
olmayan imajların kurulumları engellenebilmektedir.
Tarama, bilgili siber güvenlik uzmanlarının uyarıların yanlış olduğunu
düşündüğü durumlarda güvenlik açığı tespiti için yanlış pozitifleri (false positive) göz ardı etme
esnekliği de sağlamalıdır. Aşağıdaki şekilde gösterildiği gibi, imaj tarama işlemini uygulamaya
yönelik bir yaklaşım, bir kabul denetleyicisi (admission controller) kullanmaktır.
Kabul denetleyicisi, kurulum öncesinde, ancak isteğin kimliği doğrulandıktan
(authentication) ve yetkilendirildikten (authorization) sonra Kubernetes API'sine yapılan
istekleri durdurabilen ve işleyebilen Kubernetes'e özgü bir özelliktir. Cluster’da dağıtılmadan
önce herhangi bir imajı taramak için özel veya ticari bir webhook uygulanabilir. Bu kabul
denetleyicisi, imaj kuruluşun webhook yapılandırmasında tanımlanan güvenlik ilkeleriyle
uyumlu değilse dağıtımları engelleyebilmektedir.
Özet olarak, güvenli container imajları oluşturulması ve kullanımı sağlanmalıdır.
Bu maksatla, olası güvenlik açıkları veya yanlış yapılandırmaların önlenmesi için güvenilir
imaj repoları kullanılmalı ve container imajları zafiyet taramasından geçirilmelidir.

ORHAN FİKRET DUMAN 6 KUBERNETES GÜVENLİĞİ


Şekil 4: Sıkılaştırılmış container oluşturma iş akışı [1]

Örnek Pod güvenlik uygulaması:


Pod'larda güvenlik gereksinimlerinin uygulanması, iki mekanizma aracılığıyla
Kubernetes'te yerel olarak gerçekleştirilebilir:
(1) Pod Security Admission adlı beta1 sürüm özelliği: Production
Kubernetes yöneticileri, bu özellik Kubernetes sürüm 1.23'te varsayılan olarak
etkinleştirildiğinden Pod Security Admission'ı kullanmalıdır. Pod Security Admission, pod'ları
ayrıcalıklı (privileged), temel (baseline) ve kısıtlı (restricted) olarak sınıflandırmaya dayanır ve
PSP'lerden daha basit bir uygulama sağlar.
(2) Pod Security Policy (PSP) adı verilen kullanımdan kaldırılmış bir
özellik: Eski bir Kubernetes sürümü kullanılıyorsa ve Pod Security Admission’a geçiş
sırasında PSP kullanılıyorsa aşağıdaki örneğe uygun sıkılaştırmalar uygulanabilir:
Bir Pod Güvenlik İlkesi (PSP), Pod'ların cluster içinde çalıştırılması için güvenlik
gereksinimlerini/varsayılanlarını belirten cluster çapında (cluster-wide) bir ilkedir. Güvenlik
mekanizmaları genellikle pod/deployment yapılandırmalarında belirtilirken, PSP'ler tüm
Pod'ların uyması gereken bir minimum güvenlik eşiği belirler. Bazı PSP alanları, bir Pod
yapılandırmasında bir alan atlandığında kullanılan varsayılan değerleri sağlar. Diğer PSP
alanları, uygun olmayan Pod'ların oluşturulmasını reddetmek için kullanılır. PSP'ler bir
Kubernetes kabul denetleyicisi (admission controller) aracılığıyla uygulanır, bu nedenle
PSP'ler yalnızca Pod oluşturma sırasında gereksinimleri uygulayabilir. PSP'ler, cluster’da
halihazırda çalışan Pod'ları etkilemez.

ORHAN FİKRET DUMAN 7 KUBERNETES GÜVENLİĞİ


PSP'ler, cluster’da güvenlik önlemlerini uygulamak için yararlı teknik
kontrollerdir. PSP'ler, özellikle katmanlı rollere sahip yöneticiler tarafından yönetilen cluster’lar
için etkilidir. Bu durumlarda, üst düzey yöneticiler, gereksinimleri alt düzey yöneticilere
uygulamak için varsayılan bazı tanımları uygulayabilir.
PSP kaldırılmış bir özellik olsa da aşağıdaki tabloda belirtilen hususların
uygulanması önem arz etmektedir. Bu maksatla Pod Security Admission ihtiyaca göre farklı
seviyelerde kullanılabileceği gibi yöneticiler tarafından elle tanımlama da yapılabilir.

Alan (Field Name(s)) Kullanım (Usage) Öneriler (Recommendations)

Controls whether Pods


privileged can run privileged Set to false.
containers.

Controls whether
containers can share
hostPID, hostIPC Set to false.
host process
namespaces.

Controls whether
hostNetwork containers can use Set to false.
the host network.
Use a “dummy” path name
(such as “/foo” marked as
Limits containers to read-only). Omitting this
allowedHostPaths specific paths of the field results in no
host file system. admission restrictions
being placed on
containers.
Requires the use of a
readOnlyRootFilesystem read only root file Set to true when possible.
system.
- Set runAsUser to
Controls whether
MustRunAsNonRoot.
container
runAsUser, runAsGroup, - Set runAsGroup to non-
applications can run
supplementalGroups, zero
with root privileges
fsGroup - Set supplementalGroups
or with root group
to non-zero
membership.
- Set fsGroup to non-zero
Set to false. This measure
is required to effectively
Restricts escalation
allowPrivilegeEscalation enforce “runAsUser:
to root privileges.
MustRunAsNonRoot”
settings.
If the environment
Sets the SELinux supports SELinux, consider
seLinux context of the adding SELinux labeling to
container. further harden the
container.
Where possible, harden
Sets the AppArmor
containerized applications
AppArmor annotations profile used by
by employing AppArmor to
containers.
constrain exploitation.

ORHAN FİKRET DUMAN 8 KUBERNETES GÜVENLİĞİ


Where possible, use a
seccomp annotations seccomp auditing profile
(Artık annotations Sets the seccomp to identify required
yerine securityContext profile used to syscalls for running
içerisinde sandbox containers. applications; then enable
tanımlanmaktadır) a seccomp profile to block
all other syscalls.

Not: PSP'ler, aşağıdaki nedenlerle tüm cluster’a otomatik olarak uygulanmaz:


- PSP'lerin uygulanabilmesi için, kube-apiserver'ın bir parçası olan Kubernetes
kabul denetleyicisi için PodSecurityPolicy eklentisinin etkinleştirilmesi gerekir.
- Politika RBAC aracılığıyla yetkilendirilmelidir. Yöneticiler, cluster’larının
organizasyon içindeki her bir rolden, uygulanan PSP'lerin işlevselliğini doğrulamalıdır. Pod
oluşturma en az kısıtlayıcı yetkilendirme politikasına bağlı olduğundan, yöneticiler birden fazla
PSP'nin bulunduğu ortamlarda dikkatli olmalıdır. Aşağıdaki komut, verilen namespace için
çakışan sorunlu ilkeleri belirlemeye yardımcı olabilecek tüm Pod Güvenlik İlkelerini açıklar:
“kubectl get psp -n <namespace>”

Örnek Pod Security Policy:


apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: restricted
annotations:
seccomp.security.alpha.kubernetes.io/allowedProfileNames:
'docker/default,runtime/default'
apparmor.security.beta.kubernetes.io/allowedProfileNames:
'runtime/default'
seccomp.security.alpha.kubernetes.io/defaultProfileName:
'runtime/default'
apparmor.security.beta.kubernetes.io/defaultProfileName:
'runtime/default'
spec:
privileged: false #Yetki yükseltmeyi engellemek için gerekli
allowPrivilegeEscalation: false
requiredDropCapabilities:
- ALL
volumes:
- 'configMap'
- 'emptyDir'
- 'projected'
- 'secret'
- 'downwardAPI'
- 'persistentVolumeClaim'
hostNetwork: false
hostIPC: false
hostPID: false
runAsUser:
rule: 'MustRunAsNonRoot'
seLinux:
rule: 'RunAsAny'
supplementalGroups:
rule: 'MustRunAs'
ranges: # Root gruba ilaveyi engeller.

ORHAN FİKRET DUMAN 9 KUBERNETES GÜVENLİĞİ


- min: 1
max: 65535
runAsGroup:
rule: 'MustRunAs'
ranges: # Root gruba ilaveyi engeller.
- min: 1
max: 65535
fsGroup:
rule: 'MustRunAs'
ranges: # Root gruba ilaveyi engeller.
- min: 1
max: 65535
readOnlyRootFilesystem: true

(3) Yerel Kubernetes çözümlerine ek olarak, genellikle Kubernetes kabul


denetleyicileri olarak uygulanan üçüncü taraf çözümler, ek ayrıntılı politika denetimi
sağlayabilir. Bu çözümler bu belgenin kapsamı dışında olmakla birlikte, yöneticiler
(administrators) ihtiyaçları için en iyi çözümü belirlemek maksadıyla ortamları için mevcut
ürünleri araştırabilir.
ç. Pod Service Account Token’larının Korunması:
Varsayılan olarak, Kubernetes, bir Pod oluştururken otomatik olarak bir “service
account” ekler ve hesabın secret token’ını Pod'a mount eder. Kubernetes orkestrasyonu arka
planda gerçekleştiğinden, container tabanlı uygulamaların çoğu service account’a doğrudan
erişime ihtiyaç duymaz. Bir uygulamanın güvenliği ihlal edilirse, Pod'lardaki hesap token’ları
siber aktörler tarafından elde edilebilir ve cluster’ı istismar etmek için kullanılabilir.
Bir uygulamanın service account’una doğrudan erişmesi gerekmediğinde, Kubernetes
yöneticileri, Pod tanımlarında secret token’ların otomatik olarak mount edilmesini devre dışı
bırakmalıdır. Bu, Pod'un YAML tanımındaki "automountServiceAccountToken: false"
ifadesi kullanılarak gerçekleştirilebilir.
Bazı durumlarda, container tabanlı uygulamalar, bulut platformları gibi dış hizmetlerde
kimlik doğrulaması yapmak için sağlanan service account token’larını kullanır. Bu durumlarda,
hesap token’ını devre dışı bırakmak mümkün olmayabilir. Bunun yerine cluster yöneticileri,
cluster içindeki Pod ayrıcalıklarını kısıtlamak için RBAC'in uygulandığından emin olmalıdır.
d. Container Ortamlarının Sıkılaştırılması: Bazı platformlar ve container
engine’leri, container tabanlı ortamları sıkılaştırmak için ek seçenekler veya araçlar sağlar.
Örneğin:
(1) Hipervizör destekli container kullanımı: Hipervizörler, sanallaştırma
çerçevesini belirlemek için işletim sisteminden ziyade donanıma güvenir. Hipervizör
izolasyonu, geleneksel container izolasyonundan daha güvenlidir. Windows işletim sisteminde
çalışan container engine’leri, güvenliği artırmak için yerleşik Windows hipervizörü Hyper-V'yi
kullanacak şekilde yapılandırılabilir. Ek olarak, bazı güvenlik odaklı container engine’leri,
derinlemesine savunma için her bir container’ı hafif bir hipervisor içinde yerel olarak dağıtır.
Hipervizör destekli container’lar, container ile üzerinde çalıştığı sunucuların kernel’larının farklı
olması sayesinde, sistem çağrıları (syscall) ile siber tehdit aktörlerinin container üzerinden
sunuculara (host) geçişlerinin engellenmesini sağlar. Bu kapsamda, hipervizör destekli
container kullanımına kata container’lar örnek olarak gösterilebilir.
Kaynaklar:
https://katacontainers.io/ [2],
https://github.com/kata-containers/kata-containers/tree/main/docs/install [3],

ORHAN FİKRET DUMAN 10 KUBERNETES GÜVENLİĞİ


https://github.com/kata-containers/kata-
containers/tree/main/docs/design/architecture [4],
https://github.com/kata-containers/kata-containers/tree/main/docs/design [5]
(2) Çekirdek tabanlı çözümler: Varsayılan olarak devre dışı bırakılan
seccomp aracı, bir container’ın sistem çağrı (syscall) yeteneklerini sınırlamak için kullanılabilir,
böylece çekirdeğin saldırı yüzeyini (attack surface) düşürür. Seccomp, bir Pod security policy
aracılığıyla veya doğrudan security context kullanılarak uygulanabilir.
(3) Uygulama sandbox’ları: Bazı container engine çözümleri, container
tabanlı uygulama ile ana bilgisayar çekirdeği arasına bir izolasyon katmanı ekleme seçeneği
sunar. Bu izolasyon alanı, uygulamayı sanal bir sandbox içinde çalışmaya zorlayarak ana
bilgisayar işletim sistemini kötü niyetli veya yıkıcı işlemlerden korur. Bu yapıda, container’lar
üzerinde özelleştirilmiş ve sınırlandırılmış bir işletim sistemi çekirdeği ve runtime (runsc)
kullanır. Bu sayede container üzerinden yapılacak syscall’lar öncelikle container’a ait olan mini-
kernel’a iletilir. Sunucu kernel’ına yapılacak syscall özelleştirilerek ve filtrelenerek gönderilir.
Google tarafından geliştirilen gVisor uygulaması bu yapıya örnek olarak gösterilebilir.
Kaynaklar:
https://gvisor.dev/ [6]:
https://github.com/google/gvisor [7]:

4. Ağ Bölümleme ve Sıkılaştırma:

Cluster ağı (cluster networking), Kubernetes'in merkezi bir konseptidir. Container’lar,


Pod'lar, service’ler ve external service’ler arasındaki iletişim dikkate alınmalıdır. Varsayılan
olarak, Kubernetes kaynakları izole edilmemiştir ve bir cluster istismar edildiğinde, siber tehdit
aktörünün yatay hareketini (lateral movement) veya yetki yükseltmeyi (privilege escalation)
engellemez. Kaynak ayırma (resource seperation) ve şifreleme (encryption), bir siber tehdit
aktörünün cluster içindeki hareketini ve yetki yükseltmesini sınırlamanın etkili bir yolu olabilir.
a. Namespace:
Kubernetes namespace’leri, cluster kaynaklarını aynı cluster içindeki birden çok kişi,
ekip veya uygulama arasında bölmenin bir yoludur. Varsayılan olarak namespace’ler otomatik
olarak izole edilmemektedir. Ancak, namespace’ler, RBAC kuralları ile belirlenen yetkilendirme
tanımları ve network policy’ler aracılığıyla kullanılabilen bir kapsam (scope) belirler.
Namespace’e göre kaynaklara erişimi sınırlayan politikalara ek olarak, resource policy’ler,
namespace seviyesinde pod depolama alanlarını ve CPU kaynaklarını sınırlayabilir.
Varsayılan olarak üç ad alanı vardır ve bunlar silinemez:
- kube-system (Kubernetes bileşenleri için)
- kube-public (kamu kaynakları için)
- default (kullanıcı kaynakları için)
Kullanıcı podları, cluster hizmetleri için ayrıldığından kube-system veya kube-public
içine yerleştirilmemelidir.
Örnek bir namespace tanımı:
apiVersion: v1
kind: Namespace
metadata:

ORHAN FİKRET DUMAN 11 KUBERNETES GÜVENLİĞİ


name: <insert-namespace-name-here>

b. Temel Hususlar:
(1) Kaynakların İzolasyonu için Network Policy ve Resource Policy
Kullanılması:
(a) Network Policy: Pod’lara CNI (container network interface)
kurulumu ile belirlenen pod network içerisinden cluster’a özel (cluster-private) IP adresleri
atanır. Bu sayede, port tahsisi, isimlendirme, service discovery ve yük dengeleme açısından
sanal makinelere (VM'ler) veya fiziksel sunuculara benzer şekilde haberleşebilirler.
Kubernetes, Pod'ları farklı node’lar üzerine yerleştirebilir ve bir deployment içerisindeki sona
eren pod process’lerinin yerine yeni Pod'ları farklı node’lar üzerinde yeniden oluşturabilir.
Dolayısıyla, Pod IP adresleri yeniden oluşturulduğunda değişebilir, bu da uygulamaların Pod
IP'lerinin statik olmaması gerektiği anlamına gelir.
Bu dinamik yapıda, Pod IP adreslerinin değişmesi sorununu çözmek için
Kubernetes “service”leri kullanılır. Service, pod konfigürasyonunda kullanılan etiketler
vasıtasıyla seçilen mantıksal bir pod kümesine benzersiz bir IP adresi atamanın soyut bir
yoludur. Tahsis edilen servis IP adresi, servisin ömrüne bağlıdır ve servis çalışır durumda
olduğu müddetçe değişmeyecektir. Bir servise erişimde, yük, servisin üyesi olan pod
backend’leri arasında otomatik olarak dengelenir.
Service’ler, NodePort veya LoadBalancer servis tipleri kullanılarak harici
veya ClusterIP servis tipi ile dahili olarak sunulabilir. Bir servisi harici olarak kullanıma sunmak
için servisin, trafiği şifrelemek üzere TLS sertifikalarını kullanacak şekilde yapılandırılması
önemlidir. TLS yapılandırıldıktan sonra Kubernetes, servisi İnternet'e sunmanın iki yolunu
destekler: NodePort ve LoadBalancer.
Servis tanımına “type: NodePort” eklenerek, cluster’ın public IP adresi
ile birlikte kulanılacak rastgele bir bağlantı noktası (NodePort: 30000-32767) atanarak
İnternet’e çıkışı sağlanabilir. NodePort istenirse manuel olarak da atanabilir. Türü
LoadBalancer olarak değiştirerek harici bir yük dengeleyici ile birlikte kullanılabilir. Network
policy kullanımı ile giriş (ingress) ve çıkış (egress) trafiği kontrol edilebilir. Bir network policy
içerisinde servis adına göre tanımlama yapılamasa da, pod etiketleri (label) kullanılarak
tanımlama yapılabilir.
Network policy’ler, pod'lar, namespace’ler ve external IP adresleri
arasındaki trafik akışını kontrol eder. Varsayılan olarak, pod'lara veya namespace’lere hiçbir
network policy uygulanmaz ve bu da pod ağı içinde sınırlandırılmamış giriş ve çıkış trafiğine
neden olur. Pod’lar, pod veya pod’un namespace’i için geçerli olan bir network policy
aracılığıyla izole hale gelir. Bir network policy’nin uygulanacağı bir pod seçildiğinde, herhangi
bir geçerli politika objesi (policy object) tarafından özel olarak izin verilmeyen tüm bağlantıları
reddeder.
Network policy oluşturmak için NetworkPolicy API'sini destekleyen bir
container ağ arabirimi (CNI) eklentisi gereklidir. Pod’lar, podSelector ve/veya
namespaceSelector seçenekleri kullanılarak seçilir.
Örnek bir network policy: https://kubernetes.io/docs/tasks/administer-
cluster/declare-network-policy/ [8]
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: example-access-nginx

ORHAN FİKRET DUMAN 12 KUBERNETES GÜVENLİĞİ


namespace: prod # boş bırakılabilir.
spec:
podSelector:
matchLabels:
app: nginx
ingress:
-from:
-podSelector:
matchLabels:
access: “true”

Tanımlanan bu yeni “NetworkPolicy” aşağıdaki şekilde uygulanır:


“kubectl apply -f policy.yaml“

Default deny all ingress policy:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
spec:
podSelector: {}
policyType:
- Ingress

Default deny all egress policy:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-egress
spec:
podSelector: {}
policyType:
- Egress

Network Policy formatları, cluster için kullanılan CNI eklentisine bağlı


olarak farklılık gösterebilir. Yöneticiler, tüm giriş ve çıkış trafiğini reddetmek ve seçilmemiş
pod’ların izole edildiğinden emin olmak için tüm pod’ları seçen varsayılan bir politika
kullanmalıdır. İlave politikalar daha sonra izin verilen bağlantılar için bu kısıtlamaları
gevşetebilir.
Harici IP adresleri, “ipBlock” tanımı kullanılarak giriş ve çıkış ilkelerinde
kullanılabilir, ancak farklı CNI eklentileri, bulut sağlayıcıları veya servis uygulamaları,
NetworkPolicy işleme sırasını ve cluster içindeki adreslerin yeniden yazılmasını etkileyebilir.
Network policy’ler, ağ segmentasyonu oluşturmak için güvenlik duvarları
ve diğer harici araçlarla birlikte de kullanılabilir. Ağı ayrı alt ağlara veya güvenlik bölgelerine
bölmek, halka açık uygulamaları hassas dahili kaynaklardan yalıtmaya yardımcı olur. Ağ
segmentasyonunun en büyük faydalarından biri, saldırı yüzeyini ve yanal hareket fırsatını
sınırlamaktır. Kubernetes'te, saldırı yüzeyini sınırlamak ve uygulamaları veya kaynak türlerini
ayırmak için ağ segmentasyonu kullanılabilir.

ORHAN FİKRET DUMAN 13 KUBERNETES GÜVENLİĞİ


Network Policy Checklist:

1 Network Policy API’sini destekleyen bir CNI (weave, calico vb.) kullanılmalıdır.

Politika uygulanacak pod veya namespace’ler için podSelector veya namespaceSelector


2
yapıları kullanılmalıdır.

Tüm giriş (ingress) ve çıkış (egress) trafiğinin engellenmesi için default deny politikası
3 kullanılmalıdır. Bu sayede, politikada belirtilmeyen diğer tüm pod’ların kube-system haricindeki
tüm namespace’lere erişiminin engellenmesi teyit edilmiş olmaktadır.

LimitRange ve ResourceQuota politikaları ile pod veya namespace seviyesinde kaynak


4 kullanımı sınırlandırılmalıdır.

(b) Resource Policy: LimitRanges, ResourceQuotas ve Process


ID Limitleri; namespace’ler, node’lar veya pod'lar için kaynak kullanımını kısıtlar. Bu
politikalar, bir kaynak için işlem ve depolama alanı ayırmak ve kaynak tükenmesini önlemek
için önemlidir.
Bir LimitRange ilkesi, örneğin maksimum işlemci ve depolama
kaynaklarını zorunlu kılarak belirli bir namespace içindeki pod veya container başına tahsis
edilecek kaynakları kısıtlar. Her bir namespace için yalnızca bir LimitRange kısıtlaması
oluşturulabilir.
LimitRange desteği, Kubernetes 1.10 ve daha yeni sürümlerde
varsayılan olarak etkindir. Aşağıdaki YAML dosyası, her container için default request ve limit
değerinin yanı sıra minimum ve maksimum değerlerini içeren bir LimitRange belirtir.
Örnek “LimitRange” kullanımı:
apiVersion: v1
kind: LimitRange
metadata:
name: cpu-min-max-demo-lr
namespace: <namespace_name>
spec:
limits
- default:
cpu: 1
defaultRequest:
cpu: 0.5
max:
cpu: 2
min:
cpu 0.5
type: Container

“kubectl apply -f <example-LimitRange>.yaml” komutuyla oluşturulur.

Bu örnek LimitRange konfigürasyonu uygulandıktan sonra, namespace


içerisinde oluşturulan tüm container’lara varsayılan CPU request ve limit değerleri (ayrıca
belirtilmemişse) atanır. Namespace içerisindeki tüm container’lar, minimum değerden büyük
veya ona eşit ve maksimum CPU değerinden küçük veya ona eşit bir CPU isteğine sahip
olmalıdır, aksi takdirde container başlatılmaz.

ORHAN FİKRET DUMAN 14 KUBERNETES GÜVENLİĞİ


Her Pod veya container için ayrı ayrı uygulanan LimitRange ilkelerinin
aksine, ResourceQuotas, toplam CPU ve bellek kullanımına getirilen sınırlar gibi tüm
namespace için toplam kaynak kullanımına getirilen kısıtlamalardır.
Bir namespace içindeki toplu kaynak kullanımını sınırlamak için
ResourceQuota nesneleri, namespace’e bir YAML dosyası uygulanarak veya Pod'ların
yapılandırma dosyasında gereksinimler belirtilerek oluşturulur.
Örnek bir “ResourceQuota” politikası:
https://kubernetes.io/docs/tasks/administer-cluster/manage-
resources/quota-memory-cpu-namespace/ [9]
apiVersion: v1
kind: ResourceQuota
metadata:
name: example-cpu-mem-resourcequota
spec:
hard:
requests.cpu: “1”
requests.memory: 1Gi
limits.cpu: “2”
limits.memory: 2Gi

“kubectl apply -f example-cpu-mem-resourcequota.yaml --namespace=<insert-


namespace-here>” komutuyla oluşturulur.

“Bu ResourceQuota, seçilen namespace’e aşağıdaki kısıtlamaları uygular:

1. Her container’ın bir bellek isteği, sınırı, CPU isteği ve sınırı olmalıdır,

2. Tüm container’lar için toplam bellek talebi 1 GiB'ı geçmemelidir,

3. Tüm container’lar için toplam bellek limiti 2 GiB'ı geçmemelidir,

4. Tüm container’lar için toplam CPU talebi 1 CPU'yu geçmemelidir ve

5. Tüm container’lar için toplam CPU limiti 2 CPU'yu geçmemelidir.

Bir kullanıcı LimitRange veya ResourceQuota ilkesini ihlal eden bir Pod
oluşturmaya çalışırsa Pod oluşturma başarısız olur.”

İşlem kimlikleri (PID'ler), node’lar üzerinde temel bir kaynaktır ve diğer


kaynak sınırlarını ihlal etmeden tüketilebilir. PID tükenmesi, ana bilgisayar arka plan
programlarının (kubelet ve kube-proxy gibi) çalışmasını engeller. Yöneticiler, sistem kullanımı
ve Kubernetes system daemonları için belirli sayıda PID ayırmak için node PID limitlerini
kullanabilir. Pod PID limitleri, her Pod üzerinde çalışan işlemlerin sayısını sınırlamak için
kullanılır. Pod tahliye politikaları (pod eviction policies), hatalı davranan ve kaynakları anormal
tüketen bir container’ı sonlandırmak için kullanılabilir. Ancak tahliye politikaları periyodik olarak
hesaplanır ve uygulanır, bu nedenle limit değeri uygulanmaz.
(2) Controlplane’in Güvenliğinin Sağlanması:
Controlplane, Kubernetes'in çekirdeğidir ve kullanıcıların container’ları
görüntülemesine, yeni pod'lar planlamasına, secret’ları okumasına ve cluster içerisinde
komutları yürütmesine olanak tanır. Bu hassas yetenekler nedeniyle, controlplane yüksek
düzeyde korunmalıdır. TLS şifrelemesi, RBAC ve güçlü bir kimlik doğrulama yöntemi gibi
güvenli yapılandırmalara ek olarak, ağ ayırma (network seperation) yetkisiz kullanıcıların

ORHAN FİKRET DUMAN 15 KUBERNETES GÜVENLİĞİ


controlplane’e erişmesini önlemeye yardımcı olabilir. Kubernetes API sunucusu 6443 numaralı
bağlantı noktasında çalışmakta olduğundan, bu bağlantı noktasına erişimde yalnızca beklenen
trafiğe izin verilmesini sağlamak üzere bir güvenlik duvarı konumlandırılmalıdır. Kubernetes
API sunucusu, İnternet'e veya güvenilmeyen bir ağa maruz bırakılmamalıdır. Kube-system
namespace’i cluster içinde tüm controlplane bileşenleri ve worker node’lar ile konuşabilmeli,
ancak dış erişimlere kapatılmalıdır. Kube-system namespace’ine internet üzerinden erişimi
sınırlamak için kube-system namespace’i için network policy uygulanmalıdır. Tüm
namespace’ler için varsayılan bir reddetme ilkesi (default deny) uygulandığı durumlarda, kube-
system namespace’inin diğer controlplane bileşenleri ve worker node’lar ile iletişim kurabilmesi
sağlanmalıdır.

Aşağıdaki tablo, controlplane bileşenlerinin kullandığı port ve servisleri listelemektedir:

Protocol Trafik Yönü Port Aralığı Controlplane Bileşeni

TCP Inbound 6443 Kubernetes API server

TCP Inbound 2379-2380 etcd server client API

TCP Inbound 10250 kubelet API

TCP Inbound 10259 kube-scheduler

TCP Inbound 10257 kube-controller-manager

Controlplane Güvenliği İçin Yapılması Gereken Hususlar

1 TLS şifrelemesini ayarlanmalıdır.

2 Güçlü kimlik doğrulama yöntemleri ayarlanmalıdır.

3 İnternete ve gereksiz veya güvenilmeyen ağlara erişim devre dışı bırakılmalıdır.

4 Erişimi kısıtlamak için RBAC ilkeleri kullanılmalıdır.

5 Etcd veri deposu kimlik doğrulama ve RBAC ilkeleriyle korunmalıdır.

6 Kubeconfig dosyaları yetkisiz değişikliklerden korunmalıdır.

Kritik Controlplane Bileşenleri:


Etcd: Etcd backend veritabanı, durum (state) bilgilerini ve cluster içerisindeki
secret’ları depolar. Bu kritik bir controlplane bileşenidir ve etcd'ye yazma erişimi kazanmak, bir
siber aktörün tüm cluster’a root erişimi kazanmasını sağlayabilir. Bu nedenle güvenliği
sağlanması gereken en önemli controlplane bileşenidir.

ORHAN FİKRET DUMAN 16 KUBERNETES GÜVENLİĞİ


Etcd sunucusu, yalnızca API sunucusuna atanan sertifikalara güvenecek
şekilde yapılandırılmalıdır.
Etcd, ayrı bir controlplane node’unda çalıştırılabilir ve bir güvenlik
duvarının yalnızca API sunucularına erişecek şekilde yapılandırılmasıyla atak yüzeyi
sınırlandırılabilir. Burada ayrıca API sunucusu için cluster kimlik doğrulama yöntemi ve RBAC
politikaları ile kullanıcı yetkileri kısıtlanmalıdır.
Cluster admin’leri tarafından, etcd sunucusu ve API sunucuları arasında HTTPS
iletişimini zorlamak için TLS sertifikaları yapılandırılmalıdır.
Varsayılan olarak root CA tarafından verilen tüm sertifikalara güvendiğinden,
etcd için ayrı bir sertifika yetkilisi (CA) kullanmak güvenlik yönünden faydalı artırabilir.
Sertifika tabanlı kimlik doğrulama süreçlerinde harici bir Vault (HashiCorp
Vault vb.) kullanımı ile sertifika üretim, dağıtım ve yenileme süreçleri daha güvenli hale
getirilebilir.
Kubeconfig Dosyaları: Kubeconfig dosyaları, cluster’lar, kullanıcılar,
namespace’ler ve kimlik doğrulama mekanizmaları hakkında hassas bilgiler içerir.
Kubectl, worker node ve controlplane yerel makinelerinde $HOME/.kube
dizininde depolanan yapılandırma dosyalarını kullanır. Siber aktörler, kimlik bilgilerini elde
ederek erişim yetkisi kazanmak veya yapılandırmaları değiştirmek için bu yapılandırma
dizinine erişimden yararlanabilir. Yapılandırma dosyaları, istenmeyen değişikliklerden
korunmalı ve kimliği doğrulanmamış root olmayan kullanıcıların dosyalara erişimi
engellenmelidir.
Worker Node segmentasyonu: Bir worker node, cluster kurulumuna bağlı
olarak sanal veya fiziksel bir makine olabilir. Node’lar microservice’leri çalıştırdığından ve
cluster’daki web uygulamalarını barındırdığından, genellikle istismarların (exploit) hedefidir.
Bir node’un güvenliği ihlal edilirse, yönetici worker node’u diğer worker
node’lardan veya Kubernetes servisleri ile iletişim kurması gerekmeyen diğer ağ
kesimlerinden ayırarak saldırı yüzeyini proaktif olarak sınırlandırmalıdır.
Ağa bağlı olarak, dahili ağ kesimlerini dış ağa dönük (external-facing) çalışan
node’lardan veya tüm Kubernetes hizmetinden ayırmak için bir güvenlik duvarı kullanılabilir.
Worker node’ların olası saldırı yüzeyinden ayrılması gerekebilecek hizmetlere örnekler, gizli
veritabanları veya internet erişimi olması gerekmeyen dahili hizmetlerdir.

Aşağıdaki tablo, worker node bileşenlerinin kullandığı port ve servisleri listelemektedir:

Protocol Trafik Yönü Port Aralığı Worker Node Bileşeni

TCP Inbound 10250 Kubelet API

TCP Inbound 30000-32767 NodePort Services

ORHAN FİKRET DUMAN 17 KUBERNETES GÜVENLİĞİ


(3) Hassas Verinin Kriptolanması:
Yöneticiler, Kubernetes cluster’ındaki tüm trafiği (bileşenler, node’lar ve
controlplane dahil) TLS 1.2 veya 1.3 şifrelemesini kullanacak şekilde yapılandırmalıdır.
Şifreleme, kurulum sırasında veya sonrasında, sertifikaları oluşturmak ve node’lara dağıtmak
için Kubernetes belgelerinde ayrıntılı olarak açıklanan TLS önyüklemesi (TLS bootstrapping)
kullanılarak ayarlanabilir. Tüm yöntemlerde, güvenli bir şekilde iletişim kurmak için sertifikaların
düğümler arasında dağıtılması gerekir.
Secret Verilerinin Korunması:
Kubernetes secret’ları, parolalar, OAuth token’ları ve secure shell (SSH)
anahtarları gibi hassas bilgileri tutar.
Hassas bilgileri secret’larda depolamak, parolaları veya token’ları YAML
dosyalarında, container imajlarında veya ortam değişkenlerinde (environment variables)
saklamaktan daha fazla erişim denetimi sağlar. Secret bileşenine RBAC ilkeleri uygulanarak
erişim kısıtlanabilse de, varsayılan olarak Kubernetes, secret’ları, API erişimi olan herkes
tarafından elde edilebilen, şifrelenmemiş (unencrypted) base64 ile kodlanmış string
datası olarak depolar.

Secret’lar, API sunucusunda duran veri (data-at-rest) şifrelemesi


yapılandırılarak veya bir bulut sağlayıcısı aracılığıyla sağlanabilecek harici bir anahtar yönetim
hizmeti (KMS) kullanılarak şifrelenebilir. API sunucusunu kullanarak duran veri şifrelemesini
etkinleştirmek için, yöneticilerin kube-apserver bildirim dosyasını “--encryption-provider-
config” bağımsız değişkenini kullanarak yürütülecek şekilde değiştirmesi gerekir.
‘Secret data at rest’ verilerini şifrelemek için, aşağıdaki şifreleme yapılandırma
dosyası, istenen şifreleme türünü ve şifreleme anahtarını belirtmek için bir örnek sağlar.
Şifreleme anahtarının şifreleme dosyasında saklanması güvenliği yalnızca biraz artırır. Secret
şifrelenecek, ancak anahtara EncryptionConfiguration dosyasından erişilebilecektir. Bu
nedenle şifreleme anahtarının harici bir Vault (HashiCorp Vault vb.) veya Cloud KMS gibi
hizmetlerle harici ortamda tutulması sağlanmalıdır.
Örnek bir Secret (data-at-rest) şifrelemesi aşağıdadır:
https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data [10]
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: <base 64 encoded secret>
- identity: {}

Bu şifreleme dosyasıyla “secret data at rest” verilerini şifrelemeyi etkinleştirmek


için, API sunucusunun --encryption-provider-config tanımının config datasının konumunu
gösterecek şekilde ayarlanması, sonrasında API server’ın yeniden başlatılması
gerekmektedir.

ORHAN FİKRET DUMAN 18 KUBERNETES GÜVENLİĞİ


Şifreleme anahtarını korumak için bir KMS provider kullanmak, ham şifreleme
anahtarının yerel diskte depolanmasını engeller. Secret’ları bir KMS provider ile şifrelemek
için, “encryption-provider-config” dosyası KMS provider’ını belirtmelidir.
Örnek bir KMS Provider ile şifreleme aşağıdadır:
https://kubernetes.io/docs/tasks/administer-cluster/kms-provider [11]
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- kms:
name: myKMSPlugin
endpoint: unix://tmp/socketfile.sock
cachesize: 100
timeout: 3s
- identity: {}

Secret’ları bir KMS provider ile şifrelemek için, “encryption-provider-config”


dosyası KMS provider’ını belirtmeli, API sunucusunun --encryption-provider-config
tanımının config datasının konumunu gösterecek şekilde ayarlanması, sonrasında API
server’ın yeniden başlatılması gerekmektedir.
Yerel bir şifreleme sağlayıcısından KMS'ye geçmek için, aşağıda gösterildiği
gibi, EncryptionConfiguration dosyasının KMS sağlayıcı bölümü mevcut şifreleme yönteminin
üzerine eklenmelidir.
Örnek bir KMS + yerel şifreleme sağlayıcısı konfigürasyonu aşağıdadır:
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- kms:
name: myKMSPlugin
endpoint: unix://tmp/socketfile.sock
cachesize: 100
timeout: 3s
- aescbc:
keys:
- name: key1
secret: <base64 encoded secret>

Şifreleme konfigürasyonu yapılmadan önceki secret verileri de dahil


olmak üzere tüm secret’ların yeniden şifrelenmesini sağlamak maksadıyla API
sunucusunun yeniden başlatılıp, aşağıdaki komutun çalıştırılması yeterli olacaktır.
 kubectl get secrets --all-namespaces -o json | kubectl replace -f – 

ORHAN FİKRET DUMAN 19 KUBERNETES GÜVENLİĞİ


Hassas Bulut Altyapısı Verilerinin Korunması:
Kubernetes genellikle bulut ortamındaki sanal makineler üzerine kurulmaktadır.
Bu nedenle yöneticiler, Kubernetes worker node’larının üzerinde çalıştığı VM'lerin saldırı
yüzeyini dikkatle değerlendirmelidir.
Çoğu durumda, bu VM'lerde çalışan Pod'lar, yönlendirilemez bir adresteki
hassas bulut meta veri (cloud metadata) hizmetlerine erişime sahiptir. Bu meta veri hizmetleri,
siber aktörlere bulut altyapısı hakkında bilgi ve hatta bulut kaynakları için muhtemelen kısa
ömürlü kimlik bilgileri (short-lived credentials) sağlar.
Siber aktörler, ayrıcalık yükseltme (privilege escalation) için bu meta veri
hizmetlerini kötüye kullanır. Kubernetes yöneticileri, network policy’leri kullanarak veya bulut
yapılandırma politikaları (cloud configuration policy) aracılığıyla Pod'ların bulut meta veri
hizmetlerine erişmesini engellemelidir. Bu hizmetler bulut sağlayıcısına göre değişiklik
gösterdiğinden, yöneticiler bu erişim vektörlerini sağlamlaştırmak için hizmet sağlayıcı
kılavuzunu izlemelidir.
Örnek cloud metadata network policy tanımları aşağıdadır:
- Default namespace’de yer alan tüm pod’ların dışarıya erişimlerine izin veren
ancak metadata sunucusuna erişimlerini engelleyen politika:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: cloud-metadata-deny
namespace: default
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 169.254.169.254/32 # Cloud metadata server IP

- Sadece belirli etikete (metadata-erisim) sahip pod’ların cloud metadata


sunucusuna erişimine izin veren politika tanımı:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: cloud-metadata-allow
namespace: default
spec:
podSelector:
matchLabels:
role: metadata-erisim
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 169.254.169.254/32 # Cloud metadata server IP

ORHAN FİKRET DUMAN 20 KUBERNETES GÜVENLİĞİ


5. Kimlik Doğrulama ve Yetkilendirme (Authentication & Authorization):
Kimlik doğrulama ve yetkilendirme, cluster kaynaklarına erişimi kısıtlamak için birincil
mekanizmalardır. Siber aktörler, bilinen Kubernetes portlarını tarayabilir ve cluster’ın
veritabanına erişebilir veya cluster yanlış yapılandırılmışsa, kimliği doğrulanmadan
(anonymous) API çağrıları yapabilir. Birkaç kullanıcı kimlik doğrulama mekanizması
desteklenmektedir ancak varsayılan olarak etkinleştirilmemektedir.
a. Kimlik Doğrulama (Authentication):
Kubernetes cluster’larında iki tür kullanıcı bulunur:
- Service account,
- User account.
Service account’ları, API isteklerini container’lar adına işler. Kimlik doğrulama,
genellikle Kubernetes tarafından, bearer token’lar kullanılarak ServiceAccount Admission
Controller aracılığıyla otomatik olarak yönetilir.
Kabul denetleyicisi etkin olduğunda, Pod'ların eklenmiş bir service account’u
olup olmadığını kontrol eder. Pod tanımında bir service account yer almıyorsa, admission
controller ilgili namespace için varsayılan service account’u otomatik olarak ekler.
Pod tanımı veya service account yapılandırması,
“automountServiceAccountToken” ayarını “false” olarak ayarlayarak service token’ın
eklenmesini engelliyorsa, admission controller varsayılan service account’unu eklemeyecektir.
Service Account’ları, belirli izinler vermek için ayrı ayrı da oluşturulabilir.
Kubernetes, service account’unu oluşturduğunda, bir service account secret’ı oluşturulur ve
pod’un secret’ı kullanabilmesi için pod’u otomatik olarak günceller (mount eder).
Service Account Token Secret, API'ye erişmek için kimlik bilgilerini (credentials)
içerir. Yetersiz güvenlik altında veya şifrelenmemiş bırakılırsa, service account secret’ları,
saldırganlar tarafından cluster dışından kullanılabilir. Bu risk nedeniyle, Pod secret’larına
erişim, RBAC kullanılarak kısıtlanmalı ve yalnızca bu secret’ları görüntülemesi gereken
kişilerle sınırlandırılmalıdır.
Normal kullanıcılar ve yönetici hesapları için otomatik bir kimlik doğrulama
yöntemi yoktur. Yöneticiler, bir kimlik doğrulama yöntemi uygulamalı veya üçüncü taraf bir
hizmete kimlik doğrulama yetkisi vermelidir.
Kubernetes, cluster’dan bağımsız bir hizmetin kullanıcı kimlik doğrulamasını
yönettiğini varsayar. Kubernetes belgeleri, X509 client sertifikaları, bootstrap token’ları ve
OpenID token’ları dahil olmak üzere kullanıcı kimlik doğrulamasını uygulamanın çeşitli yollarını
listeler.
En az bir kullanıcı kimlik doğrulama yöntemi uygulanmalıdır. Birden çok kimlik
doğrulama yöntemi uygulandığında, isteği başarıyla doğrulayan ilk modülde kimlik doğrulama
işlemi başarıyla sonlanır. Zayıf yöntemler, siber aktörlerin meşru kullanıcılar olarak kimlik
doğrulamasına izin verebileceğinden, yöneticiler statik parola dosyaları gibi zayıf yöntemleri
kullanmamalıdır.
Anonim istekler, yapılandırılmış kimlik doğrulama yöntemleri tarafından
reddedilmeyen ve herhangi bir bireysel kullanıcıya veya Pod'a bağlı olmayan isteklerdir.

ORHAN FİKRET DUMAN 21 KUBERNETES GÜVENLİĞİ


Anonim isteklerin etkinleştirildiği bir sunucu kurulumunda, içeriğinde token
bulunmayan bir istek, anonim bir istek olarak gerçekleştirilecektir. Kubernetes 1.6 ve daha yeni
sürümlerde, anonim istekler (anonymous request) varsayılan olarak etkindir (enabled).
RBAC etkinleştirildiğinde, anonim istekler “system:anonymous” kullanıcısı
veya “system:unauthenticated” grubu için açık yetkilendirme gerektirir. API
sunucusunda “--anonymous-auth=false” seçeneği ilave edilerek anonim istekler devre dışı
bırakılmalıdır. Anonim istekleri etkin bırakmak, bir siber aktörün kimlik doğrulaması olmadan
küme kaynaklarına erişmesine izin verebilir.
b. Role Based Access Control (RBAC):
Kubernetes servis hesapları (service accounts), user’lar ve group’lar
Kubernetes bileşenlerini yönetmek için kube-apiserver’la iletişim halindedirler. RBAC
etkinleştirilerek, farklı kullanıcı ve servis hesaplarının Kubernetes nesneleri üzerinde farklı
yetkilerde işlem yapabilmeleri sağlanır. Örneğin, “system:masters” grubundaki kullanıcılar
“cluster-admin” rolü yetkilerine sahip olduğundan tüm Kubernetes cluster’ı üzerinde işlem
yapabilirken, “system:kube-proxy” grubundaki kullanıcılar yalnızca “kube-proxy” bileşeninin
ihtiyaç duyduğu kaynak üzerinde işlem yapabilirler. [12]
Varsayılan olarak etkinleştirilen RBAC, bir organizasyon içindeki bireylerin
rollerine dayalı olarak küme kaynaklarına erişimini denetleme yöntemidir.
RBAC, user ve service account’larına erişimi kısıtlamak için kullanılabilir.
Kubectl kullanan bir cluster’da RBAC'in etkinleştirilip etkinleştirilmediğini kontrol etmek için
“kubectl api-version” komutu çalıştırılır. RBAC etkinleştirilmişse
“.rbac.authorization.k8s.io/v1” için API sürümü listelenir.

Cloud Kubernetes hizmetlerinin, küme için RBAC'in etkinleştirilip


etkinleştirilmediğini kontrol etmek üzere farklı bir yöntemi olabilir.
RBAC etkin değilse, API sunucusu aşağıdaki komutta “--authorization-
mode” flag’iyle başlatılmalıdır:

“kube-apiserver --authorization-mode=RBAC”

“AlwaysAllow” gibi “authorization-mode” flag’lerini yerinde bırakmak, tüm


yetkilendirme isteklerine izin vererek, yetkilendirmeyi devre dışı bırakır ve erişim için “least
privilege” ilkesini uygulama yeteneğini ortadan kaldırır.
İki tür yetki ayarlanabilir:
- Roles: Namespace seviyesinde yetki tanımlamaları için kullanılır.
- ClusterRoles: Tüm cluster kaynakları için yetki tanımlamaları için kullanılır.
Tüm namespace’leri kapsar.
Hem “Roles” hem de “ClusterRoles” yalnızca yetki tanımlamak için kullanılabilir.
Bu araçlarla yetki iptali/engellemesi yapılamaz. Bir cluster RBAC kullanacak şekilde
yapılandırılırsa ve anonim erişim devre dışı bırakılırsa Kubernetes API sunucusu, açıkça izin
verilmeyen tüm yetkileri reddeder.
Örnek bir “Role” tanımı aşağıdadır: Bu rol (pod-reader) ile namespace-a
içerisinde pod’ların görüntülenmesi ve listelenmesi (get,watch,list) için yetki tanımı yapılmıştır.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:

ORHAN FİKRET DUMAN 22 KUBERNETES GÜVENLİĞİ


namespace: namespace-a
name: pod-reader
rules:
- apiGroups: [“”] # “” core API group
resources: [“pods”]
verbs: [“get”, “watch”, “list”]

“kubectl apply -f role.yaml” komutuyla tanımlanır.

Cluster genelinde tüm namespace’lerde pod’ların görüntülenmesi ve


listelenmesi (get,watch,list) için yapılan yetki tanımı aşağıdadır:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata: default
name: global-pod-reader # Clusterrole’de namespace alanı
bulunmaz.
rules:
- apiGroups: [“”] # “” core API group
resources: [“pods”]
verbs: [“get”, “watch”, “list”]

“kubectl apply -f clusterrole.yaml” komutuyla tanımlanır.

“Role” veya “ClusterRole” yetki tanımlar ancak yetkiyi bir kullanıcıya bağlamaz.
Aşağıdaki şekilde gösterildiği gibi, “RoleBindings” ve “ClusterRoleBindings”, bir “Role” veya
“ClusterRole”ü bir kullanıcı, grup veya service account’una bağlamak için kullanılır.
“RoleBindings”, tanımlanmış bir namespace’deki kullanıcılara, gruplara veya service
account’lara “Roles” veya “ClusterRoles” yetkilerini bağlar.
“ClusterRoles”, namespace’lerden bağımsız olarak oluşturulur ve namespace
kapsamını sınırlamak için bir “RoleBinding” ile birlikte birden çok kez kullanılabilir. Bu,
kullanıcılar, gruplar veya service account’lar birden çok namespace’de benzer yetkilere ihtiyaç
duyduğunda kullanışlıdır. Bir “ClusterRole”, kapsamı, farklı bireysel kullanıcılar, gruplar veya
service account’lar ile sınırlamak için farklı “RoleBindings” ile birkaç kez kullanılabilir.
“ClusterRoleBindings”, tüm cluster kaynaklarında tanımlanan kullanıcılara, gruplara
veya service account’lara “ClusterRoles” yetkilerini sağlar.

ORHAN FİKRET DUMAN 23 KUBERNETES GÜVENLİĞİ


Şekil 5: Role/ClusterRole binding alternatifleri [1]

Mümkün olan Role, ClusterRole, RoleBinding ve ClusterRoleBinding kombinasyonları:


- Role + RoleBinding  Namespace seviyesi yetki erişimi
- ClusterRole + RoleBinding  Namespace seviyesi yetki erişimi
- ClusterRole + ClusterRoleBinding  Cluster seviyesi yetki erişimi
Not: Role + ClusterRoleBinding mümkün değildir. Role, namespace seviyesinde yetki
tanımlarken, clusterrolebinding cluster seviyesinde yetki bağlar. Bu nedenle tanımlanamaz.
Örnek RoleBinding tanımı aşağıdadır:
Bu role-binding “ali” kullanıcısına “namespace-a” içerisinde pod görüntüleme, okuma,
listeleme yetkisi vermektedir. Öncesinden aynı namespace içerisinde “pod-reader” adında bir
Role tanımlanmış olmalıdır.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: namespace-a
subjects:
- kind: User # Birden fazla “subject” tanımlanabilir.
name: ali # “name” case sensitive’dir.
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role # Bu alan bir Role veya ClusterRole olabilir.
name: pod-reader
apiGroup: rbac.authorization.k8s.io

ORHAN FİKRET DUMAN 24 KUBERNETES GÜVENLİĞİ


“roleRef” Role/ClusterRole’a bağlantıyı yapar. Bu alan bağlayacağımız tanımlı
Role/ClusterRole adıyla aynı olmalıdır.

“kubectl apply -f rolebinding.yaml” komutuyla tanımlanır.

Örnek ClusterRoleBinding tanımı aşağıdadır:


# Bu clusterrolebinding tanımı “yonetici” grubundaki herkese tüm
namespace’lerdeki pod’ları okuma yetkisi vermektedir.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: global-pod-reader
subjects:
- kind: Group # Birden fazla “subject” tanımlanabilir.
name: yonetici # “name” case sensitive’dir.
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole # Role veya ClusterRole olmalıdır.
name: global-pod-reader # Bağlanacak rolle aynı adda olmalıdır.
apiGroup: rbac.authorization.k8s.io
# “roleRef” Role/ClusterRole’a bağlantıyı yapar.

“kubectl apply -f clusterrolebinding.yaml” komutuyla tanımlanır.

“Roles” ve “ClusterRoles” oluşturmak veya güncellemek için, bir kullanıcının aynı


kapsamda yeni rolde bulunan izinlere sahip olması veya rbac.authorization.k8s.io API
grubundaki Roles veya ClusterRoles kaynaklarında yükseltme fiilini gerçekleştirmek için açık
izne sahip olması gerekir. Bir binding tanımı oluşturulduktan sonra “Role” veya
“ClusterRole” değiştirilemezdir. Bir rolü değiştirmek için binding tanımı silinmelidir.

Kullanıcılara, gruplara ve service account’lara atanan ayrıcalıklar, görevleri


tamamlamak için yalnızca gerekli izinlere yetki vererek en az ayrıcalık ilkesini (least privilege
principle) takip etmelidir. Kullanıcı grupları, Rol oluşturmayı yönetmeyi kolaylaştırabilir.
Kullanıcılar, yöneticiler, geliştiriciler ve altyapı ekibi gibi farklı gruplar için farklı izinler
gerekir. Her grubun farklı kaynaklara erişmesi gerekir ve diğer grupların kaynaklarını
düzenleme veya görüntüleme izni olmamalıdır. Kullanıcılar, kullanıcı grupları ve service
account’ları, etkileşimde bulunmak ve gerekli kaynakların bulunduğu belirli namespace’leri
görüntülemek için sınırlandırılmalıdır.
Kubernetes API'sine erişim için gerekli yetki tanımları, uygun API “request verb”leri ve
istenen kaynak (resource) tanımları ile bir RBAC “Role” veya “ClusterRole” oluşturularak
sınırlandırılır. Tanımlı kullanıcı, grup ve service account’larını kendilerine atanmış Role ve
ClusterRole tanımları ile görüntüleyerek RBAC ilkelerini denetlemeye yardımcı olabilecek
araçlar mevcuttur.

ORHAN FİKRET DUMAN 25 KUBERNETES GÜVENLİĞİ


6. Denetim Günlüğü ve Tehdit Algılama (Audit Logging & Threat Detection):
Denetim günlükleri, cluster içerisindeki her türlü etkinliği tespit eder. Etkin bir günlük
kaydı çözümü ve günlük incelemesi, yalnızca hizmetlerin amaçlandığı şekilde çalışmasını ve
yapılandırılmasını sağlamak için değil, aynı zamanda sistemin güvenliğini sağlamak için de
gereklidir.
Sistematik güvenlik denetimi gereksinimleri, güvenlik ihlallerinin belirlenmesine
yardımcı olmak için güvenlik ayarlarının tutarlı ve kapsamlı kontrollerini zorunlu kılar.
Kubernetes, cluster içerisindeki her türlü işlem ile temel CPU ve bellek kullanım
bilgilerini izlemek için denetim günlüklerini yakalayabilir. Ancak Kubernetes, native olarak
kapsamlı bir izleme veya uyarı hizmeti sağlamaz. Bu maksatla açık kaynak veya üçüncü parti
ürünler kullanılabilir.

Audit Log’lar için Önemli Hususlar

Anormal etkinlik tanımlamasını etkinleştirmek için oluşturma sırasında Pod


1
baseline’ları oluşturun.

2 Cluster’ın tüm seviyelerinde günlük kaydı gerçekleştirin.

Toplu taramalar, izleme, uyarılar ve analiz için mevcut ağ güvenliği araçlarını


3
entegre edin.

Bir arıza durumunda günlük kaybını önlemek için hataya dayanıklı politikalar
4
ayarlayın.

a. Logging:
Kubernetes içinde uygulama çalıştıran sistem yöneticileri, cluster’ları için etkili
bir loglama ve izleme sistemi oluşturmalıdır. Kubernetes olaylarının günlüğe kaydedilmesi,
sistemde meydana gelen eylemlerin tam bir resmini sağlamak için tek başına yeterli değildir.
Loglama, uygun olduğu şekilde sunucu, uygulama, container, container engine, imaj, API-
server ve bulut dahil olmak üzere cluster’ın tüm seviyelerinde gerçekleştirilmelidir. Elde edilen
logların tümü, güvenlik denetçilerine, ağ güvenlik birimlerine ve olay müdahalecilerine cluster
genelinde gerçekleştirilen eylemlerin tam bir görünümünü sağlamak için tek bir hizmette
toplanmalıdır.
Kubernetes ortamında, yöneticilerin izlemesi/günlüğe kaydetmesi gereken olaylardan
bazıları aşağıda sunulmuştur:
- API request history
- Performance metrics
- Deployments
- Resource consumption
- Operating system calls
- Protocols, permission değişiklikleri
- Network traffic
- Pod scaling

ORHAN FİKRET DUMAN 26 KUBERNETES GÜVENLİĞİ


- Volume mount actions
- Image ve container değiştirme
- Privilege değişiklikleri
- Scheduled job (cronjob) oluşturma ve değiştirme işlemleri
Yöneticiler bir Pod oluşturduğunda veya güncellediğinde, bir “baseline” oluşturmak için
ağ iletişimlerinin, yanıt sürelerinin, isteklerin, kaynak tüketiminin ve diğer ilgili ölçümlerin
ayrıntılı loglarını yakalamaları gerekir. RBAC politika yapılandırmaları da periyodik olarak
ve organizasyonun sistem yöneticilerinde personel değişiklikleri meydana geldiğinde
gözden geçirilmelidir. Bunu yapmak, erişim kontrollerinin bu dokümanın rol tabanlı erişim
kontrolü bölümünde özetlenen RBAC politika sıkılaştırma kurallarına uygun kalmasını sağlar.
Rutin sistem güvenlik denetimleri, kaydedilen ölçüm ve olaylardaki önemli değişiklikleri
belirlemek için mevcut günlüklerin normal faaliyetlerin “baseline” ölçümleriyle
karşılaştırmalarını içermelidir. Sistem yöneticileri, “root cause”u belirlemek için önemli
değişiklikleri araştırmalıdır. Örneğin, kaynak tüketimindeki önemli bir artış, uygulama
kullanımındaki bir değişikliğin veya kripto madenciliği gibi kötü niyetli işlemlerin yüklenmesinin
göstergesi olabilir.
Tüm güvenlik kısıtlamalarının doğru şekilde yapılandırıldığından ve amaçlandığı gibi
çalıştığından emin olmak için dahili ve harici trafik loglarının denetimleri yapılmalıdır.
Yöneticiler (cluster administrators), harici erişimin nerede kısıtlanabileceğini değerlendirmek
için bu denetimleri kullanabilir.
Günlüklerin harici bir günlük hizmetine akışı, küme dışındaki güvenlik uzmanlarının
kullanabilirliğini sağlamaya yardımcı olacak ve anormallikleri mümkün olduğunca gerçek
zamanlıya yakın bir şekilde belirlemelerine olanak tanıyacaktır. Bu yöntem kullanılıyorsa, siber
aktörlerin geçiş sırasında günlüklere erişememesini ve çevre hakkında değerli bilgiler elde
edememesini sağlamak için günlükler aktarım sırasında TLS 1.2 veya 1.3 ile
şifrelenmelidir.

Harici bir günlük sunucusu kullanırken alınması gereken bir diğer önlem, Kubernetes
içindeki “log forwarder”ı harici depolamaya yalnızca ekleme (append-only) erişimiyle
yapılandırmaktır. Bu, harici olarak depolanan günlüklerin küme içinden silinmesine veya
üzerine yazılmasına karşı korur.
(1) Kubernetes-native Denetim Günlüğü Yapılandırması:
Kubernetes denetim günlüğü (audit logging) özellikleri varsayılan olarak devre
dışıdır.
Kube-apiserver, Kubernetes controlplane içerisinde bulunur ve bir küme için
dahili ve harici istekleri işleyerek bir frontend görevi görür. Bir kullanıcı, uygulama veya
controlplane tarafından oluşturulan her istek, yürütülmesinin her aşamasında bir denetim olayı
(audit event) üretir.
Bir denetim olayı kaydedildiğinde, kube-apiserver bir denetim ilkesi dosyası
(audit policy file) ve geçerli kural (rule) olup olmadığını kontrol eder. Böyle bir kural varsa,
sunucu olayı ilk eşleşen kural tarafından tanımlanan düzeyde günlüğe kaydeder.
Kubernetes'in bütünleşik audit logging özellikleri, varsayılan olarak hiçbir
günlük kaydı gerçekleştirmez.

ORHAN FİKRET DUMAN 27 KUBERNETES GÜVENLİĞİ


Küme yöneticileri, kuralları oluşturmak ve her bir denetim olayı türünün günlüğe
kaydedileceği istenen denetim düzeyini belirtmek için bir denetim ilkesi (audit policy) YAML
dosyası yazmalıdır. Bu denetim ilkesi dosyası daha sonra uygun flag’lerle kube-apiserver'a
iletilir.
Bir kuralın geçerli olabilmesi için dört denetim seviyesinden birini belirtmesi
gerekir:
- None
- Metadata
- Request
- RequestResponse
Tüm olayların “RequestResponse” düzeyinde günlüğe kaydedilmesi,
yöneticilere, bir ihlal olması durumunda olaya müdahale eden kişiler için mevcut olan
maksimum miktarda bilgi sağlar. Ancak bu, base64 ile kodlanmış şifresiz “secret key”lerin
loglar içerisinde yer almasına neden olabilir. Log içerisinde secret’ların yer almasını
önlemek için secret’ları içeren isteklerin günlüğe kaydetme düzeyinin “metadata”
seviyesinde olması gerekmektedir.
Ek olarak, diğer tüm olayların en üst düzeyde günlüğe kaydedilmesi, özellikle
bir production cluster’ında büyük miktarda log üretecektir. Organizasyonun politikaları
doğrultusunda, audit policy, kritik olmayan, rutin olayların günlüğe kaydetme düzeyini
azaltacak şekilde uyarlanabilir.
Böyle bir denetim ilkesi (audit policy) için gerekli olan kurallar, deployment’a
göre değişir. Kurumun cluster yapılandırması ve tehdit modeli doğrultusunda, güvenlik
açısından kritik tüm olayları günlüğe kaydetmek hayati önem taşır. Bir denetim politikasını
iyileştirmenin amacı, cluster’da meydana gelen olaylara ilişkin net bir resim ve ilişkilendirme
sağlamaya devam ederken, audit level’ı doğru şekilde ayarlayarak kritik verileri sızdırmadan
(secret vb.) ve gereksiz bilgi tutmadan doğru verileri tutmak olmalıdır.
Genel kritik ve kritik olmayan denetim olayı türlerine ve aşamalarına ilişkin bazı
örneklerin yanı sıra, secret’ları metadata düzeyinde günlüğe kaydeden bir denetim ilkesi
dosyası örneği ve RequestResponse düzeyindeki diğer tüm olaylara yönelik örnek audit policy
aşağıdadır:
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
resources:
- group: ”” # core API group
resources: [“secrets”]
- level: RequestResponse
Bu audit policy secret’larla ilgili event’leri “metadata” seviyesinde loglarken,
diğer tüm event’leri “RequestResponse” seviyesinde loglar.
Bir kurum çok sayıda günlüğü depolamak, ayrıştırmak ve incelemek için mevcut
kaynaklara sahipse, o zaman secret’ları içerenler dışındaki tüm olayları en üst düzeyde
günlüğe kaydetmek, bir ihlal meydana geldiğinde gerekli tüm işlemlerin yapılmasını
sağlamanın iyi bir yoludur, çünkü günlüklerde söz konusu kontekste bağlı tüm bilgiler bulunur.

ORHAN FİKRET DUMAN 28 KUBERNETES GÜVENLİĞİ


Kaynak tüketimi ve kullanılabilirlik hususları kurum için önemli ise, sistem için
denetim günlüğü gereksinimleri karşılandığı sürece, kritik olmayan bileşenlerin ve rutin
ayrıcalıklı olmayan eylemlerin günlüğe kaydetme düzeyini düşürmek için daha fazla günlüğe
kaydetme kuralı oluşturulabilir.
Kubernetes API olayları birden çok aşamadan oluştuğundan, günlüğe
kaydetme kuralları, günlükten çıkarılacak isteğin aşamalarını da belirtebilir. Varsayılan olarak
Kubernetes, isteğin tüm aşamalarında denetim olaylarını yakalar. Kubernetes API isteğinin
olası dört aşaması şunlardır:
- RequestReceived
- ResponseStarted
- ResponseComplete
- Panic
Kurumlardaki cluster’lar artan ihtiyaçları karşılamak üzere genişlediğinden,
denetim ilkesinin günlüğe kaydetme gereksinimlerini karşılamaya devam etmesini sağlamak
önemlidir.
Ortam öğelerinin gözden kaçırılmamasını sağlamak için denetim ilkesi, önceki
kuralların günlüğe kaydetmediği olayları günlüğe kaydetmek için bir “tümünü yakalama (catch
all)” kuralıyla sona ermelidir. Kubernetes, verilen olay için geçerli olan denetim ilkesindeki ilk
kurala dayalı olarak denetim olaylarını günlüğe kaydeder; bu nedenle, potansiyel olarak
çakışan kuralların yazıldığı sıranın farkında olmak önemlidir.
Secret’larla ilgili kural politika tanımının en üstüne yakın olmalıdır. Bu,
“Metadata” düzeyinden daha yüksek düzeyde loglama yapan ve daha üst sırada yer alan bir
politika kuralının yanlışlıkla secret’ları yakalamamasını sağlar. Benzer şekilde, tüm diğer
kuralların daha önce eşleşmesini sağlamak için, tümünü yakalama (catch-all) kuralı
politikadaki son kural olmalıdır.
Aşağıda, “Request” veya “RequestResponse” düzeyinde günlüğe kaydedilmesi
gereken kritik olay türlerine ilişkin bazı örnekler verilmiştir. Ek olarak, günlüklerdeki fazlalığı
azaltmak ve kurumun günlükleri mümkün olduğunca gerçek zamana yakın ve etkili bir şekilde
gözden geçirme yeteneğini artırmak için gerekirse daha düşük bir düzeyde günlüğe
kaydedilebilecek daha az kritik olay türleri ve aşamalarına örnekler verilmiştir.

Kritik

1 Deployments ve değişiklikler

2 Kimlik doğrulama istekleri (authentication requests)

3 RBAC kaynaklarında yapılan değişiklikler (edit clusterroles, clusterrolebindings vb.)

4 Scheduled Job Oluşturulması (create)

Pod Security Admission veya Pod Security Policy’lerde yapılan düzenlemeler


5
(editing)

ORHAN FİKRET DUMAN 29 KUBERNETES GÜVENLİĞİ


Kritik olmayan

1 RequestReceived aşaması (stage)

Kritik olmayan, rutin olarak erişilen kaynaklara yönelik kimliği doğrulanmış


2
(authenticated) istekler

Kritik olmayan aşamalar (stage) audit log’da hariç tutulabilir (omitStages).


Tüm event’ler için yalnızca “metadata” seviyesinde loglama yapan minimal bir
audit policy aşağıdadır:
https://kubernetes.io/docs/tasks/debug/debug-cluster/audit/ [13]

# Log all requests at the Metadata level.


apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata

Daha kapsamlı örnek bir audit policy dosyası aşağıdadır:


https://kubernetes.io/docs/tasks/debug/debug-cluster/audit/
apiVersion: audit.k8s.io/v1 # This is required.
kind: Policy
# Don't generate audit events for all requests in RequestReceived stage.
omitStages:
- "RequestReceived"
rules:
# Log pod changes at RequestResponse level
- level: RequestResponse
resources:
- group: ""
# Resource "pods" doesn't match requests to any subresource of pods,
# which is consistent with the RBAC policy.
resources: ["pods"]
# Log "pods/log", "pods/status" at Metadata level
- level: Metadata
resources:
- group: ""
resources: ["pods/log", "pods/status"]

# Don't log requests to a configmap called "controller-leader"


- level: None
resources:
- group: ""
resources: ["configmaps"]
resourceNames: ["controller-leader"]

ORHAN FİKRET DUMAN 30 KUBERNETES GÜVENLİĞİ


# Don't log watch requests by the "system:kube-proxy" on endpoints or
services
- level: None
users: ["system:kube-proxy"]
verbs: ["watch"]
resources:
- group: "" # core API group
resources: ["endpoints", "services"]

# Don't log authenticated requests to certain non-resource URL paths.


- level: None
userGroups: ["system:authenticated"]
nonResourceURLs:
- "/api*" # Wildcard matching.
- "/version"

# Log the request body of configmap changes in kube-system.


- level: Request
resources:
- group: "" # core API group
resources: ["configmaps"]
# This rule only applies to resources in the "kube-system" namespace.
# The empty string "" can be used to select non-namespaced resources.
namespaces: ["kube-system"]

# Log configmap and secret changes in all other namespaces at the


Metadata level.
- level: Metadata
resources:
- group: "" # core API group
resources: ["secrets", "configmaps"]

# Log all other resources in core and extensions at the Request level.
- level: Request
resources:
- group: "" # core API group
- group: "extensions" # Version of group should NOT be included.

# A catch-all rule to log all other requests at the Metadata level.


- level: Metadata
# Long-running requests like watches that fall under this rule will not
# generate an audit event in RequestReceived.
omitStages:
- "RequestReceived"

Kube-apiserver yapılandırma işlemleri ve audit policy dosyasının kube-


apiserver'a flag’lerle tanımlanmasına yönelik bir örnek aşağıda sunulmuştur:
sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml

Dosya içeriğine aşağıdaki parametreler, ihtiyaçlara göre özelleştirilerek


girilmelidir:

ORHAN FİKRET DUMAN 31 KUBERNETES GÜVENLİĞİ


--audit-policy-file=/etc/kubernetes/policy/audit-policy.yaml
--audit-log-path=/var/log/audit.log
--audit-log-maxage=1825

Audit-policy-file: Audit politikalarının tutulduğu dosya yolu.


Audit-log-path: Audit loglarının yazılmasının istendiği güvenli dosya yolu.
Audit-log-maxage: Audit loglarının ne kadar süre saklanacağını belirten
parametre.
Bunlar dışında aşağıdaki parametreler de isteğe göre ayarlanabilir:
--audit-log-maxsize: Audit logları için rotate edilmeden önceki maksimum
dosya boyutu
--audit-log-maxbackup: Saklanacak maksimum audit log dosyası adedi.
Bu parametreler içerisinde zorunlu olan parametreler “audit-policy-file” ve
“audit-log-path” parametreleridir. Diğer parametreler kurum ihtiyaçları doğrultusunda
özelleştirilebilir veya yazılmayabilir.
Apiserver’ın kubeadm ile pod şeklinde kurulması durumunda tanımlanması
gereken “volumeMount” ve “hostPath” tanımları aşağıda sunulmuştur:
https://kubernetes.io/docs/tasks/debug/debug-cluster/audit/ [13]

...
volumeMounts:
- mountPath: /etc/kubernetes/audit-policy.yaml
name: audit
readOnly: true
- mountPath: /var/log/kubernetes/audit/
name: audit-log
readOnly: false

...
volumes:
- name: audit
hostPath:
path: /etc/kubernetes/audit-policy.yaml
type: File

- name: audit-log
hostPath:
path: /var/log/kubernetes/audit/
type: DirectoryOrCreate

Not: Volume Mount kısmında audit loglarının mount edildiği volume için “readOnly: false”
olarak ayarlanmalıdır. Aksi takdirde yazma yetkisi olmadığı için loglama yapılamayacaktır.
Kube-apiserver, denetim günlüğü için yapılandırılabilir “logging” ve “webhook”
backendlerı içerir.
Logging backend’i, belirtilen denetim olaylarını bir günlük dosyasına yazar ve
webhook backend’i, dosyayı harici bir HTTP API'sine göndermek için yapılandırılabilir.

ORHAN FİKRET DUMAN 32 KUBERNETES GÜVENLİĞİ


--audit-log-path ve --audit-log-maxage flag’leri, logging backend’ini
yapılandırmak için kullanılabilecek iki flag örneğidir; denetim olaylarını bir dosyaya yazar.
log-path flag’i, günlüğe kaydetmeyi etkinleştirmek için gereken minimum
yapılandırmadır ve logging backend’i için gerekli olan tek yapılandırmadır. Bu günlük dosyaları
için varsayılan biçim Java Script Object Notation’dır (JSON), ancak gerekirse bu da
değiştirilebilir.
Logging backend için ek yapılandırma seçenekleri Kubernetes belgelerinde
bulunabilir. Kubernetes ayrıca, yöneticilerin günlükleri harici bir backend’e göndermek için
kube-apiserver'a gönderilen bir YAML dosyası aracılığıyla manuel olarak yapılandırabilecekleri
bir webhook backend seçeneği sunar. Webhook backendinin nasıl çalıştığı ve nasıl
kurulacağına ilişkin daha fazla ayrıntı Kubernetes belgelerinde bulunabilir. Bunun dışında,
günlük toplama işlemini gerçekleştirmek için kullanılabilecek birçok harici araç vardır.
(2) Worker Node ve Container Logging:
Bir Kubernetes mimarisi içinde günlüğe kaydetme yeteneklerinin
yapılandırılmasının birçok yolu vardır. Bütünleşik günlük yönetiminde (built-in log
management), günlükleri yönetmekten her düğümdeki “kubelet” sorumludur. Günlük
dosyalarını tek tek dosya uzunluğu, depolama süresi ve depolama kapasitesi ilkelerine göre
yerel olarak depolar ve döndürür. Bu günlükler kubelet tarafından kontrol edilir ve komut
satırından erişilebilir. Aşağıdaki komut, bir pod içindeki bir container’ın günlüklerini yazdırır:
kubectl logs [-f] [-p] POD [-c CONTAINER]

Günlükler stream olarak alınmak istenirse “–f” flag’i kullanılabilir. Bir container’ın
önceki örneklerinden gelen günlükler varsa ve isteniyorsa “-p” flag’i kullanılabilir. Pod
içerisinde birden fazla container varsa ilgili container’ı belirtmek için “-c” flag’i kullanılabilir. Bir
container’ın, pod'un veya node’un ölmesine neden olan bir hata oluşursa Kubernetes'teki
native günlük kaydı çözümü, ilgili nesnede depolanan günlükleri korumak için bir yöntem
sağlamaz. Bir düğümün arızalanması durumunda günlükleri korumak için bir uzaktan günlük
kaydı çözümünün yapılandırılması gerekir. Uzaktan günlüğe kaydetme (remote logging)
seçenekleri şunları içerir:

Remote Logging Yöntemi Kullanma Nedeni Konfigürasyon

Node’a, günlükleri expose


Bir Pod'daki bağımsız bir container,
etme veya günlükleri bir
Günlüklerin bir backend’e bir logging agent olarak çalışacak
backend’e gönderme
gönderilmesi için her şekilde yapılandırılarak, node’un
yeteneği vererek, bir arıza
node’da bir logging agent uygulama loglarına erişmesi ve
durumunda logları node’un
çalıştırılması günlükleri kurumun SIEM'ine
dışında tutarak korunmasını
iletmesi sağlanır.
sağlar.

Her log tipi için bir sidecar container


Logları farklı output
yapılandırılır ve bunlar, bu günlük
stream’lere göndermek için
Günlüklerin bir output dosyalarını kubelet'in yönetebileceği
kullanılır. Bu, uygulama
stream’e gönderilmesi için ayrı output stream’lerine yeniden
container’ları farklı biçimlerde
her pod’da bir sidecar yönlendirmek için kullanılır. Node
birden çok günlük dosyası
container kullanılması level logging agent daha sonra bu
yazarken yararlı bir seçenek
günlükleri SIEM'e veya diğer
olabilir.
backend’e iletebilir.

ORHAN FİKRET DUMAN 33 KUBERNETES GÜVENLİĞİ


Tüm podlar, logları direk olarak
Logları bir backend’e backend’e göndermesi için
Node level logging agent’tan
göndermek için her pod’da yapılandırılır Üçüncü parti logging
daha esnek bir loglama
logging agent sidecar agent’ların ve backend’lerin
mekanizması sağlar.
container’ı kullanılması kullanımında kullanılan metod
budur.
Günlüklerin doğrudan log Kubernetes, günlükleri doğrudan bir
aggregation platformuna backend’e göndermek için yerleşik
gitmesini sağlar. Kurumun mekanizmalara sahip değildir.
Logların uygulama
uygulama güvenliğini Kurumların, bu işlevi
içerisinden backend’e
yönetmekten Kubernetes uygulamalarına eklemeleri veya
doğrudan gönderilmesi
platform güvenliğine karşı bunu etkinleştirmek için sağlam bir
sorumlu ayrı ekipleri varsa üçüncü taraf aracı eklemeleri
yararlı olabilir. gerekecektir.

Worker node’lar üzerinde logging agent’ların sürekli olarak çalışmasını


garantiye almak için bunları bir DaemonSet olarak çalıştırmak yaygın bir uygulamadır. Bu
yöntem için bir DaemonSet yapılandırmak, her node’da her zaman logging agent’ın bir
kopyasının bulunmasını ve logging agent’ta yapılan tüm değişikliklerin cluster genelinde tutarlı
olmasını sağlar.
Kendi Kubernetes cluster’larını çalıştıran birden fazla ekibi olan büyük
kurumlar, tüm ekiplerin etkin bir çözüme sahip olmasını sağlamak için günlük kaydı
gereksinimleri ve standart bir mimari oluşturmalıdır.
(3) Seccomp: audit mode
Daha önce açıklanan node ve container günlüğüne ek olarak, sistem çağrılarını
(syscall) günlüğe kaydetmek oldukça faydalı olabilir. Kubernetes'te container sistem çağrılarını
denetlemenin bir yöntemi seccomp aracını kullanmaktır. Bu araç varsayılan olarak devre
dışıdır ancak bir container’ın syscall yeteneklerini sınırlamak için kullanılabilir, böylece kernel’in
saldırı yüzeyini düşürür. Seccomp ayrıca bir denetim profili (audit profile) kullanarak yapılan
syscall çağrılarını günlüğe kaydedebilir.
Özel bir seccomp profili, hangi sistem çağrılarına izin verildiğini, reddedildiğini
veya günlüğe kaydedildiğini ve tanımlanmayan çağrılar için varsayılan eylemleri tanımlar. Bir
pod içinde özel bir seccomp profilini etkinleştirmek için, JSON file türündeki “seccomp
profile” dosyası “/var/lib/kubelet/seccomp/” dizinine kaydedilir ve pod’un
“securityContext”ine bir “seccompProfile” alanı eklenir.
Özel (custom) bir “seccompProfile” ayrıca iki alan içermelidir: Type: Localhost
ve localhostProfile: myseccomppolicy.json. Tüm sistem çağrılarının günlüğe kaydedilmesi,
yöneticilerin, standart işlemler için hangi sistem çağrılarının gerekli olduğunu bilmelerine ve
sistem işlevselliğini kaybetmeden seccomp profilini daha fazla nasıl kısıtlayabileceklerini
bilmelerini sağlayabilir. Ayrıca, yöneticilerin bir pod’un standart işlemleri için bir “baseline”
oluşturmasına yardımcı olabilir ve bu genel paternden kötü amaçlı etkinliğin göstergesi
olabilecek büyük sapmaları belirlemelerine olanak tanır.
(4) Syslog:
Kubernetes, varsayılan olarak, servis kullanılabilir durumdaysa, kubelet
günlüklerini ve container runtime günlüklerini “journald”ye yazar. Kurumlar, syslog utility’lerini
kullanmak veya cluster’daki logları toplamak ve bunları bir syslog sunucusuna veya başka bir
log toplama ve depolama platformuna iletmek isterse, bu özelliği manuel olarak
yapılandırabilir. Syslog protokolü, bir günlük mesajı biçimlendirme standardını tanımlar.

ORHAN FİKRET DUMAN 34 KUBERNETES GÜVENLİĞİ


Syslog mesajları bir başlık (header) ve düz metin (plain text) olarak
yazılmış bir mesaj içerir. Syslog-ng® ve rsyslog gibi syslog arka plan programları, bir
sistemdeki günlükleri birleşik bir biçimde toplama ve birleştirme yeteneğine sahiptir. Çoğu
Linux işletim sistemi, varsayılan olarak “rsyslog” veya log depolama ve log çıktılarını
Journalctl aracılığıyla syslog formatına dönüştürmeyi sağlayan “journald” kullanır. Syslog
yardımcı programı, varsayılan olarak sunucu üzerinde belirli Linux dağıtımlarını çalıştıran
node’lardaki olayları günlüğe kaydeder.
Bu Linux dağıtımlarını çalıştıran container’lar, varsayılan olarak, syslog
kullanarak da günlükleri toplayacaktır. Syslog yardımcı programları, günlükleri toplamak için
bir günlük toplama platformu yapılandırılmadığı sürece, geçerli her node veya container’da
yerel dosya sisteminde günlükleri depolar. Syslog daemon’ı veya bu tür başka bir araç, hem
bunları hem de cluster genelinde toplanan diğer tüm günlükleri toplayacak ve bunları depolama
ve izleme için harici bir backend’e iletecek şekilde yapılandırılmalıdır.
(5) SIEM Platformları:
Güvenlik bilgileri ve olay yönetimi (SIEM) yazılımı, bir kuruluşun ağındaki
günlükleri toplar. Güvenlik duvarı günlüklerini, uygulama günlüklerini ve daha fazlasını bir
araya getirerek analistlerin sistem güvenliğini izleyebileceği merkezi bir platform sağlamak için
bunları ayrıştırır. SIEM araçlarının yeteneklerinde farklılıklar vardır. Genel olarak, bu
platformlar günlük toplama, birleştirme, tehdit algılama ve uyarı yetenekleri sağlar. Bazıları,
sistem davranışını daha iyi tahmin edebilen ve yanlış uyarıları azaltmaya yardımcı olan makine
öğrenimi özelliklerini içerir. Bu platformları kullanan kurumlar, cluster’ları daha iyi izlemek ve
güvenli hale getirmek için bunları Kubernetes ile entegre etmelidir. SIEM platformlarına
alternatif olarak, Kubernetes ortamlarından günlükleri yönetmek için geliştirilmiş açık kaynak
platformlar mevcuttur.
Container tabanlı altyapılarda node’lar, pod'lar, container’lar ve servisler
arasında birçok karşılıklı bağımlılık (interedependency) vardır. Bu ortamlarda, pod'lar ve
container’lar sürekli olarak silinmekte ve farklı node’larda yeniden konuşlandırılmaktadır. Bu
tür bir ortam, günlükleri ilişkilendirmek için tipik olarak IP adreslerini kullanan geleneksel
SIEM'ler için ekstra bir zorluk sunar. Yeni nesil SIEM platformları bile karmaşık Kubernetes
ortamına uygun olmayabilir. Bununla birlikte, Kubernetes en yaygın kullanılan container
yönetim platformu olarak ortaya çıktığından, SIEM araçları geliştiren kurumların çoğu,
ürünlerinin özel olarak Kubernetes ortamıyla çalışmak üzere tasarlanmış varyasyonlarını
geliştirmekte ve bu ortamlar için tam izleme çözümleri sağlamaktadır. Yöneticiler,
platformlarının yeteneklerinin farkında olmalı ve tutulan günlüklerin, gelecekteki olay yanıtlarını
(incident response) desteklemek için yeterli seviyede log yakaladığından emin olmalıdır.
(6) Service Mesh:
Service mesh, uygulama içerisindeki mikroservisler arası iletişimin uygulamanın
kendisi yerine, oluşturulan servis ağı içinde gerçekleştirilmesini sağlayarak uygulama içi
mikroservis iletişiminin yönetimini kolaylaştırır. Bu iletişim mantığının bireysel mikroservislere
kodlanması, ölçeklenmesi, arızalar meydana geldikçe hatalarının giderilmesi ve güvenliğinin
sağlanması oldukça zordur. Service mesh kullanmak, geliştiriciler için bu kodlamayı
basitleştirmektedir. Bu düzeyde günlük toplama, cluster admin’lerine cluster genelinde
servisler arası iletişim hakkında bilgi sağlar. Servis mesh aşağıdaki fonksiyonları yerine
getirilebilir:
- Bir servis kapalıyken trafiği yeniden yönlendirmek (traffic redirection),
- İletişimi optimize etmek için performans ölçütlerini (performance metrics)
toplamak,

ORHAN FİKRET DUMAN 35 KUBERNETES GÜVENLİĞİ


- Servisler arası (servis-to-service) iletişimin şifrelenmesinin yönetimi,
- Servisler arası iletişimin loglanması,
- Her servisten log toplanması,
- Geliştiricilerin mikroservislerin veya iletişim mekanizmalarının sorunlarını ve
hatalarını teşhis etmesine yardımcı olması,
- Servisleri hibrit veya çoklu bulut (multi-cloud) ortamlarına taşıma konusunda
yardımcı olması.
Servis mesh yapısı, zorunlu olmasa da, Kubernetes ortamına oldukça uygun bir
seçenektir. Loglama yetenekleri, servisler arası iletişimin analiz edilmesinde çok yararlı
olmakta ve yöneticilerin standart cluster işlemlerinin nasıl gerçekleştiğini görmelerine ve
anormallikleri daha kolay tanımlamalarına yardımcı olmaktadır. Yönetilen (managed)
Kubernetes hizmetleri genellikle kendi service mesh yapılarını içerir; bununla birlikte, farklı
birkaç platform da mevcuttur ve ihtiyaçlar doğrultusunda özelleştirilebilir.
Modern service mesh yapılarının bir diğer önemli yararı, servisler arası iletişimin
şifrelenmesidir. Birçok service mesh yapısı, geliştiricilerin bunu her bir servis için ayarlamasını
ve kendilerinin yönetmesini gerektirmeden, servisler arasında güvenli TLS kimlik
doğrulamasına izin vererek, anahtarları yönetir ve sertifikaları oluşturup döndürerek (rotation)
sağlar.
Güvenli TLS kimlik doğrulama işlemi, bileşenler arasında karşılıklı olarak
sertifika doğrulaması sağlayan mTLS (mutual TLS) ile gerçekleştirilir. Hatta bazı service mesh
yapıları, bu servisler arası şifrelemeyi varsayılan olarak gerçekleştirir. Kubernetes cluster’ı
içinde service mesh yapısını devreye alındığında, aşağıdaki şekilde gösterildiği gibi service
mesh yapısı için güncellemelerin ve güvenlik uyarılarınının takip edilmesi önem arz etmektedir:

Şekil 6: Service mesh ve loglama altyapısı kullanan Kubernetes Cluster [1]

ORHAN FİKRET DUMAN 36 KUBERNETES GÜVENLİĞİ


Şekil 7: Istio Service Mesh Altyapısı – istiod – envoy proxy [14]
Service mesh yapısında pod’lar arası kriptolu iletişim sidecar proxy’ler
aracılığıyla gerçekleştirilmektedir. Istio service mesh yapısında sidecar proxy olarak “envoy
proxy” kullanılmaktadır. Eski versiyonlarında ayrı bileşenler olarak sunulan yönetim
katmanındaki “Pilot”, “Citadel”, “Galley” modülleri “istiod” altında birleştirilmiştir. Servisler arası
iletişime yönelik olarak “Jaeger” ve “Kiali” araçları ile detaylı izleme ve analizler
yapılabilmektedir.
(7) Hata Toleransı (Fault Tolerance):
Kurumlar, hata toleransı politikalarını uygulamaya koymalıdır. Bu politikalar,
Kubernetes kullanım şekline bağlı olarak farklılık gösterebilir. Örneğin, belirlenecek politikalar
doğrultusunda, depolama kapasitesinin etkin kullanımı için, yeni günlüklerin en eski günlük
dosyalarının üzerine yazmasına izin verilebilir. Loglar harici bir servise gönderiliyorsa
kullanılabilecek bir başka politika, bir iletişim kaybı veya harici bir servis hatası meydana
geldiğinde günlüklerin yerel olarak depolanacağı bir alan oluşturmaktır. Harici servisle iletişim
yeniden sağlandığında, yerel olarak depolanan günlüklerin harici sunucuya gönderilmesi için
bir politika oluşturulmalıdır.
b. Tehdit Algılama (Threat Detection):
Etkili bir günlük kaydı çözümü iki kritik bileşenden oluşur:
- Gerekli tüm verilerin toplanması ,
- Toplanan verilerin kırmızı bayraklar (red flag) için mümkün olduğunca gerçek zamana
yakın bir şekilde aktif olarak izlenmesi.
Log çözümlerinin faydalı sonuçlar vermesi verilerin incelenmesine bağlıdır. Log
inceleme sürecinin çoğu otomatikleştirilebilir. Ancak, günlük ayrıştırma ilkeleri (log parse

ORHAN FİKRET DUMAN 37 KUBERNETES GÜVENLİĞİ


policy) yazarken veya günlükleri manuel olarak incelerken, neye bakılacağını bilmek hayati
önem taşır. Saldırganlar cluster’ı istismar etmeye çalıştıklarında günlüklerde eylemlerinin
izlerini bırakırlar.
Aşağıdaki tablo, saldırganların cluster’ı istismar etmek için kullanabilecekleri
yöntemlerden bazılarını ve bunun günlüklerde nasıl bulunabileceğini içerir. (Uyarı: Bu tablo,
bilinen bazı şüpheli göstergeleri (indicator) listeler. Yöneticiler ayrıca, ortama yönelik önemli
alanların ve ortaya çıkan tehditlerin farkında olmalı ve bunlara karşı tetikte olmalıdır. En etkili
uyarılar, belirli bir cluster için anormal etkinliği belirlemek üzere uyarlanmıştır.)

Saldırgan Eylemi Log Tespiti


(Attacker Action) (Log Detection)

Saldırganlar, kendi kötü amaçlı yazılımlarını


çalıştırmak veya saldırıları için bir hazırlık
alanı (staging ground)/pivot noktası olarak - Anormal pod ve container yüklemeleri
kullanmak için bir pod veya container (deployment) takip edilmelidir.
yüklemeyi deneyebilir. Saldırganlar, adları ve - Şüpheli imaj yüklemelerinin geçerli (valid)
adlandırma kurallarını kopyalayarak imajlarla karşılaştırılması için imaj kimlikleri
yüklenen uygulamalarını (deployment) (image id) ve layer hash’leri kullanılmalıdır.
meşru bir imaj gibi göstermeye çalışabilirler. - Root izinleriyle başlatılan pod'lar veya
Ayrıca ayrıcalık yükseltmek (privilege uygulama container’ları izlanmelidir.
escalation) için root ayrıcalıklarına sahip bir
container başlatmayı deneyebilirler.

- Bu husus, container engine veya imaj


repo’su günlüklerinde tespit edilebilir.
Saldırganlar, organizasyonun pod/container
- Ağ güvenliği personeli, standart yükleme
repo’suna zararlı bir imaj yüklemeye
sürecinden herhangi bir sapmayı
çalışabilirler. Bu sayede yükleme esnasında
incelemelidir.
kendi imajlarına erişim sağlamayı veya
- Özel durumlarda, yeni imaj sürümü
meşru bir uygulamanın kendi zararlı
kullanılarak yüklendikten sonra
imajlarını kullanmalarını sağlayabilirler.
container’ların davranışındaki değişiklikler
yoluyla da tespit edilebilir.

Saldırgan, bir uygulamayı container’da


komut yürütme (command execution) - Bir pod içinden gerçekleştirilen olağandışı
yetenekleri kazanacak şekilde istismar API istekleri (Kubernetes audit loglarından)
edebilirse, pod’un yapılandırmasına bağlı veya olağandışı sistem çağrıları (seccomp
olarak, pod içinden API istekleri yapabilir, loglarından) tespit edilebilir.
potansiyel olarak ayrıcalıkları yükselterek - Bu, bir pod IP adresini kaynak IP'si olarak
(privilege escalation), cluster içerisinde kaydeden pod oluşturma istekleri olarak da
yatayda hareket edebilir (lateral movement) gösterilebilir.
veya sunucu üzerine geçiş yapabilir.
- Hangi ilk izinlere sahip olduklarını
Bir Kubernetes kümesine ilk erişim elde eden belirlemeye çalışırken, API sunucusuna
saldırganlar, büyük olasılıkla kümeye daha birkaç başarısız istekte bulunabilirler.
fazla nüfuz etmeye başlayacak ve bu da - Belirli bir hesap için tipik olmayan
kube-apiserver ile etkileşim kurmayı tekrarlanan başarısız API istekleri ve istek
gerektirecektir. kalıpları kırmızı bayraklar (red flag)
olacaktır.

ORHAN FİKRET DUMAN 38 KUBERNETES GÜVENLİĞİ


Saldırganlar, kendi kripto madencilerini Bir saldırgan başarılı bir şekilde kripto
çalıştırmak için kurbanın kaynaklarını hırsızlığı (cryptojacking) saldırısı
kullanmak üzere cluster’ın güvenliğini başlatırsa, günlüklerde kaynak tüketiminde
aşmaya çalışabilir (cryptojacking attack vb). ani bir artış olarak görüntülenebilir.

Saldırganlar, cluster’daki etkinliklerinin


Cluster’daki anonim eylemler takip
ilişkilendirilmesini önlemek için anonim
edilmelidir.
hesapları kullanmaya çalışabilir.

Saldırganlar, sunucuya erişim elde etmek


Depolama alanı bağlantısı (volume mount)
için istismar ettikleri veya oluşturdukları bir
eylemleri anormallikler için yakından
container’a bir depolama alanı bağlantısı
izlenmelidir.
(volume mount) eklemeyi deneyebilir.

Zamanlanmış görevler (diğer adıyla


Kubernetes CronJobs) oluşturma yeteneğine
Planlanmış iş yaratma (scheduled job
sahip saldırganlar, Kubernetes'in cluster’da
creations) ve değişiklikler yakından
kötü amaçlı yazılımları otomatik olarak ve
izlenmelidir.
tekrar tekrar çalıştırmasını sağlamak için
bunu kullanmayı deneyebilir.

Bunun gibi bir ortamda oluşturulan çok büyük miktarda günlük, yöneticilerin tüm
günlükleri manuel olarak incelemesini olanaksız hale getirir ve yöneticilerin hangi göstergelere
bakması gerektiğini bilmesini daha da önemli hale getirir. Bu bilgi, otomatik yanıtları
yapılandırmak ve uyarıları tetikleme kriterlerini hassaslaştırmak için kullanılabilir.
(1) Uyarılar (Alerting):
Kubernetes, yerel olarak uyarıyı desteklemez; ancak uyarı özelliklerine sahip
birkaç izleme aracı Kubernetes ile uyumludur. Kubernetes yöneticileri bir uyarı aracını
Kubernetes ortamında çalışacak şekilde yapılandırmayı seçerse, yöneticiler uyarıları izlemek
ve yapılandırmak için çeşitli ölçümler kullanabilir.
Uyarıları tetikleyebilecek olaylara örnekler, bunlarla sınırlı olmamak üzere
şunları içerir:
- Ortamdaki sunuculardan herhangi birinde düşük disk alanı,
- Log depolama alanının kullanılabilir (available) alanındaki azalma,
- Harici loglama servisinin çevrimdışı olması,
- Root izinleriyle çalışan bir pod veya uygulama,
- Bir hesap tarafından yetkisinin olmadığı kaynaklar için yapılan talepler,
- API sunucusuna gönderilen anonim istekler,
- Pod veya Worker Node IP adreslerinin Pod oluşturma isteğinin kaynak kimliği
olarak listelenmesi,
- Olağandışı sistem çağrıları veya başarısız API çağrıları,

ORHAN FİKRET DUMAN 39 KUBERNETES GÜVENLİĞİ


- Anormal kullanıcı/yönetici davranışı (olağandışı zamanlarda veya olağandışı
bir konumdan),
- Standart operasyon metrikleri temel çizgisinden önemli sapmalar.
- Pod’ların securityContext kısmındaki değişiklikler,
- Kabul denetleyicisi (admission controller) yapılandırmalarında yapılan
güncellemeler,
- Belirli hassas dosyalara/URL'lere erişim.
Mümkün olduğunda, sistemler, yöneticiler uyarılara yanıt verirken, tehlikeleri
azaltmak için adımlar atacak şekilde yapılandırılmalıdır.
Bir pod IP'sinin bir pod oluşturma isteğinin kaynak kimliği olarak listelenmesi
durumunda, pod'un otomatik olarak çıkarılması (eviction), uygulamayı kullanılabilir tutmak ve
cluster’ın istismarını geçici olarak durdurmak için uygulanabilecek bir azaltıcı önlemdir.
Bu sayede, pod'un temiz bir sürümünün node’lardan birine yeniden planlanması
sağlanır. Bir ihlalin meydana gelip gelmediği, geldiyse kötü niyetli aktörlerin bu ihlali nasıl
yaptıkları ve bu doğrultuda nasıl bir yama yüklemesi yapılabileceğini tespit etmek için günlükler
incelenebilir. Bu tür yanıtları otomatikleştirmek, güvenlik uzmanlarının kritik olaylara yanıt
verme süresini iyileştirmeye yardımcı olabilir.
c. Araçlar (Tools):
Kubernetes, yerel olarak kapsamlı denetim yetenekleri içermez. Bununla birlikte,
sistem genişletilebilir olacak şekilde inşa edilmiştir ve kullanıcılara kendi özel çözümlerini
geliştirme veya ihtiyaçlarına uygun mevcut bir eklentiyi seçme özgürlüğü verir.
Kubernetes cluster yöneticileri, kullanıcılar için genişletilmiş arama parametreleri, veri
eşleme özellikleri ve uyarı işlevi gibi ek işlevleri gerçekleştirmek için genellikle ek backend
hizmetlerini cluster’larına dahil eder.
Halihazırda SIEM platformlarını kullanan kuruluşlar, Kubernetes'i bu mevcut
yeteneklerle entegre edebilir. Cloud Native Computing Foundation'ın Prometheus®, Grafana
Labs'ın Grafana® ve Elasticsearch'ün Elastic Stack (ELK)® gibi açık kaynaklı izleme araçları
da mevcuttur. Araçlar, olay izleme gerçekleştirebilir, tehdit analitiği çalıştırabilir, uyarıları
yönetebilir ve çalışan container’larda kaynak izolasyon parametreleri, geçmiş kullanım ve ağ
istatistikleri toplayabilir. RBAC'deki riskli izin yapılandırmalarını belirlemek için erişim denetimi
ve izin yapılandırmaları denetlenirken tarama araçları kullanılabilir.
Kubernetes ortamlarının IDS platformuna entegrasyonu, bir kurumun olağandışı
davranış belirtileri gösteren container’ları izlemesine ve potansiyel olarak yok etmesine olanak
tanır, böylece container’lar ilk temiz imajdan yeniden başlatılabilir. Birçok bulut servis
sağlayıcısı (CSP), daha fazla yönetilen ve ölçeklenebilir çözümler isteyenler için container
izleme hizmetleri de sağlar.

ORHAN FİKRET DUMAN 40 KUBERNETES GÜVENLİĞİ


7. Versiyon Yükseltme ve Uygulama Güvenliği Uygulamaları:
Bu belgede özetlenen güvenlik sıkılaştırma adımlarının uygulanması, Kubernetes
ortamında container’larda çalışan uygulamaların güvenliğini sağlamaya yönelik bir adımdır.
Ancak güvenlik devam eden bir süreçtir ve yamaları, güncellemeleri ve yükseltmeleri
takip etmek hayati önem taşır. Spesifik yazılım bileşenleri, bireysel konfigürasyona bağlı olarak
değişir, ancak genel sistemin her bir parçası mümkün olduğunca güvenli tutulmalıdır.
Bu, Kubernetes’i, hipervizörleri, sanallaştırma yazılımlarını, eklentileri, ortamın
üzerinde çalıştığı işletim sistemlerini, sunucularda çalışan uygulamaları, kurumun sürekli
entegrasyon/sürekli yükleme (CI/CD) pipeline’ının tüm unsurlarını ve sunucuda barındırılan
diğer yazılımları güncellemeyi içerir.
Hizmetlerinin 7/24 ayakta kalması gereken kurumların, servisler durmadan firmware,
kernel ve işletim sistemi güncellemelerini yapabilmesi için high available cluster yapılarını
kullanması gerekmektedir.
Center for Internet Security (CIS) [15], yazılımların güvenliğini sağlamak için
benchmark dokümanları yayınlamaktadır. Yöneticiler, Kubernetes ve diğer ilgili sistem
bileşenleri için CIS benchmark’larına uymalıdır. Yöneticiler, sistemlerinin güvenliğinin, en iyi
siber güvenlik uygulamalarıyla uyumlu olduğundan emin olmak için periyodik olarak kontrol
etmelidir. Güvenli olmayan yapılandırmaları ve sıfırıncı gün (zero-day) güvenlik açıklarını
proaktif olarak aramak için çeşitli sistem bileşenlerinde periyodik güvenlik açığı taramaları ve
sızma testleri gerçekleştirilmelidir. Herhangi bir keşif, potansiyel siber aktörler bunları keşfedip
istismar etmeden önce derhal düzeltilmelidir.
Yöneticiler güncellemeleri dağıtırken, aynı zamanda ortamdan ve pipeline’dan eski,
kullanılmayan bileşenleri kaldırmaya da devam etmelidirler. Bu uygulama, saldırı yüzeyini ve
kullanılmayan araçların sistemde kalması ve güncelliğini yitirmesi riskini azaltmaya yardımcı
olacaktır.
Yönetilen bir Kubernetes hizmeti kullanmak, işletim sistemleri ve ağ protokolleri ile
Kubernetes bileşenleri için yükseltmeleri ve yamaları otomatikleştirmeye yardımcı olabilir.
Ancak, yöneticilerin yine de dağıtımlarının güncel olduğundan ve geliştiricilerin yanlışlıkla
güncel olmayan imajların dağıtımını önlemek için yeni imajları doğru şekilde etiketlediğinden
emin olmaları gerekir.

ORHAN FİKRET DUMAN 41 KUBERNETES GÜVENLİĞİ


8. Kubernetes Güvenliği Uygulama Adımları:
Kubernetes güvenliğine yönelik yukarıda sunulan hususlar doğrultusunda, bir kurumda
uygulanması gereken adımlar ve kullanılabilecek alternatif araçlar aşağıda sunulmuştur:

S.Nu Uygulama Adımı Araçlar

Kubernetes Güncel CIS benchmark raporu doğrultusunda, “kube-bench” veya “CIS


Cluster’ı üzerinde CAT” vb. aracı ile CIS Kubernetes benchmark testi cluster’a
güvenlik durumu uygulanmalıdır, tespitler doğrultusunda düzeltici adımlar uygulanmalıdır:
1
kontrolü (Security “docker run --pid=host -v /etc:/etc:ro -v /var:/var:ro
Posture Check) -t docker.io/aquasec/kube-bench:latest --version
uygulanması 1.18”
Controlplane üzerinde çalışan
- kube-apiserver
Controlplane - kube-controller-manager
bileşenlerinin - kube-scheduler
2
binary'lerinin - etcd
doğrulanması - cni_plugin
- coreDNS gibi bileşenlerin binary’lerinin orjinalliği “sha512sum” vb.
hash kontrol uygulamaları ile kontrol edilmelidir.
Secure Secure Ingress ile Kubernetes Cluster’ına dışarıdan erişimlerin TLS
3 Ingress/Egress kriptolu hale getirilmesi, ayrıca Secure Egress kullanımı hususunun da
kullanımı güvenlik yönünden faydalı olabileceği değerlendirilmektedir.
Pod, Namespace, CIDR bazında tanımlanacak network policy’ler ile
Ingress ve Egress erişim politikaları belirlenmelidir. Kubernetes
içerisinde güvenliği sağlanması gereken kritik pod ve namespace’ler ile
Network Policy
IP blokları için erişim sağlaması gereken pod/namespace/IP adresleri ile
4 tanımlarının
izin verilecek portlar belirlenmeli ve yapılacak tanımlar ile güvenlik
yapılması
sıkılaştırmaları uygulanmalıdır. Örneğin statefulset olarak çalıştırılan bir
veritabanı uygulamasına erişim ilgili porttan, tek yönlü ve yalnızca ilgili
backend sunucusundan gelecek şekilde belirlenmelidir.
Kullanıcı ve servis hesapları için en az yetki (Principle of Least Privilege)
RBAC (Kullanıcı
ilkesi doğrultusunda tanım yapılmalı, cluster genelinde ve yüksek
ve Servis
yetkilere sahip rollerin (cluster-admin vb.) kullanımı incelenerek
5 Hesaplarının Rol
sınırlanmalıdır. Sistem yöneticileri, yazılım geliştiriciler, proje yöneticileri
bazlı
için ayrı roller tanımlanarak gereksiz yetkilendirmeler ortadan
yetkilendirmeleri)
kaldırılmalıdır.
Bulut servis sağlayıcıları (CSP) üzerinden alınan yönetilen Kubernetes
Node
hizmetlerinde Kubernetes master ve worker node’larının kurulu
Metadatalarının
6 bulunduğu sanal sunucular ve bulut erişimine yönelik tutulan node
Güvenliğinin
metadatalarına erişim network policy tanımlanarak IP bazında
Sağlanması
engellenmelidir.
Pod oluşturulurken service account’larının otomatik olarak bağlanması
Servis
service account ya da pod/deployment/statefulset tanımı içerisinde
7 hesaplarının
yapılacak tnaımla engellenmelidir:
güvenli kullanımı service account auto mount: disable
Kube-apiserver yapılandırma flag’leri içerisinde;
API Server’a
--anonymous-auth: false ile anonim erişimin engellenmesi,
yetkisiz
8 --enable-admission-plugins=MutatingAdmissionWebhook,
erişimlerin ValidatingAdmissionWebhook,NamespaceLifecycle,
kısıtlanması
LimitRanger vb.

ORHAN FİKRET DUMAN 42 KUBERNETES GÜVENLİĞİ


Kubernetes cluster’ı master ve worker node bileşenleri düzenli olarak
güncellenmelidir. Kubernetes geriye dönük olarak 3 versiyonu
Kubernetes
desteklediğinden, kurumsal politika, duyurulan Kubernetes minör
cluster'ın düzenli
9 sürümünden en fazla 3 versiyon geriden gelmek şeklinde belirlenebilir.
olarak
Örneğin Kubernetes v1.25 sürümü duyurulduğunda kurum Kubernetes
güncellenmesi
master ve worker bileşenleri en az v1.23 olacak şekilde
güncellenmelidir.
Kubernetes küme ve bileşenlerine yönelik durum (state) bilgilerinin
tutulduğu etcd cluster’ı düzenli aralıklarla yedeklenmelidir. Bir
arıza/felaket anında Kubernetes Cluster’ının geri dönülmesi için gereken
Kubernetes iki temel alan bulunmaktadır. Bunlar:
Cluster - Kubernetes Cluster Resource’ları, yapılandırmalar ve durum
resource'larının
bilgisi: etcd içerisinde tutulmaktadır. ”etcdctl snapshot save +
10 (etcd) ve
ARGS” / “etcd snapshot restore + ARGS” komutlarıyla yedek
persistent volume
(pv)'lerin alma ve yedekten dönme işlemleri gerçekleştirilmelidir.
yedeklenmesi - Kubernetes kalıcı depolama alanları (persistent volumes):
Kubernetes cluster’ında uygulamalara ait harici verinin tutulduğu
PVC/PV/SC bileşenleri kullanılarak pod’lara mount edilen kalıcı
depolama alanlarının yedeği harici bir araçla alınmalıdır.
Etcd veritabanında “etcdctl get
/registry/secrets/namespace_name/secret_name + ARGS”
ile hassas verinin (password, token vb.) ifşa olmaması için
EncryptionConfiguration tanımlanmalı ve secret datası kriptolanmalıdır.
Bunun için:
1. Encryption Configuration dosyası oluşturulur -
/etc/kubernetes/enc/enc.yaml:
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
Etcd'nin - secrets
kriptolanması ve providers:
11 secret datalarının - aescbc:
güvenli keys:
saklanması - name: key1
secret: <BASE 64 ENCODED SECRET>
- identity: {}

2. Kube-apiserver’da:
“--encryption-provider-
config=/etc/kubernetes/enc/enc.yaml” tanımı yapılır.
3. Mevcutlar da dahil olmak üzere tüm secret dataları şifrelenir:
“kubectl get secrets --all-namespaces -o json |
kubectl replace -f –“

Container runtime Pod’ların sunucu kernel’ine erişimlerini güvenli hale getirebilmek


sandbox kullanımı maksadıyla mümkün olan uygulamalarda sandbox kullanımı ile olası
12
(gvisor, kata pod istismarı durumunda host kernel’a erişim sağlanması veya zarar
containers vb.) verilmesi engellenebilir.
Security Context kullanımı ile pod veya container seviyesinde yetkili
(privileged) pod/container kullanımının ve yetki yükseltme (pivilege
Security context escalation) önlenmesi, capability’lerin kısıtlanması vb. sağlanabilir.
ve pod security securityContext:
policy/pod privileged: false
13 allowPrivilegeEscalation: false
security
admission readOnlyRootFilesystem: true #emptyDir
kullanımı runAsNonRoot: true
runAsUser: 1000
runAsGroup: 3000

ORHAN FİKRET DUMAN 43 KUBERNETES GÜVENLİĞİ


fsGroup: 2000
capabilities:
drop: ["ALL"]
add: [“SYS_NICE”] #Gerekli cap’ler

Kubernetes pod, service vb. bileşenlerinin haberleşmesinde sidecar


container ile mTLS kullanımı için service mesh yapısının oluşturulması
Service mesh
14 ile cluster içi haberleşme TLS ile kriptolu olarak sağlanabilir. Ayrıca
kullanımı
service mesh yapısı ile birlikte gelen diğer özelliklerden (monitoring,
canary deployment, gateway, routing vb.) faydalanılabilir.
Open Policy Agent (OPA) vb. politika tanımlama araçlarının kullanımı ile
Politika
kısıt (constraint) ve gatekeeper tanımları ile belirlenecek kurallara
Tanımlama
15 uyumsuzluk (violation) durumunda erişim kontrolünün (admission
Araçlarının
control) yapılması ve yetkisiz işlemlerin engellenmesi (deny)
Kullanımı
sağlanabilir.
Container imajlarının sıkılaştırılmasında uygulanması gereken adımlar:
Container
-RUN,COPY,ADD satırları ayrı katmanlar (layer) oluşturulmasına sebep
16 imajlarının
olur. Bu nedenle bu satırların Dockerfile içerisinde birleştirilmesi gerekir.
sıkılaştırılması
- Multi-stage imajlarla güvenlik açıkları azaltılabilir.
Kubesec:
Kubernetes resource’ları için güvenlik risk analiz aracı (kubesec.io) 
docker.io/kubesec/kubesec:v2

Kullanım Şekilleri:

1. “kubesec scan” komutu ile:

$ cat <<EOF > kubesec-test.yaml


apiVersion: v1
kind: Pod
metadata:
name: kubesec-demo
spec:
containers:
- name: kubesec-demo
image: gcr.io/google-samples/node-hello:1.0
securityContext:
Statik k8s
readOnlyRootFilesystem: true EOF
resource ve imaj
17 zaafiyet
“kubesec scan kubesec-test.yaml” komutuyla taranır.
analizlerinin
yapılması
2. Docker container olarak çalıştırılması:

$ docker run -i kubesec/kubesec:512c5e0 scan /dev/stdin <


kubesec-test.yaml

3. Kubesec HTTP Server olarak:

kubesec http 8080 &

$ curl -sSX POST --data-binary @test/asset/score-0-cap-


sys-admin.yml http://localhost:8080/scan
[
{
"object": "Pod/security-context-demo.default",
"valid": true,
"message": "Failed with a score of -30 points",
#Risk skorlaması yapar.
"score": -30,

ORHAN FİKRET DUMAN 44 KUBERNETES GÜVENLİĞİ


"scoring": {
"critical": [
{
"selector": "containers[] .securityContext
.capabilities .add == SYS_ADMIN",
"reason": "CAP_SYS_ADMIN is the most privileged
capability and should always be avoided" #Önerilerde
bulunur.
},
{
"selector": "containers[] .securityContext
.runAsNonRoot == true",
"reason": "Force the running image to run as a
non-root user to ensure least privilege"
},
// ...
$ kill % #Kubesec server’ı durdurur.

4. Docker HTTP Server olarak:

$ docker run -d -p 8080:8080 kubesec/kubesec:512c5e0 http


8080

$ curl -sSX POST --data-binary @test/asset/score-0-cap-


sys-admin.yml http://localhost:8080/scan
...

5. Kubesec-as-a-service:
“v2.kubesec.io/scan” adresine API request gönderilerek:
$ curl -sSX POST --data-binary @"k8s-deployment.yaml"
https://v2.kubesec.io/scan

OPA Conftest:
OPA Conftest, yapısal konfigürasyon datası için “Rego” dilinde
yazılmış kurallara göre test uygular. (https://github.com/open-policy-
agent/conftest)
(Rego dili için  https://www.openpolicyagent.org/docs/latest/policy-
language/ [16])
Örneğin, policy/deployment.rego dosyası içeriği:

package main

deny[msg] {
input.kind == "Deployment"
not
input.spec.template.spec.securityContext.runAsNonRoot
#violation satırı
msg := "Containers must not run as root"
}

deny[msg] {
input.kind == "Deployment"
not input.spec.selector.matchLabels.app #violation
satırı
msg := "Containers must provide app label for pod
selectors"
}

$ conftest test deployment.yaml

ORHAN FİKRET DUMAN 45 KUBERNETES GÜVENLİĞİ


FAIL - deployment.yaml - Containers must not run as root
FAIL - deployment.yaml - Containers must provide app
label for pod selectors
2 tests, 0 passed, 0 warnings, 2 failures, 0 exceptions

Yukarıda, violation satırındaki durum konfigürasyon üzerinde kontrol


edilir. Eğer violation tetikleniyorsa, ilgili mesajı çıktı olarak verir.
Yalnıza Kubernetes için değil policy tanımı ile IaC uygulamalarının
(Terraform, Tekton Pipeline conf. vb.) birçoğu ile birlikte kullanılabilir.

Clair:
Container imajları için (OCI, docker) kullanılan açık kaynak kodlu statik
zafiyet analiz aracıdır. (https://github.com/quay/clair [17],
https://quay.github.io/clair/ [18])

Kurulum:
git clone git@github.com:quay/clair.git
cd clair
docker-compose up -d

1. Combo Mode:
CLAIR_MODE=combo
CLAIR_CONF=/path/to/mounted/config.yaml
clair -conf "path/to/config.yaml" -mode "combo"

2. Manifest:
GO111MODULE=on go get
github.com/quay/clair/v4/cmd/clairctl@latest
clairctl --host ${net_address_of_clair} report ${image_tag}

Dashboard ve debug servisleri: localhost:8080


Clair servisi default adres: localhost:6060

Örnek:
clairctl report ubuntu:focal
ubuntu:focal found bash 5.0-6ubuntu1.1
CVE-2019-18276
ubuntu:focal found libpcre3 2:8.39-12build1
CVE-2017-11164

Trivy (Aquasec):
Container, Kubernetes, code-repository, secret, SBOM (Software
Billing of Materials), cloud config gibi konfigürasyon ve imajlarda
zafiyet, hatalı konfigürasyon vb. için statik tarama yapan araç.

https://github.com/aquasecurity/trivy [19]
https://www.aquasec.com/products/trivy/ [20]

Güvenlik taraması yapılacak hedefler:


- Container Image
- Filesystem
- Git repository (uzak)
- Kubernetes cluster veya resource

Tarayıcılar:
- İşletim sistemi paketleri ve kullanımdaki yazılım bağımlılıkları
- Bilinen zafiyetler (CVEs)
- IaC hatalı yapılandırmaları
- Hassas veriler ve secret’lar

ORHAN FİKRET DUMAN 46 KUBERNETES GÜVENLİĞİ


Kurulum:
“apt-get/yum/brew install trivy”
“docker run aquasec/trivy”

Kullanım:
trivy <target> [--security-checks <scanner1,scanner2>]
TARGET_NAME

Örnek:
- trivy image python:3.4-alpine
- trivy image –severity HIGH python:3.4-alpine

- trivy fs --security-checks vuln,secret,config myproject/

- trivy k8s --report summary cluster

Strace:
strace, Linux kernel’i için tanılama ve hata ayıklamada kullanılan bir
userspace aracıdır. Sistem çağrıları, sinyal teslimatları ve süreç
durumundaki değişiklikleri içeren süreçler ve Linux çekirdeği arasındaki
etkileşimleri izlemek ve incelemek için kullanılır. strace'in çalışması,
ptrace olarak bilinen çekirdek özelliği ile mümkün olur.
Bir süreç tarafından çağrılan sistem çağrılarını ve bir süreç tarafından
alınan sinyalleri yakalar ve kaydeder. Her sistem çağrısının adı,
argümanları ve dönüş değeri, standart hataya veya -o seçeneğiyle
belirtilen dosyaya yazdırılır. strace, belirtilen komutu çıkana kadar
çalıştırır.

https://man7.org/linux/man-pages/man1/strace.1.html [21]
https://demirten.gitbooks.io/gomulu-linux/content/misc/strace.html [22]

Komutla:
strace ls /tmp

Process’le:
strace -p $(pidof mysqld)
Dinamik
Process 26829 attached - interrupt to quit
container select(13, [10 12], NULL, NULL, NULL) = 1 (in [10])
18
runtime fcntl64(10, F_SETFL, O_RDWR|O_NONBLOCK) = 0
güvenliği …

Parameteler:
p: process id
strace –p 1234

f: follow fork
strace -f ./example
strace -f -p $(pidof mysqld)

-e: filtreleme
- “strace -f -e trace=open,write,close,connect,select –
p 4230” (adece belirli sistem çağrılarını takip etme)
- “strace -e trace=file 1223” (sadece dosya
işlemleriyle ilgili sistem çağrılarını takip etme)
- “strace -e trace=network 21234” (sadece network ile
ilgili sistem çağrılarını takip etme)

-tt: mikrosanie seviyesinde zaman bilgisi alma


strace -tt ls /tmp

ORHAN FİKRET DUMAN 47 KUBERNETES GÜVENLİĞİ


...
00:07:10.595807 openat(AT_FDCWD, ".",
O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3
00:07:10.595885 getdents(3, /* 6 entries */, 32768) =
176

-c: (count) istatistik bilgisi alma


strace -f -c -p $(pidof mysqld)
% time seconds usecs/call calls errors
syscall
------ ----------- ----------- --------- --------- ----
------------
42.89 0.592035 275 2149 151 read
28.11 0.388024 2587 150 18 futex

-w: (wrap – summarize) özetleme


strace -f -cw -p $(pidof mysqld)

-o: (output) çıktıların kaydedilmesi


strace -f -o /tmp/strace.log -e trace=file ls /tmp

Falco (sysdig):
https://falco.org/docs/getting-started/installation/ [23]
Debian/Ubuntu:
curl -s https://falco.org/repo/falcosecurity-3672BA8F.asc | apt-key add -
echo "deb https://download.falco.org/packages/deb stable main" | tee -
a /etc/apt/sources.list.d/falcosecurity.list
apt-get update –y
apt-get -y install linux-headers-$(uname -r)
apt-get install -y falco
Docker (Least Privileged):
1. Kernel Module Installation:
docker pull falcosecurity/falco-driver-loader:latest
docker run --rm -i -t \
--privileged \
-v /root/.falco:/root/.falco \
-v /proc:/host/proc:ro \
-v /boot:/host/boot:ro \
-v /lib/modules:/host/lib/modules \
-v /usr:/host/usr:ro \
-v /etc:/host/etc:ro \
falcosecurity/falco-driver-loader:latest
2. falco run (Least Privileged olarak çalıştırma):
docker pull falcosecurity/falco-no-driver:latest
docker run --rm -i -t \
-e HOST_ROOT=/ \
--cap-add SYS_PTRACE --pid=host $(ls /dev/falco* |
xargs -I {} echo --device {}) \
-v /var/run/docker.sock:/var/run/docker.sock \
falcosecurity/falco-no-driver:latest
Docker (Least Privileged with eBPF Driver):
1. eBPF Probe’un Yüklenmesi:
docker pull falcosecurity/falco-driver-loader:latest
docker run --rm -i -t \
--privileged \
-v /root/.falco:/root/.falco \
-v /proc:/host/proc:ro \
-v /boot:/host/boot:ro \

ORHAN FİKRET DUMAN 48 KUBERNETES GÜVENLİĞİ


-v /lib/modules:/host/lib/modules:ro \
-v /usr:/host/usr:ro \
-v /etc:/host/etc:ro \
falcosecurity/falco-driver-loader:latest bpf
2. falco run:
docker pull falcosecurity/falco-no-driver:latest
docker run --rm -i -t \
--cap-drop all \
--cap-add sys_admin \
--cap-add sys_resource \
--cap-add sys_ptrace \
-v /var/run/docker.sock:/host/var/run/docker.sock \
-e FALCO_BPF_PROBE="" \
-v /root/.falco:/root/.falco \
-v /etc:/host/etc \
-v /proc:/host/proc:ro \
falcosecurity/falco-no-driver:latest
Not: Sistemde apparmor etkinse; “--security-opt
apparmor:unconfined” parametresi eklenmelidir.
Docker (Fully Privileged):
1. Kernel Module Installation:
docker pull falcosecurity/falco:latest
docker run --rm -i -t \
--privileged \
-v /var/run/docker.sock:/host/var/run/docker.sock \
-v /dev:/host/dev \
-v /proc:/host/proc:ro \
-v /boot:/host/boot:ro \
-v /lib/modules:/host/lib/modules:ro \
-v /usr:/host/usr:ro \
-v /etc:/host/etc:ro \
falcosecurity/falco:latest
2. falco run:
docker pull falcosecurity/falco:latest
docker run --rm -i -t \
--privileged \
-e FALCO_BPF_PROBE="" \
-v /var/run/docker.sock:/host/var/run/docker.sock \
-v /proc:/host/proc:ro \
-v /boot:/host/boot:ro \
-v /lib/modules:/host/lib/modules:ro \
-v /usr:/host/usr:ro \
-v /etc:/host/etc:ro \
falcosecurity/falco:latest

Not: Hot Reload: falco daemon’unu restart etmeden ve process id’si


değişmeden falco konfigürasyonunu ve engine’ini yeniden başlatmak
için:
kill -1 $(cat /var/run/falco.pid)

falco konfigürasyon dosyaları:


Default Rules File: /etc/falco/falco_rules.yaml (varsayılan falco
kuralları ön tanımlı olarak bu dosya ile gelir)
Local Rules File: /etc/falco/falco_rules.local.yaml (boş olarak gelir.
Override edilmek istenen kurallar buraya kopyalanabilir. Bu kısımdaki
kurallar default rule’da yer alan kuralları değiştirir.)

Örnek falco rule’ları:

ORHAN FİKRET DUMAN 49 KUBERNETES GÜVENLİĞİ


A shell is run in a container:
- macro: container
condition: container.id != host

- macro: spawned_process
condition: evt.type = execve and evt.dir=<

- rule: run_shell_in_container
desc: a shell was spawned by a non-shell program in a
container. Container entrypoints are excluded.
condition: container and proc.name = bash and
spawned_process and proc.pname exists and not proc.pname
in (bash, docker)
output: "Shell spawned in a container other than
entrypoint (user=%user.name container_id=%container.id
container_name=%container.name shell=%proc.name
parent=%proc.pname cmdline=%proc.cmdline)"
priority: WARNING

Non-authorized container namespace change:


- rule: change_thread_namespace
desc: an attempt to change a program/thread\'s
namespace (commonly done as a part of creating a
container) by calling setns.
condition: syscall.type = setns and not proc.name in
(docker, sysdig, dragent)
output: "Namespace change (setns) by unexpected program
(user=%user.name command=%proc.cmdline
container=%container.id)"
priority: WARNING

AppArmor:
AppArmor, etkili ve kullanımı kolay bir Linux uygulama güvenlik
sistemidir. AppArmor, iyi davranışı zorunlu kılarak ve hem bilinen hem
de bilinmeyen uygulama kusurlarından yararlanılmasını önleyerek
işletim sistemini ve uygulamaları harici veya dahili tehditlere, hatta sıfır
gün saldırılarına karşı proaktif olarak korur.
AppArmor, zorunlu erişim denetimi (MAC) sağlayarak geleneksel Unix
isteğe bağlı erişim denetimi (DAC) modelini tamamlar. 2.6.36
sürümünden beri ana Linux çekirdeğine dahil edilmiştir ve gelişimi
2009'dan beri Canonical tarafından desteklenmektedir.

https://gitlab.com/apparmor/apparmor/-/wikis/Documentation [24]
https://kubernetes.io/docs/tutorials/security/apparmor/ [25]
Sistem
19
sıkılaştırması AppArmor’ın Kubernetes’le birlikte kullanımı için:
- Container runtime’ın (docker,containerd,rkt vb.) apparmor’ı
desteklemesi,
- AppArmor’ın tüm worker node’larda yüklü olması,
- AppArmor profile’larının tüm worker node’larda yüklü olması,
gerekmektedir.
- AppArmor profile’ları container seviyesinde tanımlanır (pod
seviyesinde değil) ve bu işlem annotation kullanılarak yapılır.

Örnek bir AppArmor Profile:


/profile {
/path/to/file* r, # allow read to /path/to/fil
e*

ORHAN FİKRET DUMAN 50 KUBERNETES GÜVENLİĞİ


/path/to/file1 w, # allow write to /path/to/fi
le1
deny /path/to/file2, w, # deny write to /path/to/fil
e2, without logging
audit /path/to/file3 w, # allow write to /path/to/fi
le3, with logging
audit deny /path/to/file4 r, # deny read to /path/to
/file4, with logging
}

AppArmor Profile Yükleme:


1. apt-get install apparmor-utils yüklenir.
2. AppArmor profile  /etc/apparmor.d/ klasörü içerisinde oluşturulur.
3. apparmor_parser “profile_name” komutuyla yüklenir.
4. aa-status komutuyla yüklü profiller listelenir.

AppArmor Profile Oluşturma:


1. aa-genprof /usr/bin/curl ile profil oluşturulur (finish-save ile deny rule).
2. aa-logprof ile profil güncellenir (normal izinler verilir).

K8s Pod’larında Apparmor Kullanımı:


1. Pod tanımında annotations kullanılarak tanımlanır:

“container.apparmor.security.beta.kubernetes.io/<con
tainer_name>:localhost/<profile_name>”
Örnek:
container.apparmor.security.beta.kubernetes.io/my-
container:localhost/my-profile
(ls -al /etc/apparmor.d  my-profile)

Seccomp:
seccomp (secure computing), Linux çekirdeğindeki (versiyon 2.6.12’den
beri) bir güvenlik özelliğidir. Seccomp, bir işlemin, halihazırda açık olan
dosya tanımlayıcılarına (file descriptor) exit(), sigreturn(), read() ve
write() dışında herhangi bir sistem çağrısı (syscall) yapamamasını
sağlar. Belirtilenlerden başka bir sistem çağrısı denenirse, kernel, ya
olayı günlüğe kaydeder ya da SIGKILL ya da SIGSYS ile süreci
sonlandırır. Sistemin kaynaklarını sanallaştırmaz, ancak süreci onlardan
tamamen izole eder.

Container Seviyesinde Kullanımı:


docker run --rm -it --security-opt
seccomp=/path/to/seccomp/profile.json \
hello-world
Örnek: (seccomp=unconfined ile default seccomp profilini devre dışı
bırakır)

docker run --rm -it --security-opt seccomp=unconfined


debian:jessie unshare --map-root-user --user \
sh -c whoami

Kubernetes Ortamında Kullanımı:


https://kubernetes.io/docs/tutorials/security/seccomp/ [26]

Kubernetes ortamında seccomp, kullanıcı alanından çekirdeğe


yapılabilecek çağrıları kısıtlayarak, bir işlemin ayrıcalıklarını izole etmek
için kullanılabilir. Kubernetes, bir node’a yüklenen seccomp profillerinin
pod'lara ve container’lara otomatik olarak uygulanabilmesini sağlar.

ORHAN FİKRET DUMAN 51 KUBERNETES GÜVENLİĞİ


Seccomp Profillerinin Node’lara Yüklenmesi:
3 çeşit secocmp profili vardır. Bunlar:
- Unconfined (seccomp disabled),
- RuntimeDefault,
- Localhost.
Seccomp profilleri kubelet –root-dir parametresi ile belirlenen dizin
içerisindeki seccomp dizinine yüklenir.
Default –root-dir: /var/lib/kubelet olduğundan Localhost profile’ları için
dizin tanımı genellikle: “/var/lib/kubelet/seccomp/profiles/profile.json”
şeklindedir.
Profil dosyaları oluşturulacak profiles dizini içerisine kopyalanır.

Örnek seccomp profil dosyaları:


audit.json: Tüm syscall çağrıları için yalnızca loglama yapar.
{
"defaultAction": "SCMP_ACT_LOG"
}

violation.json: Tüm syscall çağrılarını engeller.


{
"defaultAction": "SCMP_ACT_ERRNO"
}

fine-grained.json: Whitelist şeklinde syscall çağrılarına izin verir.


{
"defaultAction": "SCMP_ACT_ERRNO", #Default deny
"architectures": [
"SCMP_ARCH_X86_64",
"SCMP_ARCH_X86",
"SCMP_ARCH_X32"
],
"syscalls": [ #İzin verilen syscalls
{
"names": [
"accept4",
"epoll_wait",
"pselect6",

],
"action": "SCMP_ACT_ALLOW"
}
]
}

Localhost seccomp profilleri tüm worker node’lara yüklenmelidir.


(/var/lib/kubelet/seccomp/profiles/ alanına)

Default Seccomp Profili Olarak RuntimeDefault Tanımlanması:


- Seccomp feature gate enabled olmalıdır.
- Kubelet servis parametresi olarak --seccomp-default=true
tanımlanmalıdır. (Ya da “kubelet configuration file”a yazılmalıdır.)
Her uygulamanın syscall ihtiyaçları farklı olacağından RuntimeDefault
tanımı da bazı uygulamaların çalışmalarını etkileyebilir. Bu nedenle
Kubernetes projesi, RuntimeDefault kullanımının öncelikle sınırlı sayıda
node’daki iş yüklerinde test edilmesini, diğer node’lar için custom

ORHAN FİKRET DUMAN 52 KUBERNETES GÜVENLİĞİ


profiller oluşturulmasını, test sonucuna göre yaygınlaştırılmasını
önermektedir.

https://github.com/kubernetes/enhancements/tree/9a124fd29d1f9ddf2ff
455c49a630e3181992c25/keps/sig-node/2413-seccomp-by-
default#upgrade--downgrade-strategy [27]

Seccomp Profillerinin Pod’larla Birlikte Kullanımı:


Seccomp profilleri pod’lara “securityContext” içerisinde tanımlanır:

Pod Tarafından Yapılan Syscall’ların Denetimi: Yukarıdaki audit.json


profili ile pod tarafından yapılan syscall’ların loglanması sağlanır.
Container içerisinde privilege escalation engellenir.
apiVersion: v1
kind: Pod
metadata:
name: audit-pod
labels:
app: audit-pod
spec:
securityContext:
seccompProfile:
type: Localhost
localhostProfile: profiles/audit.json
containers:
- name: test-container
image: hashicorp/http-echo:0.2.3
args:
- "-text=just made some syscalls!"
securityContext:
allowPrivilegeEscalation: false

1. kubectl apply –f audit-pod.yaml

2. kubectl expose pod audit-pod --type NodePort --port 5678

3. kubectl get service audit-pod

NAME TYPE PORT(S)


audit-pod NodePort 5678:32373/TCP

4. crictl ps

5. crictl exec -it 6a96207fed4b curl localhost:32373

6. just made some syscalls!

7. tail -f /var/log/syslog | grep 'http-echo'

8. ... syscall=51 compat=0 ip=0x46fe1f code=0x7ffc0000


... syscall=54 compat=0 ip=0x46fdba code=0x7ffc0000

Profil Violation Durumlarının İzlenmesi: Yukarıdaki violation.json


profili ile syscall’ların engellenmesi sağlanır. Container içerisinde
privilege escalation engellenir.
apiVersion: v1
kind: Pod
metadata:
name: violation-pod

ORHAN FİKRET DUMAN 53 KUBERNETES GÜVENLİĞİ


labels:
app: violation-pod
spec:
securityContext:
seccompProfile:
type: Localhost
localhostProfile: profiles/violation.json
containers:
- name: test-container
image: hashicorp/http-echo:0.2.3
args:
- "-text=just made some syscalls!"
securityContext:
allowPrivilegeEscalation: false

1. kubectl apply –f violation-pod.yaml

2. kubectl get pod/violation-pod

NAME READY STATUS RESTARTS AGE


violation-pod 0/1 CrashLoopBackOff 1 6s

Not: Profil tanımındaki "defaultAction": "SCMP_ACT_ERRNO" tanımı


(default deny) nedeniyle gerekli sistem çağrıları yapılamadığından pod
ayağa kalkamamaktadır.

Özelleştirilmiş Seccomp Profillerinin Tanımlanması: Yukarıdaki fine-


grained.json profili ile belirli syscall’lara izin verilmesi sağlanır. Container
içerisinde privilege escalation engellenir.
apiVersion: v1
kind: Pod
metadata:
name: fine-pod
labels:
app: fine-pod
spec:
securityContext:
seccompProfile:
type: Localhost
localhostProfile: profiles/fine-grained.json
containers:
- name: test-container
image: hashicorp/http-echo:0.2.3
args:
- "-text=just made some syscalls!"
securityContext:
allowPrivilegeEscalation: false

1. kubectl apply –f fine-pod.yaml

2. kubectl expose pod fine-pod --type NodePort --port 5678

3. kubectl get service fine-pod

NAME TYPE PORT(S)


fine-pod NodePort 5678:32373/TCP

4. crictl ps #container_id bulunur (6a96207fed4b).

ORHAN FİKRET DUMAN 54 KUBERNETES GÜVENLİĞİ


5. crictl exec -it 6a96207fed4b curl localhost:32373

6. just made some syscalls!

7. tail -f /var/log/syslog | grep 'http-echo'

8. ... #syslog çıktısı bulunmaz. Tanımlı syscall’lar


haricinde bir çağrı olursa onları loglar.

Container Runtime Default Seccomp Profilinin Uygulanması:


RuntimeDefault profili uygulanır. Privilege Escalation container
seviyesinde engellenir.
apiVersion: v1
kind: Pod
metadata:
name: default-pod
labels:
app: default-pod
spec:
securityContext:
seccompProfile:
type: RuntimeDefault
containers:
- name: test-container
image: hashicorp/http-echo:0.2.3
args:
- "-text=just made some more syscalls!"
securityContext:
allowPrivilegeEscalation: false

1. kubectl apply –f default-pod.yaml

2. kubectl get pod default-pod

NAME READY STATUS RESTARTS AGE


default-pod 1/1 Running 0 20s

Pod, normal şekilde başlatılır.


Auditing:
Kubernetes denetimi, bir cluster’daki eylem sırasını belgeleyen
güvenlikle ilgili, kronolojik bir kayıt kümesi sağlar. Cluster, auditing ile,
kullanıcılar, Kubernetes API'sini kullanan uygulamalar ve controlplane’in
kendisi tarafından oluşturulan etkinlikleri takip eder.

Auditing, cluster admin’lerinin aşağıdaki soruları yanıtlamasına olanak


tanır:
Audit logların
20
etkinleştirilmesi - Ne oldu?
- Ne zaman oldu?
- Kim başlattı?
- Ne üzerine oldu?
- Nerede gözlemlendi?
- Nereden başlatıldı?
- Nereyi hedefliyordu?

ORHAN FİKRET DUMAN 55 KUBERNETES GÜVENLİĞİ


Denetim kayıtları (audit logs), yaşam döngülerine kube-apserver
bileşeni içinde başlar. Yürütülme aşamasındaki her istek, daha sonra
belirli bir ilkeye (policy) göre önceden işlenen ve bir backend’e yazılan
bir denetim olayı oluşturur. Politika, neyin kaydedildiğini belirler ve
backend kayıtları kalıcı hale getirir. Mevcut backend uygulamaları,
günlük dosyalarını (log files) ve webhook’ları içerir.

Her istek, ilişkili bir aşama (stage) ile kaydedilir. Tanımlanan aşamalar
şunlardır:

- RequestReceived: Denetim işleyicisi (audit handler) isteği alır almaz


ve işleyici zincirinde (handler chain) yetkilendirilmeden önce oluşturulan
olaylar için aşama.
- ResponseStarted: Yanıt başlıkları (response headers) gönderildikten
sonra, ancak yanıt gövdesi (response body) gönderilmeden önce. Bu
aşama yalnızca uzun süreli istekler için oluşturulur (örn. “watch”).
- ResponseComplete: Yanıt gövdesi (response body) tamamlandı ve
daha fazla bayt gönderilmeyecek.
- Panic: Panic durumu meydana geldiğinde oluşturulan olaylar.

Denetim günlüğü özelliği, her istek esnasında denetim için gereken bazı
bağlamlar (context) depolandığından, API sunucusunun bellek
tüketimini artırır. Bellek tüketimi, denetim günlüğü yapılandırmasına
bağlıdır.

Audit Policy:

Denetim politikası, hangi olayların kaydedilmesi gerektiği ve hangi


verileri içermesi gerektiğiyle ilgili kuralları tanımlar. Denetim ilkesi nesne
yapısı, “audit.k8s.io” API grubunda tanımlanır. Bir olay işlendiğinde,
sırayla kurallar listesiyle karşılaştırılır. İlk eşleştirme kuralı, olayın
denetim düzeyini (audit level) belirler. Tanımlanmış denetim seviyeleri
(audit level) şunlardır:

Audit Levels:
- None: Bu kuralla eşleşen olaylar günlüğe kaydedilmez
- Metadata: İstek metadatalarını (istek kullanıcı (user), zaman damgası
(timestamp), kaynak (resource), fiil (verb) vb.) günlüğe kaydeder, ancak
istek veya yanıt gövdesini kaydetmez.
- Request: Olay (event) metadatalarını ve istek gövdesini (request
body) günlüğe kaydeder ancak yanıt gövdesini (response body)
kaydetmez. Bu, kaynak dışı istekler (non-resource requests) için geçerli
değildir.
- RequestResponse: Olay metadatalarını, istek ve yanıt gövdelerini
günlüğe kaydeder. Bu, kaynak dışı istekler için geçerli değildir.

“--audit-policy-file” flag’i ile politika dosyası kube-apiserver'a


tanımlanabilir. Flag göz ardı (omit) edilirse, hiçbir olay günlüğe
kaydedilmez. Denetim ilkesi dosyasında “rules” alanının sağlanması
gerekmektedir. Kuralı olmayan bir politika geçersizdir.

Audit policy dosyası sıralı olarak işlenir. Yukarıdan aşağıya doğru ilk
eşleşmede belirlenen log seviyesine göre resource/user/group’lara
ilişkin loglama yapılır. Eşleşme olmazsa (tanımlanması halinde) en
alttaki “catch-all” kuralına göre işlem yapılır (genellikle level: metadata).
Omit edilen aşamalar (omitStages) göz ardı edilir, herhangi bir işlem
yapılmaz.

Örnek bir audit policy dosyası:


https://kubernetes.io/docs/tasks/debug/debug-cluster/audit/ [13]

ORHAN FİKRET DUMAN 56 KUBERNETES GÜVENLİĞİ


apiVersion: audit.k8s.io/v1 # This is required.
kind: Policy
# Don't generate audit events for all requests in
RequestReceived stage.
omitStages:
- "RequestReceived"
rules:
# Log pod changes at RequestResponse level
- level: RequestResponse
resources:
- group: ""
# Resource "pods" doesn't match requests to any
subresource of pods,
# which is consistent with the RBAC policy.
resources: ["pods"]
# Log "pods/log", "pods/status" at Metadata level
- level: Metadata
resources:
- group: ""
resources: ["pods/log", "pods/status"]

# Don't log requests to a configmap called "controller-


leader"
- level: None
resources:
- group: ""
resources: ["configmaps"]
resourceNames: ["controller-leader"]

# Don't log watch requests by the "system:kube-proxy" on


endpoints or services
- level: None
users: ["system:kube-proxy"]
verbs: ["watch"]
resources:
- group: "" # core API group
resources: ["endpoints", "services"]

# Don't log authenticated requests to certain non-


resource URL paths.
- level: None
userGroups: ["system:authenticated"]
nonResourceURLs:
- "/api*" # Wildcard matching.
- "/version"

# Log the request body of configmap changes in kube-


system.
- level: Request
resources:
- group: "" # core API group
resources: ["configmaps"]
# This rule only applies to resources in the "kube-
system" namespace.
# The empty string "" can be used to select non-
namespaced resources.
namespaces: ["kube-system"]

ORHAN FİKRET DUMAN 57 KUBERNETES GÜVENLİĞİ


# Log configmap and secret changes in all other
namespaces at the Metadata level.
- level: Metadata
resources:
- group: "" # core API group
resources: ["secrets", "configmaps"]

# Log all other resources in core and extensions at the


Request level.
- level: Request
resources:
- group: "" # core API group
- group: "extensions" # Version of group should NOT be
included.

# A catch-all rule to log all other requests at the


Metadata level.
- level: Metadata
# Long-running requests like watches that fall under
this rule will not
# generate an audit event in RequestReceived.
omitStages:
- "RequestReceived"

Not: Secret’lara ilişkin log level: “RequestResponse” olmamalıdır. Böyle


olursa secret içerisindeki hassas veri log ortamına taşınmış olur. Bu
nedenle secret resource’ları için log level: “metadata” düzeyinde
tutulmalıdır.

Tüm istekleri metadata seviyesinde loglamak için minimal bir audit policy
dosyası:

# Log all requests at the Metadata level.


apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata

Audit Backend’leri: Audit backend’leri audit event’lerini harici olarak


depolar. Kube-apiserver iki backend sağlar:
- Log Backend: Event’leri bir dosya sistemine (filesystem) yazar. Log
backend audit event’lerini JSONlines formatında bir dosyaya yazar.
Aşağıdaki kube-apiserver flag’leri ile tanımlanır:
--audit-log-path: Log’ların nereye yazılacağını belirler. Tanımlanmazsa
loglama iptal edilmiş olur.
--audit-log-maxage: Eski audit log dosyalarının ne kadar süreyle
saklanacağını belirler.
--audit-log-maxbackup: Saklanacak audit dosyalarının sayısını belirler.
--audit-log-maxsize: Log rotasyonu yapılmadan önce audit log
dosyalarının maksimum dosya boyutunu belirler.

Kubeadm kurulumu ile kube-apiserver bir statik pod olarak


çalıştırılıyorsa, aşağıdaki flag’ler /etc/kubernetes/manifests/kube-
apiserver.yaml dosyası içerisinde tanımlanır. Ayrıca policy ve log
dosyalarının saklanacağı depolama alanları hostPath olarak mount
edilir:

ORHAN FİKRET DUMAN 58 KUBERNETES GÜVENLİĞİ


--audit-policy-file=/etc/kubernetes/audit-policy.yaml
\
--audit-log-path=/var/log/kubernetes/audit/audit.log

...
volumeMounts:
- mountPath: /etc/kubernetes/audit-policy.yaml
name: audit
readOnly: true
- mountPath: /var/log/kubernetes/audit/
name: audit-log
readOnly: false
...
volumes:
- name: audit
hostPath:
path: /etc/kubernetes/audit-policy.yaml
type: File

- name: audit-log
hostPath:
path: /var/log/kubernetes/audit/
type: DirectoryOrCreate

- Webhook Backend: Event’leri harici bir HTTP API’a gönderir.


Webhook backend’i kube-apiserver’a aşağıdaki flag’lerin girilmesiyle
tanımlanabilir:

--audit-webhook-config-file: Webhook konfigürasyon dosyasına


olan path’i belirtir. Webhook konfigürasyon dosyası özelleştirilmiş bir
kubeconfig dosyasıdır. Harici servis adresi ve bağlantı için yetki
tanımlarını (credentials) içerir.
--audit-webhook-initial-backoff: İlk başarısız denemeden sonra
tekrar deneme için beklenmesi gereken süreyi belirtir.

Audit log’ları veri büyüklüğü ve daha esnek işleme olanakları nedeniyle


genellikle ElasticSearch, FileBeat, Fluentd gibi harici logging
backend’lerine gönderilir.

ORHAN FİKRET DUMAN 59 KUBERNETES GÜVENLİĞİ


Referanslar

[1] NSA,CISA, “Cybersecurity Technical Report:Kubernetes Hardening Guide v1.1”


[Online]https://media.defense.gov/2022/Aug/29/2003066362/-1/-1/0/CTR_Kubernetes_
Hardening_Guidance_1.2_20220829.PDF
[2] https://katacontainers.io/
[3] https://github.com/kata-containers/kata-containers/tree/main/docs/install
[4] https://github.com/kata-containers/kata-containers/tree/main/docs/design/architecture
[5] https://github.com/kata-containers/kata-containers/tree/main/docs/design
[6] https://gvisor.dev/
[7] https://github.com/google/gvisor
[8] https://kubernetes.io/docs/tasks/administer-cluster/declare-network-policy/
[9] https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/quota-memory-
cpu-namespace/
[10] https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data
[11] https://kubernetes.io/docs/tasks/administer-cluster/kms-provider
[12] Learn Kubernetes Security, Kaizhe Huang and Pranjal Jumde, 2020
[13] https://kubernetes.io/docs/tasks/debug/debug-cluster/audit/
[14] https://istio.io/latest/docs/ops/deployment/architecture/
[15] Center for Internet Security, "CIS Benchmarks Securing Kubernetes," 2021. [Online].
Available: https://cisecurity.org/benchmark/kubernetes/.
[16] https://www.openpolicyagent.org/docs/latest/policy-language/
[17] https://github.com/quay/clair
[18] https://quay.github.io/clair/
[19] https://github.com/aquasecurity/trivy
[20] https://www.aquasec.com/products/trivy/
[21] https://man7.org/linux/man-pages/man1/strace.1.html
[22] Strace Kullanımı https://demirten.gitbooks.io/gomulu-linux/content/misc/strace.html
[23] https://falco.org/docs/getting-started/installation/
[24] https://gitlab.com/apparmor/apparmor/-/wikis/Documentation
[25] https://kubernetes.io/docs/tutorials/security/apparmor/
[26] https://kubernetes.io/docs/tutorials/security/seccomp/
[27]https://github.com/kubernetes/enhancements/tree/9a124fd29d1f9ddf2ff455c49a630e318
1992c25/keps/sig-node/2413-seccomp-by-default#upgrade--downgrade-strategy

ORHAN FİKRET DUMAN 60 KUBERNETES GÜVENLİĞİ

You might also like