İçeriğe geç
academia.sh

Ders 11 / 16

Güvenlik Duvarı Yapılandırması

Makine düzeyinde açık yüzey kalem kalem sayılır: kurulum sonrası kaç kapı dinliyor, kaç bölgeden ulaşılabiliyor, varsayılan reddede geçilince kaç deneme duruyor, kaç meşru iş yanlışlıkla kapanıyor ve giden yön kısıtlanmadığında ne açık kalıyor.

İçindekiler

Önceki konu adın ve gönderenin doğrulanmasıyla kapandı: sorgu doğru ad sunucusuna gidiyor, e-postanın kaynağı kanıtlanabiliyor. Doğrulanan şey adın kendisiydi; adın işaret ettiği makine kurulduğu günkü ayarlarıyla duruyor ve o ayarlar onu her yerden erişilebilir bıraktı. Arkadaki makineye adı hiç kullanmadan da ulaşılır — adres yeter.

Ağ politikası daha önce küme içi ölçekte ölçüldü: hangi kapsül hangi kapsüle ulaşabiliyor. Buranın ölçeği kümenin altındaki makinedir. Sorulan üç şey var: hiçbir şey yapılmadığında kaç kalem açık kalır, kapatmak kaç satır ister, kapatınca kaç meşru iş durur.

  • ST1. Altı makine ve yirmi beş dinleyen kapıdan oluşan düzen, kurgusal bölgesel ölçüm ağına aittir. Gerçek bir makine koşturulmuyor; ölçülen şey node ile kurulan modeldir.
  • ST2. Kaynak bölge dörde indirgendi. Gerçekte bölge ayrımı adres aralıklarıyla yazılır; kalem sayısını büyütür, sonucun yönünü değiştirmez.
  • ST3. Deneme sayıları elle yazıldı; rastgelelik yok, her koşum aynı sayıları üretir.
  • ST4. Bir kapı ya açıktır ya kapalı; hız sınırı ve durum takibi modellenmiyor.
  • ST5. İzin listesi izden türetilmedi, elle yazıldı; ATLANAN ile işaretlenen iki seyrek akışın gözden kaçması modele elle konuldu. Gerçekte atlanan akış sayısı gözlem süresine bağlıdır.
  • ST6. Giden yön hedef sınıfı düzeyinde modellendi. Gerçekte giden kural adres ve kapı üzerinden yazılır; kalem sayısı büyür, kısıtlanmamış giden yönün anlamı değişmez.

Kural Kümesi Modeli

Model üç şey tutuyor: hangi makinede hangi kapı dinliyor, dönemde hangi bölgeden hangi kapıya kaç deneme geldi ve operatörün yazdığı izin listesi. Kurallar kendi küçük şemamızla yazılıyor: bir satır bir kaynak bölge, bir makine ve bir kapı adı belirtir, * o eksende ayrım yapılmadığı demektir.

// duvar.mjs — makine, dinlenen kapi, deneme ve kural kumesi modeli; gercek ag degil
export const BOLGE = ['ic-ag', 'ofis-ag', 'saha-ag', 'dis'];
const ORTAK = [['yonetim-kabugu', 'yonetim'], ['olcut-uc', 'yardimci'], ['gunluk-aktarim', 'yardimci']];
const OZGU = {                              // kurulumun makine basina acik biraktigi kapilar
  'toplayici-1': [['okuma-alim', 'is']], 'toplayici-2': [['okuma-alim', 'is']],
  'dogrulayici': [['dogrulama-api', 'is']], 'faturalama': [['fatura-api', 'is']],
  'veri-deposu': [['veri-uc', 'is'], ['yedek-uc', 'is']], 'yonetim': [['yonetim-arayuz', 'yonetim']],
};
export const MAKINE = Object.keys(OZGU);
export const KAPI = MAKINE.flatMap((m) => [...ORTAK, ...OZGU[m]].map(([ad, tur]) => ({ makine: m, ad, tur })));
export const anahtar = (b, m, k) => `${b}|${m}|${k}`;

// Otuz gunluk deneme: [bolge, makine, kapi, sayi, mesru mu]
const her = (b, k, f, ms) => MAKINE.map((m, i) => [b, m, k, f(i), ms]);
export const DENEME = [
  ['saha-ag', 'toplayici-1', 'okuma-alim', 41200, true], ['saha-ag', 'toplayici-2', 'okuma-alim', 38900, true],
  ['ic-ag', 'dogrulayici', 'dogrulama-api', 26400, true], ['ic-ag', 'veri-deposu', 'veri-uc', 91500, true],
  ['ic-ag', 'faturalama', 'fatura-api', 8600, true], ['ofis-ag', 'faturalama', 'fatura-api', 1240, true],
  ['ofis-ag', 'yonetim', 'yonetim-arayuz', 860, true], ['ofis-ag', 'yonetim', 'yonetim-kabugu', 310, true],
  ['ofis-ag', 'veri-deposu', 'yedek-uc', 4, true],       // aylik yedek dogrulamasi
  ['ofis-ag', 'dogrulayici', 'dogrulama-api', 12, true], // ceyrek sonu elle dogrulama
  ...her('ic-ag', 'olcut-uc', () => 8640, true), ...her('ic-ag', 'gunluk-aktarim', () => 30, true),
  ...her('ic-ag', 'yonetim-kabugu', () => 62, true),     // yapilandirma dagitimi
  ...her('dis', 'yonetim-kabugu', (i) => 12000 + i * 1730, false),
  ...her('dis', 'olcut-uc', (i) => 90 + i * 7, false),
  ['dis', 'veri-deposu', 'veri-uc', 2400, false], ['dis', 'veri-deposu', 'yedek-uc', 180, false],
  ['dis', 'toplayici-1', 'okuma-alim', 640, false], ['dis', 'yonetim', 'yonetim-arayuz', 5100, false],
  ['saha-ag', 'veri-deposu', 'veri-uc', 26, false], ['saha-ag', 'yonetim', 'yonetim-kabugu', 14, false],
  ['ofis-ag', 'veri-deposu', 'veri-uc', 310, false],
];
export const MESRU = DENEME.filter((d) => d[4]).map((d) => anahtar(d[0], d[1], d[2]));
// Izin listesini operator elle yazdi; iki seyrek akis gozden kacti.
const ATLANAN = ['ofis-ag|veri-deposu|yedek-uc', 'ofis-ag|dogrulayici|dogrulama-api'];
export const IZIN = MESRU.filter((a) => !ATLANAN.includes(a)).map((a) => a.split('|'));
// Ayni liste uc genislikte yazilabilir; '*' o eksende ayrim yok demektir.
export const bicimler = () => ({
  'kapi-adi': [...new Set(IZIN.map((r) => r[2]))].map((k) => ['*', '*', k]),
  'bolge+kapi': [...new Set(IZIN.map((r) => `${r[0]}|${r[2]}`))].map((s) => [s.split('|')[0], '*', s.split('|')[1]]),
  'bolge+makine+kapi': IZIN,
});
export function acilan(kural) {             // kural kumesi -> acik kalem kumesi
  const acik = new Set();
  for (const [b, m, k] of kural)
    for (const bb of (b === '*' ? BOLGE : [b]))
      for (const p of KAPI)
        if ((m === '*' || p.makine === m) && (k === '*' || p.ad === k)) acik.add(anahtar(bb, p.makine, p.ad));
  return acik;
}
export const HEPSI = acilan([['*', '*', '*']]);  // varsayilan izinli duzen tek satira esit
export function say(acik) {
  const kapali = (d) => !acik.has(anahtar(d[0], d[1], d[2]));
  const top = (f) => DENEME.filter(f).reduce((a, d) => a + d[3], 0);
  return { kalem: acik.size, karsiliksiz: [...acik].filter((a) => !MESRU.includes(a)).length,
    duran: top((d) => !d[4] && kapali(d)), gecen: top((d) => !d[4] && !kapali(d)),
    yanlisKapali: DENEME.filter((d) => d[4] && kapali(d)).length };
}
export const GIDEN_MESRU = [
  ['toplayici-1', 'ic:kuyruk'], ['toplayici-2', 'ic:kuyruk'], ['dogrulayici', 'ic:veri-deposu'],
  ['faturalama', 'ic:veri-deposu'], ['faturalama', 'dis:posta-gecidi'], ['yonetim', 'dis:paket-deposu'],
  ['veri-deposu', 'ic:yedek-alan'], ...MAKINE.map((m) => [m, 'dis:zaman-kaynagi']),
];
export const GIDEN_IZIN = GIDEN_MESRU.filter(([m, h]) => h !== 'dis:zaman-kaynagi' || m === 'yonetim');

HEPSI satırı modelin sessiz iddiasıdır: varsayılan izinli düzen tek bir * -> * -> * kuralına eşittir; kimse o kuralı yazmadı ama etkisi yazılmış gibidir. say bir açık kalem kümesi alıp beş sayı döndürüyor: kaç kalem açık, kaçının karşılığı yok, meşru olmayan denemelerden kaçı durdu, kaçı geçti ve kaç meşru akış yanlışlıkla kapandı.

Varsayılanın Bıraktığı Yüzey

// kosum1.mjs — kurulum sonrasi hicbir sey yapilmadiginda acik kalan kalemler sayilir
import { BOLGE, MAKINE, KAPI, DENEME, MESRU, GIDEN_MESRU, HEPSI, say } from './duvar.mjs';

const s = say(HEPSI);
const tur = (t) => KAPI.filter((k) => k.tur === t).length;
const top = (f) => DENEME.filter(f).reduce((a, d) => a + d[3], 0);
const kapiTuru = (m, k) => KAPI.find((x) => x.makine === m && x.ad === k).tur;
for (const [ad, deger, not = ''] of [
  ['dinlenen kapi', KAPI.length, `${MAKINE.length} makine: is ${tur('is')}, yardimci ${tur('yardimci')}, yonetim ${tur('yonetim')}`],
  ['gelen yon acik kalem', s.kalem, `${KAPI.length} kapi x ${BOLGE.length} bolge`],
  ['  mesru akisa karsilik gelen', MESRU.length],
  ['  karsiliksiz acik', s.karsiliksiz],
  ['dis bolgeden erisilen yonetim kapisi', tur('yonetim')],
  ['giden yon kisitlamasi', '-', `${MAKINE.length} makinenin hedefi sinirsiz, ${GIDEN_MESRU.length} mesru akis`],
  ['otuz gunluk mesru olmayan deneme', top((d) => !d[4]), `${new Set(DENEME.filter((d) => !d[4]).map((d) => d[0])).size} kaynak bolgeden`],
  ['  yonetim kapisina gelen', top((d) => !d[4] && kapiTuru(d[1], d[2]) === 'yonetim')],
  ['  durdurulan', s.duran],
  ['  hedefe ulasan', s.gecen],
]) console.log(`${ad.padEnd(38)}${String(deger).padStart(7)}  ${not}`.trimEnd());
dinlenen kapi                              25  6 makine: is 6, yardimci 12, yonetim 7
gelen yon acik kalem                      100  25 kapi x 4 bolge
  mesru akisa karsilik gelen               28
  karsiliksiz acik                         72
dis bolgeden erisilen yonetim kapisi        7
giden yon kisitlamasi                       -  6 makinenin hedefi sinirsiz, 13 mesru akis
otuz gunluk mesru olmayan deneme       107265  3 kaynak bolgeden
  yonetim kapisina gelen               103064
  durdurulan                                0
  hedefe ulasan                        107265

Yirmi beş dinleyen kapının yalnız altısı işin kendisi için açık. Kalan on dokuzu ölçüt toplama, günlük aktarımı ve yönetim kabuğu içindir; hiçbiri kasten açılmadı, kurulum açtı. Yüz kalem bu kapıların dört bölgeden birden erişilebilir olmasından geliyor — yirmi sekizinin karşılığında meşru bir akış var, yetmiş ikisinin yok.

Yönetim kapılarının yedisi dış bölgeden de erişilebilir ve dönemin meşru olmayan yüz yedi bin denemesinin yüz üç bini tam olarak oraya geliyor. Son iki satır çıkış noktasıdır: bu denemelerin sıfır tanesi durdu. Varsayılan kararı “izin ver” olan bir güvenlik duvarı katmanıyla hiç olmayan katman aynı sayıyı üretiyor. Giden yönde ise kısıtlama diye bir kalem bile yok.

Varsayılan Reddet ve Kuralın Genişliği

// kosum2.mjs — varsayilan reddede gecilir; ayni izin listesi uc kural genisliginde yazilir
import { BOLGE, IZIN, bicimler, acilan, HEPSI, say } from './duvar.mjs';

const satir = (ad, n, acik) => {
  const s = say(acik);
  console.log(`${ad.padEnd(35)} ${String(n).padEnd(6)} ${String(s.kalem).padEnd(6)} ` +
    `${String(s.karsiliksiz).padEnd(12)} ${String(s.duran).padEnd(13)} ${String(s.gecen).padEnd(13)} ${s.yanlisKapali}`);
};
console.log(`ayni izin listesi (${IZIN.length} akis) uc genislikte:\n` +`${'kural genisligi'.padEnd(35)} satir  kalem  karsiliksiz  duran deneme  gecen deneme  yanlis kapali`);
satir('varsayilan izin', 0, HEPSI);
for (const [ad, k] of Object.entries(bicimler())) satir(ad, k.length, acilan(k));
const dar = bicimler()['bolge+makine+kapi'];
const A = ['ofis-ag', '*', '*'], B = ['dis', 'yonetim', 'yonetim-kabugu'], C = ['*', '*', 'olcut-uc'];
console.log('\nen dar bicime gecici satir eklenirse:');
for (const [ad, ek] of [['ofis-ag -> * -> *', [A]], ['dis -> yonetim -> yonetim-kabugu', [B]],
  ['ucu birden (+ * -> * -> olcut-uc)', [A, B, C]]]) satir(`  ${ad}`, dar.length + ek.length, acilan([...dar, ...ek]));
const genis = bicimler()['kapi-adi'].map(([b, m, k]) => [k, acilan([[b, m, k]]).size]).filter(([, n]) => n > 4);
console.log(`\nkapi adina yazilan tek kuralin actigi kalem (${BOLGE.length} bolge x kapiyi dinleyen makine):`);
console.log('  ' + genis.map(([k, n]) => `${k} ${n}`).join(', '));
ayni izin listesi (26 akis) uc genislikte:
kural genisligi                     satir  kalem  karsiliksiz  duran deneme  gecen deneme  yanlis kapali
varsayilan izin                     0      100    72           0             107265        0
kapi-adi                            8      96     69           180           107085        1
bolge+kapi                          10     31     5            107265        0             2
bolge+makine+kapi                   26     26     0            107265        0             2

en dar bicime gecici satir eklenirse:
  ofis-ag -> * -> *                 27     48     20           106955        310           0
  dis -> yonetim -> yonetim-kabugu  27     27     1            86615         20650         2
  ucu birden (+ * -> * -> olcut-uc) 29     61     33           85660         21605         0

kapi adina yazilan tek kuralin actigi kalem (4 bolge x kapiyi dinleyen makine):
  okuma-alim 8, yonetim-kabugu 24, olcut-uc 24, gunluk-aktarim 24

Varsayılanı reddet yapmak tek başına bir sayı üretmiyor. kapi-adi satırı bunu gösteriyor: sekiz kural yazıldı, varsayılan reddedir, izin listesi uygulanıyor — ve açık kalem yüzden doksan altıya indi, meşru olmayan denemelerin yalnız yüz sekseni durdu. Son satır nedenini veriyor: yonetim-kabugu tek kural olarak yazıldığında yirmi dört kalem açıyor, çünkü altı makinenin ve dört bölgenin hepsini birden kapsıyor. İzin listesinde bu kapı için altı satır vardı ve altısı da iç ağdandı; bölge eksenini düşürmek dış bölgeyi de açıyor. Üç geniş kural, doksan altı kalemin yetmiş ikisini üretiyor.

Bölge eksenini eklemek satırı sekizden ona çıkarıyor: açık kalem otuz bire iniyor ve meşru olmayan denemelerin tamamı duruyor. İki satır, yüz yedi bin denemeyi kapatıyor. Makine eksenini de eklemek yirmi altı satır istiyor; karşılıksız kalem beşten sıfıra iniyor ama durdurulan deneme değişmiyor. Bölge ekseni kapatan eksendir, makine ekseni yalnız artığı temizler: on altı satırlık emek beş kaleme karşılık geliyor.

Yanlış kapatma sütunu her iki dar biçimde de iki — modelde ATLANAN ile işaretlenen aylık yedek doğrulaması ve çeyrek sonu elle doğrulaması, dönemde dört ve on iki deneme. Yüz binlerce satırlık bir izde bu on altı satır görünmez. Kural yazıldığı gün hiçbir şey bozulmaz; ay ve çeyrek sonunda bozulur ve görünen şey bir bağlantı hatasıdır, bir izin listesi satırı değil.

Ortadaki blok kapatmanın kendi getirdiği yüzeyi ölçüyor; kural kümesi de yazılan, gerekçeli olarak genişletilen ve çoğu zaman geri alınmayan bir kalemdir. ofis-ag için açılan joker satır yirmi iki kalem ekliyor ama yalnız üç yüz on deneme geçiriyor; dış bölgeye açılan tek yönetim kapısı bir kalem ekleyip yirmi bin altı yüz elli deneme geçiriyor — kalemin hangi bölgeye baktığı sayıdan önemlidir. Joker satırın son sütunu asıl sorunu gösteriyor: yanlış kapatma ikiden sıfıra iniyor, çünkü satır atlanmış iki meşru akışı kazara açıyor. Eksiklik fark edilmiyor, satırın kaldırılması için bir neden de doğmuyor. Üçü birlikte kaldığında yirmi dokuz satır altmış bir kalem açıyor; kural kümesi tek yönde büyür, çünkü satır eklemenin gerekçesi olur, satır silmenin olmaz.

Giden Yön

Buraya kadar sayılan her kalem gelen yöne aitti. Giden yön çoğu düzende hiç kısıtlanmaz ve kalem sayısında görünmediği için yüzey olduğu fark edilmez.

// kosum3.mjs — giden yon ayri sayilir; gelen kural bu sayilarin hicbirine dokunmuyor
import { MAKINE, IZIN, GIDEN_MESRU, GIDEN_IZIN, bicimler, acilan, say } from './duvar.mjs';

const dis = (l) => new Set(l.filter(([, h]) => h.startsWith('dis:')).map(([, h]) => h)).size;
const kalem = say(acilan(bicimler()['bolge+makine+kapi'])).kalem;
const duran = GIDEN_MESRU.filter(([k, h]) => !GIDEN_IZIN.some(([a, b]) => a === k && b === h));
console.log('makine        varsayilan  izinli hedef  duran mesru akis');
for (const m of MAKINE)
  console.log((`${m.padEnd(13)} ${'sinirsiz'.padEnd(11)} ` +
    `${String(GIDEN_IZIN.filter(([k]) => k === m).length).padEnd(13)} ` +
    duran.filter(([k]) => k === m).map(([, h]) => h).join(', ')).trimEnd());
console.log(`\nmesru giden akis              ${GIDEN_MESRU.length}   (${dis(GIDEN_MESRU)} dis hedef sinifina)`);
console.log(`giden kural satiri            ${GIDEN_IZIN.length}   (varsayilanda 0, hedef sinirsiz)`);
console.log(`izin verilen dis hedef sinifi ${dis(GIDEN_IZIN)}   (varsayilanda herhangi)`);
console.log(`yanlis kapatilan mesru akis   ${duran.length}`);
console.log(`gelen yon acik kalemi         ${kalem} -> ${kalem}   (degismedi)`);
console.log(`toplam kural satiri           ${IZIN.length} -> ${IZIN.length + GIDEN_IZIN.length}`);
makine        varsayilan  izinli hedef  duran mesru akis
toplayici-1   sinirsiz    1             dis:zaman-kaynagi
toplayici-2   sinirsiz    1             dis:zaman-kaynagi
dogrulayici   sinirsiz    1             dis:zaman-kaynagi
faturalama    sinirsiz    2             dis:zaman-kaynagi
veri-deposu   sinirsiz    1             dis:zaman-kaynagi
yonetim       sinirsiz    2

mesru giden akis              13   (3 dis hedef sinifina)
giden kural satiri            8   (varsayilanda 0, hedef sinirsiz)
izin verilen dis hedef sinifi 3   (varsayilanda herhangi)
yanlis kapatilan mesru akis   5
gelen yon acik kalemi         26 -> 26   (degismedi)
toplam kural satiri           26 -> 34

Sekiz satır giden kural, makine başına açık hedefi bire ya da ikiye indiriyor; varsayılanda bu sütunda “sınırsız” yazıyordu. Aradaki fark ele geçirilen bir makinenin ne yapabileceğidir: gelen kural kümesi eksiksiz olsa bile içeride çalışan bir süreç dışarıya bağlanabiliyorsa veriyi taşıyabilir, komut alabilir ve kendi kalıcılığını kurabilir. Bu yolun kapanması gelen yönün hiçbir kalemini değiştirmiyor; açık kalem yirmi altıda kalıyor, kural sayısı otuz dörde çıkıyor.

Yanlış kapatma sütunu beş. İzin listesini yazan kişi zaman kaynağı bağımlılığını yönetim düğümünde gördü ve orada yazdı, ötekilerde aklına gelmedi. Özelliği hemen görünmemesidir: saat bir anda durmaz, kayar. Kayma birkaç gün sonra imza doğrulamasında, günlük sıralamasında ve ölçüt pencerelerinde ortaya çıkar; hepsi başka bir şeyin belirtisi gibi görünür. Gelen yöndeki iki yanlış kapatma bir bağlantı hatası verip düzeltilir, giden yöndeki beş tanesi haftalarca yanlış teşhis edilebilir.

Kapatmanın getirdiği yeni yüzey de burada. İzin verilen üç dış hedef sınıfından biri paket deposudur ve yönetim düğümü için açıktır; yama alabilmenin bedeli, dışarıya çıkan bir yolun kalıcı olarak açık kalmasıdır. Otuz dört satırlık kural kümesi kapatılamayan bir kalem bırakıyor: iki yönde birden ayrıcalıklı olan yönetim düğümü.

Özet

  • Kurulum sonrası altı makinede 25 kapı dinliyor; yalnız 6’sı işin kendisi için. Dört bölgeden erişilebilirlik bunu 100 açık kaleme çeviriyor, 72’sinin karşılığında meşru akış yok ve dönemin meşru olmayan 107.265 denemesinin tamamı hedefe ulaşıyor — 103.064’ü yönetim kapılarına.
  • Varsayılanı reddet yapmak tek başına yetmiyor: kapı adına yazılan 8 satır yalnız 180 denemeyi durduruyor. Bölge ekseni 10 satırla denemelerin tamamını kapatıyor; makine ekseni 26 satır isteyip karşılıksız kalemi 5’ten 0’a indiriyor, durdurulan denemeye bir şey eklemiyor.
  • Her iki dar biçim de 2 meşru akışı yanlışlıkla kapatıyor; ikisi dönemde toplam 16 deneme ürettiği için izde görünmüyor ve ay ile çeyrek sonunda bozuluyor.
  • Kural kümesinin kendisi bir yüzeydir: dış bölgeye açılan tek satır 1 kalem ekleyip 20.650 deneme geçiriyor, ofis ağına açılan joker satır 22 kalem ekleyip yanlış kapatmayı 2’den 0’a indirerek eksik izin listesini gizliyor.
  • Giden yön 8 satırla kısıtlandığında makine başına açık hedef 1–2’ye iniyor ve gelen yönün 26 kalemi değişmiyor; bedeli, günler sonra saat kayması olarak görünen 5 yanlış kapatmadır. Kapatılamayan kalem, yama alabilmek için dışarıya bakan tek makinedir.

Sonraki Adım

En dar kural kümesi yönetim kabuğunu altı makinede iç ağa açık bıraktı. Kapı daraldı, arkasındaki şey değişmedi: bağlanan taraf hâlâ bir parolayla giriyor ve parola denemesi güvenlik duvarının izin verdiği bölgelerden serbestçe yapılabiliyor. Sonraki dersin sorusu kapının hangi bölgeye açık olduğu değil, kapıdan geçmenin neye bağlı olduğudur: parola tabanlı erişimde bir dönemde kaç deneme kaç kaynaktan geliyor, anahtar tabanlıya geçince bu yüzeyin ne kadarı kapanıyor, anahtar kaç kopya hâlinde nerede duruyor ve kaç makinede yetkili, iptal etmek kaç dokunuş istiyor — ve erişimi bir sıçrama sunucusuna indirmek doğrudan erişilebilir makine sayısını düşürürken karşılığında hangi tek hedefi doğuruyor.

İ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