İçeriğe geç
academia.sh

Ders 06 / 12

Kod Olarak Altyapı Güvenliği

Önceki beş dersin bulduğu yanlış kalemler şablon kümesine geri konur ve kural setinden geçirilir: 11 yanlış kalemin 4'ü dağıtımdan önce yakalanır ve toplam 34 birimlik yarıçap payının 23'ünü (%68) kapatır, 5 kalem ancak koşarken çözülür, 2 kalemin şablonda okunacak bir değeri yoktur. Kural seti 3 meşru kalemi yanlış işaretler; kuralı kapatmak yanlış işareti de gerçek bulguyu da siler.

İçindekiler

Beş ders boyunca yanlış kalemler tek tek bulundu: aşırı geniş bir güven listesi, kapatılmamış bir genel uç, nesne düzeyinde unutulmuş bir izin, zincirin üzerinde duran bir anahtar izni. Hepsi çalışan sistemde bulundu ve her biri bulunduğunda çoktan yerindeydi. Bu ders son bir soru soruyor: bunların kaçı sisteme konmadan önce, şablonda görülebilirdi.

Altyapının şablonla kurulması DevOps ve Platform Mühendisliği müfredatının Kod Olarak Altyapı kursunda ölçüldü; sağlama modelleri ve sapma taraması burada tekrarlanmaz. Ölçülen tek ayrım şudur: dağıtımdan önce bilinen değer ile ancak koşarken bilinen değer. Bir kural yalnız birinciye karar verebilir.

  • BG28. Şablon bir kaynağın alanlarını yazar. Bir alanın değeri ya çözünürdür (şablon okunarak bilinir) ya da değildir: dağıtım parametresi, başka bir şablonun çıktısı, sağlayıcının belirlediği varsayılan, şablon dışında elle yapılan bir değişiklik ya da bir dosyanın içeriği.
  • BG29. Kural seti belirli alanlara bakar. Bir kuralın sonucu üç sınıftan biridir: yakalandı (çözünür değer, kural ateşledi), bilinmiyor (kural alana bakıyor ama değeri çözemiyor), görülmüyor (hiçbir kural o alana bakmıyor).
  • BG30. Her alanın yarıçap payı, önceki beş derste o kalem için ölçülen yarıçap düşüşüdür. Sayılar oradan okunur, burada yeniden türetilmez.
  • BG31. Bir alan meşru da olabilir. Kural ateşlediği hâlde kalem doğruysa bu bir yanlış işaretlemedir ve bir dağıtımı durdurur.
  • BG32. Koşarken tarama, bilinmiyor sınıfındaki alanların değerini çalışan sistemden okur; görülmüyor sınıfına dokunamaz. Tarama günlüktür ve ortalama gecikme yarım gün alınır.

Şablon Kümesi Kural Setinden Geçiyor

// bulut/sablon.mjs — sablon kumesi ve kural seti MODELIDIR. Saglama modelleri ve sapma taramasi
// bu derste yoktur; olculen sey dagitimdan once bilinen ile ancak kosarken bilinen kalemdir.

// Bir alanin degeri '<' ile basliyorsa sablon okunarak COZULEMEZ: degeri dagitim aninda ya da
// kosarken belli olur. yaricap = onceki bes derste olculen yaricap payi. mesru = kalem dogru mu.
export const ALAN = `
  kimlik.tpl  rol-arsiv            guven-listesi  rol-yedek      hayir   5
  kimlik.tpl  rol-yedek            guven-listesi  rol-yonetim    hayir   3
  kimlik.tpl  hesap-toplayici      guven-listesi  rol-arsiv      evet    0
  kimlik.tpl  rol-yonetim          anahtar-izni   k-sir          hayir  10
  kimlik.tpl  rol-dagitim          anahtar-izni   k-sir          evet    0
  depo.tpl    sablon-deposu        genel-erisim   acik           hayir   5
  depo.tpl    portal-varlik-deposu genel-erisim   acik           evet    0
  depo.tpl    yukleme-onizleme     genel-erisim   <devralinan>   hayir   1
  depo.tpl    olcum-deposu         genel-erisim   <parametre>    hayir   1
  anahtar.tpl sir-deposu           genel-uc       <varsayilan>   hayir   1
  anahtar.tpl anahtar-yonetimi     genel-uc       <varsayilan>   hayir   1
  ag.tpl      ozel-uc-eslemesi     hedef          <cikti>        hayir   2
  islem.tpl   ornek-yonetimi       yonetim-ucu    <sablon-disi>  hayir   1
  kod.tpl     dagitim-sablonu      dosya-icerigi  <dosya>        hayir   4`
  .trim().split('\n').map((s) => {
    const [sablon, kaynak, alan, deger, mesru, yaricap] = s.trim().split(/\s+/);
    return { sablon, kaynak, alan, deger, mesru: mesru === 'evet', yaricap: Number(yaricap) };
  });
export const cozunur = (a) => !a.deger.startsWith('<');
// Kural seti: hangi alana bakiyor ve cozunur bir degerde ne zaman atesliyor.
export const KURAL = [
  ['guven-listesi', (d) => d.startsWith('rol-')],
  ['anahtar-izni', (d) => d === 'k-sir'],
  ['genel-erisim', (d) => d === 'acik'],
  ['genel-uc', (d) => d === 'acik'],
  ['hedef', () => false],
];
// Sinif: yakalandi (cozunur deger, kural atesledi), bilinmiyor (kural alana bakiyor ama deger
// cozulemiyor), gormuyor (hicbir kural o alana bakmiyor).
export const sinif = (a, istisna = () => false) => {
  const k = KURAL.find(([ad]) => ad === a.alan);
  if (istisna(a)) return 'gormuyor';
  if (k === undefined) return 'gormuyor';
  if (cozunur(a)) return k[1](a.deger) ? 'yakalandi' : 'temiz';
  return 'bilinmiyor';
};
export const SINIF = ['yakalandi', 'bilinmiyor', 'gormuyor'];
export const say = (c, istisna, f = () => true) =>
  ALAN.filter((a) => f(a) && sinif(a, istisna) === c);
export const pay = (l) => l.reduce((x, a) => x + a.yaricap, 0);
export const YANLIS = ALAN.filter((a) => !a.mesru);
// bulut/kosum1.mjs — sablon kumesi kural setinden gecirilir: hangi kalem dagitimdan once biliniyor
import { ALAN, SINIF, YANLIS, pay, say, sinif } from './sablon.mjs';

const yaz = (g, ...s) => console.log(s.map((v, i) =>
  g[i] < 0 ? String(v).padEnd(-g[i]) : String(v).padStart(g[i])).join(''));
const A = [-21, -14, -15, 8, 9, 12];
yaz(A, 'kaynak', 'alan', 'deger', 'mesru', 'yaricap', 'sinif');
for (const a of ALAN)
  yaz(A, a.kaynak, a.alan, a.deger, a.mesru ? 'evet' : 'hayir', a.yaricap, sinif(a));
console.log(`\n${ALAN.length} alanin ${YANLIS.length}'i yanlis; toplam yaricap payi ${pay(YANLIS)}`);
const B = [-13, 9, 11, 10];
yaz(B, 'sinif', 'yanlis', 'yaricap', 'payin');
yaz(B, '', 'kalem', 'payi', 'yuzdesi');
for (const c of SINIF) {
  const l = say(c, undefined, (a) => !a.mesru);
  yaz(B, c, l.length, pay(l), `%${Math.round(pay(l) / pay(YANLIS) * 100)}`);
}
const yanlisIsaret = say('yakalandi', undefined, (a) => a.mesru);
console.log(`\nyanlis isaretlenen mesru kalem ${yanlisIsaret.length}: ` +
  yanlisIsaret.map((a) => a.kaynak).join(', '));
kaynak               alan          deger             mesru  yaricap       sinif
rol-arsiv            guven-listesi rol-yedek         hayir        5   yakalandi
rol-yedek            guven-listesi rol-yonetim       hayir        3   yakalandi
hesap-toplayici      guven-listesi rol-arsiv          evet        0   yakalandi
rol-yonetim          anahtar-izni  k-sir             hayir       10   yakalandi
rol-dagitim          anahtar-izni  k-sir              evet        0   yakalandi
sablon-deposu        genel-erisim  acik              hayir        5   yakalandi
portal-varlik-deposu genel-erisim  acik               evet        0   yakalandi
yukleme-onizleme     genel-erisim  <devralinan>      hayir        1  bilinmiyor
olcum-deposu         genel-erisim  <parametre>       hayir        1  bilinmiyor
sir-deposu           genel-uc      <varsayilan>      hayir        1  bilinmiyor
anahtar-yonetimi     genel-uc      <varsayilan>      hayir        1  bilinmiyor
ozel-uc-eslemesi     hedef         <cikti>           hayir        2  bilinmiyor
ornek-yonetimi       yonetim-ucu   <sablon-disi>     hayir        1    gormuyor
dagitim-sablonu      dosya-icerigi <dosya>           hayir        4    gormuyor

14 alanin 11'i yanlis; toplam yaricap payi 34
sinif           yanlis    yaricap     payin
                 kalem       payi   yuzdesi
yakalandi            4         23       %68
bilinmiyor           5          6       %18
gormuyor             2          5       %15

yanlis isaretlenen mesru kalem 3: hesap-toplayici, rol-dagitim, portal-varlik-deposu

Kalem sayısıyla yarıçap payı bu tabloda ters yönde okunuyor. On bir yanlış kalemin yalnız dördü dağıtımdan önce yakalanıyor — yüzde otuz altısı. Ama o dört kalem otuz dört birimlik yarıçap payının yirmi üçünü, yani yüzde altmış sekizini taşıyor. Nedeni tek bir satırdadır: rol-yonetim rolüne yazılan k-sir izni on birim taşır ve şablonda düz bir değer olarak durur.

Ters yönde de bir sonuç var. bilinmiyor sınıfındaki beş kalem toplam altı birim taşır — kalem başına bir virgül iki. Bunlar sayıca çoktur ve yarıçapa az katkı yapar. Bir kural seti “kaç bulgu kapattı” diye ölçülürse bu beş kalemin ağırlığı abartılır; “kaç birim yarıçap kapattı” diye ölçülürse yerine oturur.

Alt satır kural setinin karşı yüzünü veriyor. Aynı kurallar üç meşru kalemi de işaretliyor: toplayıcının arşiv rolünü üstlenmesi, dağıtım rolünün sır anahtarını kullanması ve portal varlık deposunun genel açık olması. Üçü de doğru yapılandırmadır ve üçü de bir dağıtımı durdurur. Kural metni bu üçünü ötekilerden ayıramaz, çünkü değerler birbirinin aynısıdır.

İstisnanın İki Yazımı

// bulut/kosum2.mjs — dort kural seti varyanti ve kosarken taramanin kapattigi pay
import { YANLIS, pay, say } from './sablon.mjs';

const ISTISNA_KAYNAK = ['hesap-toplayici', 'rol-dagitim', 'portal-varlik-deposu'];
const VARYANT = [
  ['istisna yok', () => false],
  ['kaynak duzeyinde istisna (3 satir)', (a) => ISTISNA_KAYNAK.includes(a.kaynak)],
  ['anahtar-izni kurali kapatilir', (a) => a.alan === 'anahtar-izni'],
  ['uc kural da kapatilir', (a) =>
    ['guven-listesi', 'anahtar-izni', 'genel-erisim'].includes(a.alan)],
];
const yaz = (g, ...s) => console.log(s.map((v, i) =>
  g[i] < 0 ? String(v).padEnd(-g[i]) : String(v).padStart(g[i])).join(''));
const A = [-36, 9, 9, 10, 13, 13];
yaz(A, 'kural seti', 'once', 'once', 'yanlis', 'tarama ile', 'hic gorulen');
yaz(A, '', 'kalem', 'pay', 'isaret', 'kapanan pay', 'olmayan pay');
for (const [ad, ist] of VARYANT) {
  const y = say('yakalandi', ist, (a) => !a.mesru);
  const b = say('bilinmiyor', ist, (a) => !a.mesru);
  yaz(A, ad, y.length, pay(y), say('yakalandi', ist, (a) => a.mesru).length,
    pay(y) + pay(b), pay(YANLIS) - pay(y) - pay(b));
}
console.log(`\ntoplam yanlis kalem ${YANLIS.length}, toplam yaricap payi ${pay(YANLIS)}`);
const gor = say('gormuyor', undefined, (a) => !a.mesru);
console.log(`hicbir kuralin bakmadigi alan: ` +
  gor.map((a) => `${a.alan} (${a.deger.slice(1, -1)})`).join(', '));
console.log(`bu ${gor.length} kalemin yaricap payi ${pay(gor)}/${pay(YANLIS)} ` +
  `(%${Math.round(pay(gor) / pay(YANLIS) * 100)}); sablonda okunacak bir deger yok`);
// Gecikme: dagitimdan once yakalanan 0 gun, gunluk taramada ortalama 0.5 gun, gormeyen hic.
const y0 = pay(say('yakalandi', undefined, (a) => !a.mesru));
const b0 = pay(say('bilinmiyor', undefined, (a) => !a.mesru));
console.log(`agirlikli gecikme: ${y0} pay 0 gun, ${b0} pay 0.5 gun -> ` +
  `${(b0 * 0.5 / (y0 + b0)).toFixed(2)} gun; kalan ${pay(YANLIS) - y0 - b0} pay hic gorulmuyor`);
kural seti                               once     once    yanlis   tarama ile  hic gorulen
                                        kalem      pay    isaret  kapanan pay  olmayan pay
istisna yok                                 4       23         3           29            5
kaynak duzeyinde istisna (3 satir)          4       23         0           29            5
anahtar-izni kurali kapatilir               3       13         2           19           15
uc kural da kapatilir                       0        0         0            4           30

toplam yanlis kalem 11, toplam yaricap payi 34
hicbir kuralin bakmadigi alan: yonetim-ucu (sablon-disi), dosya-icerigi (dosya)
bu 2 kalemin yaricap payi 5/34 (%15); sablonda okunacak bir deger yok
agirlikli gecikme: 23 pay 0 gun, 6 pay 0.5 gun -> 0.10 gun; kalan 5 pay hic gorulmuyor

İkinci satır aranan yanıttır. İstisna kaynak düzeyinde yazıldığında — üç ad, üç satır — yanlış işaretleme üçten sıfıra iner ve yakalanan pay yirmi üçte kalır. Bedeli üç satırlık bir listenin bakımıdır: her yeni meşru kalem bir satır daha ister ve listeden düşmeyen bir ad, artık meşru olmasa bile işaretlenmez.

Üçüncü ve dördüncü satır ucuz yolun ne kadara mal olduğunu gösteriyor. Yanlış işaretlemeyi kuralı kapatarak gidermek, o kuralın yakaladığı gerçek bulguyu da siler: anahtar-izni kuralı kapatıldığında yakalanan pay yirmi üçten on üçe iner ve hiç görülmeyen pay beşten on beşe çıkar. Üç kural birden kapatıldığında dağıtımdan önce hiçbir şey yakalanmaz. Kuralı kapatmak yanlış işareti de gerçek bulguyu da siler; istisna yazmak yalnız yanlış işareti siler ve bir bakım yükü bırakır.

Son üç satır dersin kalıcı sınırını çiziyor. İki kalem hiçbir kural setiyle görülemez: bir kaynağın yönetim ucu şablon dışında elle açılmıştır ve bir kimlik referansı bir dosyanın içeriğindedir. Kural seti genişletilebilir ama şablonda okunacak bir değer yoktur. Bu iki kalem toplam yarıçap payının yüzde on beşini taşır.

Çözünürlük Şablona Göre Değişiyor

Toplam sayı altı şablona dağılmıştır ve dağılım düzgün değildir.

// bulut/kosum3.mjs — sablon basina yaricap payi ve cozunurluk: tarama nerede ise yariyor
import { ALAN, cozunur, pay, sinif } from './sablon.mjs';

const yaz = (g, ...s) => console.log(s.map((v, i) =>
  g[i] < 0 ? String(v).padEnd(-g[i]) : String(v).padStart(g[i])).join(''));
const A = [-14, 7, 11, 10, 11, 10];
yaz(A, 'sablon', 'alan', 'cozunur', 'yaricap', 'yakalanan', 'yakalanan');
yaz(A, '', 'sayisi', 'alan', 'payi', 'pay', 'oran');
for (const s of [...new Set(ALAN.map((a) => a.sablon))]) {
  const l = ALAN.filter((a) => a.sablon === s), y = l.filter((a) => !a.mesru);
  const yak = l.filter((a) => !a.mesru && sinif(a) === 'yakalandi');
  yaz(A, s, l.length, `${l.filter(cozunur).length}/${l.length}`, pay(y), pay(yak),
    pay(y) === 0 ? '-' : `%${Math.round(pay(yak) / pay(y) * 100)}`);
}
const c = ALAN.filter((a) => !a.mesru && cozunur(a));
console.log(`\ncozunur yanlis alan ${c.length}/${ALAN.filter((a) => !a.mesru).length}, ` +
  `payi ${pay(c)}/${pay(ALAN.filter((a) => !a.mesru))}; ` +
  `cozunurluk sablon basina %0 ile %100 arasinda degisiyor`);
sablon           alan    cozunur   yaricap  yakalanan yakalanan
               sayisi       alan      payi        pay      oran
kimlik.tpl          5        5/5        18         18      %100
depo.tpl            4        2/4         7          5       %71
anahtar.tpl         2        0/2         2          0        %0
ag.tpl              1        0/1         2          0        %0
islem.tpl           1        0/1         1          0        %0
kod.tpl             1        0/1         4          0        %0

cozunur yanlis alan 4/11, payi 23/34; cozunurluk sablon basina %0 ile %100 arasinda degisiyor

Kimlik şablonu iki bakımdan uçtadır: en büyük yarıçap payını taşır — otuz dördün on sekizi — ve bütün alanları çözünürdür. Tarama orada yüzde yüz oranında iş görüyor. Depo şablonunda dört alanın ikisi çözünür ve yakalanan oran yüzde yetmiş bire iniyor.

Alt dört satırda oran sıfırdır ve nedeni aynı değildir. Anahtar şablonunda alanlar hiç yazılmamıştır ve varsayılan sağlayıcıda belirlenir; ağ şablonunda değer başka bir şablonun çıktısından gelir; işlem şablonunun kaynağı sonradan elle değiştirilmiştir; kod şablonu bir dosyaya işaret eder ve dosyanın içeriği alan değildir. Dördü de “şablonda yazmıyor” durumudur ama üçü tarama ile çözülebilir, biri çözülemez.

Bu dağılımın pratik sonucu, tarama yatırımının nereye yapılacağıdır. Yarıçap payının yarısından çoğu tek bir şablonda ve tamamen çözünür alanlarda durur; o şablona bakan kural seti en yüksek getiriyi verir. Alt dört satır için kural yazmak hiçbir şey kazandırmaz — kazanç ancak koşan sistemden okuyan bir düzenekle gelir.

Yakalanan, Geciken ve Hiç Görülmeyen

Sonuç üç bölüme ayrılır. Yirmi üç birim yarıçap payı dağıtımdan önce kapanır: dağıtım engellenir, gecikme sıfır gündür ve yanlış hiç sisteme girmez. Altı birim ancak koşarken çözülür; günlük bir tarama bunları ortalama yarım gün sonra görür. Beş birim hiç görülmez.

Ağırlıklı gecikme sıfır virgül on gündür ve bu sayı yanıltıcı görünebilir — ortalama küçüktür, çünkü ağırlığın çoğu sıfır gecikmeli sınıftadır. Ama ortalama, hiç görülmeyen beş birimi hesaba katmaz; o pay bir gecikme değil, bir yokluktur.

Bu ayrımın pratik sonucu şudur: şablon taraması yarıçap payının üçte ikisini kapatabilir ve bunu sıfır gecikmeyle yapar, ama üçte biri için başka bir düzenek gerekir. O düzeneğin bir bölümü koşarken tarama, bir bölümü ise şablonun hiç bilmediği bir kaynaktır. Kural setinin genişliği birinci payı büyütür; ikinci payı hiç değiştirmez.

Özet

  • Şablondaki 14 alanın 11’i yanlıştır ve toplam yarıçap payı 34 birimdir. Dağıtımdan önce yakalanan 4 kalem bu payın 23’ünü (%68) taşır; kalem sayısıyla yarıçap payı ters yönde okunur.
  • bilinmiyor sınıfındaki 5 kalem toplam 6 birim taşır — kalem başına 1,2. Kural setini “kaç bulgu” ile ölçmek bu kalemlerin ağırlığını abartır.
  • Kural seti 3 meşru kalemi de işaretler ve 3 dağıtımı durdurur; değerler birbirinin aynısı olduğu için kural metni ayıramaz.
  • Kaynak düzeyinde istisna yanlış işaretlemeyi 3’ten 0’a indirir ve yakalanan payı 23’te bırakır; bedeli 3 satırlık bir listenin bakımıdır. Kuralı kapatmak yakalanan payı 23’ten 13’e düşürür.
  • 2 kalem hiçbir kural setiyle görülemez — biri şablon dışında elle açılmış bir yönetim ucu, öteki bir dosyanın içeriğindeki kimlik referansı. Toplam payın %15’i buradadır.
  • Ağırlıklı gecikme 0,10 gündür; ortalama küçüktür çünkü ağırlığın çoğu sıfır gecikmeli sınıftadır. Hiç görülmeyen 5 birim bu ortalamaya hiç girmez.

Sonraki Adım

Bu konu bir soruyu sonuna kadar götürdü: bir kalem yanlışsa oradan kaç kaleme ulaşılır. Sorumluluk sınırı bir denetim listesine çevrildi, sızan tek bir kimlikten yürüyüş koşturuldu, ağ yolu izinle kesiştirildi, genel erişime açık kalem sayıldı, anahtar sahipliği üç kipte ölçüldü ve son olarak yanlış kalemlerin kaçının dağıtımdan önce görülebileceği hesaplandı. Her adımda bir sayı çıktı ve her denetimin bedeli yazıldı.

Bütün bu ölçümlerin ortak bir yanı var: hepsi yapılandırmaya bakarak yapıldı. Bir güven listesi okundu, bir izin kümesi tarandı, bir şablon alanı çözüldü. Yapılandırmanın kendisi doğruyken de yarıçap ölçülebilir — ama o zaman ölçülecek bir şey yoktur, çünkü yanlış kalem yoktur. Sorulmayan soru şudur: yapılandırma doğruyken bir kimlik bilgisi sızarsa bu nereden anlaşılır. O anda hiçbir alan yanlış değildir, hiçbir kural ateşlemez, hiçbir tarama bir şey bulmaz; yürüyüşün gerçekten koşup koşmadığını gösterebilecek tek şey bir kayıttır. Sonraki konu, Bulutta Tespit ve Sertleştirme, o kayıtla başlıyor: yönetim düzlemi denetim günlüğü yarıçap yürüyüşünün kaç adımını görüyor, kaçını hiç görmüyor.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat