Ders 15 / 20
Erişim Denetim Listeleri
On kural ve on altı bilinen akış üzerinde kural değerlendirme sırası koşturulur: her akış için ilk eşleşen kural bulunur, aynı liste beş ayrı sırada değerlendirilir ve sıra değişince kaç akışın sonucunun değiştiği sayılır; sertleştirme amaçlı bir taşımanın kaç meşru akışı kestiği ve özgülden genele sıralamanın açtığı yol ölçülür.
İçindekiler
Altı derstir yazılan her savunma sonunda aynı şeye indi: bir kural listesi. Bölge sınırları on beş satır, uzak erişim bölgeleri dört satır, denetim noktası ve engelleme listeleri kendi satırlarını getirdi. Bu satırlar tek bir kutuda yan yana durur ve bir akış geldiğinde hepsine birden bakılmaz — sırayla bakılır ve ilk eşleşen kazanır.
Bu dersin sorusu hangi kuralın yazıldığı değil, hangisinin önce geldiğidir. Kural metni tek bir karakter değişmeden, yalnız satırların sırası değiştiğinde aynı akış kümesinin sonuçları değişebilir. Ölçülen şey budur: bilinen bir akış kümesinde her akış için ilk eşleşen kural bulunur ve sıra değiştiğinde kaç akışın sonucunun değiştiği sayılır.
- CS34. On kural, on altı akış ve bölge adları kurgusal bölgesel ölçüm ağına aittir. Gerçek
paket akmıyor; ölçülen şey
nodeile kurulan modeldir. - CS35. Eşleşme üç eksende yapılıyor: kaynak bölge, hedef bölge ve hizmet adı. Gerçekte adres aralığı, protokol ve kapı da yazılır; eksen sayısını büyütür, sıranın etkisini değiştirmez.
- CS36. Akışların meşru olup olmadığı elle işaretlendi ve model boyunca sabittir.
- CS37. Kural numaraları operatörün yazdığı sıradır: eski satırlar küçük numaralı, sonradan eklenenler büyük. Taşıma, satıra yeni bir numara vermekle modellendi.
- CS38. Durum bilgisi ve dönüş yönü modellenmedi; her akış tek yönde değerlendiriliyor.
- CS39. Bir akış listedeki her kurala uyabilir; sonucu yalnız ilk eşleşen belirler.
Liste ve İlk Eşleşen Kural
Kural listesi bir kerede yazılmadı. En küçük numaralı satır en eskisidir ve yönetim bölgesine her yere erişim verir; bölütleme dersinde ölçülen satır tam olarak budur. Yüz altmış numaralı satır sonradan, sertleştirme sırasında eklendi ve yönetim kabuğunu her yerden reddediyor. İkisi aynı listede duruyor ve ikisi de aynı akışlara uyuyor.
// liste.mjs — numarali kural listesi ve bilinen akis kumesi; model, gercek filtre degil // [no, kaynak bolge, hedef bolge, hizmet, karar] — '*' o eksende ayrim yok demektir export const KURAL = [ [100, 'yonetim', '*', '*', 'izin'], // en eski satir: yonetim her yere [110, '*', 'dmz', 'genel-arayuz', 'izin'], [120, 'dmz', 'uygulama', 'uygulama-api', 'izin'], [130, 'sube', 'uygulama', 'fatura-api', 'izin'], [140, 'saha', 'dmz', 'olcum-alim', 'izin'], [150, 'uygulama', 'veri', 'veri-uc', 'izin'], [160, '*', '*', 'yonetim-kabugu', 'reddet'], // sertlestirme sirasinda eklendi [170, 'uzak', 'dmz', '*', 'izin'], [180, 'veri', 'yedek', 'yedek-uc', 'izin'], [190, '*', '*', '*', 'reddet'], // varsayilan reddet ]; // [ad, kaynak, hedef, hizmet, mesru mu] export const AKIS = [ ['yonetim -> uygulama kabugu', 'yonetim', 'uygulama', 'yonetim-kabugu', true], ['yonetim -> veri kabugu', 'yonetim', 'veri', 'yonetim-kabugu', true], ['yonetim -> dmz arayuzu', 'yonetim', 'dmz', 'genel-arayuz', true], ['sube -> fatura api', 'sube', 'uygulama', 'fatura-api', true], ['saha -> olcum alimi', 'saha', 'dmz', 'olcum-alim', true], ['dis -> genel arayuz', 'dis', 'dmz', 'genel-arayuz', true], ['dmz -> uygulama api', 'dmz', 'uygulama', 'uygulama-api', true], ['uygulama -> veri ucu', 'uygulama', 'veri', 'veri-uc', true], ['veri -> yedek ucu', 'veri', 'yedek', 'yedek-uc', true], ['uzak -> genel arayuz', 'uzak', 'dmz', 'genel-arayuz', true], ['uzak -> olcum alimi', 'uzak', 'dmz', 'olcum-alim', true], ['saha -> veri ucu (ceyrek sonu)', 'saha', 'veri', 'veri-uc', true], ['uzak -> dmz kabugu', 'uzak', 'dmz', 'yonetim-kabugu', false], ['sube -> uygulama kabugu', 'sube', 'uygulama', 'yonetim-kabugu', false], ['dis -> uygulama api', 'dis', 'uygulama', 'uygulama-api', false], ['dmz -> veri ucu', 'dmz', 'veri', 'veri-uc', false], ]; const uyar = (k, a) => (k[1] === '*' || k[1] === a[1]) && (k[2] === '*' || k[2] === a[2]) && (k[3] === '*' || k[3] === a[3]); export const ilkEslesen = (liste, a) => liste.find((k) => uyar(k, a)); export const karar = (liste, a) => ilkEslesen(liste, a)[4]; export function say(liste) { const r = AKIS.map((a) => [a, karar(liste, a)]); const n = (f) => r.filter(([a, k]) => f(a, k)).length; return { izin: n((a, k) => k === 'izin'), reddet: n((a, k) => k === 'reddet'), yanlisKapali: n((a, k) => a[4] && k === 'reddet'), kacan: n((a, k) => !a[4] && k === 'izin') }; } export const golge = (liste) => liste.filter((k) => !AKIS.some((a) => ilkEslesen(liste, a)[0] === k[0])); export const tasi = (no, yeni) => [...KURAL].map((k) => (k[0] === no ? [yeni, ...k.slice(1)] : k)) .sort((a, b) => a[0] - b[0]); export const jokerSayisi = (k) => k.slice(1, 4).filter((x) => x === '*').length; export const SIRA = { 'yazildigi sira': KURAL, '160 -> 95': tasi(160, 95), '170 -> 105': tasi(170, 105), 'ozgulden genele': [...KURAL].sort((a, b) => jokerSayisi(a) - jokerSayisi(b) || a[0] - b[0]), 'ters': [...KURAL].reverse(), }; export const degisen = (a1, a2) => AKIS.filter((a) => karar(a1, a) !== karar(a2, a));
// kosum1.mjs — yazildigi sirada her akis icin ilk eslesen kural ve sonuc import { KURAL, AKIS, ilkEslesen, karar, say, golge } from './liste.mjs'; console.log(`${KURAL.length} kural, ${AKIS.length} bilinen akis\n`); console.log(`${'akis'.padEnd(32)} ${'mesru'.padStart(5)} ${'ilk eslesen'.padStart(11)} ${'karar'.padStart(6)} sonuc`); for (const a of AKIS) { const k = ilkEslesen(KURAL, a), c = karar(KURAL, a); const s = a[4] === (c === 'izin') ? 'dogru' : (a[4] ? 'yanlis kapali' : 'kacan'); console.log(`${a[0].padEnd(32)} ${String(a[4] ? 'evet' : 'hayir').padStart(5)} ${String(k[0]).padStart(11)} ${c.padStart(6)} ${s}`); } const s = say(KURAL); console.log(`\nizin ${s.izin}, reddet ${s.reddet}, yanlis kapali ${s.yanlisKapali}, kacan ${s.kacan}`); console.log(`golgede kalan kural: ${golge(KURAL).map((k) => k[0]).join(', ') || 'yok'}`); const k160 = AKIS.filter((a) => a[3] === 'yonetim-kabugu'); console.log(`\n"yonetim-kabugu" hizmetine bakan ${k160.length} akis ve her birine karar veren kural:`); for (const a of k160) console.log(` ${a[0].padEnd(32)} ${ilkEslesen(KURAL, a)[0]} numarali satir -> ${karar(KURAL, a)}`);
10 kural, 16 bilinen akis akis mesru ilk eslesen karar sonuc yonetim -> uygulama kabugu evet 100 izin dogru yonetim -> veri kabugu evet 100 izin dogru yonetim -> dmz arayuzu evet 100 izin dogru sube -> fatura api evet 130 izin dogru saha -> olcum alimi evet 140 izin dogru dis -> genel arayuz evet 110 izin dogru dmz -> uygulama api evet 120 izin dogru uygulama -> veri ucu evet 150 izin dogru veri -> yedek ucu evet 180 izin dogru uzak -> genel arayuz evet 110 izin dogru uzak -> olcum alimi evet 170 izin dogru saha -> veri ucu (ceyrek sonu) evet 190 reddet yanlis kapali uzak -> dmz kabugu hayir 160 reddet dogru sube -> uygulama kabugu hayir 160 reddet dogru dis -> uygulama api hayir 190 reddet dogru dmz -> veri ucu hayir 190 reddet dogru izin 11, reddet 5, yanlis kapali 1, kacan 0 golgede kalan kural: yok "yonetim-kabugu" hizmetine bakan 4 akis ve her birine karar veren kural: yonetim -> uygulama kabugu 100 numarali satir -> izin yonetim -> veri kabugu 100 numarali satir -> izin uzak -> dmz kabugu 160 numarali satir -> reddet sube -> uygulama kabugu 160 numarali satir -> reddet
Yazıldığı sırada liste iyi görünüyor: on altı akışın on beşi doğru sonuçlanıyor, tek yanlış kapatma çeyrek sonu mutabakatıdır — bölütleme dersinde de aynı akış kesilmişti ve yine hiçbir satır ona bakmıyor. Kaçan akış yok, gölgede kalan kural yok.
Alt liste dersin asıl sorusunu koyuyor. Yönetim kabuğu hizmetine bakan dört akış var ve bunların ikisine yüz numaralı satır, ikisine yüz altmış numaralı satır karar veriyor. Yüz altmış numaralı satır “yönetim kabuğunu her yerden reddet” diye yazıldı; metni bunu söylüyor ve denetim belgesinde de böyle görünüyor. Koşumda yaptığı şey ise “yönetim bölgesi dışındaki her yerden reddet”tir, çünkü yönetim bölgesinden gelen akışlar ona hiç ulaşmıyor — yüz numaralı satırda duruyorlar. İki satır çakışıyor ve çakışmayı çözen şey metin değil, numaradır.
Aynı listede ters yönde bir örnek daha var. Uzak erişim bölgesinden ölçüm alımına giden akışa yüz yetmiş numaralı satır karar veriyor; genel arayüze giden akışa ise yüz on numaralı satır, çünkü o önce geliyor ve kaynak ekseninde joker taşıyor. İki akış da izin alıyor, sonuç aynı — ama kararı veren satırlar farklı. Bir denetim kaydında “hangi kural izin verdi” sorusunun cevabı, kuralı yazan kişinin beklediği satır olmayabilir. Yüz yetmiş numaralı satırı kaldıran biri, uzak erişimin genel arayüze ulaşmaya devam ettiğini görüp değişikliğin etkisiz olduğunu düşünebilir; ölçüm alımı akışı o sırada zaten kesilmiştir.
Sıra Değişince
// kosum2.mjs — ayni kural kumesi bes sirada; sira degisince kac akisin sonucu degisiyor import { KURAL, AKIS, SIRA, karar, say, golge, degisen } from './liste.mjs'; console.log(`${'sira'.padEnd(17)} ${'izin'.padStart(4)} ${'reddet'.padStart(6)} ${'yanlis kapali'.padStart(13)} ` + `${'kacan'.padStart(5)} ${'degisen akis'.padStart(12)} ${'golgede kural'.padStart(13)}`); for (const [ad, liste] of Object.entries(SIRA)) { const s = say(liste), g = golge(liste); console.log(`${ad.padEnd(17)} ${String(s.izin).padStart(4)} ${String(s.reddet).padStart(6)} ${String(s.yanlisKapali).padStart(13)} ` + `${String(s.kacan).padStart(5)} ${String(degisen(KURAL, liste).length).padStart(12)} ${(g.map((k) => k[0]).join(',') || '-').padStart(13)}`); } for (const ad of ['160 -> 95', 'ozgulden genele']) { console.log(`\n"${ad}" sirasinda sonucu degisen akislar:`); for (const a of degisen(KURAL, SIRA[ad])) console.log(` ${a[0].padEnd(32)} ${karar(KURAL, a)} -> ${karar(SIRA[ad], a)} (mesru: ${a[4] ? 'evet' : 'hayir'})`); } console.log(`\nkural metni ${KURAL.length} satirda hic degismedi; degisen tek sey siradir`); const O = KURAL.filter((k) => k[0] !== 190); // varsayilan reddet her izin satiriyla catisir, disarida const cift = O.flatMap((a, i) => O.slice(i + 1).filter((b) => AKIS.some((x) => [a, b].every((k) => (k[1] === '*' || k[1] === x[1]) && (k[2] === '*' || k[2] === x[2]) && (k[3] === '*' || k[3] === x[3]))) && a[4] !== b[4]).map((b) => [a[0], b[0]])); console.log(`varsayilan reddet disinda, ayni akista eslesip farkli karar veren cift: ${cift.map(([a, b]) => `${a}/${b}`).join(', ')}`);
sira izin reddet yanlis kapali kacan degisen akis golgede kural yazildigi sira 11 5 1 0 0 - 160 -> 95 9 7 3 0 2 - 170 -> 105 12 4 1 1 1 - ozgulden genele 12 4 1 1 1 - ters 0 16 12 0 11 180,170,160,150,140,130,120,110,100 "160 -> 95" sirasinda sonucu degisen akislar: yonetim -> uygulama kabugu izin -> reddet (mesru: evet) yonetim -> veri kabugu izin -> reddet (mesru: evet) "ozgulden genele" sirasinda sonucu degisen akislar: uzak -> dmz kabugu reddet -> izin (mesru: hayir) kural metni 10 satirda hic degismedi; degisen tek sey siradir varsayilan reddet disinda, ayni akista eslesip farkli karar veren cift: 100/160, 160/170
İkinci satır sertleştirme sezgisinin sonucudur. Yönetim kabuğunu reddeden satır listenin başına taşınıyor; artık gerçekten her yerden reddediyor. Yanlış kapatma birden üçe çıkıyor ve değişen iki akışın ikisi de meşrudur: yönetim bölgesinden uygulama ve veri bölgelerine giden kabuk oturumları. Hamle metinde bir düzeltmedir, koşumda yönetim erişiminin kesilmesidir. Kesintinin ne zaman fark edileceği de belirlidir — bir sonraki bakım penceresinde.
Üçüncü ve dördüncü satırlar ters yönde aynı şeyi yapıyor. “Özgül kural önce, genel kural sonra” yaygın bir sıralama sezgisidir ve burada koşturulduğunda kaçan akış sıfırdan bire çıkıyor. Neden son satırdaki çift listesinde: yüz altmış numaralı reddet satırı iki eksende joker taşır, yüz yetmiş numaralı izin satırı bir eksende. Özgüllüğe göre sıralayan bir düzen izin satırını öne alır ve uzak erişim bölgesinden yönetim kabuğuna giden akış geçer. Aynı sonuç yüz yetmişi elle öne taşımakla da çıkıyor; iki hamle farklı gerekçelere sahip, sonuçları aynı.
Beşinci satır sınırdır. Liste ters çevrildiğinde varsayılan reddet başa geçiyor, on altı akışın tamamı reddediliyor ve dokuz kural gölgede kalıyor. Gölge sütunu bu yüzden bir sağlık ölçüsüdür: hiçbir akışa karar vermeyen bir kural ya gereksizdir ya da önündeki bir satır tarafından örtülmüştür. İkisi farklı şeylerdir ve liste metnine bakarak ayırt edilemez; ayırt eden şey akış kümesi üzerindeki koşumdur.
İki taşıma hamlesi bir arada okunduğunda dersin ölçüsü ortaya çıkıyor. Yüz altmışı öne almak iki meşru akışı kesti, yüz yetmişi öne almak bir gayrimeşru akışı geçirdi. İkisi de tek satırlık değişikliklerdi, ikisinin de gerekçesi makuldü ve ikisi de listenin metnine bakılarak değerlendirilemezdi. Ölçülebilir hâle gelmelerinin tek yolu bilinen bir akış kümesini iki sırada koşturup sonuçları karşılaştırmaktı: değişen akış sütunu sırasıyla iki ve bir yazıyor. Bu sütun olmadan yapılan her sıralama değişikliği, sonucu bir sonraki arıza kaydından öğrenilen bir değişikliktir.
Son satır çakışan iki çifti veriyor: yüz ile yüz altmış, yüz altmış ile yüz yetmiş. On kurallık bir listede sıraya duyarlı olan yalnız bu iki çifttir ve ikisinin ortasında aynı satır durur. Kural sayısı büyüdükçe çift sayısı hızla büyür; sıranın etkisi tek tek satırlara bakarak değil, bilinen bir akış kümesini koşturarak ölçülür.
Konunun ölçüsü burada tamamlanıyor. Yedi derste sayılan her savunma sonunda bir alana bakıyordu: kaynak bölge, hedef bölge, hizmet adı, özne kimliği. Bu alanların hepsi birer iddiadır ve ilk derste hangilerinin kanıtlanabildiği sayılmıştı. Kural listesi o iddiaları kullanır ama kanıtlamaz; kaynak bölge alanına yazılan değer, paketin gerçekten o bölgeden geldiğinin kanıtı değil, geldiği yönün beklenen bloğuna uyduğunun kanıtıdır. Sıralama tartışması bu yüzden bir kat daha derindir: liste yalnız hangi kuralın kazanacağını değil, hangi iddianın hiç sınanmayacağını da belirler. Bir akış yüz numaralı satırda dururken hizmet ekseni hiç okunmaz.
Özet
- Yazıldığı sırada 16 akışın 15’i doğru sonuçlanıyor; tek yanlış kapatma bölütleme dersinde de kesilen çeyrek sonu mutabakatıdır ve yine hiçbir satır ona bakmıyor.
- “Yönetim kabuğunu her yerden reddet” diye yazılan satır, koşumda “yönetim bölgesi dışındaki her yerden reddet” anlamına geliyor: 4 kabuk akışının 2’sine ondan önceki satır karar veriyor.
- O satırı listenin başına taşımak metinde bir düzeltmedir; koşumda 2 meşru yönetim akışını kesip yanlış kapatmayı 1’den 3’e çıkarıyor.
- “Özgül önce, genel sonra” sıralaması kaçanı 0’dan 1’e çıkarıyor: reddet satırı 2 joker, izin satırı 1 joker taşıdığı için izin öne geçiyor ve uzak erişim bölgesinden yönetim kabuğuna giden akış geçiyor.
- Liste ters çevrildiğinde 16 akışın tamamı reddediliyor ve 9 kural gölgede kalıyor. Kural metni hiçbir sırada değişmedi; değişen tek şey sıradır ve sıraya duyarlı çift 10 kuralda 2 tanedir.
Sonraki Adım
Yedi ders boyunca çevre çizildi, bölgeler ayrıldı, denetim noktaları kondu ve kurallar sıraya
dizildi. Bölge grafiğinde kapanan yol sayıldı, tünelin indiği bölge ölçüldü, ilk eşleşen kural
akış akış bulundu. Bütün bu sınırların ortak bir özelliği vardı ve hiçbir yerde yazılmadı: hepsi
kablonun sınırıydı. Bir bölgeye ait olmak, o bölgenin anahtarına bağlı bir kablonun ucunda
bulunmak demekti; kural listesindeki kaynak bölge alanı da bu varsayıma dayanıyordu. Sinyal binanın
duvarında durmuyor. Sonraki konu Kablosuz Güvenlik: erişim noktasının kapsama alanı bina
sınırının ne kadar dışına taşıyor, hangi iddia havada doğrulanabiliyor ve bir bölgeye ait olmak
kablo olmadığında neye dayanıyor.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.