İçeriğe atla
0 XP 0
12 dkderinleşmeyle 13 dk60 XP6 etkinlik

RBAC ve ServiceAccount jetonu

Bu derste
  • RBAC dört nesneden kurulur ve her pod bir ServiceAccount kimliğiyle API sunucusuna konuşur; yetkiyi denemeden sorabilirsin.
  • Her pod bir hizmet hesabıyla çalışır ve jetonu dosya olarak taşır.
  • Yetkiyi denemeden sormanın yolu kubectl auth can-i komutudur.

Puan bütün etkinlikleri cevaplayınca hesaba yazılır. Bu dersi tamamlayınca +60 XP alacaksın. Giriş yapmadan ilerlersen puan yalnız bu tarayıcıda durur.

Kubernetes'te yetkiyi anlamak, az sayıda nesneyi ve aralarındaki bağları çözmekten geçer. Yetki rol tabanlıdır: ne yapılabileceğini roller söyler, kime verildiğini bağlar söyler.

Bu iki soruyu ayrı tutarsan karmaşa dağılır. Bu derste önce dört parçayı tanırsın, sonra podların hangi kimlikle konuştuğunu izlersin, ardından yetkiyi hiçbir nesneye dokunmadan nasıl sorgulayacağını öğrenirsin, en sonda yükseltme yollarını kapatırsın. Komutları kendi laboratuvar kümende çalıştırabilirsin; hepsi okuma amaçlıdır ve kümeyi değiştirmez.

RBAC'in dört parçası

RBAC dört nesneden kurulur. Role tek bir ad alanında izin tanımlar. ClusterRole aynı işi küme genelinde yapar.

RoleBinding bir rolü bir ad alanında bir özneye takar. ClusterRoleBinding ise bir küme rolünü her ad alanında geçerli kılar. Bu dörtlüyü iki eksende düşün: biri kapsam (ad alanı mı, küme mi), öteki iş (izin tanımlamak mı, izni birine bağlamak mı).

İzinler yalnız eklenir; RBAC'te red kuralı yoktur. Yani bir kimliğin yetkisi, ona bağlanan tüm rollerin birleşimidir ve bir yerde verilen izni başka bir yerde geri almak mümkün değildir.

Bir izin üç alandan yazılır: hangi API grubunda, hangi kaynakta, hangi fiillerle. Fiiller get, list, watch, create, update, patch ve delete gibi işlemlerdir ve her biri ayrı bir yetkidir. Fiil listesine yıldız yazmak o kaynağın bütün işlemlerini açar ve silme de o listenin içindedir.

Çoğu rol gereğinden geniş yazılır, çünkü yıldız yazmak tek tek fiil saymaktan kolaydır. Oysa okuma yeten yerde yazma ve silme vermek, bugün kullanılmasa bile yarın bir açık olduğunda saldırgana hazır bir kapı bırakır. En az yetki ilkesi tam da bu fiil listesinde başlar.

Sık yapılan karışıklık bağ türündedir. Bir küme rolünü ad alanı bağıyla verirsen, iznin o ad alanına daralır. Aynı rolü küme bağıyla verirsen her ad alanında geçerli olur.

Bir RoleBinding, bir ClusterRole'e de işaret edebilir; bu durumda küme rolündeki izinler yalnız o bağın bulunduğu ad alanında uygulanır. Bu desen aslında işe yarar: tek bir hazır küme rolünü yazar, onu farklı ekiplere kendi ad alanlarında bağlarsın. Tehlike ters yöndedir: geniş bir yerleşik rolü yanlışlıkla küme bağıyla vermek, dar sandığın bir yetkiyi kümenin tamamına açar.

Etkinlik 1 / 6

RBAC nesnesini kapsamı ile eşleştir.

Soldan bir tane seç, sağdan eşini seç. Kullanılmış bir seçeneği yeniden seçersen yeni öğeye taşınır.

ServiceAccount jetonu

Bağların hedefi yalnız insan değildir. Her pod bir ServiceAccount kimliğiyle çalışır ve bu hesap da RBAC'te sıradan bir özne sayılır; API sunucusu insanı, grubu ve hizmet hesabını aynı yetkilendirme mantığıyla değerlendirir. Bir hesabın küme içi kimliği system:serviceaccount:<ad alanı>:<ad> biçimindedir, yani ada bağlıdır; ad alanı değişince kimlik de değişir.

Pod bir hesap belirtmezse ad alanının varsayılan hesabıyla çalışır. Varsayılan hesaba yetki bağlamak, o ad alanındaki her poda o yetkiyi vermek demektir, bu yüzden varsayılan hesabı dar ve yetkisiz bırakmak güvenli yoldur.

Hesabın jetonu poda bir birim olarak bağlanır ve dosya sisteminde durur. Güncel sürümlerde kubelet bu jetonu TokenRequest API'siyle alır; jeton süreli bir jetondur, bir hedef kitleye ve poda bağlıdır, süresi dolmadan kendiliğinden yenilenir.

Eski sürümlerin süresiz Secret jetonlarının aksine bu jetonun bir son kullanma zamanı vardır ve pod silinince geçersiz olur. Yine de pod yaşadığı sürece geçerli bir jeton taşır. Bu yüzden uygulamada bir dosya okuma açığı varsa saldırganın ilk arayacağı yol budur; jetonu bulursa artık API sunucusuna o hesabın yetkisiyle konuşabilir.

apiVersion: v1
kind: Pod
metadata:
  name: api
spec:
  serviceAccountName: api-hesabi
  automountServiceAccountToken: false
  containers:
    - name: api
      image: uygulama:1.4
Uygulama küme API'sine konuşmuyorsa jetonu hiç bağlamazsın; automountServiceAccountToken değerini false yaparsın.

Jeton varsayılan olarak podun içinde sabit bir yola bağlanır: /var/run/secrets/kubernetes.io/serviceaccount altında token, ca.crt ve namespace dosyaları durur. token API sunucusuna kimlik kanıtlar, ca.crt sunucunun sertifikasını doğrular, namespace podun ad alanını söyler. Uygulama küme API'sine hiç konuşmuyorsa bu dosyaları bağlamanın bir gereği yoktur.

automountServiceAccountToken değerini false yapmak, pod ele geçse bile içeride hazır bekleyen kimliği ortadan kaldırır. Bu ayarı pod düzeyinde verdiğinde hesap ayarını geçersiz kılar, yani jetona gerçekten ihtiyacı olan iş yükleri yine bağlayabilir; bedava bir kazançtır.

Etkinlik 2 / 6

Pod içindeki ServiceAccount jetonu varsayılan olarak nereden okunur?

Derinleş:Kısa ömürlü jetonlar nasıl çalışır

Kubernetes 1.22'den beri pod jetonu bir projeksiyon birimiyle verilir ve TokenRequest API'si üstünden üretilir. Jetonun bir süresi, bir hedef kitlesi ve bağlı olduğu pod vardır; pod silinince jeton da geçersiz olur. kubelet varsayılan olarak 3607 saniyelik, yani bir saatten biraz uzun bir jeton ister ve süre dolmadan yenisini alır.

Bir ayrıntıyı bilmek gerekir: API sunucusu, eski istemciler kırılmasın diye bu jetonların geçerliliğini varsayılan olarak bir yıla kadar uzatabilir. Bu davranışı --service-account-extend-token-expiration bayrağı yönetir. 1.24'ten beri bir ServiceAccount oluşturulduğunda kalıcı bir jeton Secret'ı artık otomatik üretilmez.

Güncel sürümlerde kullanılmayan eski otomatik jetonlar bir yıl sonra geçersiz işaretlenir, bir süre daha kullanılmazsa silinir. Elle süreli bir jeton gerekiyorsa kubectl create token komutuyla, istenen süreyle istenir.

Yetkiyi denemeden sormak

Yetkiyi anlamak için onu kullanman gerekmez. kubectl auth can-i komutu kararı API sunucusuna sordurur ve hiçbir nesneye dokunmaz; bir sırrı okumadan sır okuyabilir misin diye sorabilirsin. Tek bir soruyu da sorabilirsin, bütün izinlerini de listeleyebilirsin.

Yetkili bir denetimde yetki haritasını böyle çıkarırsın: hiçbir pod oluşturmadan, hiçbir sır okumadan kimin neye erişebildiğini görürsün. Komut, bir hesabın gerçek yetkisini güvenle ölçmenin en zararsız yoludur ve bir yanlış yapılandırmayı kanıta çevirirken kümeyi hiç riske atmaz.

$ kubectl auth can-i --list -n uretim
Resources                                       Non-Resource URLs   Resource Names   Verbs
selfsubjectreviews.authentication.k8s.io        []                  []               [create]
selfsubjectaccessreviews.authorization.k8s.io   []                  []               [create]
selfsubjectrulesreviews.authorization.k8s.io    []                  []               [create]
configmaps                                      []                  []               [get list watch]
pods                                            []                  []               [get list watch]
pods/log                                        []                  []               [get]
                                                [/healthz]          []               [get]
auth can-i --list bir ad alanındaki tüm izinlerini özetler: burada sır okuma yetkisi yok.

Çıktıyı oku. İlk üç satır her kimliğe verilen yerleşik izinlerdir; kimliğin kendi yetkisini sorabilmesi bunlar sayesindedir. configmaps ve pods üstünde yalnız okuma fiilleri var, pods/log tek başına get taşır. secrets satırı hiç yok, yani bu kimlik sır okuyamaz.

Köşeli parantezli adres bir kaynak değil, kaynak dışı bir uçtur; burada sağlık ucu. Başka bir hesabın yetkisine bakmak istersen komuta --as bayrağıyla hedef kimliği eklersin, örneğin --as=system:serviceaccount:ci:derleyici. Bunun için senin bürünme yetkin olmalıdır, bu yüzden bu soruyu çoğu zaman küme yöneticisi sorar. Sırları kimin okuyabildiği sorusunun yanıtı genelde beklenenden uzun çıkar, çünkü yerleşik roller ve geniş bağlar beklenmedik hesaplara izin taşır.

Etkinlik 3 / 6

Kendi laboratuvar kümende, uretim ad alanında sır okuma yetkin olup olmadığını sor.

ogrenci@lab

Aşırı yetki ve yükseltme yolları

RBAC denetiminde yalnız yönetici rollerine bakmak eksiktir, çünkü bazı sıradan görünen izinler dolaylı olarak kümeyi açar. Sırlar üstünde list ve watch yetkisi, get kadar tehlikelidir: bir liste yanıtı sırların içeriğini de döndürür, yani tek tek okuma yetkisi olmadan da bütün sırlar görünür. Pod oluşturma yetkisi, o ad alanındaki her hizmet hesabına bürünmeye yakındır; istediğin hesapla bir pod açıp jetonunu okursun ve o hesabın yetkisini devralırsın.

pods/exec çalışan konteynerin içine girmeyi verir. nodes/proxy ise kubelet API'sine ulaşmayı verir; resmî belgeye göre bu yol denetim günlüğünü ve kabul denetimini de atlar ve get fiili bile yeter. Bu izinler ayrı ayrı listelenmezse gözden kaçar.

Üç özel fiil de bu tabloya girer. RBAC normalde bir kimliğin kendinde olmayan bir izni bir role yazmasını engeller. escalate fiili bu korumayı aşar; ona sahip bir kullanıcı kendi rolüne sır okuma ekleyip yetkisini kendi kendine büyütebilir. bind fiili de benzer bir kapıdır: ona sahip kullanıcı, kendinde olmayan izinleri taşıyan bir rolü bir özneye, örneğin kendine bağlayabilir.

impersonate ise başka bir kimlik gibi davranmayı verir. Bu üç fiil yalnız güvenilen yöneticilerde durur. Bir de PersistentVolume oluşturma yetkisi dolaylı bir yol açar: keyfi bir hostPath birimi düğümün dosya sistemini poda açar ve konteyner sınırı delinir. Resmî iyi uygulama belgesi bu yolları tek tek sayar.

Etkinlik 4 / 6

Bu rol tanımında aşırı geniş olan satırı bul.

Zafiyetli satıra tıkla.

Denetim ritmi ve bulut kimliği

RBAC denetimini düzenli yapmanın basit bir yolu var. Üç soruyu her çeyrekte sorarsın: sırları kim okuyabiliyor, pod oluşturmayı kim yapabiliyor, küme yöneticisi kimler? Üç listenin de kısa ve tanıdık olması gerekir. Yerleşik rolleri bilmek de yardımcıdır.

view rolü sır okumaz, çünkü sır okumak hizmet hesaplarına bürünmeye açılır. edit rolü ise sır okur ve pod oluşturur. Bu yüzden adının çağrıştırdığından güçlüdür ve bir hizmet hesabına verildiğinde dikkat ister. Listede beklenmedik bir hesap görünüyorsa izini sürer, hangi bağdan geldiğini bulursun.

Bu denetimi elle yapmak büyük kümede yorucu olur, bu yüzden araçlarla desteklenir. kubectl-who-can bir fiili bir kaynakta kimlerin yapabildiğini listeler.

rbac-lookup bir kullanıcı ya da hizmet hesabının tüm bağlarını özetler. Bu araçların çıktısını üç ayda bir alıp bir öncekiyle karşılaştırırsın; aradaki fark, kümede sessizce büyüyen bir yetkiyi erken yakalar. Yeni bir yıldız, yeni bir geniş bağ ya da küme yöneticisi listesine eklenmiş bir hesap, bu karşılaştırmada hemen göze çarpar ve gerekçesi sorulur.

Otomasyon hesapları özel dikkat ister. Dağıtım araçları genelde geniş yetkiyle kurulur, çünkü kurulum belgesi kolaylık olsun diye öyle söyler. Oysa çoğu araç yalnız birkaç kaynak türüne dokunur. Gerçek kullanımı bir süre izleyip yetkiyi daraltmak, kümedeki en büyük tek kazançtır.

RBAC'i yazarken şablonla ilerlemek de hata payını düşürür: okuyucu, dağıtımcı ve operatör için üç hazır rol tanımlanır, yeni ihtiyaç çıktığında şablon genişletilir ve yeni bir yıldız eklenmez. Böylece roller zamanla şişmez, tanıdık ve denetlenebilir kalır. Küme API'sine hiç konuşmayan iş yüklerinde ise jetonu baştan bağlamazsın; ele geçen bir podda hazır bekleyen kimlik kalmaz.

Kümedeki yetki, bulut hesabındaki yetkiyle birleşir ve asıl risk bu birleşimde saklanır. Hizmet hesaplarını bulut kimlikleriyle eşlemek bu birleşimi düzene sokar: her iş yüküne kendi bulut rolü bağlandığında yalnız kendi ihtiyacını alır. Düğüm rolüne yaslanan kurulumlarda ise aynı yetki o düğümdeki tüm podlara açıktır; bir pod ele geçtiğinde düğümün rolü de ele geçer.

Kümeden buluta yanal hareketin bilinen yolu budur ve OWASP'ın Kubernetes risk listesinde ayrı bir madde olarak durur. İki katmanı ayrı ayrı denetlemek eksik kalır; ikisini birleştiren bir harita çıkarmak gerekir.

Etkinlik 5 / 6

Doğru mu, yanlış mı?

Bir poda jeton gerekmiyorsa automountServiceAccountToken değerini false yapmak saldırı yüzeyini daraltır.

Bir otomasyon hesabını incelerken iki soruyu ayrı tutarsın: hesap kim ve hesap ne yapabilir? Birincisinin yanıtı ServiceAccount nesnesinin kendisinde durur. İkincisinin yanıtı ise o hesaba işaret eden RoleBinding ve ClusterRoleBinding nesnelerine dağılmıştır. Bu ayrımı karıştırmak, bir hesabın yetkisini yanlış raporlamanın en sık yoludur.

Nesneye bakıp yetkiyi gördüğünü sanırsın, oysa yetki başka nesnelerde yazar. Denetim raporunda bu iki bilgiyi ayrı satırlarda yazmak, okuyanın da aynı hataya düşmesini önler.

Etkinlik 6 / 6

Bu komut ne döner?

Önce kodu oku, sonra çıktıyı seç.

$ kubectl describe sa derleyici -n ci

Bu derste bir hata mı gördün? Bildir