Professional Documents
Culture Documents
Kubernetes Hardening
Kubernetes Hardening
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.
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:
Ş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.
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:
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.
4. Ağ Bölümleme ve Sıkılaştırma:
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
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
spec:
podSelector: {}
policyType:
- Ingress
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-egress
spec:
podSelector: {}
policyType:
- Egress
1 Network Policy API’sini destekleyen bir CNI (weave, calico vb.) 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.
1. Her container’ın bir bellek isteği, sınırı, CPU isteği ve sınırı olmalıdır,
Bir kullanıcı LimitRange veya ResourceQuota ilkesini ihlal eden bir Pod
oluşturmaya çalışırsa Pod oluşturma başarısız olur.”
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
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
“kube-apiserver --authorization-mode=RBAC”
“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.
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.
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
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.
Kritik
1 Deployments ve değişiklikler
# 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.
...
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.
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:
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ı,
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 –“
Kullanım Şekilleri:
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"
}
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}
Ö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]
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
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
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)
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 \
- 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
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.
“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.
https://github.com/kubernetes/enhancements/tree/9a124fd29d1f9ddf2ff
455c49a630e3181992c25/keps/sig-node/2413-seccomp-by-
default#upgrade--downgrade-strategy [27]
4. crictl ps
Her istek, ilişkili bir aşama (stage) ile kaydedilir. Tanımlanan aşamalar
şunlardır:
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:
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 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.
Tüm istekleri metadata seviyesinde loglamak için minimal bir audit policy
dosyası:
...
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