İçeriğe geç
academia.sh

Ders 06 / 15

Derinlemesine Savunma

Aynı erişim grafiği üzerinde beş savunma katmanı sırayla eklenir: her katmanın kapattığı yeni yol, kalan yol, istisna gerektiren meşru akış ve yönetilen kalem sayılır. Hiçbir yeni yol kapatmayan katman bulunur ve sıranın kapanma dağılımını nasıl değiştirdiği gösterilir.

İçindekiler

Önceki konu saldırı yüzeyini sayılabilir bir birime çevirdi: bir varlığa ulaşmanın kaç ayrı yolu olduğu yazıldı. Sayılan şey açık kalan yoldu ve hiçbir savunma o sayının üzerinde koşturulmadı. Bu konu aynı ölçü birimini alır ve altı savunma ilkesini tek tek üzerinde çalıştırır. Her ders üç sütun verir: kaç yol var, ilke kaçını kapatıyor, karşılığında kaç meşru iş duruyor.

Ağ modeli bir noktada genişletiliyor. Yüzey sayımı iki hedefe giden yolları saymıştı; savunma ilkelerinin ölçülebilmesi için ağın dört korunan varlığı ve satıcı bakım bağlantısı da modele giriyor, çünkü bir ilkenin hangi varlığı koruduğu ancak varlıklar ayrı ayrı sayıldığında görünür. Genişletilmiş model aynı kurgusal ağdır ve aşağıda yeniden kuruluyor; bundan sonraki altı dersin tamamı bu tek yol kümesi üzerinde koşuyor.

İlk ilke derinlemesine savunmadır (defense in depth): tek bir denetime güvenmek yerine birbirinden bağımsız katmanlar üst üste konur, biri aşıldığında bir sonraki devrededir. Bu ifade bir karar taşımaz — kaç katman, hangi sırayla ve ne pahasına sorusunun yanıtı yoktur. Bu ders katmanları aynı grafiğe sırayla ekler ve her birinin kapattığı yeni yolu sayar. Yol sayımı burada savunmanın kapsamını ölçmek için yapılır; gerçek bir ağ üzerinde böyle bir sayım yazılı yetki ve tanımlı kapsam olmadan yürütülemez, yürütülmesi hem yasadışı hem de meslek dışıdır.

  • SI1. Ağ kurgusaldır: bölgesel ölçüm ağının dört giriş noktası, altı ara düğümü ve dört varlığı node ile modellenir. Ölçülen şey bu modeldir; yüzey sayımındaki daraltılmış grafiğin yerine bu genişletilmiş grafik geçer ve konu boyunca değişmez.
  • SI2. Yol, bir giriş noktasından bir varlığa giden, düğüm tekrarı olmayan adım dizisidir.
  • SI3. Katmanların hangi adımı durdurduğu ölçülmedi, seçildi. Gerçek bir ağda bu eşleme denenerek çıkarılır; dersin noktası eşlemenin kendisi değil, üzerinde yapılan sayımdır.
  • SI4. Bir katman bir adımı ya durdurur ya durdurmaz. Kısmi engelleme ve atlatma olasılığı modellenmiyor; bunlar kapanan yol sayısını düşürür, yönünü değiştirmez.
  • SI5. Meşru akış aynı grafiğin kenarlarından geçer. Bir katman meşru akışın adımını durduruyorsa o akış elle yazılan bir istisna gerektirir; istisna sayısı ve etkilediği günlük istek bedelin ölçüsüdür.
  • SI6. Yönetilen kalem sayısı her katman için verilmiş bir model değeridir: o katmanın bakımını gerektiren kural, eşleme ve dışlama satırlarının toplamı.

Korunan Ağ ve Yol Kümesi

Model üç düğüm türünü ayırır: dışarıdan erişilen giriş noktaları, aradaki servisler ve korunan varlıklar. Kenarlar bir düğümden diğerine geçilebilen adımlardır.

// ag.mjs — kurgusal bolgesel olcum aginin erisim grafigi ve mesru akislari (model)
export const GIRIS = ['saha-uc', 'sube-agi', 'genel-uc', 'bakim-uc'];
export const VARLIK = ['olcum-deposu', 'fatura-vt', 'abone-kayit', 'yapilandirma'];
export const KENAR = [
  ['saha-uc', 'toplayici'], ['saha-uc', 'is-emri'], ['sube-agi', 'toplayici'],
  ['sube-agi', 'is-emri'], ['sube-agi', 'yonetim'], ['genel-uc', 'toplayici'],
  ['bakim-uc', 'yonetim'], ['bakim-uc', 'kuyruk'], ['toplayici', 'kuyruk'],
  ['toplayici', 'olcum-deposu'], ['kuyruk', 'dogrulayici'], ['kuyruk', 'faturalama'],
  ['dogrulayici', 'olcum-deposu'], ['dogrulayici', 'fatura-vt'], ['faturalama', 'fatura-vt'],
  ['faturalama', 'abone-kayit'], ['is-emri', 'kuyruk'], ['is-emri', 'abone-kayit'],
  ['yonetim', 'toplayici'], ['yonetim', 'dogrulayici'], ['yonetim', 'is-emri'],
  ['yonetim', 'yapilandirma'],
];
// Mesru akis: gunluk kosan is; adim dizisi ayni grafigin kenarlarindan gecer.
export const AKIS = [
  ['saha-okuma', ['saha-uc', 'toplayici', 'kuyruk'], 1440],
  ['dogrulama', ['kuyruk', 'dogrulayici', 'olcum-deposu'], 1440],
  ['genel-okuma', ['genel-uc', 'toplayici', 'olcum-deposu'], 300],
  ['sube-sorgu', ['sube-agi', 'toplayici', 'olcum-deposu'], 210],
  ['fatura-yazimi', ['kuyruk', 'faturalama', 'fatura-vt'], 48],
  ['is-emri-acma', ['sube-agi', 'is-emri', 'abone-kayit'], 32],
  ['is-emri-kuyruk', ['sube-agi', 'is-emri', 'kuyruk'], 32],
  ['abone-guncelleme', ['faturalama', 'abone-kayit'], 6],
  ['yapilandirma-degisikligi', ['sube-agi', 'yonetim', 'yapilandirma'], 2],
  ['bakim-oturumu', ['bakim-uc', 'yonetim', 'toplayici'], 1],
  ['kuyruk-bakimi', ['bakim-uc', 'kuyruk'], 1],
  ['mutabakat', ['yonetim', 'dogrulayici', 'fatura-vt'], 1],
];
export const ad = (a, b) => `${a}>${b}`;
export const adimlar = (d) => d.slice(0, -1).map((x, i) => ad(x, d[i + 1]));
export function yollar(kapali = new Set()) {
  const komsu = new Map();
  for (const [a, b] of KENAR) if (!kapali.has(ad(a, b))) komsu.set(a, [...(komsu.get(a) || []), b]);
  const s = [];
  const yuru = (d, y) => {
    if (VARLIK.includes(d)) return void s.push(y);
    for (const k of komsu.get(d) || []) if (!y.includes(k)) yuru(k, [...y, k]);
  };
  for (const g of GIRIS) yuru(g, [g]);
  return s;
}
export const kesilen = (kapali) => AKIS.filter(([, d]) => adimlar(d).some((k) => kapali.has(k)));
// kosum1.mjs — yol kumesi kurulur: giris noktasindan varliga kac ayri yol var
import { GIRIS, VARLIK, KENAR, AKIS, yollar } from './ag.mjs';

const y = yollar();
const ara = [...new Set(KENAR.flat())].filter((d) => !GIRIS.includes(d) && !VARLIK.includes(d));
console.log(`giris ${GIRIS.length}, ara dugum ${ara.length}, varlik ${VARLIK.length}, kenar ${KENAR.length}, yol ${y.length}`);
const say = (f) => y.reduce((m, p) => m.set(f(p), (m.get(f(p)) || 0) + 1), new Map());
const yaz = (b, m) => { console.log(`\n${b}`); for (const [k, v] of m) console.log(`  ${String(k).padEnd(16)}${v}`); };
yaz('giris noktasi basina yol', say((p) => p[0]));
yaz('varlik basina yol', say((p) => p.at(-1)));
yaz('adim sayisina gore yol', new Map([...say((p) => p.length - 1)].sort()));
yaz('ara dugumden gecen yol', new Map(ara.map((d) => [d, y.filter((p) => p.includes(d)).length])
  .sort((a, b) => b[1] - a[1])));
console.log(`\nmesru akis ${AKIS.length}, gunluk mesru istek ${AKIS.reduce((s, [, , n]) => s + n, 0)}`);
giris 4, ara dugum 6, varlik 4, kenar 22, yol 55

giris noktasi basina yol
  saha-uc         10
  sube-agi        23
  genel-uc        5
  bakim-uc        17

varlik basina yol
  olcum-deposu    17
  fatura-vt       22
  abone-kayit     14
  yapilandirma    2

adim sayisina gore yol
  2               7
  3               12
  4               20
  5               16

ara dugumden gecen yol
  kuyruk          40
  yonetim         26
  toplayici       25
  dogrulayici     24
  is-emri         20
  faturalama      20

mesru akis 12, gunluk mesru istek 3513

On dört düğüm ve yirmi iki kenar elli beş yol üretiyor. Yol sayısı kenar sayısının iki buçuk katıdır; grafiğe eklenen her kenar kendi başına bir yol değil, geçtiği her yolun katlanmasıdır. Şube ağı tek başına yirmi üç yolun başlangıcıdır, çünkü üç ayrı ara düğüme bağlanır. Bakım ucu yalnız iki kenara sahip olduğu hâlde on yedi yol açar: bağlandığı yönetim istasyonu dört ayrı düğüme daha bağlıdır. Bir giriş noktasının tehlikesi kaç bağlantısı olduğuyla değil, bağlandığı düğümün kaç bağlantısı olduğuyla ölçülür.

Varlık dağılımı ikinci bir şeyi gösteriyor. Fatura veritabanına yirmi iki yol gidiyor, yapılandırma deposuna iki. İkisi de aynı ağda duruyor ama biri on bir kat daha çok yoldan erişilebilir durumda. Adım dağılımı ise savunmanın nereye konacağını belirler: yolların yalnız yedisi iki adımlık, otuz altısı dört adım ve üzeridir. Uzun yollar ara düğümlerin çoğundan geçer, yani ortada duran tek bir denetim onların hepsini birden keser.

Son tablo o denetimin nereye konacağını doğrudan söylüyor. Kuyruk elli beş yolun kırkından geçiyor; kuyruğa giren her adımı durduran bir denetim, tek başına yolların yüzde yetmiş üçüne dokunur. Yönetim istasyonu yirmi altı, ölçüm toplayıcı yirmi beş yol taşıyor. Sıralamanın alt ucundaki iş emri ve faturalama servisleri yirmişer yolla en az yükü taşıyor. Bu sayılar savunmanın yerleştirileceği noktaları önem sırasına koyar, ancak bir uyarıyla: darboğaz aynı zamanda meşru işin de darboğazıdır. Kuyruğa konan bir denetim günde bin dört yüz kırk okuma yüklemesi ve bin dört yüz kırk doğrulama isteğinin üzerinden geçecektir.

Katman Katman Kapanan Yol

Beş katman aynı grafiğe sırayla ekleniyor. Her katman belirli adımları durduruyor; bir yol, adımlarından en az biri durdurulmuşsa kapanmış sayılıyor.

// katman.mjs — bes savunma katmani ve her birinin durdurdugu adim (model karari)
export const KATMAN = [
  ['ag-suzgeci', 22, ['saha-uc>is-emri', 'sube-agi>yonetim', 'bakim-uc>yonetim', 'bakim-uc>kuyruk']],
  ['kimlik-dogrulama', 14, ['genel-uc>toplayici', 'sube-agi>yonetim', 'bakim-uc>yonetim', 'yonetim>yapilandirma']],
  ['uc-nokta-denetimi', 9, ['saha-uc>is-emri', 'sube-agi>yonetim', 'bakim-uc>kuyruk']],
  ['girdi-dogrulama', 11, ['kuyruk>faturalama', 'dogrulayici>fatura-vt']],
  ['veri-denetimi', 7, ['dogrulayici>olcum-deposu', 'yonetim>dogrulayici']],
];
// kosum2.mjs — katmanlar sirayla eklenir; her katmanin kapattigi yeni yol sayilir
import { yollar, kesilen } from './ag.mjs';
import { KATMAN } from './katman.mjs';

const tum = yollar().length, kapali = new Set();
let onceki = tum;
console.log('katman             kalem  tek basina  yeni kapanan  kalan  istisna  gunluk ek adim');
for (const [k, kalem, kenarlar] of KATMAN) {
  const tek = tum - yollar(new Set(kenarlar)).length;
  kenarlar.forEach((e) => kapali.add(e));
  const kalan = yollar(kapali).length, kes = kesilen(kapali);
  console.log(`${k.padEnd(19)}${String(kalem).padEnd(7)}${String(tek).padEnd(12)}${String(onceki - kalan).padEnd(14)}` +
    `${String(kalan).padEnd(7)}${String(kes.length).padEnd(9)}${kes.reduce((s, [, , n]) => s + n, 0)}`);
  onceki = kalan;
}
console.log('\nbes katmandan sonra kalan yol:');
for (const p of yollar(kapali)) console.log(`  ${p.join(' > ')}`);
katman             kalem  tek basina  yeni kapanan  kalan  istisna  gunluk ek adim
ag-suzgeci         22     35          35            20     3        4
kimlik-dogrulama   14     31          5             15     4        304
uc-nokta-denetimi  9      22          0             15     4        304
girdi-dogrulama    11     32          9             6      6        353
veri-denetimi      7      14          3             3      7        1793

bes katmandan sonra kalan yol:
  saha-uc > toplayici > olcum-deposu
  sube-agi > toplayici > olcum-deposu
  sube-agi > is-emri > abone-kayit

İlk katman elli beş yolun otuz beşini kapatıyor ve bedeli neredeyse yok: üç meşru akış istisna gerektiriyor, bunlar günde toplam dört istek. Ağ süzgeci ucuz görünmesinin nedeni budur — sık koşan işler zaten süzgecin içinden geçen kenarlarda durur.

Sonraki katmanlarda oran tersine dönüyor. Kimlik doğrulama beş yeni yol kapatıyor ama istisna gerektiren günlük istek dörtten üç yüz dörde çıkıyor, çünkü genel okuma ucu bu katmanın altına giriyor. Veri denetimi yalnız üç yol kapatıyor; karşılığında bin yedi yüz doksan üç günlük istek ek bir adım kazanıyor — doğrulama akışının tamamı bu katmandan geçiyor. Kapanan yol başına ödenen bedel ilk katmanda sekizde bir istek, son katmanda beş yüz doksan yedi istektir.

İstisna sütunu ayrı bir yük biriktiriyor. Beş katman sonunda on iki meşru akıştan yedisi elle yazılmış bir istisnaya bağlı; yani akışların yüzde elli sekizi bir denetimin dışına çıkarılmış durumda. Bir istisna kaldırıldığında ya da yanlış yazıldığında kapanan sayılan bir yol geri açılır, ancak tablo bunu göstermez — tablo istisnaların doğru olduğunu varsayar.

Son üç satır bu dersin sert bulgusudur. Beş katmandan sonra elli beş yolun elli ikisi kapandı, üçü hâlâ açık. Kalan üç yol saha ucundan ölçüm deposuna, şube ağından ölçüm deposuna ve şube ağından abone kayıtlarına gidiyor — yani meşru kanalın kendisi. Katman eklemek bu üçünü kapatmaz; onları kapatmak işi durdurmaktır. Derinlemesine savunma yol sayısını sıfırlamaz, meşru kanalın genişliğine indirir.

Bedava Sanılan Katman

Tablodaki üçüncü satır sıfır yazıyor: uç nokta denetimi hiçbir yeni yol kapatmıyor. Aynı satırın sol tarafı tek başına yirmi iki yol kapattığını söylüyor. İki sayı çelişmiyor; katmanın değerinin sıraya bağlı olduğunu söylüyor.

// kosum3.mjs — sira degisince kapanan yol nasil dagiliyor, katman cikarilinca ne oluyor
import { yollar } from './ag.mjs';
import { KATMAN } from './katman.mjs';

const tum = yollar().length, kisa = (a) => a.split('-')[0];
function kos(liste) {
  const kapali = new Set(), m = new Map();
  let onceki = tum;
  for (const [a, , kenarlar] of liste) {
    kenarlar.forEach((e) => kapali.add(e));
    const kalan = yollar(kapali).length;
    m.set(a, onceki - kalan); onceki = kalan;
  }
  return [m, onceki, liste.reduce((s, [, n]) => s + n, 0)];
}
const uc = KATMAN.find(([a]) => a.startsWith('uc-'));
console.log(`sira                 ${KATMAN.map(([a]) => kisa(a).padEnd(9)).join('')}kalan  kalem`);
for (const [etiket, liste] of [['yazildigi sira', KATMAN],
  ['uc nokta basta', [uc, ...KATMAN.filter((k) => k !== uc)]],
  ['uc nokta cikarilmis', KATMAN.filter((k) => k !== uc)]]) {
  const [m, kalan, kalem] = kos(liste);
  console.log(`${etiket.padEnd(21)}${KATMAN.map(([a]) => String(m.get(a) ?? '-').padEnd(9)).join('')}` +
    `${String(kalan).padEnd(7)}${kalem}`);
}
const tek = KATMAN.reduce((s, [, , k]) => s + tum - yollar(new Set(k)).length, 0);
console.log(`\ntek basina toplami ${tek}, gercekte kapanan ${tum - kos(KATMAN)[1]}, ` +
  `kalem basina ${((tum - kos(KATMAN)[1]) / kos(KATMAN)[2]).toFixed(2)} yol`);
sira                 ag       kimlik   uc       girdi    veri     kalan  kalem
yazildigi sira       35       5        0        9        3        3      63
uc nokta basta       13       5        22       9        3        3      63
uc nokta cikarilmis  35       5        -        9        3        3      54

tek basina toplami 134, gercekte kapanan 52, kalem basina 0.83 yol

Üç satır aynı sonuca varıyor: kalan yol her durumda üç. Sıra değiştiğinde yalnız kapanmanın dağılımı değişiyor. Uç nokta denetimi başa alındığında yirmi iki yol ona, on üç yol ağ süzgecine yazılıyor; sonda kaldığında ona sıfır düşüyor. Bir katmanın “kaç yol kapattığı” tek başına bir sayı değildir, ondan önce ne olduğuna bağlıdır.

Üçüncü satır asıl kararı veriyor. Uç nokta denetimi tamamen çıkarıldığında kalan yol yine üç, ancak yönetilen kalem altmış üçten elli dörde iniyor. Bu yol kümesi üzerinde katman dokuz kalemlik bakım yükü karşılığında hiçbir şey kazandırmıyor. “Bir katman daha eklemek zarar vermez” cümlesi burada sayıyla yanlışlanıyor: eklemenin bedeli sıfır değil, dokuz kalemdir.

Karar bu kadar kısa değildir. Ölçüm, ağ süzgecinin ayakta kaldığı varsayımı altında yapıldı. Süzgeç aşılırsa uç nokta denetimi tek başına yirmi iki yolu kapatan katmandır ve o durumda kalan yol üç değil, çok daha fazla olur. Doğru okuma şudur: bu katman kapsam kazandırmıyor, yedeklilik kazandırıyor — ve yedekliliğin bedeli dokuz kalemdir. Üst satırdaki toplam da aynı yanılgının sayısal karşılığıdır: tek başına ölçümlerin toplamı yüz otuz dört, gerçekte kapanan elli iki. Aynı yolu iki kez sayan bir savunma raporu, kapsamını iki buçuk kat büyük gösterir.

Modelin sessiz varsayımı da burada ortaya çıkıyor. Her katman bağımsız kabul edildi: birinin düşmesi diğerini etkilemiyor. Gerçekte katmanların birçoğu aynı yönetim düzlemi üzerinden yapılandırılır ve aynı kimlik kümesiyle yönetilir. Ağ süzgecinin kural tablosunu değiştirebilen bir özne, uç nokta denetiminin dışlama listesini de değiştirebiliyorsa iki katman tek katman sayılır ve tablodaki elli iki sayısı üst sınırdır. Yönetilen kalem sayısının ikinci anlamı budur: altmış üç kalem yalnız bakım yükü değil, aynı zamanda yanlış yapılandırılabilecek altmış üç yerdir. Derinlemesine savunmanın ölçüsü katman sayısı değil, katmanların gerçekten kaç ayrı denetim yüzeyine dağıldığıdır.

Özet

  • Kurgusal ağ dört giriş, altı ara düğüm ve dört varlıkla yirmi iki kenar taşıyor; giriş noktasından varlığa 55 ayrı yol çıkıyor. Fatura veritabanına 22 yol gidiyor, yapılandırma deposuna 2 — aynı ağda erişilebilirlik on bir kat farklıdır.
  • Beş katman sırayla eklendiğinde 55 yolun 52’si kapanıyor, 3’ü açık kalıyor. Kalan üç yol meşru kanalın kendisidir; katman eklemek onları kapatmaz.
  • Kapanan yol başına bedel katman ilerledikçe büyüyor: ağ süzgeci 35 yolu günde 4 istisna isteğiyle kapatıyor, veri denetimi 3 yolu günde 1.793 ek adımla.
  • Uç nokta denetimi sırasında 0 yeni yol kapatıyor ama tek başına 22 yol kapatıyor; katmanın sayısı kendisine değil, kendisinden öncekilere bağlıdır.
  • Katman çıkarıldığında kalan yol yine 3, yönetilen kalem 63’ten 54’e iniyor. Katman kapsam değil yedeklilik kazandırıyor ve yedekliliğin bedeli 9 kalemdir.
  • Katmanların tek başına kapattığı yolların toplamı 134, gerçekte kapanan 52. Üst üste sayım savunmanın kapsamını 2,5 kat şişirir.

Sonraki Adım

Bu ders katmanları ağ üzerinde konumlandırdı ve her birinin kaç yol kapattığını saydı. Kapanan yolların hepsi bir adımın geçilememesiyle kapandı: süzgeç geçirmedi, kimlik tanınmadı, girdi kabul edilmedi. Ama grafikte bir adımı geçmenin ikinci bir koşulu daha var — o adımı atan öznenin hedef kaleme dokunma izni. Beş katmanın hiçbiri o izne bakmadı; hepsi adımın kendisini denetledi. Sonraki dersin sorusu izin kümesidir: her özneye verilen izin kalemleri yol kümesine çevrildiğinde kaç yol açılıyor, izinler gerçekten kullanılana kadar daraltıldığında kaç yol kapanıyor ve daraltmanın karşılığında hangi meşru akış, günde kaç istekle duruyor.

İ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