---
title: 'Sunucu, Ağ ve Sertleştirme'
source: 'https://academia.sh/tr/kurslar/sunucu-ve-sertlestirme'
language: tr
updated: '2026-08-17T04:40:44+00:00'
license: 'CC BY-SA 4.0'
lessons: 16
outcomes:
    - 'Ters vekil ve yük dengeleyici yapılandırmasını yazar'
    - 'Sertifika ve alan adı kayıtlarını otomatik yönetir'
    - 'Sunucu ve erişim katmanını sertleştirir'
---

# Sunucu, Ağ ve Sertleştirme

Kurulum sonrası açık kalan yüzeyin sayılması ve kapatılması: web sunucusunun statik sunum, vekil ve yük dağıtımı rolleri, ters vekilde yukarı akış tanımı ve başlık aktarımı, TLS sonlandırma ve sertifika otomasyonu, kenar ve kaynak önbelleği, yan araba vekilleriyle trafik yönetimi, bölge dosyası ve kayıt yaşam süresi, gönderen doğrulama ve politika kayıtları, posta teslim sorunları, varsayılan reddet güvenlik duvarı, anahtar tabanlı uzak erişim ve sıçrama sunucusu, merkezî sır deposu ve dinamik kimlik bilgisi, yama penceresi, yedekleme kapsamı ve geri yükleme tatbikatı.

## Web Sunucuları ve Vekiller

İsteğin uygulamaya varana kadar geçtiği katman: statik sunum, vekil ve yük dağıtımı rollerinin ayrımı, ters vekilde yukarı akış tanımı ve başlık aktarımının yanlış yapıldığında kaybettiği bilgi, TLS sonlandırma ve protokol seçimi, sertifikanın otomatik yenilenmesi ve yenileme başarısızlığının penceresi, kenar ile kaynak önbelleğinin isabet ve tazelik dengesi ve yan araba vekilleriyle trafik yönetiminin bedeli.

### Web Sunucusu Rolleri

Source: https://academia.sh/tr/kurslar/sunucu-ve-sertlestirme/web-sunucusu-rolleri

Statik sunum, ters vekil ve yük dağıtımı rollerinin varsayılan kurulumdan sonra açık bıraktığı yüzey: on sekiz kalemin rol rol sayımı, üç rolü tek süreçte birleştirmenin on dört benzersiz kalemi on yediye çıkarması ve dış kapıdan erişilebilir kalem sayısını ondan on yediye taşıması, dört sertleştirme adımının kapattığı on üç kaleme karşılık durdurduğu dört meşru iş ve geriye kalan dört kapatılamayan kalem.

Önceki kurs sistemi görünür yaptı: ölçüm noktaları kondu, kayıtlar bir yerde toplandı, uyarılar
bir nöbetçiye ulaştı, olayın kim tarafından nasıl kapatıldığı yazıldı. Görünürlük kurulunca
görülen şey de değişti — panolar uygulamanın davranışını gösteriyor, ama uygulamanın **üstünde
durduğu makine** hakkında hiçbir şey söylemiyor.

O makine bir gün kuruldu ve kurulduğu gün ne verildiyse onunla duruyor. Paket açıldı, süreç
başlatıldı, istekler akmaya başladı ve iş görünce kimse bir daha bakmadı. Bu ders o bakışı bir
sayıya çevirir: kurulumdan sonra hiçbir şey yapılmadığında **kaç kalem açık kalır**.

Ölçü birimi **açık yüzey kalemi**dir. Bir kalem, dışarıdan ya da içeriden erişilebilen tek bir
şeydir: dinlenen bir kapı, sunulan bir yol, yanıtta görünen bir bilgi, kimlik sorulmayan bir
yönetim ucu. Kalem sayısı bir güvenlik notu değildir; bir sayımdır ve sayım yapılmadan hiçbir
sertleştirme adımı savunulamaz.

#### Üç Rol Ayrı Ayrı

Bir web sunucusu üç işten birini ya da üçünü birden yapar.

**Statik sunum** diskteki dosyayı isteğe karşılık verir. Girdi bir yol, çıktı bir dosyadır;
arada uygulama kodu yoktur. **Ters vekil** isteği alır, kendi bir şey üretmez ve arkadaki bir
yukarı akışa iletir; yanıtı geri taşır. **Yük dağıtımı** aynı işi birden çok yukarı akış üyesi
arasında böler; hangi üyenin ayakta olduğunu izler ve düşeni havuzdan çıkarır. Üç rolün de ne
olduğu daha önce kurulmuştu; bu ders rolleri yeniden tanımlamaz, **kurulum sonrası bıraktıkları
kalemi** sayar.

Sayım kurgu bir sistem üzerinde yapılır: bölgesel bir su sayacı ölçüm ağı. Saha ekipleri el
terminalleriyle sayaç okur, bir toplayıcı okumaları alır, bir doğrulayıcı denetler, faturalama
ve iş emri servisleri devralır. Üç ortam vardır ve gecelik bir toplu iş koşar. Sistem de
sayılar da kurgudur; ölçülen, sayıların birbirine oranıdır.

- **WS1.** Kalem listesi bir ürünün varsayılan yapılandırma dosyasından okunmaz; kurulum sonrası
  tipik olarak açık kalan şeylerin kurgu bir listesidir. Ölçülen liste değil, listeden çıkan orandır.
- **WS2.** Bir kalem "dış" ise genel kapıdan, "iç" ise yalnız iç ağdan erişilir. Ayrı süreçlerde
  bu ayrım süreç sınırıyla korunur.
- **WS3.** Meşru iş akışı, bir kalem kapandığında duran gerçek bir işi temsil eder; altı akış
  vardır ve her biri tek bir kaleme yaslanır.
- **WS4.** Paylaşım anahtarı aynı olan kalemler birleştirmede tek kaleme iner: üç rolün de
  dinlediği şifresiz kapı tek kapıdır, üçünün de bastığı sürüm başlığı tek başlıktır.

```js
// roller/yuzey.mjs — model: uc web sunucusu rolunun varsayilan kurulumundan sonra acik
// kalan yuzey kalemleri. Gercek bir urunun varsayilan dosyasi degil, kurgu olcum aginin
// kurulum sonrasi kalem listesidir; butun sayilar bu listeden turetilir.

// [rol, kalem, tur, erisim, paylasim anahtari]
const KALEM = [
  ["statik",  "sifresiz-kapi",       "dinlenen kapi", "dis", "kapi-80"],
  ["statik",  "varlik-kok",          "sunulan yol",   "dis", null],
  ["statik",  "dizin-listesi",       "sunulan yol",   "dis", null],
  ["statik",  "yedek-dosyalar",      "sunulan yol",   "dis", null],
  ["statik",  "ornek-sayfa",         "sunulan yol",   "dis", null],
  ["statik",  "surum-basligi",       "gorunen bilgi", "dis", "surum"],

  ["vekil",   "sifresiz-kapi",       "dinlenen kapi", "dis", "kapi-80"],
  ["vekil",   "sifreli-kapi",        "dinlenen kapi", "dis", null],
  ["vekil",   "yukari-akis-kapisi",  "dinlenen kapi", "ic",  null],
  ["vekil",   "surum-basligi",       "gorunen bilgi", "dis", "surum"],
  ["vekil",   "hata-sayfasi-izi",    "gorunen bilgi", "dis", null],
  ["vekil",   "vekil-durum-ucu",     "yonetim ucu",   "ic",  null],

  ["dagitim", "sifresiz-kapi",       "dinlenen kapi", "dis", "kapi-80"],
  ["dagitim", "surum-basligi",       "gorunen bilgi", "dis", "surum"],
  ["dagitim", "uye-adresi-basligi",  "gorunen bilgi", "dis", null],
  ["dagitim", "oturum-cerezi-uye",   "gorunen bilgi", "dis", null],
  ["dagitim", "saglik-ucu",          "yonetim ucu",   "ic",  null],
  ["dagitim", "uye-yonetim-ucu",     "yonetim ucu",   "ic",  null],
];

// Tek surecte birlestirmenin dogurdugu, hicbir rolde tek basina bulunmayan kalemler.
const BIRLESME = [
  ["birlesik", "capraz-kok",           "sunulan yol",   "dis"],
  ["birlesik", "ortak-yonetim-kapisi", "yonetim ucu",   "dis"],
  ["birlesik", "tek-surec-kimligi",    "birlesik yetki","dis"],
];

// Mesru is akislari: her akis hangi kaleme yaslaniyor.
const AKIS = [
  ["el-terminali-okuma",   "statik/sifresiz-kapi"],
  ["saha-varlik-sunumu",   "statik/varlik-kok"],
  ["toplayici-yuklemesi",  "vekil/sifreli-kapi"],
  ["nobetci-saglik-cagrisi","dagitim/saglik-ucu"],
  ["dagitim-akisi",        "dagitim/uye-yonetim-ucu"],
  ["oturum-yapiskanligi",  "dagitim/oturum-cerezi-uye"],
];

const kimlik = (r, k) => `${r}/${k}`;
const roller = ["statik", "vekil", "dagitim"];

const EN = [10, 7, 10, 9, 9, 9, 6, 5];
const satir = (h) => h.map((d, i) => String(d)[i ? "padStart" : "padEnd"](EN[i])).join("");
const olc = (s) => [s.length, ...["dinlenen kapi", "sunulan yol", "gorunen bilgi", "yonetim ucu"]
  .map((t) => s.filter((x) => x[2] === t).length),
  s.filter((x) => x[3] === "dis").length, s.filter((x) => x[3] === "ic").length];

console.log(satir(["rol", "kalem", "dinlenen", "sunulan", "gorunen", "yonetim", "dis", "ic"]));
for (const rol of roller) console.log(satir([rol, ...olc(KALEM.filter((x) => x[0] === rol))]));
console.log(satir(["toplam", ...olc(KALEM)]));

// Birlestirme: paylasim anahtari ayni olan kalemler tek kaleme iner.
const gorulen = new Set();
const tekil = [];
for (const [rol, kalem, tur, erisim, pay] of KALEM) {
  const anahtar = pay ?? kimlik(rol, kalem);
  if (gorulen.has(anahtar)) continue;
  gorulen.add(anahtar);
  tekil.push([rol, kalem, tur, erisim, pay]);
}
const birlesik = [...tekil.map((x) => [...x]), ...BIRLESME.map((x) => [...x, null])];
console.log(`\nayri uc surec:   ${KALEM.length} kalem -> ${tekil.length} benzersiz` +
  `  (dis ${tekil.filter((x) => x[3] === "dis").length}, ic ${tekil.filter((x) => x[3] === "ic").length})`);
// Tek surec tek dinleyiciyle koser: "ic" isaretli kalem de genel kapidan erisilir.
for (const k of birlesik) k[3] = "dis";
console.log(`tek surec:       ${tekil.length} + ${BIRLESME.length} dogan = ${birlesik.length} kalem` +
  `  (dis ${birlesik.length}, ic 0)`);

// Sertlestirme adimlari: her adim bir yuklem, kapattigi kalem ve getirdigi yeni kalem.
const ADIM = [
  ["gorunen bilgiyi kapat", (x) => x[2] === "gorunen bilgi", []],
  ["sunulan yolu daralt",   (x) => x[2] === "sunulan yol" && x[1] !== "varlik-kok",
    [["izin-listesi-dosyasi", "bakim yuzeyi"]]],
  ["yonetim ucunu dis kapidan al", (x) => x[2] === "yonetim ucu",
    [["ayri-yonetim-dinleyicisi", "dinlenen kapi"], ["yonetim-kimligi", "sir"]]],
  ["sifresiz kapiyi kapat", (x) => x[1] === "sifresiz-kapi", []],
];

let acik = birlesik.map((x) => [...x]);
const yeni = [];
console.log("\nadim                             kapatilan  yanlis kapatilan  yeni yuzey  kalan acik");
for (const [ad, yuklem, getirdigi] of ADIM) {
  const dusen = acik.filter(yuklem);
  acik = acik.filter((x) => yuklem(x) === false);
  const bozulan = AKIS.filter(([, k]) => dusen.some((d) => kimlik(d[0], d[1]) === k));
  yeni.push(...getirdigi);
  console.log(ad.padEnd(32) + String(dusen.length).padStart(9) +
    String(bozulan.length).padStart(18) + String(getirdigi.length).padStart(12) +
    String(acik.length + yeni.length).padStart(12) +
    (bozulan.length ? `   ${bozulan.map((b) => b[0]).join(", ")}` : ""));
}
console.log(`\nkapatilamayan kalem (${acik.length}): ${acik.map((x) => x[1]).join(", ")}`);
console.log(`kapatmanin getirdigi (${yeni.length}): ${yeni.map((x) => x[0]).join(", ")}`);
```

```
rol         kalem  dinlenen  sunulan  gorunen  yonetim   dis   ic
statik          6         1        4        1        0     6    0
vekil           6         3        0        2        1     4    2
dagitim         6         1        0        3        2     4    2
toplam         18         5        4        6        3    14    4

ayri uc surec:   18 kalem -> 14 benzersiz  (dis 10, ic 4)
tek surec:       14 + 3 dogan = 17 kalem  (dis 17, ic 0)

adim                             kapatilan  yanlis kapatilan  yeni yuzey  kalan acik
gorunen bilgiyi kapat                   4                 1           0          13   oturum-yapiskanligi
sunulan yolu daralt                     4                 0           1          10
yonetim ucunu dis kapidan al            4                 2           2           8   nobetci-saglik-cagrisi, dagitim-akisi
sifresiz kapiyi kapat                   1                 1           0           7   el-terminali-okuma

kapatilamayan kalem (4): varlik-kok, sifreli-kapi, yukari-akis-kapisi, tek-surec-kimligi
kapatmanin getirdigi (3): izin-listesi-dosyasi, ayri-yonetim-dinleyicisi, yonetim-kimligi
```

Sayım belirlenimlidir: liste sabittir, rastgelelik yoktur, süre ölçülmez.

#### Rolün Kendi Yüzeyi

İlk tablo üç rolü yan yana koyuyor. Üçünün de kalem sayısı altı, ama kalemlerin **türü** farklı.

Statik sunumun altı kaleminin dördü **sunulan yol**dur ve tek bir ayara bağlıdır: kök dizin.
Kök dizinde ne varsa sunulur. Varlık kökü meşrudur — saha ekiplerinin tarayıcısı oradan
beslenir. Dizin listesi, kurulumla gelen örnek sayfa ve kökün içine bir gün bırakılmış
yapılandırma yedeği ise kimsenin karar vermediği şeylerdir. Statik rolün bütün altı kalemi
**dıştan erişilebilir**: bu rolün iç yüzeyi yoktur, çünkü kendine ait bir yönetim ucu yoktur.

Ters vekilin altı kaleminin üçü **dinlenen kapı**dır ve burada bir ayrıntı önemlidir: üçüncü
kapı yukarı akışın kendi kapısıdır. Vekil kurulurken arkadaki uygulama bir kapıda dinlemeye
başlar ve o kapı çoğu kurulumda makinenin bütün arayüzlerine bağlanır. Vekil bir kapı açmaz;
vekilin varlığı **arkasında ikinci bir kapı** açar ve o kapıya vekile uğramadan da gidilebilir.
Vekilin bütün ayarları, arkadaki kapıya doğrudan gelen bir isteği hiç görmez.

Yük dağıtımının altı kaleminin üçü **görünen bilgi**dir ve üçü de havuzun iç yapısını dışarıya
taşır: yanıt başlığındaki üye adresi, oturum çerezindeki üye kimliği, sağlık ucunun döktüğü üye
listesi. Bu rol iç yapıyı görünür kılmak için kurulur — hangi üyenin cevap verdiğini bilmek
sorun ararken gereklidir — ve aynı görünürlük dışarıya da açıktır.

Üç rolün toplamı on sekiz kalem: beş dinlenen kapı, dört sunulan yol, altı görünen bilgi, üç
yönetim ucu. On dördü dış, dördü iç.

Dağılımdaki asimetri bir şey söylüyor. Statik rolde yüzey **dosya sisteminde** duruyor: kalemi
kapatmak bir dizinin içeriğine karar vermektir. Vekil rolünde yüzey **ağ topolojisinde**
duruyor: kalemi kapatmak bir kapının hangi arayüze bağlandığına karar vermektir. Dağıtım
rolünde yüzey **yanıtın kendisinde** duruyor: kalemi kapatmak bir başlığı ya da çerezi
çıkarmaktır. Üç rol için tek bir sertleştirme yordamı yazılamamasının nedeni budur; sayı eşit
olsa da kapatma işi üç ayrı yerde yapılır.

#### Birleştirmenin Yaptığı

İkinci ölçüm üç rolü **tek sürece** koyuyor. Bu, bir makinede en sık görülen düzendir: aynı
süreç hem statik dosyayı sunar, hem isteği arkaya iletir, hem üyeler arasında böler.

Birleştirme önce bir **azalma** üretir. Üç rolün de dinlediği şifresiz kapı tek kapıya iner, üç
rolün de bastığı sürüm başlığı tek başlığa iner. On sekiz kalem on dört benzersiz kaleme düşer.
Kalem sayısına bakan biri burada durup birleştirmenin yüzeyi **daralttığını** söyleyebilir.

İki şey bu okumayı bozar.

Birincisi, birleştirme kendi kalemlerini **doğurur**. Statik kök artık vekilin genel kapısından
da erişilebilir; ayrı süreçlerde bu iki yol arasında bir sınır vardı, tek süreçte yoktur. Üç
rolün yönetim uçları tek dinleyicide toplanır. Tek süreç üç rolün izinlerini birden taşır: aynı
kimlik hem statik kökü okur, hem yukarı akışa bağlanır, hem havuz üyeliğini değiştirir. Üç yeni
kalem, on dördü on yediye çıkarır.

İkincisi ve daha ağırı, **erişim damgası düşer**. Ayrı üç süreçte on dört kalemin onu dıştan
erişilebilirdi; dördü — iki yönetim ucu, sağlık ucu ve yukarı akış kapısı — süreç sınırının
arkasındaydı. Tek süreç tek dinleyiciyle koşar ve o dinleyici genel kapıdır. On yedi kalemin
**on yedisi** dıştan erişilebilir hâle gelir.

Birleştirmenin ölçüsü budur: kalem sayısı on sekizden on yediye düşerken dıştan erişilebilir
kalem sayısı ondan on yediye çıkar. Sayım kalem üzerinden yapıldığında birleştirme iyi görünür;
erişim üzerinden yapıldığında yüzey yüzde yetmiş büyümüştür.

#### Dört Adım ve Durdurduğu İş

Üçüncü tablo on yedi kalemli yüzeye dört sertleştirme adımı uyguluyor. Her adım iki sayı
üretir: kaç kalem kapandı ve **kaç meşru iş durdu**.

İlk adım görünen bilgiyi kapatıyor: sürüm başlığı, hata sayfasının izi, üye adresi başlığı ve
üye çerezi. Dört kalem kapanıyor ve bir iş duruyor — oturum yapışkanlığı. Saha ekibinin çok
adımlı okuma formu, ilk adımı hangi üye karşıladıysa sonraki adımların da o üyeye gitmesine
yaslanıyordu ve bunu üye çerezinden okuyordu. Çerez gidince form ikinci adımda başka bir üyeye
düşüyor. Bu adım "sızdırılan bilgiyi kapat" başlığıyla savunulur ve savunma eksiktir: kapattığı
dördüncü kalem bilgi sızıntısı değil, taşıma düzeneğiydi.

İkinci adım sunulan yolu daraltıyor: dizin listesi, yedek dosyalar, örnek sayfa ve birleşmenin
doğurduğu çapraz kök. Dört kalem kapanıyor, hiçbir iş durmuyor. Bedeli başka yerde: kapatma bir
izin listesi dosyasıyla yapılıyor ve o dosya artık bakılması gereken bir yer. Yeni bir varlık
dizini eklendiğinde listeye eklenmezse sunulmaz; bu, ilerideki bir arızanın kaynağıdır.

Üçüncü adım yönetim uçlarını dış kapıdan alıyor. Dört kalem kapanıyor ve **iki iş duruyor**:
nöbetçinin sağlık çağrısı ve dağıtım akışının üye ekleme çağrısı. İkisi de meşrudur ve ikisi de
o uçlardan geçiyordu. Adım tamamlanabilmesi için iki yeni kalem getiriyor: yalnız iç ağdan
erişilen ayrı bir yönetim dinleyicisi ve o dinleyiciye giren bir yönetim kimliği. İkinci kalem
bir sırdır ve sırların kendi ömrü, kendi sızıntı penceresi vardır.

Dördüncü adım şifresiz kapıyı kapatıyor. Tek kalem kapanıyor, bir iş duruyor: sahadaki eski el
terminalleri yalnız şifresiz konuşuyor. Bu, en küçük kapatma ve en görünür kırılmadır — durduğu
gün bütün saha ekibi arar.

Dört adım on üç kalem kapattı, dört meşru işi durdurdu ve üç yeni kalem getirdi. Oran on üçe
dörttür: kapatılan her üç kaleme karşılık bir iş durmuştur. Bu oran adımlar arasında hiç eşit
dağılmıyor — ikinci adım dört kalemi sıfır durdurmayla kapatırken, dördüncü adım tek kalemi bir
durdurmayla kapatıyor. Sıralamayı belirleyen budur: ucuz adım önce, pahalı adım sonra. Yüzey
kalemi sayısına bakan bir sıralama dördüncü adımı en sona koymazdı, çünkü o adım en çok
konuşulan kalemi kapatıyor ve sayı olarak en azını veriyor.

#### Kapatılamayan Dördü

Dört adımın sonunda geriye dört kalem kalıyor ve dördü de kapatılamaz kalemdir.

**Varlık kökü** ve **şifreli kapı** makinenin var oluş nedenidir; kapatmak sistemi kapatmaktır.
**Yukarı akış kapısı** kapatılamaz çünkü vekilin arkaya bağlanması ondan geçer; daraltılabilir
— yalnız geri döngü arayüzüne bağlanabilir — ama açık kalır. **Tek süreç kimliği** ise ancak
birleştirmeyi geri alarak, yani üç rolü üç sürece bölerek kapanır; hiçbir yapılandırma satırı
onu kapatmaz.

Sondaki tablo yedi açık kalem gösteriyor: dört kapatılamayan ve üç yeni. Başlangıçtaki on yedi
ile karşılaştırıldığında bu bir kazançtır. Yeni yüzeyin sayılmadığı bir raporda kazanç on yedi
kalemden dört kaleme inmek diye yazılırdı; sayıldığında yediye inmektir.

#### Özet

- Üç web sunucusu rolünün varsayılan kurulumu on sekiz kalem bıraktı: beş dinlenen kapı, dört
  sunulan yol, altı görünen bilgi, üç yönetim ucu; on dördü dış, dördü iç erişimli.
- Rollerin kalem sayısı eşitti, türü değildi: statik sunumun dördü sunulan yol, ters vekilin üçü
  dinlenen kapı, yük dağıtımının üçü görünen bilgiydi.
- Tek süreçte birleştirme on sekiz kalemi on dört benzersize indirdi, üç kalem doğurdu ve iç
  erişimli dört kalemi dışa taşıdı: dıştan erişilebilir kalem sayısı ondan on yediye çıktı.
- Dört sertleştirme adımı on üç kalem kapattı, dört meşru işi durdurdu ve üç yeni kalem getirdi;
  yönetim uçlarını kapatan adım tek başına iki işi durdurdu ve iki yeni kalem ekledi.
- Geriye dört kapatılamayan kalem kaldı; biri olan tek süreç kimliği hiçbir ayarla değil, yalnız
  rolleri ayrı süreçlere bölerek kapanır.

#### Sonraki Adım

Bu ders yüzeyi **dışarıdan** saydı: kaç kapı dinliyor, kaç yol sunuluyor, kaç uç açık. Sayımın
tamamı isteğin sunucuya **varmasıyla** ilgiliydi. İstek vardıktan sonra ne olduğuna hiç
bakılmadı.

Ters vekil isteği alıp arkaya ilettiğinde istek olduğu gibi geçmez. Bağlantı vekilde biter ve
arkaya yeni bir bağlantı açılır; o yeni bağlantının öteki ucunda istemci değil vekil durur.
İstemcinin adresi, isteğin şifreli gelip gelmediği, istemcinin hangi adı istediği ve isteğin
özgün yolu — dördü de bağlantının kendisinde taşınıyordu ve bağlantı bitti. Sonraki ders
`node:http` ile iki katlı bir vekil zinciri kurar, gerçek istek geçirir, zincirden geçerken
kaybolan dört bilgiyi tek tek sayar, her kaybın uygulamada ürettiği yanlış kararı gösterir ve
kaybı kapatmak için eklenen başlığa **güvenmenin** açtığı yüzeyi ölçer.

### Ters Vekil Yapılandırması

Source: https://academia.sh/tr/kurslar/sunucu-ve-sertlestirme/ters-vekil-yapilandirmasi

İki katlı bir vekil zincirinden gerçek istek geçirilerek kaybolan dört bilginin sayılması: istemci adresi, protokol, sunucu adı ve isteğin özgün yolu; her kaybın uygulamada ürettiği yanlış karar (üç üyenin tek kimlikle kaydedilmesi, iç adrese giden mutlak bağlantı, önek soyulunca 404 veren bağ), ikinci atlamanın ilk atlamanın aktarımını silmesi ve aktarılan başlığa güvenmenin açtığı iddia edilen kimlik yüzeyi.

Önceki ders yüzeyi sunucunun dışından saydı: kaç kapı dinliyor, kaç yol sunuluyor, kaç uç açık.
Sayımın tamamı isteğin **varmasıyla** ilgiliydi. Bu ders istek vardıktan sonrasını ölçer.

Ters vekil isteği alır ve arkaya iletir. "İletir" sözcüğü olup biteni gizler: vekil isteği taşımaz,
**yeniden kurar**. İstemcinin açtığı bağlantı vekilde biter; vekil arkaya kendi adına yeni bir
bağlantı açar. Yeni bağlantının öteki ucunda istemci yoktur, vekil vardır. Bağlantının kendisinde
taşınan ne varsa o noktada silinir. Ters vekilin ne olduğu ve uygulamayı üretime alırken nasıl
yapılandırıldığı daha önce ölçülmüştü; burada ölçülen **kaybolan bilgi kalemi** ve o kaybın açtığı
yüzeydir.

Kurgu bölgesel ölçüm ağının önünde iki vekil vardır: dışa bakan bir kenar vekil ve ortamı seçen
bir iç vekil. Saha el terminalleri `/api` önekiyle kenar vekile bağlanır, kenar vekil iç vekile,
iç vekil ölçüm uygulamasına. İki atlama, üç bağlantı.

- **WS7.** Uygulama aktarım başlığındaki **soldaki ilk girdiyi** okur; aktarım zinciri virgülle
  uzadığında okunan değer değişmez. Bu, aktarılan kimliğin yaygın okunma biçimidir.
- **WS8.** Tek makinede bütün istemciler aynı geri döngü adresini paylaşır. Kurgu üye adresi
  kenar vekilde kaynak bağlantı noktası bloğundan türetilir; gerçek bir dağıtımda bu değer
  doğrudan bağlantıdan gelir.
- **WS9.** Kenar vekil ile iç vekil **aynı dosyadır**; aralarındaki bütün fark ayar dizgesindedir.
- **WS10.** Uygulamanın iç özet ucu yalnız `10.9.` önekli adreslerden çağrılabilir; erişim kararı
  **çözülen adrese** dayanır.
- **WS11.** Ölçüm süre ölçmez; istek sayısı, kaynak bağlantı noktası blokları ve beklenen değerler
  koşumdan bağımsız sabitlerdir.

```js
// zincir/uygulama.mjs — olcum uygulamasi. Istegin dort bilgisini once "x-ileti-*" basligindan,
// yoksa baglantinin kendisinden cozer ve her cozumden bir karar uretir.
import { createServer } from "node:http";

const nokta = Number(process.argv[2]);
const IC_AG = "10.9.";                                  // ic ag oneki
const kayit = { adres: new Set(), giren: 0, reddedilen: 0 };

const coz = (i) => ({
  // Aktarim zinciri virgulle uzar; uygulama soldaki ilk girdiyi okur.
  adres: String(i.headers["x-ileti-adres"] ?? i.socket.remoteAddress).split(",")[0].trim(),
  sema: i.headers["x-ileti-sema"] ?? "sifresiz",
  ad: i.headers["x-ileti-ad"] ?? i.headers.host,
  onek: i.headers["x-ileti-onek"] ?? "",
});

if (Number.isInteger(nokta) === false) console.log("kullanim: node zincir/uygulama.mjs <nokta>");
else createServer((istek, yanit) => {
  yanit.sendDate = false;
  const yol = istek.url;
  const c = coz(istek);
  if (yol === "/dokum") {
    yanit.writeHead(200).end(JSON.stringify({ ...kayit, kimlik: kayit.adres.size, adres: [...kayit.adres] }));
    return;
  }
  if (yol === "/ic/ozet") {                             // yalniz ic agdan cagrilmasi gereken uc
    if (c.adres.startsWith(IC_AG)) { kayit.giren += 1; yanit.writeHead(200).end("ic ozet"); }
    else { kayit.reddedilen += 1; yanit.writeHead(403).end("disaridan"); }
    return;
  }
  const parca = yol.split("/");
  if (parca[1] !== "olcum" || parca.length > 4) { yanit.writeHead(404).end("yol yok"); return; }
  if (parca.length === 4 && parca[3] !== "ayrinti") { yanit.writeHead(404).end("yol yok"); return; }
  kayit.adres.add(c.adres);                             // denetim kaydina yazilan kimlik
  yanit.writeHead(200, {
    "x-adres": c.adres, "x-sema": c.sema, "x-ad": c.ad, "x-onek": c.onek || "yok",
    "x-karar": c.sema === "sifreli" ? "sun" : "yonlendir",
    "x-bag": `${c.sema}://${c.ad}${c.onek}${yol}/ayrinti`,
  }).end("olcum");
}).listen(nokta, "127.0.0.1");
```

Vekil altı ayarı bir dizgeden alır. Bir üründe bunların her biri bir yapılandırma satırıdır;
burada bir dizge alanıdır.

```js
// zincir/vekil.mjs — ters vekil. Ayni dosya hem kenar hem ic vekil olarak kosar; davranisi ayar
// dizgesi belirler. Ayar: adres,sema,ad,onekb = acik|kapali; onek=<yol>; temizle=acik;
// zincir=yaz|ekle|koru; harita=acik (yalniz kenar vekilde: baglanti -> kurgu istemci adresi).
import { createServer, request } from "node:http";

const [nokta, hedef, ayarMetni] = [Number(process.argv[2]), Number(process.argv[3]), process.argv[4] ?? ""];
const A = Object.fromEntries(ayarMetni.split(",").filter(Boolean).map((p) => p.split("=")));
// WS8: tek makinede butun istemciler ayni geri dongu adresini paylasir. Kurgu uye adresi kaynak
// baglanti noktasi blogundan turetilir; gercek dagitimda deger dogrudan baglantidan gelir.
const AG = { 512: "203.0.113.11", 513: "203.0.113.12", 514: "203.0.113.13" };
const kaynak = (s) => (A.harita === "acik" ? AG[Math.floor(s.remotePort / 100)] : undefined) ?? s.remoteAddress;

if (Number.isInteger(nokta) === false || Number.isInteger(hedef) === false) {
  console.log("kullanim: node zincir/vekil.mjs <nokta> <hedef> <ayar>");
} else createServer((disIstek, disYanit) => {
  disYanit.sendDate = false;
  const b = { ...disIstek.headers };
  if (A.temizle === "acik") for (const k of Object.keys(b)) if (k.startsWith("x-ileti-")) delete b[k];
  const gelen = b["x-ileti-adres"];
  if (A.adres === "acik") {
    const kendi = kaynak(disIstek.socket);
    if (A.zincir === "koru" && gelen) b["x-ileti-adres"] = gelen;
    else if (A.zincir === "ekle" && gelen) b["x-ileti-adres"] = `${gelen}, ${kendi}`;
    else b["x-ileti-adres"] = kendi;
  }
  if (A.sema === "acik") b["x-ileti-sema"] = "sifreli";
  if (A.ad === "acik") b["x-ileti-ad"] = b["x-ileti-ad"] ?? disIstek.headers.host;
  let yol = disIstek.url;
  if (A.onek) {
    if (yol.startsWith(A.onek) === false) { disYanit.writeHead(404).end("yol yok"); return; }
    yol = yol.slice(A.onek.length) || "/";              // onek soyulur; arka uc onu bilmez
    if (A.onekb === "acik") b["x-ileti-onek"] = A.onek;
  }
  b.host = `127.0.0.1:${hedef}`;                        // istenen ad yukari akisin adiyla degistirilir
  const icIstek = request({ port: hedef, path: yol, method: disIstek.method, headers: b }, (icYanit) => {
    disYanit.writeHead(icYanit.statusCode, icYanit.headers);
    icYanit.pipe(disYanit);
  });
  icIstek.on("error", () => { if (disYanit.headersSent === false) disYanit.writeHead(502).end("kesildi"); });
  disIstek.pipe(icIstek);
}).listen(nokta, "127.0.0.1");
```

İstemci üç üyeyi ayrı kaynak bağlantı noktası bloklarından bağlar, çözülen dört değeri beklenenle
karşılaştırır, uygulamanın ürettiği bağlantıyı izler ve denetim kaydındaki kimlik sayısını okur.

```js
// zincir/istemci.mjs — uc uye ayri kaynak baglanti noktasi bloklarindan zincire baglanir.
// Kullanim: node zincir/istemci.mjs <kenar> <uygulama> <senaryo> <etiket> <kayma>
import { request } from "node:http";

const [kenar, uyg, senaryo, etiket, kayma] =
  [Number(process.argv[2]), Number(process.argv[3]), process.argv[4], process.argv[5] ?? "-", Number(process.argv[6] ?? 0)];
const AD = "olcum.ornek.gecersiz";                      // kurgu ad
const BEKLENEN = { adres: "203.0.113.11", sema: "sifreli", ad: AD, onek: "/api" };

const cagir = ({ yol, kaynak, port = kenar, basliklar = {} }) => new Promise((coz) => {
  const r = request({ port, path: yol, agent: false, localPort: kaynak, headers: { host: AD, ...basliklar } },
    (y) => { let g = ""; y.on("data", (d) => { g += d; }); y.on("end", () => coz({ kod: y.statusCode, b: y.headers, govde: g })); });
  r.on("error", (e) => coz({ kod: 0, b: {}, govde: e.code }));
  r.end();
});

if (senaryo === "kayip") {
  let ilk = null;
  for (let i = 0; i < 3; i += 1) {
    const y = await cagir({ yol: "/api/olcum/7", kaynak: 51200 + i * 100 + kayma * 5 });
    ilk = ilk ?? y;
  }
  const dokum = JSON.parse((await cagir({ yol: "/dokum", port: uyg, kaynak: 51700 + kayma })).govde);
  const bag = ilk.b["x-bag"] ?? "-";
  const yolu = bag.slice(bag.indexOf("://") + 3).replace(/^[^/]*/, "");
  const izlenen = await cagir({ yol: yolu, kaynak: 51800 + kayma });
  const dogru = ["adres", "sema", "ad", "onek"].filter((k) => ilk.b[`x-${k}`] === BEKLENEN[k]).length;
  console.log(`${etiket.padEnd(18)}cozulen ${dogru}/4  kayitta ${dokum.kimlik} kimlik  ` +
    `karar ${String(ilk.b["x-karar"]).padEnd(10)}bag izlendi ${izlenen.kod}`);
  console.log(`${" ".repeat(18)}adres ${String(ilk.b["x-adres"]).padEnd(15)} ad ${String(ilk.b["x-ad"]).padEnd(22)} onek ${ilk.b["x-onek"]}`);
} else if (senaryo === "sahte") {
  let giren = 0;
  for (let i = 0; i < 4; i += 1) {
    const y = await cagir({ yol: "/api/ic/ozet", kaynak: 51500 + i + kayma * 10, basliklar: { "x-ileti-adres": "10.9.0.5" } });
    if (y.kod === 200) giren += 1;
  }
  const dokum = JSON.parse((await cagir({ yol: "/dokum", port: uyg, kaynak: 51900 + kayma })).govde);
  console.log(`${etiket.padEnd(18)}ic uca giren ${giren}/4  uygulamanin reddettigi ${dokum.reddedilen}`);
} else console.log("kullanim: node zincir/istemci.mjs <kenar> <uygulama> <senaryo> <etiket> <kayma>");
```

```bash
# olc.sh — ayni istek zinciri farkli aktarim ayarlariyla. Her kosumda ucu de yeniden baslatilir.
K0="onek=/api,harita=acik"                # her kosumda ayni: onek soyulur, kaynak haritasi kenarda
kos() {                                   # kos <kenar-ek> <ic-ayar> <senaryo> <etiket> <kayma>
  node zincir/uygulama.mjs 8942 & U=$!
  node zincir/vekil.mjs 8941 8942 "$2" & I=$!
  node zincir/vekil.mjs 8940 8941 "$K0$1" & K=$!
  sleep 0.5
  node zincir/istemci.mjs 8940 8942 "$3" "$4" "$5"
  kill $K $I $U 2>/dev/null; wait $K $I $U 2>/dev/null; sleep 0.2
}
D=",temizle=acik,adres=acik,sema=acik,ad=acik,onekb=acik"   # dort basligin hepsi aktarilir

kos ",temizle=acik"                     "" kayip "aktarim yok"    0
kos ",temizle=acik,adres=acik,sema=acik" "" kayip "adres+sema"     1
kos "$D"                                "" kayip "dort baslik"    2
kos "$D"       "adres=acik,zincir=yaz"     kayip "ikinci atlama"  3
kos ",adres=acik,sema=acik,ad=acik,onekb=acik,zincir=ekle" "" sahte "temizleme yok" 4
kos "$D"                                "" sahte "temizleme var"  5
```

```
aktarim yok       cozulen 0/4  kayitta 1 kimlik  karar yonlendir bag izlendi 404
                  adres 127.0.0.1       ad 127.0.0.1:8942         onek yok
adres+sema        cozulen 2/4  kayitta 3 kimlik  karar sun       bag izlendi 404
                  adres 203.0.113.11    ad 127.0.0.1:8942         onek yok
dort baslik       cozulen 4/4  kayitta 3 kimlik  karar sun       bag izlendi 200
                  adres 203.0.113.11    ad olcum.ornek.gecersiz   onek /api
ikinci atlama     cozulen 3/4  kayitta 1 kimlik  karar sun       bag izlendi 200
                  adres 127.0.0.1       ad olcum.ornek.gecersiz   onek /api
temizleme yok     ic uca giren 4/4  uygulamanin reddettigi 0
temizleme var     ic uca giren 0/4  uygulamanin reddettigi 4
```

#### Sıfırdan Dörde

İlk satır varsayılan durumdur: iki vekil de isteği iletiyor, hiçbiri hiçbir şey aktarmıyor.
Uygulama dört bilginin **dördünü de** kaybediyor ve dört ayrı yanlış karar üretiyor.

**İstemci adresi.** Üç ayrı üye üç ayrı istek gönderdi; denetim kaydında **bir** kimlik var.
Kayıt eksik değil, dolu — yalnız yazdığı adres iç vekilin adresi. Bir olayın hangi el
terminalinden geldiği sorulduğunda kayıt yanıt verir ve yanıtı yanlıştır.

**Protokol.** Uygulamaya gelen bağlantı şifresizdir, çünkü şifreleme kenar vekilde bitmiştir.
Uygulama şifresiz bir istek gördüğüne karar verip `yonlendir` diyor. Kararın kendisi doğru
yazılmış bir kuraldır; girdisi yanlıştır.

**Sunucu adı.** İstemci `olcum.ornek.gecersiz` adını istedi. Vekil arkaya bağlanırken istenen adı
yukarı akışın adıyla değiştirdi — bu bir hata değil, bağlantının kurulma biçimidir. Uygulama
kendi ürettiği mutlak bağlantıya `127.0.0.1:8942` yazıyor. Bu bağlantı bir sayfada gösterilse ya
da bir bildirim e-postasına konsa, iç adres dışarı çıkmış olur.

**Özgün yol.** Kenar vekil `/api` önekini soydu. Uygulama önekten habersiz olduğu için ürettiği
bağlantıya öneki koymuyor. Bağlantı izlendiğinde kenar vekil onu kendi yönlendirme kuralına
uydurmuyor ve **404** dönüyor. Saha ekibine giden bildirim e-postasındaki bağlantı, açıldığı gün
çalışmayan bir bağlantıdır.

İkinci satır iki başlığı açıyor. Denetim kaydındaki kimlik sayısı bire değil **üçe** çıkıyor ve
karar `sun` oluyor. İki kalem kapandı; ad ile önek hâlâ kayıp ve bağ hâlâ 404. Bu satır kısmi
aktarımın en yanıltıcı yanını gösteriyor: kayıt düzeldiği için yapılandırmanın tamam olduğu
düşünülür, oysa kapanan iki kalemin ikisi de kaydın içinde görünen kalemlerdi. Kayıtta
görünmeyen iki kalem, kayda bakarak bulunamaz.

Üçüncü satır dört başlığı da açıyor: dört bilginin dördü çözülüyor, kayıtta üç kimlik var,
üretilen bağ izlendiğinde 200 dönüyor.

#### İkinci Atlamanın Sildiği

Dördüncü satırda kenar vekilin ayarı üçüncü satırla **birebir aynı**. Değişen tek şey iç vekilin
de adres aktarımını açması.

Sonuç: çözülen bilgi dörtten üçe düşüyor ve denetim kaydındaki kimlik sayısı üçten bire iniyor.
İç vekil, kenar vekilin yazdığı başlığın üstüne kendi gördüğü adresi yazdı; onun gördüğü adres
kenar vekilin adresidir. Aktarım iki atlamada da açık olmasına karşın uygulamaya varan değer
istemcinin adresi değil.

Bu, ilk satırdan daha zor bulunan bir arızadır. İlk satırda hiçbir aktarım yoktu ve durum bir
yapılandırma incelemesinde görülür. Dördüncü satırda **her iki vekilde de aktarım açıktır**;
inceleme "aktarım açık" der ve geçer. Aradaki fark tek bir kelimede — ikinci atlama gelen değeri
korumak yerine üzerine yazıyor.

Zincir uzunluğu burada bir çarpan olur: aktarımın doğru çalışması için zincirdeki **her**
atlamanın gelen değeri koruması ya da ona eklemesi gerekir. İki atlamada iki karar, dört
atlamada dört karar vardır ve hepsinin doğru olması gerekir; birinin yanlış olması yeter.

#### Aktarılan Başlığa Güvenmek

Son iki satır ölçünün öteki yüzüdür. Uygulama artık aktarılan adrese **karar bağlıyor**: iç özet
ucu yalnız iç ağ adreslerinden çağrılabiliyor. Kaybı kapatan başlık, kapattığı anda bir yetki
girdisine dönüştü.

Beşinci satırda kenar vekil gelen `x-ileti-*` başlıklarını temizlemiyor ve zincire ekleme
yapıyor. İstemci kendi isteğine `10.9.0.5` yazıyor. Kenar vekil bunun üstüne kendi gördüğü
adresi ekliyor, başlık iki girdili oluyor ve uygulama soldaki ilk girdiyi okuyor: istemcinin
yazdığını. Dört isteğin **dördü de** iç uca giriyor, uygulama hiçbirini reddetmiyor ve dört
istek kayıtlarda başarılı iç çağrı olarak duruyor.

Altıncı satırda kenar vekil temizliyor. Dört isteğin sıfırı giriyor, uygulama dördünü de
reddediyor.

Açılan yüzeyin adı **iddia edilen kimlik yüzeyi**dir: uygulamanın güvendiği her aktarım başlığı,
önündeki her atlama onu silmediği sürece istemcinin denetimindeki bir girdidir. Bu yüzey iki
biçimde açılır. Birincisi temizlemenin unutulmasıdır — beşinci satır. İkincisi, önceki dersin
saydığı **yukarı akış kapısı**dır: iç vekil ile uygulamanın kapısı makinenin bütün arayüzlerinde
dinliyorsa, kenar vekile hiç uğramayan bir istek başlığını kendisi yazar ve temizleme hiç
çalışmaz. Kenar vekildeki tek satırlık temizleme kuralı, ancak zincirin tek girişi olduğu sürece
bir kural sayılır.

#### Dört Kalem, İki Yön

Dört bilginin her biri iki ayrı kalem üretir: kapalıyken bir yanlış karar, açıkken bir güven
noktası.

| Bilgi | Kapalıyken üretilen yanlış karar | Açıkken doğan yüzey |
|---|---|---|
| İstemci adresi | üç üye kayıtta tek kimliğe düşer | adrese bağlı erişim kararı istemcinin yazdığı değere düşer |
| Protokol | şifreli istek şifresiz sayılır, karar `yonlendir` olur | uygulama şifrelemeyi kendisi doğrulamaz, başlığa güvenir |
| Sunucu adı | üretilen bağlantı iç adrese işaret eder | ad başına ayrım yapan kural sahte adla atlatılabilir |
| Özgün yol | önek düşer, üretilen bağ 404 alır | önek başına yetkilendirme kuralı sahte önekle atlatılabilir |

Tablonun sağ sütunu dersin asıl sonucudur. Kaybı kapatan tek yol bilgiyi bir başlıkta taşımaktır
ve başlık bağlantının kendisi gibi kanıtlanabilir değildir. Aktarım kapalıyken uygulama yanlış
bilgiyle doğru davranır; açıkken doğru bilgiyle davranır ve bilginin doğruluğu artık zincirdeki
her atlamanın disiplinine bağlıdır. Kaybolan dört kalem kapatıldı; yerine denetlenmesi gereken
dört güven noktası geldi.

#### Özet

- Vekil zincirinden geçerken dört bilgi kaybolur: istemci adresi, protokol, istenen sunucu adı
  ve isteğin özgün yolu; aktarım kapalıyken uygulama dördünü de yanlış çözdü.
- Dört kaybın dördü de görünür bir karar üretti: üç üye kayıtta tek kimliğe düştü, karar
  `yonlendir` oldu, üretilen bağlantı iç adrese işaret etti ve önek eksikliği yüzünden izlendiğinde
  404 döndü.
- İki başlığın aktarılması kaydı düzeltti ama bağı düzeltmedi: kayıtta üç kimlik göründü, bağ
  yine 404 aldı; kayda bakarak kalan iki kalem bulunamaz.
- Her iki vekilde de aktarım açıkken bile ikinci atlama gelen değeri koruyacak yerde üzerine
  yazdığında çözülen bilgi dörtten üçe, kayıttaki kimlik üçten bire indi.
- Aktarılan başlığa karar bağlandığında iddia edilen kimlik yüzeyi açıldı: temizleme kapalıyken
  sahte başlıklı dört isteğin dördü de iç uca girdi; temizleme açıkken sıfırı girdi.

#### Sonraki Adım

Bu dersin bütün ölçümleri şifrelemenin **bir yerde bittiğini** varsaydı: kenar vekil şifreyi
çözüyor, arkası şifresiz taşıyor. Sonlandırmanın kenar vekilde olduğu hiç sorgulanmadı, oysa bu
bir karardır ve üç yerde verilebilir.

Sonlandırma noktası değiştiğinde üç sayı birden değişir: zincirde kaç bacak şifresiz kalır,
sertifika kaç ayrı yerde durur ve yenileme sırasında kaç noktaya dokunulur. Üçü aynı yöne
gitmez; şifresiz bacağı sıfıra indiren seçenek sertifikanın bulunduğu yer sayısını ve yenileme
maliyetini artırır. Sonraki ders üç sonlandırma seçeneğini bu üç sayıyla karşılaştırır ve kabul
edilen protokol sürümleriyle şifre takımlarını bir kalem kümesi olarak modelleyip varsayılanın
kaç eski seçeneği açık bıraktığını, kısıtlamanın kaç istemciyi düşürdüğünü ölçer.

### Taşıma Katmanı Güvenliği Sonlandırma

Source: https://academia.sh/tr/kurslar/sunucu-ve-sertlestirme/tls-sonlandirma

Sonlandırmanın nerede yapıldığının üç seçenekle karşılaştırılması: kenarda, vekilde ve uygulamada sonlandırmanın bıraktığı şifresiz bacak sayısı, sertifikanın bulunduğu yer sayısı, yenilemede dokunulan nokta sayısı ve kenarın kaybettiği iş; protokol sürümü ile şifre takımının kalem kümesi olarak modellenmesi, varsayılanın açık bıraktığı yirmi sekiz kalem ve kısıtlamanın düşürdüğü cihaz ile okuma sayısı.

Önceki dersin bütün ölçümleri bir şeyi verili aldı: şifreleme bir yerde bitiyor. Kenar vekil
şifreyi çözüyor, arkası düz metin taşıyor ve kaybolan bilgi başlıklarla geri veriliyordu.
"Kenar vekilde biter" bir varsayım değil, bir karardır ve verilebileceği üç yer vardır.

Bu ders o kararı üç sayıyla ölçer: zincirde kaç bacak şifresiz kalır, sertifika kaç ayrı yerde
durur, yenileme sırasında kaç noktaya dokunulur. Üçü aynı yöne gitmez. Şifresiz bacağı sıfıra
indiren seçenek öteki iki sayıyı üçe katlar.

Yanıtın içeriğine konan güvenlik başlıklarının hangileri olduğu ve kaçının varsayılan olarak
gelmediği daha önce **güvenlik başlıkları ve TLS** dersinde ölçülmüştü; o ölçüm burada
tekrarlanmaz. Burada ölçülen başlığın kendisi değil, **şifrenin nerede bittiğidir**.

Kurgu bölgesel ölçüm ağının istek yolu dört bileşenden geçer: istemci, kenar vekil, ortamı seçen
iç vekil, ölçüm uygulaması. Üç bacak vardır.

- **WS13.** Bileşen kopya sayıları kurgudur: kenar vekil iki kopya, iç vekil üç, uygulama altı.
  Sertifikanın "kaç yerde durduğu" sonlandırmayı yapan bileşenin kopya sayısıdır.
- **WS14.** Yenilemede dokunulan nokta sayısı sertifikanın bulunduğu yer sayısına eşit alınır;
  yenileme akışının kendi adımları sonraki derste ölçülür.
- **WS15.** Sürüm adları kurgudur: `s1` en eski, `s4` en yeni. Şifre takımları `t01`–`t12` diye
  adlandırılır ve her takım kendi en düşük sürümünden itibaren kullanılabilir.
- **WS16.** Bir kalem, kabul edilen bir **(sürüm, takım)** ikilisidir. Varsayılan politika hiçbir
  alt sınır koymaz ve bütün takımları kabul eder.
- **WS17.** Bir istemci topluluğu, desteklediği en yüksek sürüm politikanın alt sınırından küçükse
  ya da kabul listesinde kullanabileceği tek bir takım kalmadıysa düşer.
- **WS18.** Model süre ölçmez; gerçek bir el sıkışma yapılmaz, kalem ve cihaz sayıları listelerden
  türetilir.

```js
// sonlandirma/nokta.mjs — model: tasima katmani guvenligi sonlandirmasinin uc secenegi.
// Zincir kurgu olcum aginin istek yoludur; kopya sayilari kurgudur. Model, sifresiz kalan
// bacagi, sertifikanin bulundugu yer sayisini ve yenilemede dokunulan nokta sayisini sayar.
const ZINCIR = ["istemci", "kenar", "ic-vekil", "uygulama"];
const KOPYA = { kenar: 2, "ic-vekil": 3, uygulama: 6 };   // her bilesenin ornek sayisi
// Kenarin yapabildigi isler: duz metin gerektirenler ve el sikismada gorunen tek is.
const YETENEK = [
  ["yol tabanli yonlendirme", "duz"], ["kenar onbellegi", "duz"],
  ["yol basina hiz siniri", "duz"],   ["govde boyu denetimi", "duz"],
  ["ad tabanli yonlendirme", "el-sikisma"],
];

function olc(nokta) {
  const i = ZINCIR.indexOf(nokta);
  const bacak = ZINCIR.slice(0, -1).map((_, b) => (b < i ? "sifreli" : "sifresiz"));
  const duzGoren = ZINCIR.slice(i);                        // sonlandirmadan sonrasi duz metni gorur
  const kenarDuz = duzGoren.includes("kenar");
  return {
    sifresizBacak: bacak.filter((x) => x === "sifresiz").length,
    sertifikaYeri: KOPYA[nokta],
    yenilemeNoktasi: KOPYA[nokta],
    duzGoren: duzGoren.length,
    kenarYetenegi: YETENEK.filter(([, k]) => k === "el-sikisma" || kenarDuz).length,
  };
}

const E = [12, 16, 16, 18, 17, 15];
const yaz = (h) => h.map((d, i) => String(d)[i ? "padStart" : "padEnd"](E[i])).join("");
console.log(yaz(["sonlandirma", "sifresiz bacak", "sertifika yeri", "yenileme noktasi",
  "duz metni goren", "kenar yetenegi"]));
for (const n of ["kenar", "ic-vekil", "uygulama"]) {
  const o = olc(n);
  console.log(yaz([n, o.sifresizBacak, o.sertifikaYeri, o.yenilemeNoktasi, o.duzGoren,
    `${o.kenarYetenegi}/${YETENEK.length}`]));
}

// --- Protokol ve sifre takimi: kalem kumesi ---------------------------------
// Surum adlari kurgudur; s1 en eski, s4 en yeni. Bir takim ancak kendi en dusuk
// suruminden itibaren kullanilabilir.
const TAKIM = [
  ["t01", 1, false], ["t02", 1, false], ["t03", 2, false], ["t04", 2, false],
  ["t05", 2, false], ["t06", 3, true],  ["t07", 3, true],  ["t08", 3, false],
  ["t09", 3, true],  ["t10", 4, true],  ["t11", 4, true],  ["t12", 4, true],
];
// Kurgu istemci toplulugu: [ad, cihaz sayisi, destekledigi en yuksek surum, gunluk okuma]
const ISTEMCI = [
  ["saha-el-terminali-eski", 40, 1, 1200], ["faturalama-istemcisi", 25, 2, 400],
  ["saha-el-terminali-yeni", 180, 3, 5400], ["is-emri-uygulamasi", 95, 3, 950],
  ["toplayici", 60, 4, 28800], ["tarayici-panosu", 300, 4, 900],
];

function politika(altSurum, yalnizGuclu) {
  const kabulTakim = TAKIM.filter(([, , g]) => (yalnizGuclu ? g : true));
  const kalem = [];
  for (let s = altSurum; s <= 4; s += 1)
    for (const [ad, en, guclu] of kabulTakim) if (en <= s) kalem.push([s, ad, guclu]);
  const baglanan = ISTEMCI.filter(([, , enUst]) =>
    enUst >= altSurum && kabulTakim.some(([, en]) => en <= enUst));
  const dusen = ISTEMCI.filter((x) => baglanan.includes(x) === false);
  return {
    kalem: kalem.length, zayif: kalem.filter((k) => k[2] === false).length,
    cihaz: baglanan.reduce((t, x) => t + x[1], 0),
    dusenCihaz: dusen.reduce((t, x) => t + x[1], 0),
    dusenOkuma: dusen.reduce((t, x) => t + x[3], 0),
    dusenAd: dusen.map((x) => x[0]),
  };
}

const P = [10, 15, 14, 13, 18, 15, 16];
const yaz2 = (h) => h.map((d, i) => String(d)[i ? "padStart" : "padEnd"](P[i])).join("");
console.log("\n" + yaz2(["alt surum", "takim listesi", "kabul kalem", "zayif kalem",
  "baglanan cihaz", "dusen cihaz", "dusen okuma/gun"]));
for (const [alt, guclu] of [[1, false], [2, false], [3, false], [3, true], [4, true]]) {
  const r = politika(alt, guclu);
  console.log(yaz2([`s${alt}`, guclu ? "yalniz guclu" : "tumu", r.kalem, r.zayif, r.cihaz,
    r.dusenCihaz, r.dusenOkuma]) + (r.dusenAd.length ? `   ${r.dusenAd.join(", ")}` : ""));
}
```

```
sonlandirma   sifresiz bacak  sertifika yeri  yenileme noktasi  duz metni goren kenar yetenegi
kenar                      2               2                 2                3            5/5
ic-vekil                   1               3                 3                2            1/5
uygulama                   0               6                 6                1            1/5

alt surum   takim listesi   kabul kalem  zayif kalem    baglanan cihaz    dusen cihaz dusen okuma/gun
s1                   tumu            28           19               700              0               0
s2                   tumu            26           17               660             40            1200   saha-el-terminali-eski
s3                   tumu            21           12               635             65            1600   saha-el-terminali-eski, faturalama-istemcisi
s3           yalniz guclu             9            0               635             65            1600   saha-el-terminali-eski, faturalama-istemcisi
s4           yalniz guclu             6            0               360            340            7950   saha-el-terminali-eski, faturalama-istemcisi, saha-el-terminali-yeni, is-emri-uygulamasi
```

#### Üç Seçenek, Üç Sayı

Birinci tablo üç seçeneği yan yana koyuyor ve hiçbir satır ötekinden her sütunda iyi değil.

**Kenarda sonlandırma** en yaygın düzendir ve en az bakım isteyendir: sertifika iki yerde durur,
yenilemede iki noktaya dokunulur. Bedeli iki şifresiz bacaktır. Kenar vekilden uygulamaya kadar
olan yolda sayaç okumaları, abone kimlikleri ve fatura tutarları düz metin taşınır. Bu yol
"iç ağ" diye adlandırılır ve iç ağın güvenilir sayılması bir ölçüm değil, bir alışkanlıktır.
Düz metni görebilen bileşen sayısı üçtür.

**Vekilde sonlandırma** kenar vekili bir taşıyıcıya indirger: şifreli bağlantı kenardan olduğu
gibi geçer ve iç vekilde biter. Şifresiz bacak bire iner, düz metni gören bileşen sayısı ikiye
iner. Karşılığında sertifika üç yerde durmaya başlar ve yenileme üç noktaya dokunur.

**Uygulamada sonlandırma** şifresiz bacağı sıfıra indirir. Düz metni yalnız uygulama görür.
Sertifika altı yerde durur ve yenileme altı noktaya dokunur. Sayı üç kat büyümüştür ve büyüyen
şey bir güvenlik ayarı değil, **bir bakım yüzeyi**dir: altı yere dağıtılan bir anahtar altı ayrı
kopya, altı ayrı dosya izni, altı ayrı yenileme başarısızlığı olasılığıdır.

Üç satır tek bir eğilimi gösteriyor: şifresiz bacak azaldıkça anahtarın bulunduğu yer sayısı
artıyor. Sıfır şifresiz bacak, sıfır risk anlamına gelmez; riski taşıma yolundan **anahtar
dağıtımına** taşır.

İki sayının aynı yönde gitmemesinin nedeni yapısaldır. Bir bacağı şifrelemek, o bacağın alıcı
ucundaki bileşenin şifreyi çözebilmesini gerektirir; çözebilmek için anahtarı bulundurmak
gerekir. Şifreleme zincirde ne kadar derine inerse anahtar o kadar çok kopyaya iner. Zincirin
sonuna doğru bileşen sayısı da artar — kenar iki, iç vekil üç, uygulama altı kopyadır — ve bu
artış tesadüf değildir: ölçeklenen katman uygulamadır, kenar değil.

#### Kenarın Kaybettiği İş

Son sütun kararın öteki bedelini gösteriyor. Kenar vekil beş iş yapar ve dördü isteğin içeriğini
okumayı gerektirir: yola göre yönlendirme, kenar önbelleği, yol başına hız sınırı, gövde boyu
denetimi. Beşincisi el sıkışmada görünen sunucu adına dayanır ve şifre çözülmeden de yapılabilir.

Kenarda sonlandırıldığında beş işin beşi de yapılabilir. Sonlandırma kenardan uzaklaştığında
**dört iş birden düşer** ve ikinci ile üçüncü satır bu sütunda aynı değeri verir: `1/5`.

Bu, kursun "yanlış kapatma" sütunudur ve buradaki yanlış kapatma büyüktür. Şifresiz bacağı
kapatan adım, kenar önbelleğini kapatır — bir sonraki dersin ölçtüğü bütün kenar isabeti sıfıra
iner. Yol başına hız sınırını kapatır — kötüye kullanan bir istemci artık ancak uygulamada
durdurulabilir ve o noktaya varmak için bütün zinciri kat etmiştir. Gövde boyu denetimini
kapatır — büyük bir gövde altı uygulama kopyasından birine kadar taşınır.

Üç seçenek arasında karar verirken sorulacak soru "hangisi daha güvenli" değildir; sayılar bu
soruya tek bir yanıt vermez. Soru şudur: iki şifresiz bacağı kabul edip kenarda dört iş yapmak
mı, yoksa bacağı kapatıp o dört işi uygulamanın içine taşımak mı. İkinci yol seçildiğinde
uygulama kendi hız sınırını, kendi gövde denetimini ve kendi önbelleğini taşımak zorundadır ve
bu, kapatmanın getirdiği yeni yüzeydir.

#### Kapatmanın Getirdiği Yüzey

Şifresiz bacağı kapatmak yeni kalemler doğurur ve bunlar tabloda görünmez.

Sertifika iki yerde dururken bir yenileme ya iki kopyaya da uygulanmıştır ya da hiçbirine.
Altı yerde dururken **kısmi durum** mümkündür: dört kopya yenilenmiş, ikisi eski anahtarla
duruyor olabilir. Bu ara durum bir arıza vermez — istekler dağıtılırken hangi kopyaya
düştüklerine göre farklı sertifikayla karşılanır ve dışarıdan bakan bir istemci bunu ancak
süresi dolan kopyaya düştüğünde görür. Yenileme noktası sayısı arttıkça arızanın **görünme
olasılığı** artmaz, **bulunma süresi** uzar.

İkinci yeni kalem anahtarın dağıtımıdır. İki kopyaya elle konabilen bir dosya, altı kopyaya
konmak için bir dağıtım yolu ister ve o yol yeni bir yetkidir: bir bileşen anahtarı okuyup altı
yere yazabiliyor olmalıdır. Anahtarın altı yerde durması bir kalem değil, yedi kalemdir — altı
kopya ve onları yazan tek yol.

Üçüncüsü sertifika ile uygulama sürümünün birbirine bağlanmasıdır. Sonlandırma uygulamadayken
sertifika yenilemesi uygulamanın yeniden yüklenmesini gerektirir; iki ayrı takvim — yayın
takvimi ve yenileme takvimi — aynı sürece dokunur.

#### Kalem Kümesi Olarak Protokol

İkinci tablo başka bir varsayılanı ölçüyor. Sonlandırma noktasına karar verildikten sonra
sonlandıran bileşen **hangi el sıkışmaları kabul edeceğine** karar verir ve bu kararı çoğu
kurulumda kimse vermez.

Varsayılan satır ilk satırdır: alt sınır yok, bütün takımlar kabul. Yirmi sekiz kalem açık ve
bunların **on dokuzu zayıf**. Yedi yüz cihazın hepsi bağlanabiliyor, hiçbir okuma düşmüyor.
Varsayılanın çekiciliği tam olarak budur: sıfır kırılma. Kimse şikâyet etmez ve on dokuz zayıf
kalem, kimsenin şikâyet etmediği için kimsenin bakmadığı bir listede durur.

Alt sınırı `s2` yapmak kalem sayısını yirmi altıya indiriyor: iki kalem kapandı. Bedeli kırk
eski el terminali ve günde bin iki yüz okuma. `s3` alt sınırı yirmi bir kaleme iniyor, altmış
beş cihaz düşüyor, günde bin altı yüz okuma kesiliyor — ve **hâlâ on iki zayıf kalem açık**.

Bu, sürüm alt sınırının yalnız başına yetmemesinin ölçüsüdür. Alt sınır bir kalemi sürümüne
bakarak kapatır; zayıf bir takım, yeni bir sürümün altında da kabul edilmeye devam eder. Sekiz
numaralı takım `s3`'ten itibaren kullanılabilir ve zayıftır; sürüm alt sınırı onu hiçbir zaman
kapatmaz.

#### Bedavaya Kapanan On İki Kalem

Dördüncü satır ölçümün en keskin sonucudur. Alt sınır `s3`'te sabit tutuluyor, yalnız takım
listesi güçlülerle sınırlanıyor.

Kabul edilen kalem sayısı yirmi birden **dokuza** iniyor, zayıf kalem sayısı on ikiden **sıfıra**
iniyor ve düşen cihaz sayısı hiç değişmiyor: altmış beş. Düşen okuma sayısı da aynı kalıyor.
On iki kalem, ek bir kırılma olmadan kapandı.

İki lever arasındaki fark budur. Sürüm alt sınırı pahalıdır: her basamak bir istemci topluluğunu
düşürür. Takım listesi ucuzdur: zayıf takımları çıkarmak, aynı sürümü konuşan istemcilerin
kullanabileceği güçlü takımlar kaldığı sürece kimseyi düşürmez. Sertleştirme sırası bunu
izlemelidir — önce takım listesi, sonra sürüm alt sınırı.

Sıranın tersine çevrilmesi ölçülebilir bir zarar verir. Önce alt sınırı yükselten bir ekip
altmış beş cihazı düşürür, telefonlar çalar, adım geri alınır ve zayıf takımlar da açık kalır —
kırılma yaşandı, kalem kapanmadı. Aynı ekip önce takım listesini daraltsaydı on iki kalemi
sıfır kırılmayla kapatmış, ardından alt sınır tartışmasını bu on iki kalem olmadan yapıyor
olurdu.

Beşinci satır sınırın nerede durduğunu gösteriyor. Alt sınır `s4`'e çıkarıldığında kalem altıya
iniyor ama üç yüz kırk cihaz düşüyor ve günde yedi bin dokuz yüz elli okuma kesiliyor. Dokuz
kalemden altı kaleme inmek için ödenen bedel, sistemin yarısını kaybetmektir. Dördüncü satır on iki
kalemi sıfır ek cihazla kapatmıştı; beşinci satır üç kalemi iki yüz yetmiş beş ek cihazla
kapatıyor. Aynı tablodaki iki adım arasındaki bu fark, kalem sayısını tek başına bir hedef
saymanın neden yanıltıcı olduğunu gösterir.

Kapatılamayan kalem burada adıyla görünür: **kırk eski el terminali**. Bu cihazlar `s1`'in
üstünü konuşamıyor ve değiştirilene kadar alt sınır `s1`'in üstüne çıkamıyor. Tek çıkış yol,
onlar için ayrı bir dinleyici açmaktır — eski sürümü yalnız o dinleyicide kabul etmek. Bu bir
çözüm değil, bir taşımadır: yüzey kalemi kapanmaz, adres değiştirir ve önceki derste sayılan
**dinlenen kapı** listesine bir kalem daha eklenir.

#### Özet

- Sonlandırma kenardan uygulamaya doğru taşındıkça şifresiz bacak sayısı ikiden sıfıra indi,
  buna karşılık sertifikanın bulunduğu yer ve yenilemede dokunulan nokta sayısı ikiden altıya çıktı.
- Düz metni görebilen bileşen sayısı üçten bire indi; sıfır şifresiz bacak riski taşıma yolundan
  anahtar dağıtımına taşıdı.
- Sonlandırma kenardan uzaklaştığında kenar vekilin beş işinden dördü düştü: yol tabanlı
  yönlendirme, kenar önbelleği, yol başına hız sınırı ve gövde boyu denetimi.
- Varsayılan politika yirmi sekiz kalem kabul etti ve on dokuzu zayıftı; hiçbir cihaz düşmediği
  için varsayılan hiç sorgulanmadı.
- Sürüm alt sınırını `s3` yapmak yedi kalem kapattı, altmış beş cihaz düşürdü ve on iki zayıf
  kalem bıraktı; takım listesini güçlülerle sınırlamak kalan on iki zayıf kalemin hepsini
  **ek cihaz kaybı olmadan** kapattı.
- Kırk eski el terminali alt sınırın `s1`'in üstüne çıkmasını engelledi; onlar için ayrı bir
  dinleyici açmak kalemi kapatmaz, dinlenen kapı listesine bir kalem ekler.

#### Sonraki Adım

Bu ders sertifikanın **kaç yerde durduğunu** saydı ve yenilemede dokunulan nokta sayısını o
sayıya eşit aldı. Yenilemenin kendisi bir kutu olarak kaldı: bir gün olur, biter, sertifika
tazelenir.

O kutunun içi bir durum makinesidir ve iki ayarı vardır: sertifikanın ömrü ve yenilemeye kaç gün
kala başlanacağı. Eşik erken konursa gereksiz yenileme koşar; geç konursa süre dolmadan yenileme
bitmeyebilir ve arada **kaç saatlik bir açık pencere** kaldığı sorusu doğar. Yenileme akışının
ortasında bir doğrulama adımı vardır ve o adım başarısız olabilir; kaç deneme yapıldığı, hangi
denemede sertifikanın süresinin dolduğu ve uyarının ne zaman gelmesi gerektiği ayrı sayılardır.
Sonraki ders yenileme akışını `node` ile bir durum makinesi olarak yazar, ömür ile eşiği tarar,
doğrulama başarısızlığını modelleyip açık pencereyi saatle ölçer ve elle yenilemenin bir dönemde
kaç kalemde unutulduğunu sayar.

### Sertifika Otomasyonu

Source: https://academia.sh/tr/kurslar/sunucu-ve-sertlestirme/sertifika-otomasyonu

Yenileme akışının bir durum makinesi olarak yazılması ve ömür ile eşiğin taranması: erken eşiğin ürettiği on iki gereksiz yenileme, geç eşiğin bıraktığı otuz sekiz saatlik açık pencere, doğrulama başarısızlığında beş deneme ile uyarının hangi anda verilmesi gerektiği ve üç yıllık bir dönemde elle yenilemenin dokuz kalemde unutulup bin yedi yüz saat açık pencere bırakması.

Önceki ders sertifikanın kaç yerde durduğunu saydı ve yenilemede dokunulan nokta sayısını o
sayıya eşit aldı. Yenilemenin kendisi bir kutu olarak kaldı: bir gün olur, biter, sertifika
tazelenir.

O kutunun içi bir **durum makinesi**dir. Bir istek gönderilir, alan adının denetiminde olunduğu
doğrulanır, imza alınır, yeni sertifika kopyalara dağıtılır. Dört adımın her biri sürer ve
ikincisi başarısız olabilir. İki ayar bu makinenin dışındadır ve sonucu belirler: sertifikanın
**ömrü** ve yenilemeye kaç saat kala başlanacağını söyleyen **eşik**.

Ölçüm kurgu bölgesel ölçüm ağının on iki sertifikası üzerinde, üç yıllık bir dönemde yapılır.
Sağlayıcı yoktur; adımlar, süreleri ve sertifika listesi kurgudur.

- **WS19.** Adım süreleri saat cinsinden sabittir: istek 1, doğrulama 2, imza 1, dağıtım 2.
  Doğrulama başarısız olursa geri çekilme dizisi `1, 2, 4, 8, 16` saattir ve beşinci denemeden
  sonra otomasyon vazgeçer.
- **WS20.** Otomasyon vazgeçtiğinde insan devralır ve işi sekiz saatte bitirir; elle yapılan her
  yenileme de sekiz saat sürer.
- **WS21.** Unutulan bir elle yenilemenin **fark edilme süresi** görünürlüğe bağlıdır: dışa
  bakan bir kalem iki saatte, iç bir kalem doksan altı saatte fark edilir.
- **WS22.** Unutma ve doğrulama hatası kendi üretecimizle üretilir; tohum `4711` görünürdür ve
  koşumdan koşuma aynı diziyi verir. Unutma oranı `0,25`, doğrulama hata oranı `0,30` alınır.
- **WS23.** Model süre ölçmez; bütün saat değerleri yukarıdaki sabitlerden aritmetikle türer.
- **WS24.** Açık pencere, yenileme akışının süresi eşiği aştığında geçen saat sayısıdır; sertifika
  o saatlerde süresi dolmuş olarak durur.

```js
// yenileme/akis.mjs — model: sertifika yenileme akisi bir durum makinesidir. Sure birimi saat,
// donem uc yil. Saglayici yoktur; adimlar ve sureleri kurgudur, butun sayilar bunlardan turer.
const DONEM = 26280;                       // 3 yil, saat
const ELLE = 8;                            // insanin devralip bitirmesi (saat)
const GERI = [1, 2, 4, 8, 16];             // dogrulama hatasindan sonra bekleme (saat)
const ADIM = { istek: 1, dogrulama: 2, imza: 1, dagitim: 2 };

// Durum makinesi: istek -> dogrulama -> (hata -> bekle -> dogrulama)* -> imza -> dagitim.
// "kotu" kacinci denemede basarili olundugunu soyler; GERI.length ise hic basarilamaz.
function kos(kotu) {
  let t = ADIM.istek;
  for (let d = 0; d < GERI.length; d += 1) {
    t += ADIM.dogrulama;
    if (d === kotu) return { sure: t + ADIM.imza + ADIM.dagitim, sonuc: "tamam" };
    t += GERI[d];
  }
  return { sure: t + ELLE, sonuc: "elle devralindi" };
}

const SURE = [0, 4, GERI.length].map((k) => kos(k).sure);   // 0 hata, 4 hata, vazgecis
const pencere = (esik, sure) => Math.max(0, sure - esik);
const yenilemeSayisi = (omur, esik) => Math.floor(DONEM / (omur - esik));
const zorunlu = (omur) => Math.ceil(DONEM / omur) - 1;

const E = [12, 12, 16, 10, 12, 12, 19, 13];
const yaz = (h) => h.map((d, i) => String(d)[i ? "padStart" : "padEnd"](E[i])).join("");
console.log(yaz(["omur(saat)", "esik(saat)", "yenileme/donem", "gereksiz", "pencere(0)",
  "pencere(4)", "pencere(vazgecis)", "uyari"]));
for (const omur of [2160, 8760])
  for (const esik of [1080, 720, 336, 48, 12]) {
    const n = yenilemeSayisi(omur, esik);
    console.log(yaz([omur, esik, n, n - zorunlu(omur), ...SURE.map((s) => pencere(esik, s)),
      SURE[2] > esik ? "ilk hatada" : "vazgecisde"]));
  }

// --- Elle yenileme ile otomatik yenileme, ayni donemde --------------------------
// Kurgu olcum aginin sertifikalari: [ad, omur(saat), gorunurluk]. Gorunurluk unutmanin
// fark edilme suresini belirler: disa bakan uc saatte, ic kalem gunlerce sonra gorulur.
const FARK = { dis: 2, ic: 96 };
const SERTIFIKA = [
  ["kenar-vekil-dis", 2160, "dis"], ["ic-vekil-orta", 2160, "ic"],
  ["ic-vekil-uretim", 2160, "ic"], ["olcum-uygulamasi", 8760, "dis"],
  ["toplayici-istemcisi", 8760, "ic"], ["faturalama-istemcisi", 8760, "ic"],
  ["yonetim-dinleyicisi", 8760, "ic"], ["bildirim-gecidi", 2160, "ic"],
  ["yedek-hedefi", 8760, "ic"], ["is-emri-uygulamasi", 2160, "dis"],
  ["sayac-agi-gecidi", 17520, "ic"], ["pano", 2160, "dis"],
];
// Kendi uretecimiz; tohum gorunur, kosumdan kosuma ayni diziyi verir.
const uretec = (tohum) => { let s = tohum >>> 0; return () => (s = (Math.imul(s, 1664525) + 1013904223) >>> 0) / 4294967296; };
const TOHUM = 4711, UNUTMA = 0.25, HATA = 0.30;

function elle() {
  const r = uretec(TOHUM);
  let olay = 0, kacan = 0, saat = 0; const kalem = new Set();
  const kirilim = { dis: [0, 0], ic: [0, 0] };            // [unutulan olay, acik saat]
  for (const [ad, omur, gor] of SERTIFIKA)
    for (let k = 0; k < Math.floor(DONEM / omur); k += 1) {
      olay += 1;
      if (r() < UNUTMA) {
        kacan += 1; saat += FARK[gor] + ELLE; kalem.add(ad);
        kirilim[gor][0] += 1; kirilim[gor][1] += FARK[gor] + ELLE;
      }
    }
  return { olay, kacan, saat, kalem: kalem.size, kirilim };
}

function otomatik(esik) {
  const r = uretec(TOHUM);
  let olay = 0, kacan = 0, saat = 0; const kalem = new Set();
  for (const [ad, omur] of SERTIFIKA)
    for (let k = 0; k < yenilemeSayisi(omur, esik); k += 1) {
      olay += 1;
      let d = 0;
      while (d < GERI.length && r() < HATA) d += 1;      // kacinci denemede basarili
      const p = pencere(esik, kos(d).sure);
      if (d === GERI.length) kacan += 1;
      if (p > 0) { saat += p; kalem.add(ad); }
    }
  return { olay, kacan, saat, kalem: kalem.size };
}

const Y = [24, 8, 22, 12, 16];
const yaz2 = (h) => h.map((d, i) => String(d)[i ? "padStart" : "padEnd"](Y[i])).join("");
console.log("\n" + yaz2(["yontem", "olay", "unutulan/vazgecilen", "acik saat", "etkilenen kalem"]));
const E0 = elle();
for (const [ad, r] of [["elle (esik yok)", E0], ["otomatik (esik 168)", otomatik(168)],
  ["otomatik (esik 12)", otomatik(12)]])
  console.log(yaz2([ad, r.olay, r.kacan, r.saat, r.kalem]));
console.log(`\nelle unutulanin kirilimi: dis ${E0.kirilim.dis[0]} olay / ${E0.kirilim.dis[1]} saat` +
  `   ic ${E0.kirilim.ic[0]} olay / ${E0.kirilim.ic[1]} saat`);
```

```
omur(saat)    esik(saat)  yenileme/donem  gereksiz  pencere(0)  pencere(4)  pencere(vazgecis)        uyari
2160                1080              24        12           0           0                  0   vazgecisde
2160                 720              18         6           0           0                  0   vazgecisde
2160                 336              14         2           0           0                  0   vazgecisde
2160                  48              12         0           0           0                  2   ilk hatada
2160                  12              12         0           0          17                 38   ilk hatada
8760                1080               3         1           0           0                  0   vazgecisde
8760                 720               3         1           0           0                  0   vazgecisde
8760                 336               3         1           0           0                  0   vazgecisde
8760                  48               3         1           0           0                  2   ilk hatada
8760                  12               3         1           0          17                 38   ilk hatada

yontem                      olay   unutulan/vazgecilen   acik saat etkilenen kalem
elle (esik yok)               88                    29        1700               9
otomatik (esik 168)           94                     0           0               0
otomatik (esik 12)            88                     0          56               8

elle unutulanin kirilimi: dis 14 olay / 140 saat   ic 15 olay / 1560 saat
```

#### Eşiğin İki Ucu

İlk tablonun iki ucu iki ayrı arıza türü üretiyor ve ikisi de arıza gibi görünmüyor.

**Erken uç.** Ömrü doksan gün olan bir sertifikada eşik kırk beş güne konduğunda yenileme
sertifika henüz yarı yoldayken başlar. Dönem boyunca yirmi dört yenileme koşuyor; zorunlu sayı
on iki. On iki yenileme **gereksiz**dir: hiçbiri bir açık pencereyi kapatmıyor, her biri bir
istek, bir doğrulama, bir imza ve bir dağıtım üretiyor. Eşik yirmi bir güne indiğinde altı,
on dört güne indiğinde iki gereksiz yenileme kalıyor.

Gereksiz yenilemenin bedeli iki yerde ödenir. Birincisi doğrulama adımının kendisidir; her
yenileme bir dış çağrı ve bir dış bağımlılıktır. İkincisi dağıtımdır: her yenileme sertifikanın
bulunduğu her yere dokunur ve önceki dersin saydığı altı kopyalı düzende her dokunuş kısmi
durum riski taşır. Yirmi dört yenileme, on iki gereksiz kısmi durum fırsatıdır.

**Geç uç.** Eşik kırk sekiz saate indiğinde sıfır gereksiz yenileme kalıyor. Ölçünün bu sütunu
artık temiz; öteki sütunlar açılıyor. Doğrulama dört kez başarısız olduğunda akış yirmi dokuz
saat sürüyor ve kırk sekiz saatlik eşiğe sığıyor — pencere sıfır. Otomasyon beş denemenin
beşinde de başarısız olup insana devrettiğinde toplam elli saat sürüyor ve **iki saatlik** bir
pencere açılıyor.

Eşik on iki saate indiğinde iki sütun birden açılıyor: dört hatada **on yedi saat**, vazgeçişte
**otuz sekiz saat** açık pencere. Otuz sekiz saat, sertifikanın süresi dolmuş olarak durduğu ve
her bağlanan istemcinin bir uyarı ya da bir ret aldığı süredir.

#### Ömrün Eşiği Nasıl Değersizleştirdiği

Tablonun ikinci yarısı aynı beş eşiği bir yıllık ömürde tekrarlıyor ve `gereksiz` sütunu artık
hareket etmiyor: beş eşiğin beşinde de bir. Ömür uzadıkça eşik, gereksiz yenileme sayısı
üzerindeki etkisini kaybediyor.

Nedeni oran: kırk beş günlük eşik doksan günlük bir ömrün yarısı, bir yıllık ömrün sekizde
biridir. Kısa ömürde eşik döngüyü ikiye böler, uzun ömürde ucundan kırpar. Bu, uzun ömrün
otomasyon için daha kolay olduğu anlamına gelmez — `pencere` sütunları iki yarıda **birebir
aynıdır**. Açık pencere ömre değil, yalnız eşiğe ve akışın süresine bağlıdır; bir yıllık bir
sertifikada on iki saatlik eşik, doksan günlükte olduğu gibi otuz sekiz saat açık pencere
bırakır.

İki yarı arasındaki gerçek fark yenileme sayısındadır: doksan günlük ömürde dönemde on iki ile
yirmi dört arası yenileme koşuyor, bir yıllık ömürde üç. Yenileme ne kadar seyrekse akış o kadar
az sınanır. Üç yılda üç kez koşan bir akışın bozulduğu, ancak dördüncü koşumda anlaşılır ve o
koşum sertifikanın süresinin dolmasından on iki saat öncedir.

#### Uyarı Ne Zaman Gelmeli

Son sütun bir sayı değil, bir kural veriyor ve kuralı eşiğin kendisi belirliyor.

Otomasyonun en kötü durumdaki toplam süresi kırk iki saattir: beş doğrulama denemesi ve
aralarındaki otuz bir saatlik geri çekilme. İnsanın devralıp bitirmesi sekiz saat sürer. İkisi
toplam elli saattir.

Eşik elli saatten büyükse otomasyon sonuna kadar deneyebilir; vazgeçtiğinde bile insan için
yeterli zaman kalır ve uyarı **vazgeçiş anında** verilebilir. İlk üç eşik değeri bu durumdadır.
Eşik elli saatten küçükse durum tersine döner: otomasyonun sonuna kadar denemesini beklemek,
insanın devralacağı anı sertifikanın süresinin dolmasından sonraya atar. Bu durumda uyarı
**ilk doğrulama hatasında** verilmelidir.

Kural şu biçime iner: uyarı eşiği bir tercih değil, `en kötü otomatik süre + insan süresi`
toplamının eşikle karşılaştırılmasıdır. Kırk sekiz ve on iki saatlik eşiklerde otomasyonun
sessiz kalması bir arıza olur — otomasyon çalışıyor, deniyor, geri çekiliyor ve kimse haberdar
değil. Sessiz otomasyon, elle yenilemeden daha geç fark edilir.

#### Elle Yenilemenin Dönem Faturası

İkinci tablo aynı on iki sertifikayı üç yıl boyunca elle yenilenmiş sayıyor.

Dönemde seksen sekiz yenileme olayı var. Yirmi dokuzu unutuldu — dörtte biri. Unutmalar dokuz
ayrı kaleme dağıldı: on iki sertifikanın dokuzunda en az bir kez süre doldu. Toplam açık
pencere **bin yedi yüz saat**, yani üç yılda yetmiş günün üstünde.

Kırılım satırı asıl bulguyu veriyor. Dışa bakan kalemlerde on dört unutma oldu ve toplam yüz
kırk saat açık pencere bıraktı. İç kalemlerde on beş unutma oldu ve **bin beş yüz altmış saat**
bıraktı. Olay sayıları neredeyse eşit; saatler on bir katı farklı.

Fark tek bir yerden geliyor: fark edilme süresi. Dışa bakan bir sertifikanın süresi dolduğunda
saha ekipleri iki saat içinde arar. İç bir sertifikanın süresi dolduğunda ne olur — toplayıcı
doğrulayıcıya bağlanamaz, gecelik toplu iş bir uyarı yazar, bildirim geçidi e-posta gönderemez —
ve bunların hiçbiri kimseyi aramaz. Doksan altı saat, arızanın bir insanın gözüne değmesi için
geçen süredir.

Bu, "elle yenileme yeterli" savunmasının nerede kırıldığını gösterir. Savunma dışa bakan
sertifikaya bakarak yapılır ve orada haklıdır: iki saatlik pencere kabul edilebilir. Aynı
disiplin iç kalemlere uygulandığında pencere kırk sekiz kat uzar ve kimse ölçmediği için bu
uzama hiçbir raporda görünmez.

#### Otomasyonun Kapattığı ve Getirdiği

Son iki satır otomasyonu aynı döneme uyguluyor.

Eşiği yüz altmış sekiz saat olan otomasyon doksan dört yenileme koşuyor — elleden altı fazla,
çünkü eşik döngüyü kısaltıyor. Vazgeçilen yenileme yok, açık pencere **sıfır**, etkilenen kalem
sıfır. Bin yedi yüz saatlik pencere sıfıra indi.

Eşiği on iki saat olan otomasyon aynı seksen sekiz olayı koşuyor ve elli altı saat açık pencere
bırakıyor; sekiz kalem etkileniyor. Vazgeçilen yenileme yine yok — beş denemenin beşinin birden
başarısız olması ender bir olaydır — ama iki ya da üç denemeye kalan yenilemeler on iki saatlik
eşiğe sığmıyor. Otomasyonun kendisi doğru çalışıyor; eşik yanlış.

İki satır birlikte okunduğunda otomasyonun neyi kapattığı nettir: **unutmayı** kapattı, hatayı
kapatmadı. Elle yenilemede bin yedi yüz saatin tamamı unutmadan geliyordu. Otomasyonda kalan
elli altı saatin tamamı doğrulama hatasından geliyor ve o hata bir eşik ayarıyla soğurulabilir.

Kapatmanın getirdiği yeni yüzey de sayılabilir. Otomasyon bir bileşendir: bir kimlikle koşar,
sertifikanın bulunduğu her yere yazma yetkisi vardır, dış bir doğrulama adımına bağımlıdır ve
kendi yapılandırmasında bir eşik taşır. Dört kalem. Elle yenilemede bu dört kalem yoktu; onun
yerine dokuz kalemde unutulan bir alışkanlık vardı. Otomasyon **kalem sayısını değiştirmedi**,
kalemin türünü değiştirdi: hatırlanması gereken bir işi, izlenmesi gereken bir bileşene çevirdi.

#### Özet

- Eşik erken konduğunda dönemde yirmi dört yenileme koştu ve on ikisi gereksizdi; eşik on dört
  güne indiğinde gereksiz yenileme ikiye, kırk sekiz saate indiğinde sıfıra düştü.
- Eşik geç konduğunda pencere açıldı: on iki saatlik eşikte dört doğrulama hatası on yedi saat,
  otomasyonun vazgeçişi otuz sekiz saat açık pencere bıraktı.
- Uyarının anı eşikten türer: en kötü otomatik süre kırk iki saat ile insan süresi sekiz saatin
  toplamı eşikten büyükse uyarı ilk doğrulama hatasında verilmelidir, küçükse vazgeçiş anı yeter.
- Üç yıllık dönemde elle yenilemenin seksen sekiz olayının yirmi dokuzu unutuldu, on iki
  sertifikanın dokuzunda süre doldu ve toplam bin yedi yüz saat açık pencere kaldı.
- Unutmaların yarısı dışa bakan kalemlerdeydi ama açık saatin yalnız yüz kırkı oradan geldi;
  iç kalemlerin on beş unutması bin beş yüz altmış saat bıraktı — fark edilme süresi farkı.
- Eşiği yüz altmış sekiz saat olan otomasyon açık pencereyi sıfıra indirdi ve yerine dört yeni
  kalem getirdi: bir kimlik, bir yazma yetkisi, bir dış bağımlılık ve bir eşik ayarı.

#### Sonraki Adım

Bu ders ile önceki iki ders isteğin yolunu kurdu ve şifreledi: kim geldiği aktarıldı, şifre bir
yerde sonlandı, sertifika kendi kendine tazeleniyor. Yolun tamamı artık her istek için baştan
sona koşuyor — her istek için.

Ölçüm ağının panosu her açılışta aynı bölge haritasını, aynı sayaç listesini ve aynı gecelik
özet dosyasını istiyor. Bu isteklerin çoğu aynı yanıtı üretiyor ve her biri kenar vekilden iç
vekile, oradan uygulamaya ve veri katmanına kadar gidiyor. Yanıt bir yerde tutulabilir — ama
"bir yer" iki ayrı yerdir: kenarda, istemciye yakın; kaynakta, uygulamaya yakın. İkisi birden
konduğunda isabetin nasıl bölündüğü, bir içerik değiştiğinde eskisinin kenarda kaç saniye daha
durduğu ve tazelik ayarının bu pencereyi nasıl değiştirdiği ayrı sayılardır. Sonraki ders iki
katmanlı önbelleği bu üç sayıyla ölçer ve yanlış önbelleklemenin açtığı yüzeyi adıyla yazar.

### Önbellek Sunucusu

Source: https://academia.sh/tr/kurslar/sunucu-ve-sertlestirme/onbellek-sunucusu

İki katmanlı önbellekte isabetin kenar ile kaynak arasında nasıl bölündüğü: kenarı üç düğüme bölmenin uygulamaya inen isteği elliden yüz kırk üçe çıkarması ve kaynak önbelleğinin onu ona indirmesi, geçersizleştirmenin yayılma penceresinin üç yüz altmış saniyeden on bir saniyeye inmesi, tazelik ayarının bu pencereye etkisi ve kişiye özel yanıtın paylaşılan önbelleğe düşmesiyle açılan paylaşılan anahtar yüzeyi.

Son üç ders isteğin yolunu kurdu ve şifreledi: kim geldiği aktarıldı, şifre bir yerde sonlandı,
sertifika kendi kendine tazeleniyor. Yolun tamamı her istek için baştan sona koşuyor.

Ölçüm ağının panosu her açılışta aynı bölge haritasını, aynı sayaç listesini ve aynı gecelik
özet dosyasını istiyor. Bu isteklerin çoğu aynı yanıtı üretiyor. Yanıt bir yerde tutulabilir —
ama "bir yer" iki ayrı yerdir. **Kenar önbelleği** istemciye yakın durur ve isteği ağın uzağına
hiç göndermez. **Kaynak önbelleği** uygulamanın önünde durur ve uygulamanın aynı yanıtı iki kez
üretmesini engeller.

Önbelleğin ne olduğu, isabet oranının nasıl hesaplandığı ve tazeliğin ne anlama geldiği daha
önce ölçülmüştü; bu ders o mekaniği tekrarlamaz. Burada ölçülen üç şeydir: iki katman arasında
isabetin nasıl **bölündüğü**, bir içerik değiştiğinde eskisinin kenarda kaç saniye daha durduğu
ve yanlış bir önbellek anahtarının açtığı yüzey.

- **WS25.** İstek akışı kendi üretecimizle üretilir; tohum `20260` görünürdür ve koşumdan
  koşuma aynı diziyi verir. İki bin istek, altı yüz saniyeye yayılır.
- **WS26.** Beş içerik vardır ve ağırlıkları sabittir; biri (`/fatura/ozet`) kişiye özeldir,
  yani yanıtı isteği yapan aboneye göre değişir.
- **WS27.** Bir abone hep aynı kenar düğümüne düşer: düğüm, abone kimliğinin düğüm sayısına
  bölümünden kalandır.
- **WS28.** Varsayılan önbellek anahtarı **yalnız yoldur**; kimlik anahtara girmez. İki seçenek
  daha ölçülür: anahtara kimliği eklemek ve kişiye özel içeriği hiç saklamamak.
- **WS29.** Geçersizleştirme yayınının üç kenar düğümüne ulaşma süresi kurgudur: iki, beş ve on
  bir saniye. Pencere en yavaş düğüme göre hesaplanır.
- **WS30.** Model süre ölçmez; saniye değerleri tazelik ayarlarından ve kurgu gecikmelerden
  türer, eski yanıt alan istek sayısı değişen içeriğin trafik payından hesaplanır.

```js
// onbellek/katman.mjs — model: iki katmanli onbellek (kenar + kaynak). Kurgu olcum aginin
// istek akisi kendi uretecimizle uretilir; tohum gorunur. Onbellek mekanigi yeniden
// tanimlanmaz, iki katman arasindaki isabet dagilimi ve gecersizlestirme penceresi olculur.
const DONEM = 600, ISTEK = 2000, ABONE = 6, TOHUM = 20260;
// [yol, agirlik, tur]
const ICERIK = [
  ["/bolge/harita", 40, "paylasik"], ["/sayac/liste", 25, "paylasik"],
  ["/gecelik/ozet", 15, "paylasik"], ["/varlik/logo", 10, "paylasik"],
  ["/fatura/ozet", 10, "kisiye-ozel"],
];
const TOPLAM = ICERIK.reduce((a, x) => a + x[1], 0);
const uretec = (tohum) => { let s = tohum >>> 0; return () => (s = (Math.imul(s, 1664525) + 1013904223) >>> 0) / 4294967296; };
const sec = (u) => { let e = u * TOPLAM; return ICERIK.find((x) => (e -= x[1]) < 0) ?? ICERIK[0]; };

function simule({ dugum, kaynakVar, kenarTazelik, kaynakTazelik, anahtar }) {
  const r = uretec(TOHUM);
  const kenar = Array.from({ length: dugum }, () => new Map());
  const kaynak = new Map();
  const s = { kenarIsabet: 0, kaynakIsabet: 0, uygulama: 0, sizanIstek: 0 };
  const sizanAbone = new Set();
  for (let i = 0; i < ISTEK; i += 1) {
    const t = Math.floor((i * DONEM) / ISTEK);
    const [yol, , tur] = sec(r());
    const abone = Math.floor(r() * ABONE);
    const ozel = tur === "kisiye-ozel";
    if (ozel && anahtar === "ozel-gecer") { s.uygulama += 1; continue; }   // ozel icerik hic saklanmaz
    const a = anahtar === "yol+kimlik" && ozel ? `${yol}#${abone}` : yol;
    const k = kenar[abone % dugum];
    const kayitla = (giris) => {                        // isabette kimin yaniti dondu
      if (ozel && giris.abone !== abone) { s.sizanIstek += 1; sizanAbone.add(giris.abone); }
    };
    const ke = k.get(a);
    if (ke && t - ke.t < kenarTazelik) { s.kenarIsabet += 1; kayitla(ke); continue; }
    const kk = kaynakVar ? kaynak.get(a) : undefined;
    if (kk && t - kk.t < kaynakTazelik) {
      s.kaynakIsabet += 1; kayitla(kk); k.set(a, { t, abone: kk.abone }); continue;
    }
    s.uygulama += 1;                                    // iki katman da isabetsiz: uygulama uretir
    if (kaynakVar) kaynak.set(a, { t, abone });
    k.set(a, { t, abone });
  }
  return { ...s, sizanAbone: sizanAbone.size };
}

const E = [8, 9, 14, 15, 16, 18, 14, 13];
const yaz = (h) => h.map((d, i) => String(d)[i ? "padStart" : "padEnd"](E[i])).join("");
console.log(yaz(["dugum", "kaynak", "anahtar", "kenar isabet", "kaynak isabet", "uygulamaya inen",
  "sizan istek", "sizan abone"]));
const AYAR = [
  [1, false, "yol"], [3, false, "yol"], [3, true, "yol"],
  [3, true, "yol+kimlik"], [3, true, "ozel-gecer"],
];
for (const [dugum, kaynakVar, anahtar] of AYAR) {
  const o = simule({ dugum, kaynakVar, kenarTazelik: 60, kaynakTazelik: 300, anahtar });
  console.log(yaz([dugum, kaynakVar ? "var" : "yok", anahtar, o.kenarIsabet, o.kaynakIsabet,
    o.uygulama, o.sizanIstek, o.sizanAbone]));
}

// --- Gecersizlestirmenin yayilma penceresi -------------------------------------
// Icerik kaynakta t=0'da degisti. Pencere, kenarda kac saniye eski icerik kaldigidir.
// Yayin gecikmesi kurgudur: uc kenar dugumune sirasiyla su saniyelerde ulasir.
const GECIKME = [2, 5, 11];
const DEGISEN = ICERIK[0];                              // degisen icerik: /bolge/harita
const HIZ = (ISTEK / DONEM) * (DEGISEN[1] / TOPLAM);    // o icerige gelen istek/saniye
function pencere(yontem, kenarTazelik, kaynakTazelik) {
  if (yontem === "yok") return kenarTazelik + kaynakTazelik;      // iki tazelik ust uste biner
  if (yontem === "kaynakta") return kenarTazelik;                 // kenar kendi suresini bekler
  if (yontem === "her katmanda") return Math.max(...GECIKME);
  return kenarTazelik;                                            // bir dugum yayini kacirdi
}
const P = [22, 16, 17, 20, 22];
const yaz2 = (h) => h.map((d, i) => String(d)[i ? "padStart" : "padEnd"](P[i])).join("");
console.log("\n" + yaz2(["gecersizlestirme", "kenar tazelik", "kaynak tazelik", "pencere(saniye)",
  "eski yanit alan istek"]));
for (const [y, kt, kk] of [["yok", 60, 300], ["yok", 10, 60], ["kaynakta", 60, 300],
  ["kaynakta", 10, 300], ["her katmanda", 60, 300], ["bir dugum kacirdi", 60, 300]]) {
  const p = pencere(y, kt, kk);
  console.log(yaz2([y, kt, kk, p, Math.round(p * HIZ)]));
}
```

```
dugum      kaynak       anahtar   kenar isabet   kaynak isabet   uygulamaya inen   sizan istek  sizan abone
1             yok           yol           1950               0                50           169            5
3             yok           yol           1857               0               143            95            6
3             var           yol           1857             133                10           179            2
3             var    yol+kimlik           1837             143                20             0            0
3             var    ozel-gecer           1664             107               229             0            0

gecersizlestirme         kenar tazelik   kaynak tazelik     pencere(saniye) eski yanit alan istek
yok                                 60              300                 360                   480
yok                                 10               60                  70                    93
kaynakta                            60              300                  60                    80
kaynakta                            10              300                  10                    13
her katmanda                        60              300                  11                    15
bir dugum kacirdi                   60              300                  60                    80
```

#### Kenarı Bölmenin Bedeli

İlk iki satır aynı iki bin isteği aynı tazelik ayarlarıyla geçiriyor. Değişen tek şey kenar
düğümü sayısı.

Tek düğümde kenar isabeti bin dokuz yüz elli, uygulamaya inen istek elli. Kenar üç düğüme
bölündüğünde isabet bin sekiz yüz elli yediye iniyor ve uygulamaya inen istek **elliden yüz
kırk üçe** çıkıyor. Yaklaşık üç katı.

Nedeni doğrudan: her düğümün kendi önbelleği vardır ve aynı içeriği üç kez ayrı ayrı ister.
Bir içerik yenilendiğinde artık bir istek değil, üç istek uygulamaya iner. Kenar düğümü sayısı
bir ölçek kararıdır — daha çok düğüm, istemciye daha yakın yanıt demektir — ve uygulamaya inen
yükü **düğüm sayısı kadar çarpar**.

Bu, iki katmanlı önbelleğin varlık nedenidir. Üçüncü satır kaynak önbelleğini ekliyor: kenar
isabeti değişmiyor (bin sekiz yüz elli yedi), yüz otuz üç istek kaynak önbelleğinde karşılanıyor
ve uygulamaya inen istek **ona** düşüyor. Üç düğümün çoğalttığı isteğin neredeyse tamamını
kaynak önbelleği soğuruyor.

Sayılar birlikte okunduğunda kaynak önbelleğinin işi görünür oluyor: kenardan gelen isteğin
kendisini azaltmıyor, o isteğin **uygulamaya varmasını** engelliyor. Üçüncü satırın uygulama
yükü tek düğümlü birinci satırdan da düşüktür — kaynak önbelleği yalnız düğüm çoğalmasını değil,
tek düğümün kendi tazelik dolumlarını da soğuruyor.

#### Yayılma Penceresi

İkinci tablo başka bir soruyu ölçüyor. Bölge haritası değişti; yeni harita ne zaman görünür
olur?

Birinci satır varsayılan durumdur: geçersizleştirme yok, iki katman da kendi tazelik süresini
bekliyor. Pencere altmış artı üç yüz, yani **üç yüz altmış saniye**. İki tazeliğin toplanmasının
nedeni üst üste binmedir: kenar, kaynaktan bir kopya çektiğinde o kopya kaynakta üç yüz saniyeye
kadar beklemiş olabilir ve kenar onu altmış saniye daha tutar. Pencere boyunca değişen içeriğe
gelen dört yüz seksen istek eski haritayı alır.

İkinci satır tazelik ayarlarını kısaltıyor: altmış ve üç yüz yerine on ve altmış. Pencere yetmiş
saniyeye, eski yanıt alan istek doksan üçe iniyor. Bedeli tabloda görünmüyor ama ilk tablodan
okunabilir: tazelik kısaldıkça isabet düşer ve uygulamaya inen istek artar. Tazeliği kısaltmak
pencereyi kapatmanın **pahalı** yoludur.

Üçüncü satır kaynağa geçersizleştirme gönderiyor. Kaynak önbelleği hemen temizleniyor, kenar
kendi altmış saniyesini bekliyor: pencere altmış saniye, eski yanıt alan istek seksen. Üç yüz
altmıştan altmışa inen bir kazanç, kaynağa gönderilen tek bir mesajla elde ediliyor.

Dördüncü satır kaynağa geçersizleştirme gönderirken kenar tazeliğini ona indiriyor: pencere on
saniye. Beşinci satır geçersizleştirmeyi her katmana yayıyor: pencere en yavaş kenar düğümünün
gecikmesine, **on bir saniyeye** iniyor ve kenar tazeliği artık pencereyi hiç belirlemiyor.

Buradaki sıra önemlidir. Tazelik ayarını kısaltmak pencereyi kapatır ve isabeti düşürür;
geçersizleştirmeyi yaymak pencereyi kapatır ve isabete dokunmaz. Beşinci satır altmış saniyelik
kenar tazeliğiyle çalışıyor — yani birinci satırın isabet oranıyla — ve penceresi on bir saniye.

#### Yayının Kaçtığı Yer

Altıncı satır beşincinin kapatamadığını gösteriyor. Geçersizleştirme her katmana yayınlanıyor
ama bir kenar düğümü mesajı almıyor: ağ kesintisi, düğümün yeniden başlaması, kuyruğun taşması.
O düğümde pencere kenar tazeliğine geri dönüyor: **altmış saniye**.

Bu, geçersizleştirmenin getirdiği yeni yüzeydir. Tazelik süresi bir **üst sınır** verir ve hiçbir
şey yapılmasa da geçerlidir. Geçersizleştirme yayını üst sınır vermez; bir **umut** verir ve
umut tutmadığında sistem sessizce üst sınıra döner. Sistemin durumu iki düğümde on bir saniye,
bir düğümde altmış saniyedir ve dışarıdan bakan hiç kimse hangi düğüme düştüğünü bilmez.

Sonuç, tazeliğin geçersizleştirme yayınıyla birlikte **korunması** gerektiğidir. Yayın hızlı yolu
verir, tazelik geri düşüş sınırını verir. Tazeliği sonsuza çekip her şeyi yayına bağlamak, kaçan
tek bir mesajı süresiz eski içeriğe çevirir.

#### Paylaşılan Anahtar Yüzeyi

Son sütunlar dersin yüzey ölçümüdür. Varsayılan önbellek anahtarı yalnız yoldur ve
`/fatura/ozet` kişiye özeldir: her abone kendi fatura özetini alır.

İlk satırda yüz altmış dokuz istek **başka bir abonenin** fatura özetini aldı; beş abonenin
verisi başkalarına gitti. Üç düğümlü ikinci satırda sızan istek doksan beşe iniyor ama sızan
abone sayısı altıya çıkıyor — bölünme sızıntıyı azaltmıyor, dağıtıyor.

Üçüncü satır en keskin olanıdır. Kaynak önbelleği eklendiğinde sızan istek yüz yetmiş dokuza
çıkıyor ve sızan abone sayısı **ikiye** iniyor. Paylaşılan tek bir kaynak girdisi, iki abonenin
faturasını üç kenar düğümüne birden dağıtıyor. Kaynak önbelleği sızıntıyı yoğunlaştırıyor: daha
az kişinin verisi, daha çok kişiye.

Bu yüzeyin adı **paylaşılan anahtar yüzeyi**dir. Açılması için bir hata gerekmez; varsayılan
anahtarın yolu içermesi ve kimliği içermemesi yeter. Yanıtın kişiye özel olduğu bilgisi
uygulamadadır, önbellekte değildir ve iki katman da bu bilgiyi sormaz.

Dördüncü satır anahtara kimliği ekliyor: sızan istek sıfır, sızan abone sıfır. Uygulamaya inen
istek ondan yirmiye çıkıyor — altı ayrı abone için altı ayrı girdi tutulduğundan tazelik
dolumları çoğalıyor. On isteklik bir bedelle yüz yetmiş dokuz sızıntı kapandı.

Beşinci satır kişiye özel içeriği hiç saklamıyor. Sızıntı yine sıfır, ama uygulamaya inen istek
**iki yüz yirmi dokuza** çıkıyor. İki güvenli seçenek arasında yirmi kat fark var ve ikisi de
aynı yüzeyi kapatıyor. Anahtarı doğru kurmak, önbelleklemeyi kapatmaktan yirmi kat ucuzdur.

#### Önbelleğin Kendi Yüzeyi

İki katman uygulamanın yükünü elliden ona indirdi ve bunu yaparken dört yeni kalem getirdi.

Birincisi **saklanan yanıtın kendisidir**. Kenarda ve kaynakta artık üretilmiş yanıtlar durur;
bunlar diskte ya da bellekte bir yerdedir ve o yeri okuyabilen, uygulamanın verdiği yanıtları
kimlik doğrulamadan okur. İkincisi **geçersizleştirme kanalıdır**: bir mesaj gönderip bir girdiyi
silebilen bir uç, önceki derslerin saydığı yönetim ucu listesine iki kalem ekler — kenardaki bir
uç ve kaynaktaki bir uç. Bu uç kimliksizse, dışarıdan gönderilen bir geçersizleştirme akışı
bütün önbelleği boşaltabilir ve uygulamaya inen istek ondan iki bine çıkar.

Üçüncüsü **anahtar kuralının kendisidir**. Beşinci satırdan görüldüğü gibi kural bir
yapılandırma satırıdır ve yanlış yazıldığında hata vermez; yalnız başka bir abonenin yanıtını
döndürür. Dördüncüsü **tazelik ayarının ikiye bölünmüş olmasıdır**: pencerenin gerçek değeri iki
ayrı katmandaki iki ayrı sayıdan çıkar ve hiçbir katman tek başına o değeri bilmez.

Dört kalemin hiçbiri "önbellek açıldı" cümlesinde görünmez. Kursun kuralı burada da geçerlidir:
kapatılan yük, açılan yüzeyle birlikte yazılmadıkça karar savunulamaz. Uygulamaya inen isteği
kırk kalem azaltan bir adım, dört kalem açık yüzey ekliyorsa iki sayı da rapora aynı satırda
girmelidir.

#### Özet

- Kenarı üç düğüme bölmek kenar isabetini bin dokuz yüz elliden bin sekiz yüz elli yediye
  indirdi ve uygulamaya inen isteği elliden yüz kırk üçe çıkardı; düğüm sayısı uygulama yükünü
  çarpar.
- Kaynak önbelleği yüz otuz üç isteği karşılayarak uygulamaya inen isteği ona indirdi — tek
  düğümlü düzenden de düşük; kaynak katmanının işi kenarın çoğalttığı isteği soğurmaktır.
- Geçersizleştirme yokken pencere iki tazeliğin toplamıdır: üç yüz altmış saniye ve dört yüz
  seksen eski yanıt. Kaynağa geçersizleştirme pencereyi altmışa, her katmana yayın on bir
  saniyeye indirdi.
- Tazeliği kısaltmak pencereyi kapatır ve isabeti düşürür; geçersizleştirmeyi yaymak pencereyi
  kapatır ve isabete dokunmaz — ama yayını kaçıran bir düğümde pencere sessizce tazelik süresine
  geri döner.
- Varsayılan anahtar yalnız yolu içerdiği için yüz yetmiş dokuz istek başka abonenin fatura
  özetini aldı; kaynak önbelleği sızıntıyı yoğunlaştırdı — iki abonenin verisi yüz yetmiş dokuz
  isteğe gitti.
- Anahtara kimliği eklemek sızıntıyı sıfırladı ve uygulama yükünü ona değil yirmiye çıkardı;
  kişiye özel içeriği hiç saklamamak da sızıntıyı sıfırladı ama yükü iki yüz yirmi dokuza çıkardı.

#### Sonraki Adım

Bu ders trafiğe kenarda ve kaynakta iki kural koydu: neyin saklanacağı ve ne kadar tazelikle.
Kuralların ikisi de **isteğin yolunda** durdu ve dışarıdan gelen trafiğe uygulandı.

Servisler birbirine de istek gönderir. Doğrulayıcı faturalamaya, faturalama iş emrine, iş emri
bildirim geçidine bağlanır ve bu trafiğin hiçbiri kenar vekilden geçmez. Zaman aşımı, yeniden
deneme, hangi servisin hangisini çağırabileceği — bu kurallar bugün her servisin kendi kodunda
duruyor. Aynı kurallar her servisin yanına konan bir vekile taşınabilir. Sonraki ders iki
yerleşimi aynı kural değişikliği üzerinde karşılaştırır: kural değiştiğinde kaç servise
dokunulur, her isteğe kaç atlama ve kaç milisaniye eklenir, yan araba vekilinin kendisi ne
tüketir ve hangi yeni yüzeyi getirir. Üç servisli bir sistemde bedelin kazançtan büyük olduğu
nokta sayıyla gösterilir.

### Servis Ağı

Source: https://academia.sh/tr/kurslar/sunucu-ve-sertlestirme/servis-agi

Aynı trafik kurallarının uygulama kodunda ve yan araba vekilinde uygulanmasının karşılaştırılması: kural değişikliğinde dokunulan servis sayısı ve yıllık iş kalemi, gerçek bir yan araba atlamasının ölçülmesi, her isteğe eklenen atlama ile gecikme, yan arabaların bellek ve çekirdek tüketimi, getirdikleri yeni yüzey kalemi ve üç servisli bir sistemde bedelin kazançtan büyük olduğu başabaş noktası.

Önceki ders trafiğe kenarda ve kaynakta iki kural koydu. İkisi de isteğin yolunda durdu ve
dışarıdan gelen trafiğe uygulandı.

Servisler birbirine de istek gönderir. Kurgu ölçüm ağında doğrulayıcı faturalamaya, faturalama
iş emrine, iş emri bildirim geçidine bağlanır ve bu trafiğin hiçbiri kenar vekilden geçmez. Bu
çağrıların da kuralları vardır: zaman aşımı kaç saniye, kaç kez yeniden denenir, hangi servis
hangisini çağırabilir, çağrı şifreli mi taşınır.

Bu kurallar iki yere konabilir. **Uygulama kodunda**: her servis kendi istemcisini yapılandırır.
**Yan araba vekilinde**: her servis örneğinin yanına bir vekil konur, bütün giden ve gelen trafik
o vekilden geçer, kurallar vekile yazılır. İkinci yerleşimin adı **servis ağı**dır.

Bu ders iki yerleşimi aynı kural değişikliği üzerinde karşılaştırır ve tek soruyu sorar: yan
arabanın kazandırdığı, ödettiğinden büyük mü.

- **WS31.** Her servisin iki örneği vardır ve her örneğe bir yan araba düşer.
- **WS32.** "İş kalemi" kurgu bir birimdir: bir değişiklik, bir gözden geçirme ya da bir yayın.
  Kod yerleşiminde bir kural değişikliği servis başına üç iş kalemi, ağ yerleşiminde toplam iki
  iş kalemi tutar.
- **WS33.** Ağ yerleşiminin yıllık sabit bedeli kırk iş kalemidir (denetim düzlemi) ve her yan
  araba örneği yılda iki iş kalemi ekler (sürüm yükseltme, kimlik dönüşü). Yılda altı trafik
  kuralı değişir.
- **WS34.** Bir yan araba örneği altmış dört megabayt bellek ve onda bir çekirdek tüketir; bir
  atlamanın eklediği gecikme kurguda kırk mikrosaniyenin on katı, yani `0,4` milisaniyedir.
- **WS35.** Gerçek ölçüm bloğu süre basmaz: beklenen atlama ve bağlantı sayısı girdiden
  türetilerek yazılır, ölçülen ek gecikme yalnız sıfır ile elli milisaniye arasında olup
  olmadığına bakılarak `evet` ya da `hayir` yazılır.
- **WS36.** Yeni yüzey kalemi sayımı şudur: her yan araba örneği için bir yönetim ucu ve bir
  kimlik, artı denetim düzlemi ile kural deposu.

#### Bir Atlamanın Kendisi

Yan arabanın her isteğe eklediği şey önce bir atlamadır. Aşağıdaki blok bunu modellemez,
gerçekten koşar: bir uygulama sunucusu ve önüne konan bir yan araba vekili kurulur, iki yol da
aynı sayıda istekle sınanır.

```js
// yanaraba/atlama.mjs — gercek olcum: yan araba vekilinin bir istege ekledigi atlama.
// Sunucular bu dosyada kurulur, olcum bitince kapatilir. Ham sure ciktiya basilmaz:
// beklenen degerler girdiden turetilir, olculen ek gecikme yalniz bant denetiminden gecer.
import { createServer, request } from "node:http";

const ISTEK = 200, ISINMA = 50, BANT = [0, 50];            // bant: milisaniye
const UYG = 8951, YAN = 8950;
const uygulama = createServer((i, y) => { y.sendDate = false; y.end("olcum"); }).listen(UYG, "127.0.0.1");
const yanAraba = createServer((di, dy) => {                // tek isi: istegi bir atlama oteye tasimak
  dy.sendDate = false;
  const ii = request({ port: UYG, path: di.url, method: di.method, headers: di.headers },
    (iy) => { dy.writeHead(iy.statusCode, iy.headers); iy.pipe(dy); });
  ii.on("error", () => dy.writeHead(502).end("kesildi"));
  di.pipe(ii);
}).listen(YAN, "127.0.0.1");

const cagir = (port) => new Promise((coz) => {
  request({ port, path: "/olcum", agent: false }, (y) => { y.resume(); y.on("end", coz); }).end();
});
async function olc(port, n) {                              // istek basina ms
  const b = process.hrtime.bigint();
  for (let i = 0; i < n; i += 1) await cagir(port);
  return Number(process.hrtime.bigint() - b) / 1e6 / n;
}

await olc(UYG, ISINMA); await olc(YAN, ISINMA);            // isinma: iki yol da bir kez kosar
const ek = (await olc(YAN, ISTEK)) - (await olc(UYG, ISTEK));
uygulama.close(); yanAraba.close();

console.log(`istek / yol                       ${ISTEK}`);
console.log(`beklenen atlama                   dogrudan 1, yan arabali 2   (fark 1)`);
console.log(`beklenen baglanti / istek         dogrudan 1, yan arabali 2   (fark 1)`);
console.log(`ek gecikme ${BANT[0]}-${BANT[1]} ms bandinda        ${ek >= BANT[0] && ek <= BANT[1] ? "evet" : "hayir"}`);
```

```
istek / yol                       200
beklenen atlama                   dogrudan 1, yan arabali 2   (fark 1)
beklenen baglanti / istek         dogrudan 1, yan arabali 2   (fark 1)
ek gecikme 0-50 ms bandinda        evet
```

Ölçülen süre çıktıya girmez, çünkü makineden makineye değişir ve karşılaştırılamaz. Girdiden
türeyen iki sayı değişmez: yan arabalı yolda her istek **iki atlama** ve **iki bağlantı**
harcar, doğrudan yolda bir. Bu, tek yönlü bir çağrı içindir; iki servis arasındaki bir çağrıda
her iki uçta da yan araba durduğu için atlama sayısı ikiye çıkar.

#### Kural Değiştiğinde Dokunulan

İkinci blok yerleşimlerin defterini tutuyor.

```js
// yanaraba/bedel.mjs — model: ayni trafik kurallarinin iki yerde uygulanmasi. "Is kalemi"
// kurgu bir birimdir (bir degisiklik, bir gozden gecirme, bir yayin); butun sayilar
// asagidaki sabitlerden turer. Urun yoktur, yerlesim vardir.
const ORNEK = 2;            // her servisin ornek sayisi
const KOD_KALEM = 3;        // kod yerlesiminde servis basina: degisiklik + gozden gecirme + yayin
const AG_KALEM = 2;         // ag yerlesiminde kural basina toplam: yapilandirma + dagitim denetimi
const DENETIM = 40;         // denetim duzleminin yillik sabit is kalemi
const YAN_BAKIM = 2;        // yan araba ornegi basina yillik: surum yukseltme + kimlik donusu
const KURAL = 6;            // yilda degistirilen trafik kurali sayisi
const ATLAMA_MS = 0.4;      // kurgu: bir yan araba atlamasinin ekledigi gecikme
const BELLEK = 64, CEKIRDEK = 0.1;   // yan araba ornegi basina

const SERVIS = [3, 5, 8, 20, 40];
const kodIs = (n) => KURAL * n * KOD_KALEM;
const agIs = (n) => KURAL * AG_KALEM + DENETIM + n * ORNEK * YAN_BAKIM;

const E = [8, 8, 17, 14, 15, 13, 12, 11, 10];
const yaz = (h) => h.map((d, i) => String(d)[i ? "padStart" : "padEnd"](E[i])).join("");
console.log(yaz(["servis", "ornek", "kodda dokunulan", "kodda is/yil", "agda dokunulan",
  "agda is/yil", "ag sabiti", "ag is/yil", "kazanan"]));
for (const n of SERVIS)
  console.log(yaz([n, n * ORNEK, n, kodIs(n), 0, KURAL * AG_KALEM,
    DENETIM + n * ORNEK * YAN_BAKIM, agIs(n), kodIs(n) < agIs(n) ? "kod" : "ag"]));
const basabas = [...Array(60).keys()].map((i) => i + 1).find((n) => kodIs(n) >= agIs(n));
console.log(`basabas servis sayisi: ${basabas}  (bu sayinin altinda kod yerlesimi ucuzdur)`);

// Istek basina bedel ve yan arabanin getirdigi yeni yuzey.
const P = [8, 16, 12, 18, 16, 12, 20];
const yaz2 = (h) => h.map((d, i) => String(d)[i ? "padStart" : "padEnd"](P[i])).join("");
console.log("\n" + yaz2(["servis", "ic cagri/istek", "ek atlama", "ek gecikme(ms)",
  "yan araba MB", "cekirdek", "yeni yuzey kalemi"]));
for (const n of SERVIS) {
  const cagri = Math.min(n - 1, 4), atlama = 2 * (cagri + 1), ornek = n * ORNEK;
  console.log(yaz2([n, cagri, atlama, (atlama * ATLAMA_MS).toFixed(1), ornek * BELLEK,
    (ornek * CEKIRDEK).toFixed(1), ornek * 2 + 2]));
}
```

```
servis     ornek  kodda dokunulan  kodda is/yil agda dokunulan  agda is/yil   ag sabiti  ag is/yil   kazanan
3              6                3            54              0           12          52         64       kod
5             10                5            90              0           12          60         72        ag
8             16                8           144              0           12          72         84        ag
20            40               20           360              0           12         120        132        ag
40            80               40           720              0           12         200        212        ag
basabas servis sayisi: 4  (bu sayinin altinda kod yerlesimi ucuzdur)

servis    ic cagri/istek   ek atlama    ek gecikme(ms)    yan araba MB    cekirdek   yeni yuzey kalemi
3                      2           6               2.4             384         0.6                  14
5                      4          10               4.0             640         1.0                  22
8                      4          10               4.0            1024         1.6                  34
20                     4          10               4.0            2560         4.0                  82
40                     4          10               4.0            5120         8.0                 162
```

#### Dokunulan Servis Sayısı

Birinci tablonun asıl sütunu üçüncüsüdür. Bir trafik kuralı — diyelim zaman aşımı beş saniyeden
iki saniyeye indirilecek — kod yerleşiminde **her servise ayrı ayrı** dokunur. Üç servisli
sistemde üç, kırk servisli sistemde kırk. Her dokunuş bir değişiklik, bir gözden geçirme ve bir
yayındır; kırk servislik bir sistemde tek bir kural değişikliği yüz yirmi iş kalemi eder ve
yayınlar birbirinden bağımsız olduğu için kuralın **her yerde aynı anda geçerli olduğu bir an
yoktur**.

Ağ yerleşiminde dokunulan servis sayısı **sıfır**dır. Kural bir kez yazılır, yan arabalara
dağıtılır ve uygulama kodu değişmez. Kural değişikliği başına iki iş kalemi, servis sayısından
bağımsızdır. Kırk servisli sistemde yıllık yedi yüz yirmi iş kalemi, iki yüz on ikiye iner.

Bu tek sütuna bakıldığında servis ağı her ölçekte kazanır. Öteki sütunlar bunu bozar.

#### Üç Servis: Bedel Kazançtan Büyük

İlk satır ölçünün kırıldığı yerdir. Üç servisli sistemde kod yerleşimi yılda elli dört iş
kalemi, ağ yerleşimi altmış dört. Ağ **daha pahalı**dır ve nedeni sabit bedeldir: denetim
düzleminin kırk iş kalemi, üç servisin toplam kural değişikliği maliyetinden büyüktür.

Başabaş servis sayısı dörttür. Bunun altında kural değişikliğinden kazanılan iş, denetim
düzleminin bakımından azdır.

İkinci tablo aynı satırı öteki yönden okuyor. Üç servisli sistemde yan arabalar üç yüz seksen
dört megabayt bellek ve onda altı çekirdek tüketiyor, her isteğe altı atlama ve iki virgül dört
milisaniye ekliyor ve **on dört yeni yüzey kalemi** getiriyor. Bu üç bedelin hiçbiri iş kalemi
defterinde görünmez.

Servis ağının kazandırmadığı durum budur ve nadir değildir: üç servisli sistemler çoğunluktadır.
Kararın "servis ağı iyi bir uygulamadır" cümlesiyle verildiği yerlerde ödenen bedel, kazanılan
altı iş kaleminin karşılığı değil, eksi on iş kalemi artı on dört yüzey kalemidir.

#### Merkezî Kuralın Yanlış Kapattığı

`agda dokunulan` sütunundaki sıfır bir koşula bağlıdır: kuralın **her servise aynı biçimde**
uyması. Bu koşul çoğu kuralda tutmaz.

Zaman aşımını iki saniyeye indiren kural otuz sekiz servis için doğrudur; gecelik toplu işi
çağıran servis için değildir, çünkü o çağrı zaten yavaştır. Merkezde tek satırla yazılan kural,
o servisin bütün çağrılarını iki saniyede keser. Kod yerleşiminde bu sorun doğmaz — kural zaten
her serviste ayrı yazılıdır ve o servis kendi değerini korur. Merkezî yerleşimde çözüm bir
istisnadır ve istisna, kuralın kendisi kadar iş kalemi tutar: modelin sabitlerine göre her
istisna yılda iki iş kalemi, tıpkı bir kural gibi.

Bu, kursun "yanlış kapatma" sütununun servis ağındaki karşılığıdır. Kural değişikliğinde
dokunulan servis sayısını sıfıra indiren adım, kuralın **hangi servise ne kadar uyduğu**
sorusunu ortadan kaldırmaz; o soruyu kod tabanından yapılandırma dosyasına taşır ve orada
görünürlüğü azalır. Bir servisin kendi istisnasına kendi kodunda sahip olması bir gözden
geçirmede görülür; merkezî kural kümesindeki bir istisna, kümeyi okuyan kişinin dikkatine
bağlıdır.

Sayı olarak sonuç şudur: istisna sayısı arttıkça ağ tarafının yıllık iş kalemi kural sayısı gibi
büyür ve başabaş servis sayısı dörtten yukarı kayar. On istisnalı bir sistemde ağ tarafı yılda
yirmi iş kalemi daha eder ve başabaş noktası altı servise çıkar.

#### İstek Başına Ödenen

İkinci tablonun ortası ölçek büyüdükçe **doymuyor**. İç çağrı sayısı dörtte duruyor — zincir
uzunluğu servis sayısıyla sınırsız artmaz — ve ek atlama onda, ek gecikme dört milisaniyede
sabitleniyor. Bu, servis ağının iyi haberidir: istek başına bedel ölçekle büyümüyor.

Dört milisaniye küçük görünür. Ölçüm ağının gecelik toplu işi her koşumda yüz binlerce iç çağrı
yapar ve orada dört milisaniye saatlere döner. Kenar önbelleğinden geçen bir pano isteğinde ise
hiç görünmez. Ek gecikmenin anlamı çağrı sayısıyla belirlenir, sayının kendisiyle değil.

Kaynak tüketimi ise ölçekle **doğrusal** büyüyor. Kırk servisli sistemde yan arabalar beş
gigabayt bellek ve sekiz çekirdek tutuyor. Bu, sekiz uygulama örneğinin kaynağıdır; servis ağı
çalışması için sistemin yüzde on beş ila yirmisi kadar bir donanımı kendine ayırır ve bu satır
hiçbir kural tartışmasında geçmez.

#### Yan Arabanın Kendi Yüzeyi

Son sütun kursun ölçü birimidir. Her yan araba örneği iki kalem getirir.

Birincisi **yönetim ucudur**. Yan araba yapılandırmasını gösterir, ölçümlerini döker, kendini
yeniden yükler. Bu uç uygulamanın yanında, aynı ağ ad alanında dinler; ilk dersin saydığı
"yönetim ucu" kalemi artık makine başına değil, **örnek başına** vardır. Kırk servisli sistemde
seksen yönetim ucu.

İkincisi **kimliktir**. Yan arabalar birbirine şifreli konuşur ve her birinin bir sertifikası
olur. Bu, üçüncü dersin "uygulamada sonlandırma" satırının en uç hâlidir: sertifika artık altı
değil, seksen yerde durur. Dördüncü dersin otomasyonu burada zorunlu hâle gelir — seksen
sertifikayı elle yenilemek dokuz kalemde değil, seksen kalemde unutulur.

Üçüncüsü tek kalemdir ve en ağırıdır: **denetim düzlemi**. Bütün yan arabaların kuralını dağıtan
bileşen, her servise yazma yetkisi olan tek bir yerdir. Kural deposuyla birlikte iki kalem eder
ve ikisi de kapatılamaz — servis ağının varlık nedeni onlardır.

On dört kalemden kırk servisli sistemde yüz altmış ikiye çıkan bu sayım, ilk dersin tek bir
makinede saydığı on yedi kalemin yanına konmalıdır. Servis ağı trafik kurallarını tek yere
topladı ve yönetim uçlarını her yere dağıttı.

#### Özet

- Kural değişikliğinde kod yerleşimi her servise dokunur (üç servis üç, kırk servis kırk), ağ
  yerleşimi hiçbirine; kırk servislik sistemde yıllık iş kalemi yedi yüz yirmiden iki yüz on
  ikiye iner.
- Gerçek ölçüm yan arabalı yolun her isteğe bir atlama ve bir bağlantı eklediğini doğruladı;
  ölçülen ek gecikme sıfır ile elli milisaniye bandının içinde kaldı ve ham süre basılmadı.
- Üç servisli sistemde ağ yerleşimi kod yerleşiminden pahalıdır: altmış dörde karşı elli dört iş
  kalemi. Başabaş servis sayısı dörttür ve denetim düzleminin sabit kırk iş kalemi bu eşiği belirler.
- İstek başına bedel ölçekle doymuyor — on atlama, dört milisaniye — ama kaynak tüketimi doğrusal
  büyüyor: kırk serviste beş gigabayt bellek ve sekiz çekirdek.
- Yan araba her örneğe iki yüzey kalemi ekler (yönetim ucu ve kimlik); üç serviste on dört,
  kırk serviste yüz altmış iki kalem. Denetim düzlemi ile kural deposu kapatılamaz kalemlerdir.

#### Sonraki Adım

Bu konu isteğin yolunu baştan sona kurdu. Yol üç rolden geçiyor, vekil zincirinden geçerken
kaybolan dört bilgi aktarılıyor, şifre bir noktada sonlanıyor ve sertifikası kendini
tazeliyor, yanıt iki katmanda saklanıyor ve servisler arası trafik tek bir kural kümesine
bağlanıyor. Bütün bu ölçümler bir şeyi verili aldı.

İstemci bir yere bağlandı. Bağlandığı yerin **bir adı** vardı ve o ad bir adrese çözüldü. İkinci
derste `olcum.ornek.gecersiz` diye bir ad kullanıldı; üçüncü derste sertifika o ad için düzenlendi
sayıldı; beşinci derste bir kenar düğümüne düşen istemcinin oraya nasıl düştüğü hiç sorulmadı. Adın
kendisi, o adın hangi adresi gösterdiği, değiştiğinde eskisinin ne kadar süre geçerli kaldığı ve o
adı kimin adına kaydettiği bu konuda bir kez bile ölçülmedi. Sonraki konu adın kendisini ele alır:
kayıt kümesinin varsayılan hâli, yaşam süresinin bir karar olarak sonuçları ve adı taşıyan kaydın
kime ait olduğu.

## Alan Adı ve E-posta Kayıtları

Adın ve gönderenin doğrulanması: bölge dosyası, kayıt türleri ve yaşam süresinin değişiklik penceresine etkisi, gönderim politikası ve imza kayıtlarıyla gönderen doğrulama, uyumsuz iletiler için politika bildiriminin aşamalı sıkılaştırılması ve teslim sorunlarında itibarın ölçülmesi.

### DNS Yönetimi

Source: https://academia.sh/tr/kurslar/sunucu-ve-sertlestirme/dns-yonetimi

Bölge dosyasını bir envanter olarak saymak, öksüz kayıtların bıraktığı devralma yüzeyi ve yaşam süresini bir karar olarak ölçmek: yayılma penceresi, geri alma hızı ve sorgu yükü.

İsteğin yolu kuruldu: bağlantı bir noktada sonlandırıldı, başlıklar arkaya aktarıldı, yanıt
önbellekten döndü. Bütün bu zincir boyunca hiç sorulmayan bir soru var — istek **hangi ada**
geldi ve o ad kime ait?

Ad, makineden önce gelir. Bir istemci adresi değil adı bilir; adresi bir başkasından öğrenir ve
öğrendiği yanıtı bir süre saklar. Bu iki cümle, alan adı kayıtlarını bir yapılandırma ayrıntısı
olmaktan çıkarıp ölçülecek bir yüzey haline getirir. Bu ders o yüzeyi iki eksende sayar: bölge
dosyası bir **envanterdir** ve envanterin gerçeklikten kayması sayılabilir bir açıklık bırakır;
**yaşam süresi** ise kurulumdan kalma bir varsayılan değil, üç değeri aynı anda belirleyen bir
karardır.

Kayıt türlerinin ne olduğu — adres, takma ad, posta, ad sunucusu, metin — Bilgisayar Ağları
kursunda kuruldu. Burada türler adıyla anılır, yeniden tanımlanmaz; ölçülen şey türün tanımı
değil, kaydın **bakım durumu** ve **süresidir**.

#### Bölge Bir Envanterdir

Bir bölge, yetkili sunucunun sorumlu olduğu kayıtlar bütünüdür. İşletme tarafında ise bir şeyden
daha fazlasıdır: bölgede yazılı her hedef, bir zamanlar var olduğu varsayılan bir şeye işaret
eder. Sistemler taşınır, denemeler kapatılır, dış hizmetlerle sözleşme biter — kayıt kalır.

Aşağıdaki program bölgesel ölçüm ağının bölgesini **model olarak** kurar. Ağ kurgudur: su sayacı
okumalarını toplayan bir toplayıcı, bir doğrulayıcı, faturalama ve iş emri servisleri. Model iki
listeyi ayrı tutar; bölgede yazan hedefler ve gerçekten ayakta olan adresler.

**AK1.** Bölge tek bir yetkili küme altındadır ve kayıtlar elle yönetilir.
**AK2.** Canlı envanter bölgeden bağımsız tutulur; iki listeyi eşleyen bir süreç yoktur.

```javascript
// Model: bölgesel ölçüm ağının kurgu bölgesi. Gerçek bir bölge değil; kayıtların
// ad, tür, yaşam süresi ve hedef alanlarını taşıyan bir veri yapısı.
const BOLGE = [
  { ad: 'olcumag.gecersiz',             tur: 'NS',    ttl: 86400, hedef: 'ad1.olcumag.gecersiz' },
  { ad: 'olcumag.gecersiz',             tur: 'NS',    ttl: 86400, hedef: 'ad2.olcumag.gecersiz' },
  { ad: 'olcumag.gecersiz',             tur: 'A',     ttl: 3600,  hedef: '198.51.100.10' },
  { ad: 'olcumag.gecersiz',             tur: 'MX',    ttl: 3600,  hedef: 'posta.olcumag.gecersiz' },
  { ad: 'olcumag.gecersiz',             tur: 'TXT',   ttl: 3600,  hedef: '(metin)' },
  { ad: 'www.olcumag.gecersiz',         tur: 'CNAME', ttl: 3600,  hedef: 'olcumag.gecersiz' },
  { ad: 'posta.olcumag.gecersiz',       tur: 'A',     ttl: 3600,  hedef: '198.51.100.20' },
  { ad: 'ad1.olcumag.gecersiz',         tur: 'A',     ttl: 86400, hedef: '198.51.100.2' },
  { ad: 'ad2.olcumag.gecersiz',         tur: 'A',     ttl: 86400, hedef: '198.51.100.3' },
  { ad: 'toplayici.olcumag.gecersiz',   tur: 'A',     ttl: 300,   hedef: '198.51.100.11' },
  { ad: 'dogrulayici.olcumag.gecersiz', tur: 'A',     ttl: 300,   hedef: '198.51.100.12' },
  { ad: 'faturalama.olcumag.gecersiz',  tur: 'A',     ttl: 3600,  hedef: '198.51.100.13' },
  { ad: 'isemri.olcumag.gecersiz',      tur: 'A',     ttl: 3600,  hedef: '198.51.100.14' },
  { ad: 'saha.olcumag.gecersiz',        tur: 'CNAME', ttl: 300,   hedef: 'isemri.olcumag.gecersiz' },
  { ad: 'pano.olcumag.gecersiz',        tur: 'CNAME', ttl: 3600,  hedef: 'eski-pano.olcumag.gecersiz' },
  { ad: 'prova.olcumag.gecersiz',       tur: 'A',     ttl: 86400, hedef: '198.51.100.71' },
  { ad: 'deneme.olcumag.gecersiz',      tur: 'A',     ttl: 86400, hedef: '198.51.100.72' },
  { ad: 'rapor.olcumag.gecersiz',       tur: 'CNAME', ttl: 3600,  hedef: 'gecici.disarisi.gecersiz' },
];

// Canlı envanter: şu an gerçekten ayakta olan adresler.
const CANLI_ADRES = new Set([
  '198.51.100.2', '198.51.100.3', '198.51.100.10', '198.51.100.11',
  '198.51.100.12', '198.51.100.13', '198.51.100.14', '198.51.100.20',
]);
const ICBOLGE = 'olcumag.gecersiz';

function cozumle(ad, derinlik = 0) {
  if (derinlik > 8) return { durum: 'dongu' };
  if (!ad.endsWith(ICBOLGE)) return { durum: 'bolge-disi' };
  const adres = BOLGE.find((k) => k.ad === ad && k.tur === 'A');
  if (adres) {
    return CANLI_ADRES.has(adres.hedef)
      ? { durum: 'canli', adres: adres.hedef }
      : { durum: 'olu-adres', adres: adres.hedef };
  }
  const takma = BOLGE.find((k) => k.ad === ad && k.tur === 'CNAME');
  if (takma) return cozumle(takma.hedef, derinlik + 1);
  return { durum: 'kayit-yok' };
}

const turDagilimi = {};
const ttlDagilimi = {};
for (const k of BOLGE) {
  turDagilimi[k.tur] = (turDagilimi[k.tur] || 0) + 1;
  ttlDagilimi[k.ttl] = (ttlDagilimi[k.ttl] || 0) + 1;
}
console.log('toplam kayit:', BOLGE.length);
console.log('gorunur ad  :', new Set(BOLGE.map((k) => k.ad)).size);
console.log('tur dagilimi:', Object.entries(turDagilimi).map(([t, n]) => `${t}=${n}`).join(' '));
console.log('ttl dagilimi:', Object.keys(ttlDagilimi).map(Number).sort((a, b) => a - b)
  .map((t) => `${t}s=${ttlDagilimi[t]}`).join(' '));

const hedefli = BOLGE.filter((k) => k.tur !== 'TXT');
const oksuz = [];
for (const k of hedefli) {
  const s = /^\d/.test(k.hedef)
    ? (CANLI_ADRES.has(k.hedef) ? { durum: 'canli' } : { durum: 'olu-adres' })
    : cozumle(k.hedef);
  if (s.durum !== 'canli') oksuz.push({ ...k, durum: s.durum });
}

console.log('\noksuz kayit:', oksuz.length, '/', hedefli.length);
for (const k of oksuz) {
  console.log(`  ${k.ad.padEnd(26)} ${k.tur.padEnd(5)} -> ${k.hedef.padEnd(26)} ${k.durum}`);
}
const devralinabilir = oksuz.filter((k) => k.durum === 'kayit-yok' || k.durum === 'bolge-disi');
console.log('\nbaskasinin talep edebilecegi bos hedef:', devralinabilir.length);
console.log('bu hedeflerden bolge disinda olan       :', oksuz.filter((k) => k.durum === 'bolge-disi').length);
```

```
toplam kayit: 18
gorunur ad  : 14
tur dagilimi: NS=2 A=10 MX=1 TXT=1 CNAME=4
ttl dagilimi: 300s=3 3600s=9 86400s=6

oksuz kayit: 4 / 17
  pano.olcumag.gecersiz      CNAME -> eski-pano.olcumag.gecersiz kayit-yok
  prova.olcumag.gecersiz     A     -> 198.51.100.71              olu-adres
  deneme.olcumag.gecersiz    A     -> 198.51.100.72              olu-adres
  rapor.olcumag.gecersiz     CNAME -> gecici.disarisi.gecersiz   bolge-disi

baskasinin talep edebilecegi bos hedef: 2
bu hedeflerden bolge disinda olan       : 1
```

Varsayılanın bıraktığı ilk kalem burada: on yedi hedefli kaydın **dördü** artık var olmayan bir
şeyi gösteriyor. İki tanesi ölü adrese işaret ediyor; bunlar yalnızca gürültü, çözümleme sonunda
bağlantı kurulamaz. Diğer ikisi farklıdır ve **öksüz kayıt** adını asıl bunlar hak eder: kayıt
boş bir **ada** işaret eder, o ad da kimseye ait değildir. Adı kim önce alırsa, `olcumag.gecersiz`
altındaki bir alt ad onun sunduğu içeriği göstermeye başlar. Bu, kaydın **devralınmasıdır**;
tarayıcı açısından içerik hâlâ ölçüm ağının adı altındadır. Bölge dışına işaret eden kayıt daha
ağırdır, çünkü o adı almak için ölçüm ağının hiçbir sistemine dokunmak gerekmez.

Bölgenin kendisinin ikinci bir yüzeyi de sayıda görünüyor: **on dört görünür ad**. Bölgede yazılı
her ad, ağın iç yapısını okunabilir kılar — hangi servisler var, hangi ortam ayrı duruyor. Kayıt
adları bir keşif kaynağıdır ve bu kalem kapatılamaz; bölge yayınlanmak için vardır.

#### Yaşam Süresi Bir Karardır

Her kaydın bir yaşam süresi vardır ve kurulum sırasında çoğu kayda dokunulmaz. Oysa bu tek sayı
üç ayrı şeyi birden belirler: bir değişikliğin **yayılma penceresi** (eski yanıt ne kadar
dolaşımda kalır), hatalı bir değişikliğin **geri alma hızı** ve yetkili sunucuya düşen **sorgu
yükü**. Üçü aynı yönde iyileşmez; süre düşürüldüğünde ilk ikisi kazanır, üçüncüsü kaybeder.

**AK3.** Kaydı 240 çözümleyici önbelleği sürekli talep eder; değişiklik anında her önbellekteki
kopyanın yaşı süre içinde düzgün dağılmıştır.
**AK4.** Yetkili sunucuya düşen yük yalnız önbellek yenilemesinden gelir.

```javascript
// Model: yaşam süresi taraması. Değişiklik anında her önbellekteki kopyanın yaşı
// [0, ttl) aralığındadır; kalan süre boyunca eski yanıt dolaşımda kalır.
const ONBELLEK = 240;          // kurgu çözümleyici önbelleği sayısı
const TOHUM = 4242;            // üreteç tohumu görünürdür

function uretec(tohum) {
  let x = tohum % 2147483647;
  return () => { x = (x * 48271) % 2147483647; return (x - 1) / 2147483646; };
}

function pencere(ttl) {
  const rast = uretec(TOHUM);
  const kalan = [];
  for (let i = 0; i < ONBELLEK; i++) kalan.push(Math.round(ttl * (1 - rast())));
  kalan.sort((a, b) => a - b);
  const y = (p) => kalan[Math.min(kalan.length - 1, Math.floor(kalan.length * p))];
  const eskiKalan = (t) => kalan.filter((k) => k > t).length;
  return {
    p50: y(0.50), p95: y(0.95), enUzun: kalan[kalan.length - 1],
    besDakika: eskiKalan(300), birSaat: eskiKalan(3600),
    gunlukSorgu: Math.round(ONBELLEK * (86400 / ttl)),
  };
}

const sure = (s) => (s < 90 ? `${s}s` : s < 5400 ? `${(s / 60).toFixed(0)}dk` : `${(s / 3600).toFixed(1)}sa`);

console.log('onbellek sayisi:', ONBELLEK, '| tohum:', TOHUM);
console.log('ttl      yayilma p50  yayilma p95  en uzun   5dk sonra eski  1sa sonra eski  gunluk sorgu');
for (const ttl of [60, 300, 900, 3600, 21600, 86400]) {
  const o = pencere(ttl);
  console.log(
    sure(ttl).padEnd(9) + sure(o.p50).padEnd(13) + sure(o.p95).padEnd(13) +
    sure(o.enUzun).padEnd(10) + `${o.besDakika}/${ONBELLEK}`.padEnd(16) +
    `${o.birSaat}/${ONBELLEK}`.padEnd(16) + String(o.gunlukSorgu),
  );
}
```

```
onbellek sayisi: 240 | tohum: 4242
ttl      yayilma p50  yayilma p95  en uzun   5dk sonra eski  1sa sonra eski  gunluk sorgu
60s      29s          55s          60s       0/240           0/240           345600
5dk      2dk          5dk          5dk       0/240           0/240           69120
15dk     7dk          14dk         15dk      156/240         0/240           23040
60dk     29dk         55dk         60dk      215/240         0/240           5760
6.0sa    2.9sa        5.5sa        6.0sa     233/240         202/240         960
24.0sa   11.6sa       22.0sa       23.9sa    239/240         230/240         240
```

Tabloda ödünleşim tek satırda okunur. Bir günlük sürede bir adres değişikliği yapıldığında
önbelleklerin **230'u bir saat sonra hâlâ eski yanıtı** verir; en uzun bekleyen yaklaşık yirmi
dört saat sürer. Beş dakikalık sürede aynı değişiklik beş dakikada tamamlanır, bedeli günde 240
yerine 69.120 sorgudur — **288 kat**. Aradaki değerler doğrusaldır: süre yarıya inince pencere
yarıya iner, sorgu iki katına çıkar.

Buradan çıkan kural sürenin kendisi değil, **kaydın değişme olasılığıdır**. Ad sunucusu kayıtları
yıllarca değişmez; onlarda uzun süre doğru karardır ve sorgu yükünü düşürür. Adres kayıtları
taşınmaya konudur. Modeldeki bölgede yaşam süresi dağılımı bu ayrımı hiç yansıtmıyor: dokuz kayıt
bir saatte, altı kayıt bir günde duruyor ve bunların arasında hem hiç değişmeyen ad sunucusu
kayıtları hem de taşınabilir deneme adresleri var.

#### Planlı Değişiklikten Önce

Yaşam süresi bir değişiklikten **önce** düşürülür. Bunun neden işe yaradığı ve neden yarım
yapıldığında işe yaramadığı sayılabilir.

**AK5.** Saha isteği hızı saniyede 8'dir ve önbelleklere eşit dağılır.
**AK6.** Değişiklik anında yeni yanıt tüm yetkili sunuculardan aynı anda verilir; yetkili
sunucular arası kopyalama gecikmesi bu modelde sayılmaz.

```javascript
// Model: planlı bir adres değişikliğinden önce süreyi düşürmenin bedeli. Zaman
// ekseninde 0 anı değişiklik anıdır; onPencere, süreyi kaç saniye önce düşürdüğümüzdür.
const ONBELLEK = 240, TOHUM = 4242, ESKI_TTL = 3600, DUSUK_TTL = 300, ISTEK_HIZI = 8;

function uretec(tohum) {
  let x = tohum % 2147483647;
  return () => { x = (x * 48271) % 2147483647; return (x - 1) / 2147483646; };
}

function senaryo(ad, onPencere, ttlDusuruldu) {
  const rast = uretec(TOHUM);
  const kalanlar = [];
  for (let i = 0; i < ONBELLEK; i++) {
    let bitis = -onPencere + rast() * ESKI_TTL;
    while (bitis <= 0) bitis += ttlDusuruldu ? DUSUK_TTL : ESKI_TTL;
    kalanlar.push(Math.round(bitis));
  }
  kalanlar.sort((a, b) => a - b);
  const y = (p) => kalanlar[Math.floor(kalanlar.length * p)] ?? kalanlar[kalanlar.length - 1];
  return {
    ad, onPencere, p50: y(0.5), p95: y(0.95),
    yanlis: Math.round(kalanlar.reduce((a, b) => a + b, 0) * (ISTEK_HIZI / ONBELLEK)),
    ekstra: ttlDusuruldu ? Math.round(ONBELLEK * onPencere * (1 / DUSUK_TTL - 1 / ESKI_TTL)) : 0,
    geriAl: ttlDusuruldu ? DUSUK_TTL : ESKI_TTL,
  };
}

const sure = (s) => (s < 90 ? `${s}s` : s < 5400 ? `${Math.round(s / 60)}dk` : `${(s / 3600).toFixed(1)}sa`);
const senaryolar = [
  senaryo('sureye dokunulmadi', 0, false),
  senaryo('30dk once dusuruldu', 1800, true),
  senaryo('24sa once dusuruldu', 86400, true),
];

console.log('istek hizi:', ISTEK_HIZI, 'istek/sn | onbellek:', ONBELLEK, '| tohum:', TOHUM);
console.log('senaryo               on pencere  ekstra sorgu  yayilma p50  yayilma p95  yanlis yonlenen  geri alma');
for (const s of senaryolar) {
  console.log(
    s.ad.padEnd(22) + (s.onPencere ? sure(s.onPencere) : '-').padEnd(12) +
    (s.ekstra ? String(s.ekstra) : '-').padEnd(14) + sure(s.p50).padEnd(13) +
    sure(s.p95).padEnd(13) + String(s.yanlis).padEnd(17) + sure(s.geriAl),
  );
}

const unutulan = Math.round(ONBELLEK * 86400 * (1 / DUSUK_TTL - 1 / ESKI_TTL));
console.log('\nsure geri yukseltilmezse gunluk ekstra yetkili sorgu:', unutulan);
console.log('sure dusurulmesi unutulursa plansiz geri alma penceresi (p95):', sure(senaryolar[0].p95));
```

```
istek hizi: 8 istek/sn | onbellek: 240 | tohum: 4242
senaryo               on pencere  ekstra sorgu  yayilma p50  yayilma p95  yanlis yonlenen  geri alma
sureye dokunulmadi    -           -             32dk         57dk         14812            60dk
30dk once dusuruldu   30dk        1320          5dk          27dk         4292             5dk
24sa once dusuruldu   24.0sa      63360         2dk          5dk          1142             5dk

sure geri yukseltilmezse gunluk ekstra yetkili sorgu: 63360
sure dusurulmesi unutulursa plansiz geri alma penceresi (p95): 57dk
```

Ortadaki satır asıl derstir. Süre otuz dakika önce düşürüldüğünde işin **yarısı yapılmış olur**:
önbelleklerin bir bölümü bu otuz dakika içinde yenilenip kısa süreyi almıştır, geri kalanı hâlâ
bir saatlik kopyayı tutmaktadır. Sonuç, p50'de kazanç ama p95'te **yirmi yedi dakikalık** bir
kuyruktur. Kısa süre, ancak eski sürenin bir tam dönemi geçtikten sonra her yere yerleşir; ön
pencere eski süreden **kısa olursa** düşürme kâğıt üstünde kalır.

Bedel iki kalemdir. Yirmi dört saatlik ön pencere 63.360 fazladan yetkili sorgu getirir ve bu
sorgular değişiklik olsun olmasın ödenir. İkincisi daha sinsidir: süre değişiklikten sonra geri
yükseltilmezse aynı 63.360 sorgu **her gün** ödenmeye devam eder — ve kimse bunu bir olay olarak
görmez, çünkü bir şey bozulmaz.

Düşürmenin unutulmasının bedeli ise plansız durumda ortaya çıkar. Bir yanlış kayıt yayınlandığında
geri alma hızı, o an yürürlükte olan süredir: bir saatlik kayıtta yanlış adrese giden istek sayısı
**14.812**; beş dakikalık kayıtta **1.142**. Aradaki 13.670 istek, bir alan adı ayarının değil,
kimsenin vermediği bir kararın sonucudur.

#### Kapatmanın Getirdiği Yeni Yüzey

Her iki adımın da kendi yüzeyi var. Öksüz kayıt temizliği dört kalemi kapatır, ama `prova` ve
`deneme` adlarını hâlâ bir yerden çağıran bir iş varsa **iki meşru akışı** durdurur; bu yüzden
temizlik silmeden önce sorgu sayımı ister ve o sayım bölgede değil, çözümleyici günlüklerindedir.
Envanteri sürekli eşlemek için bölgeye yazabilen bir otomasyon kurulursa, ortaya **yeni bir
ayrıcalıklı kimlik** çıkar: bölgeye kayıt yazabilen, o adın yetkilisidir.

Süre düşürmenin yüzeyi de ölçülebilir. Beş dakikalık süre, yetkili sunucu erişilemez olduğunda
**beş dakikalık bir tampon** bırakır; bir günlük sürede aynı arıza saatlerce fark edilmezdi.
Yayılma penceresini kapatmak, yetkili sunucunun erişilebilirliğini kritik hale getirir.

#### Özet

- Bölge dosyası bir envanterdir; modeldeki on yedi hedefli kaydın dördü var olmayan bir hedefi
  gösteriyor ve ikisi boş bir **ada** işaret ettiği için devralınmaya açıktır.
- Bölgede yazılı on dört görünür ad bir keşif yüzeyidir ve bu kalem kapatılamaz; bölge
  yayınlanmak için vardır.
- Yaşam süresi tek başına üç şeyi belirler: yayılma penceresi, geri alma hızı ve sorgu yükü. Bir
  günden beş dakikaya inmek pencereyi 22 saatten 5 dakikaya çeker, sorguyu 288 katına çıkarır.
- Ön pencere eski süreden kısa olduğunda düşürme yarım kalır: otuz dakikalık ön pencerede p95
  hâlâ 27 dakikadır.
- Süreyi geri yükseltmeyi unutmak günde 63.360 fazladan sorgu, düşürmeyi unutmak ise plansız geri
  almada 14.812 yanlış yönlenen istek demektir.
- Kapatmanın yüzeyi vardır: envanter otomasyonu bölgeye yazma yetkisi olan yeni bir kimlik,
  kısa süre ise yetkili sunucu arızasına karşı yalnızca beş dakikalık tampon getirir.

#### Sonraki Adım

Bu ders adın **nereyi gösterdiğini** ölçtü. Aynı ad, gösterdiği yerin dışında bir iş daha yapar:
o adın altından **ileti gönderilir**. Bölgesel ölçüm ağı saha ekiplerine bildirim e-postaları
yolluyor ve bu iletiler `olcumag.gecersiz` adını taşıyor. Adı taşıyan iletinin gerçekten o addan
çıktığını hiçbir şey söylemiyor — varsayılan durumda o adın adına ileti göndermek için o ada
sahip olmak gerekmez. Sonraki ders gönderen doğrulamasını bir yüzey olarak ölçer: yetkili gönderen
listesi ve imza kaydı kurgu bir ileti kümesinde koşturulur, kaç sahte iletinin yakalandığı, kaçının
geçtiği ve kaç meşru iletinin yanlışlıkla düştüğü sayılır.

### Gönderen Doğrulama Kayıtları

Source: https://academia.sh/tr/kurslar/sunucu-ve-sertlestirme/gonderen-dogrulama-kayitlari

Gönderim politikası ve imza kayıtlarını kurgu bir ileti kümesinde koşturmak: yakalanan sahte ileti, geçen sahte ileti ve yanlışlıkla düşen meşru ileti sayıları ile fazla geniş yetkilendirmenin açtığı yüzey.

Önceki ders adın nereyi gösterdiğini ölçtü. Aynı ad ikinci bir iş daha yapar: bölgesel ölçüm ağı
saha ekiplerine bildirim e-postaları gönderir ve bu iletilerin üzerinde `olcumag.gecersiz` yazar.
Ağ kurgudur; sayaç okumalarını toplayan bir toplayıcı, bir doğrulayıcı, faturalama ve iş emri
servisleri her gece ileti üretir.

Varsayılan durumda o iletilerin gerçekten bu addan çıktığını hiçbir şey söylemez. Gönderen alanı
iletinin içinde yazan bir metindir; onu yazmak için o ada sahip olmak gerekmez. Kurulumdan sonra
hiçbir şey yapılmadığında **açık kalem tektir ve büyüktür**: adın adına ileti göndermek herkese
açıktır ve ad ne kadar tanıdıksa taklit o kadar işe yarar. Faturalama bildirimi taklit
edildiğinde saha ekibi bunu ayırt edemez.

Bu boşluğu kapatan iki kayıt vardır ve ikisi **ayrı sorulara** yanıt verir. **Gönderen politikası
kaydı**, bu adın adına ileti göndermeye yetkili makinelerin listesidir; sorusu "bu ileti hangi
makineden geldi" sorusudur. **İmza kaydı** bir açık anahtar yayınlar; gönderen makine iletiyi
karşılık gelen gizli anahtarla imzalar, alıcı taraf imzayı kayıttaki anahtarla doğrular. Sorusu
"bu içerik anahtarı elinde tutandan mı çıktı ve yolda değişti mi" sorusudur. İkisi birbirinin
yerine geçmez ve aşağıda görüleceği gibi ikisi de tek başına yetmez.

#### İki Denetim, Bir Koşum

Aşağıdaki program iki denetimi de gerçekten çalıştırır. İmzalar `node:crypto` ile üretilir ve
doğrulanır; anahtarlar koşum sırasında yaratılır, hiçbir anahtar gövdesi metne yazılmaz.

**AK7.** İleti kümesi 16 kurgu iletidir: 10 meşru bildirim, 6 sahte. `sinif` alanı yalnız sayım içindir;
denetleyici o alanı görmez. **AK8.** İmza, gönderen–konu–gövde üçlüsü üzerinden alınır; gerçek bir posta
iletisinin başlık kümesi modellenmez. **AK9.** Alıcı taraf iki denetimi de yapar ve sonuçlarını görür;
sonuçla **ne yapacağı** bu dersin konusu değildir.

```javascript
import { generateKeyPairSync, sign, verify } from 'node:crypto';

// Model: gönderen doğrulaması. Anahtarlar koşum sırasında üretilir, hiçbir anahtar
// gövdesi yazılmaz ya da basılmaz. İleti kümesi ve kayıtlar kurgudur.
const ANAHTAR = {
  k1: generateKeyPairSync('ed25519'),   // ölçüm ağının kendi anahtarı
  k2: generateKeyPairSync('ed25519'),   // üçüncü taraf göndericinin anahtarı
};
const SAHTE_ANAHTAR = generateKeyPairSync('ed25519');   // saldırganın anahtarı

// Bölgedeki iki kayıt. Gönderen politikası kaydı yetkili gönderen listesidir;
// imza kaydı etiket başına bir açık anahtar taşır.
const POLITIKA_KAYDI = {
  tekil: ['198.51.100.11', '198.51.100.12', '198.51.100.13', '198.51.100.14', '198.51.100.20'],
  agBloklari: [{ onek: '203.0.113.', boyut: 256 }],   // üçüncü taraf göndericinin tüm çıkış ağı
};
const IMZA_KAYDI = { k1: ANAHTAR.k1.publicKey, k2: ANAHTAR.k2.publicKey };

const govdeleyaz = (i) => `${i.gonderen}|${i.konu}|${i.govde}`;

function imzala(i, etiket, ozelAnahtar) {
  i.etiket = etiket;
  i.imza = sign(null, Buffer.from(govdeleyaz(i)), ozelAnahtar);
  return i;
}

function politikaDenetimi(kaynak) {
  if (POLITIKA_KAYDI.tekil.includes(kaynak)) return true;
  return POLITIKA_KAYDI.agBloklari.some((b) => kaynak.startsWith(b.onek));
}

function imzaDenetimi(i) {
  if (!i.imza || !IMZA_KAYDI[i.etiket]) return false;
  return verify(null, Buffer.from(govdeleyaz(i)), IMZA_KAYDI[i.etiket], i.imza);
}

// 16 kurgu ileti: 10 meşru bildirim, 6 sahte.
const ILETILER = [
  { id: 'm01', kaynak: '198.51.100.11', gonderen: 'toplayici@olcumag.gecersiz', konu: 'sayac paketi', govde: 'gece toplu is tamam', sinif: 'mesru', anahtar: 'k1' },
  { id: 'm02', kaynak: '198.51.100.12', gonderen: 'dogrulayici@olcumag.gecersiz', konu: 'sapma uyarisi', govde: 'bolge 4 sapma', sinif: 'mesru', anahtar: 'k1' },
  { id: 'm03', kaynak: '198.51.100.13', gonderen: 'faturalama@olcumag.gecersiz', konu: 'donem kapanisi', govde: 'donem 7 kapandi', sinif: 'mesru', anahtar: 'k1' },
  { id: 'm04', kaynak: '198.51.100.14', gonderen: 'isemri@olcumag.gecersiz', konu: 'saha is emri', govde: 'ekip 2 icin 5 emir', sinif: 'mesru', anahtar: 'k1' },
  { id: 'm05', kaynak: '198.51.100.20', gonderen: 'bildirim@olcumag.gecersiz', konu: 'haftalik ozet', govde: 'ozet ektedir', sinif: 'mesru', anahtar: 'k1' },
  { id: 'm06', kaynak: '203.0.113.40', gonderen: 'bildirim@olcumag.gecersiz', konu: 'toplu duyuru', govde: 'bakim penceresi', sinif: 'mesru', anahtar: 'k2' },
  { id: 'm07', kaynak: '203.0.113.41', gonderen: 'bildirim@olcumag.gecersiz', konu: 'toplu duyuru', govde: 'bakim penceresi', sinif: 'mesru', anahtar: 'k2' },
  { id: 'm08', kaynak: '198.51.100.13', gonderen: 'faturalama@olcumag.gecersiz', konu: 'gecelik rapor', govde: 'toplu is ciktisi', sinif: 'mesru', anahtar: null },
  { id: 'm09', kaynak: '192.0.2.77', gonderen: 'uyari@olcumag.gecersiz', konu: 'esik asimi', govde: 'yeni uyari servisi', sinif: 'mesru', anahtar: 'k1' },
  { id: 'm10', kaynak: '198.51.100.30', gonderen: 'isemri@olcumag.gecersiz', konu: 'saha is emri', govde: 'ekip 3 icin 2 emir', sinif: 'mesru', anahtar: 'k1', bozulan: ' -- iletildi' },
  { id: 'f01', kaynak: '203.0.113.200', gonderen: 'faturalama@olcumag.gecersiz', konu: 'odeme talebi', govde: 'hesap degisti', sinif: 'sahte', anahtar: null },
  { id: 'f02', kaynak: '192.0.2.200', gonderen: 'isemri@olcumag.gecersiz', konu: 'acil is emri', govde: 'sayaci sokun', sinif: 'sahte', anahtar: null },
  { id: 'f03', kaynak: '192.0.2.201', gonderen: 'bildirim@olcumag.gecersiz', konu: 'sifre yenileme', govde: 'baglantiya gidin', sinif: 'sahte', anahtar: 'sahte' },
  { id: 'f04', kaynak: '203.0.113.201', gonderen: 'faturalama@olcumag.gecersiz', konu: 'donem kapanisi', govde: 'yeni hesap no', sinif: 'sahte', anahtar: 'sahte' },
  { id: 'f05', kaynak: '198.51.100.13', gonderen: 'faturalama@olcumag.gecersiz', konu: 'donem kapanisi', govde: 'ele gecirilmis makine', sinif: 'sahte', anahtar: 'k1' },
  { id: 'f06', kaynak: '192.0.2.202', gonderen: 'toplayici@olcumag.gecersiz', konu: 'sayac paketi', govde: 'gece toplu is tamam', sinif: 'sahte', anahtar: 'k1', bozulan: ' ek satir' },
];

for (const i of ILETILER) {
  if (i.anahtar === 'sahte') imzala(i, 'k1', SAHTE_ANAHTAR.privateKey);
  else if (i.anahtar) imzala(i, i.anahtar, ANAHTAR[i.anahtar].privateKey);
  if (i.bozulan) i.govde += i.bozulan;   // imzadan sonra gövde değişir
}

const denetle = () => ILETILER.map((i) => ({
  id: i.id, sinif: i.sinif, politika: politikaDenetimi(i.kaynak), imza: imzaDenetimi(i),
}));
const KURALLAR = {
  'yalniz politika': (s) => s.politika,
  'yalniz imza': (s) => s.imza,
  'herhangi biri': (s) => s.politika || s.imza,
  'ikisi de': (s) => s.politika && s.imza,
};
const mesru = ILETILER.filter((i) => i.sinif === 'mesru').length;
const sahte = ILETILER.length - mesru;

function tablo(baslik) {
  const sonuc = denetle();
  console.log(`\n[${baslik}]  kural             yakalanan sahte  gecen sahte  dusen mesru`);
  for (const [ad, kural] of Object.entries(KURALLAR)) {
    const gecen = sonuc.filter((s) => s.sinif === 'sahte' && kural(s)).length;
    const dusen = sonuc.filter((s) => s.sinif === 'mesru' && !kural(s)).length;
    console.log('  '.padEnd(baslik.length + 5) + ad.padEnd(18) + `${sahte - gecen}/${sahte}`.padEnd(17) +
      String(gecen).padEnd(13) + `${dusen}/${mesru}`);
  }
}

console.log('ileti  sinif   politika  imza');
for (const s of denetle()) {
  console.log(`${s.id.padEnd(6)} ${s.sinif.padEnd(7)} ${(s.politika ? 'gecti' : 'dustu').padEnd(9)} ${s.imza ? 'gecti' : 'dustu'}`);
}
console.log(`\nmesru ileti: ${mesru}  sahte ileti: ${sahte}`);
tablo('genis');

const genisYetki = POLITIKA_KAYDI.tekil.length +
  POLITIKA_KAYDI.agBloklari.reduce((a, b) => a + b.boyut, 0);
const kullanilan = [...new Set(ILETILER.filter((i) => i.sinif === 'mesru' && politikaDenetimi(i.kaynak))
  .map((i) => i.kaynak))];
console.log('\nyetkilendirilen adres:', genisYetki, '| gercekten gonderen:', kullanilan.length,
  '| fazladan yetkili:', genisYetki - kullanilan.length);

POLITIKA_KAYDI.agBloklari = [];                 // ağ bloğu kaldırılır
POLITIKA_KAYDI.tekil = kullanilan;              // yalnız kullanılan adresler kalır
tablo('dar');
```

```
ileti  sinif   politika  imza
m01    mesru   gecti     gecti
m02    mesru   gecti     gecti
m03    mesru   gecti     gecti
m04    mesru   gecti     gecti
m05    mesru   gecti     gecti
m06    mesru   gecti     gecti
m07    mesru   gecti     gecti
m08    mesru   gecti     dustu
m09    mesru   dustu     gecti
m10    mesru   dustu     dustu
f01    sahte   gecti     dustu
f02    sahte   dustu     dustu
f03    sahte   dustu     dustu
f04    sahte   gecti     dustu
f05    sahte   gecti     gecti
f06    sahte   dustu     dustu

mesru ileti: 10  sahte ileti: 6

[genis]  kural             yakalanan sahte  gecen sahte  dusen mesru
          yalniz politika   3/6              3            2/10
          yalniz imza       5/6              1            2/10
          herhangi biri     3/6              3            1/10
          ikisi de          5/6              1            3/10

yetkilendirilen adres: 261 | gercekten gonderen: 7 | fazladan yetkili: 254

[dar]  kural             yakalanan sahte  gecen sahte  dusen mesru
        yalniz politika   5/6              1            2/10
        yalniz imza       5/6              1            2/10
        herhangi biri     5/6              1            1/10
        ikisi de          5/6              1            3/10
```

#### Sayının Okunuşu

Hiçbir satır altı sahtenin altısını da yakalamıyor ve hiçbir satır meşru iletilerin hepsini
geçirmiyor. Karar, iki sütun arasında yapılıyor.

**Yalnız politika kaydı** üç sahteyi kaçırır. Nedeni sütunda görünür: `f01` ve `f04` yetkili ağ
bloğunun içinden gelmiştir, `f05` ise doğrudan meşru makinenin kendisinden. Politika kaydı adresi
sorar, içeriği sormaz — yetkili bir adresten gönderilen her şeyi geçirir.

Bu denetimin neyi sorduğu, ne kadarını kapattığını da belirler. Politika kaydı **bağlanan
makinenin adresini** sınar; iletinin içinde yazan gönderen alanını değil. İkisi arasında zorunlu
bir bağ yoktur ve denetim yalnız adresi gördüğü için, yetkili bir adresten gönderilen ileti
içinde hangi adı taşırsa taşısın geçer. Kaydın kapattığı şey, ağın herhangi bir yerinden bu adın
adına ileti göndermektir — az bir şey değil, ama içeriğe dair hiçbir şey söylemez.

**Yalnız imza kaydı** beş sahteyi yakalar ve tek kaçırdığı `f05`'tir. Buna karşılık iki meşru
iletiyi düşürür: `m08` imzalanmamıştır (gecelik toplu iş imzalama adımından geçmiyor), `m10` ise
imzalandıktan sonra gövdesi değişmiştir — bir ara sunucu iletiyi yönlendirirken sonuna bir satır
eklemiştir. İmza içeriği sorar, kaynağı sormaz.

**İkisinin birleştirilmesi bir üçüncü karardır.** Gevşek birleşim (herhangi biri geçerse kabul)
düşen meşru iletiyi 1'e indirir ama geçen sahteyi 3'te tutar; sıkı birleşim (ikisi de geçmeli)
geçen sahteyi 1'e indirir, bedeli üç meşru iletinin düşmesidir. Aynı iki kayıt, birleştirme
kuralına göre **üç kat farklı** sonuç verir. Bu kuralın kim tarafından ve nasıl bildirileceği
sonraki dersin konusudur.

#### Kaydın Gerçeklikten Kayması

Önceki derste bölge dosyası ile canlı envanterin ayrışması sayılmıştı. Aynı kayma burada da var
ve daha hızlı ilerler, çünkü gönderen kümesi kayıt kümesinden bağımsız büyür.

Modelde meşru iletiler dokuz ayrı adresten çıkıyor, politika kaydı bunlardan **yedisini** tanıyor.
Tanınmayan ikisi konuşuyor: `m09` yeni kurulmuş bir eşik uyarısı servisidir, ileti göndermeye
başlamış ama kayda eklenmemiştir; `m10` ise bir yönlendirme sonucu başka bir makineden çıkmıştır.
Kayda ekleme adımı bir kurulumun parçası değildir — servis yazılır, dağıtılır, çalışır, ileti
gönderir ve kimse bölgeye bakmaz. Kayma **tek yönlüdür** ve sessizdir: eksik kayıt bir hata
üretmez, yalnız iletinin bir denetimi kaybetmesine yol açar.

Bu kaymanın ölçüsü, iki listeyi karşılaştırmaktır: kayıtta yetkili adresler ile son bir dönemde
gerçekten gönderim yapmış adresler. Farkın iki yönü de kalemdir. Kayıtta olup göndermeyen adres
gereksiz yüzeydir; gönderip kayıtta olmayan adres ise **düşmeye aday meşru iletidir**. Bu iki
sayının nereden okunacağı, sonraki dersin rapor akışının varlık nedenidir; şu an için ikisi de
yalnız bu koşumda görünüyor, işletmede görünmüyor.

#### Fazla Geniş Yetkilendirme

Politika kaydında bir tek adres yerine bir ağ bloğu yetkilendirmek yaygın bir kısayoldur; üçüncü
taraf gönderici çıkış adresini değiştirdiğinde kayıt bozulmasın diye yapılır. Bedeli sayıda:

**AK10.** Politika kaydındaki ağ bloğu 256 adres taşır; üçüncü taraf gönderici bunlardan ikisini
kullanır.

Kayıt **261 adresi** yetkilendiriyor ve gerçekten gönderen adres **7**. Aradaki **254 adres** kimsenin
kullanmadığı ama ölçüm ağının adına ileti göndermeye yetkili olan adreslerdir. Bunlar üçüncü taraf
göndericinin başka müşterilerine ayrılmış olabilir; o müşterilerden biri ele geçirildiğinde
`olcumag.gecersiz` adına ileti gönderme yetkisi de onunla birlikte el değiştirir. Koşumdaki `f01` ve
`f04` tam olarak budur.

Blok daraltıldığında sayı yerine oturuyor: yalnız politika kuralı 3/6'dan **5/6**'ya çıkıyor,
geçen sahte 3'ten 1'e iniyor ve **düşen meşru ileti hiç artmıyor**. Bu, açık kalemi meşru işi
durdurmadan kapatan bir adımdır ve konuda tek örneğidir. Karşılığında bir bakım yükü doğar: üçüncü
taraf gönderici adres değiştirdiğinde kayıt güncellenmezse meşru duyurular düşer ve bu düşüş
sessizdir.

Yetkilendirmenin ikinci katmanı ayrıca sayılmalıdır. Üçüncü taraf gönderici yalnız adres
bloğuyla değil, imza kaydındaki ikinci etiketle de yetkilidir: `m06` ve `m07` iletileri onun
anahtarıyla imzalanmıştır ve doğrulamadan geçerler. Yani o taraf, ölçüm ağının adına **geçerli
imza üretebilen** ikinci bir taraftır. Adres bloğu daraltılsa bile bu yetki durur; ancak etiket
kayıttan çıkarılarak geri alınır. İki katman iki ayrı kalemdir ve ikisi ayrı ayrı sayılmadıkça
"gönderen doğrulaması kuruldu" cümlesi bir sayı taşımaz.

#### Kapatılamayan Kalem ve Yeni Yüzey

`f05` hiçbir kuralda yakalanmıyor.

**AK11.** Ele geçirilmiş meşru makine, o makinede duran imzalama anahtarına da erişir.

Bu kalem **kapatılamaz**, çünkü iki kayıt da makinenin yetkili olup olmadığını sorar, o an kimin
elinde olduğunu değil. Sonucun yönü de ters işler: doğrulamadan geçen ileti, alıcı tarafta
geçmeyenden **daha güvenilir** görünür. `f05` yalnız yakalanmamakla kalmaz, iki denetimden de
geçtiği için taklit iletilerin en inandırıcısı durumundadır. Gönderen doğrulaması kurmak, bu tek
iletinin değerini yükseltir; kapatılan beş kalemin karşılığında kalan bir kalem ağırlaşır. Gönderen doğrulaması adın taklit edilmesini engeller; adın kendi
makinesinden kötüye kullanılmasını engellemez. Bunun ölçüsü bu konuda değil, makinenin
sertleştirilmesindedir.

`m10` de kapatılamayanlar arasındadır: bir ileti yönlendirildiğinde kaynak adres değişir ve gövde
değişebilir. İki denetim de bunu bir saldırı gibi görür. Yönlendirmeyi kimse bölge dosyasından
yönetemez.

**AK12.** Anahtar değiştirilirken eski etiket kayıtta bir süre daha kalır; o süre boyunca iki
anahtarla üretilmiş imza da doğrulanır.

Kapatmanın kendi yüzeyi ise anahtarın yerindedir. İmza kaydı bir **açık** anahtar yayınlar, ama
karşılığındaki gizli anahtar bir makinede durur ve orada bir sırdır. Kayıt etiket başına anahtar
taşıdığı için birden çok etiket bir arada yayınlanabilir — anahtar değiştirilirken yeni etiket
eklenir, eski etiket bir süre kalır. O süre boyunca **iki anahtar birden geçerlidir** ve eski
anahtarı ele geçiren biri hâlâ geçerli imza üretir. Anahtar döndürme, kapanan bir kalemin
karşılığında açılan bir penceredir; penceresinin uzunluğu önceki derste ölçülen yaşam süresine
bağlıdır.

#### Özet

- Varsayılan durumda bir adın adına ileti göndermek için o ada sahip olmak gerekmez; kurulum
  sonrası açık kalem tektir ve adın tanınırlığıyla büyür.
- Gönderen politikası kaydı "hangi makineden" sorusuna, imza kaydı "içerik anahtar sahibinden mi
  ve değişti mi" sorusuna yanıt verir; ikisi birbirinin yerine geçmez.
- 16 iletilik kurgu kümede yalnız politika 3/6, yalnız imza 5/6 sahteyi yakalar; imza iki meşru
  iletiyi düşürür (imzasız toplu iş ve yönlendirilirken gövdesi değişen bildirim).
- Birleştirme kuralı sonucu belirler: gevşek kural düşen meşruyu 1'e indirir ama 3 sahte geçirir,
  sıkı kural 1 sahte geçirir ama 3 meşru ileti düşürür.
- Politika kaydındaki ağ bloğu 261 adresi yetkilendirir ve gerçekte 7 adres gönderir; 254 fazladan
  yetkili adres bir yüzeydir ve blok daraltıldığında meşru ileti kaybı olmadan kapanır.
- Ele geçirilmiş meşru makineden gönderilen ileti hiçbir kuralda yakalanmaz; anahtar döndürme ise
  iki anahtarın birlikte geçerli olduğu bir pencere açar.

#### Sonraki Adım

İki denetim artık bir sonuç üretiyor: her ileti için iki bit. Bu dersin bıraktığı asıl boşluk şu
ki, o iki bitle **ne yapılacağını** kimse söylemiyor. Denetimden düşen bir iletiyi alıcı tarafın
teslim mi, karantinaya mı alacağı, yoksa reddedecek mi olduğu ad sahibinin değil alıcının kararı
durumunda ve alıcılar farklı davranıyor. Sonraki ders bu kararın bölgeden bildirilmesini ele alır:
politika bildirimi aşamalı sıkılaştırılır — yalnız raporla, karantina, reddet — ve her aşamada
düşen meşru ileti ile engellenen sahte ileti ayrı ayrı sayılır. Rapor akışının kendisi de bir
ölçüm aracıdır: yetkilendirilmemiş göndericilerin ne kadarı oradan bulunuyor.

### Alan Adı Politika Kaydı

Source: https://academia.sh/tr/kurslar/sunucu-ve-sertlestirme/alan-adi-politika-kaydi

Uyumsuz iletiler için politika bildirimini aşamalı sıkılaştırmak: her aşamada düşen meşru ileti ve engellenen sahte ileti sayısı, rapor akışının yetkilendirilmemiş gönderen bulma oranı ve doğrudan reddetmenin bedeli.

Önceki ders iki denetimi koşturdu ve her ileti için iki sonuç üretti. Orada açıkta kalan soru,
sonucun **ne işe yaradığıydı**: bir ileti denetimden düştüğünde alıcı taraf onu teslim mi eder,
ayırır mı, yoksa hiç almaz mı? Varsayılan durumda bu kararı ad sahibi vermez. Her alıcı kendi
ölçütüyle davranır; kimi düşen iletiyi olduğu gibi teslim eder, kimi kendi kestirimini uygular.
Sonuç, aynı sahte iletinin bir yerde gelen kutusuna, başka bir yerde hiçbir yere gitmesidir.

**Politika bildirimi** bu kararı ad sahibine geri taşır. Bölgede yayınlanan bir kayıttır ve şunu
söyler: bu adın adına gelen ama denetimlerden geçmeyen iletiye şu işlem uygulansın. Üç aşaması
vardır — **yalnız raporla**, **karantina**, **reddet** — ve aralarındaki fark, gönderim
altyapısındaki eksiklerin kime fatura edileceğidir.

Aşamalar arasında sıçramak, bu kursta sayılabilen en pahalı hatalardan biridir. Bu ders bir
dönem koşturur ve her aşamada iki sayıyı birlikte çıkarır: **kaç meşru ileti düşer** ve **kaç
sahte ileti engellenir**.

#### Bildirimin Taşıdığı Alanlar

Kayıt bölgeye bir metin olarak yazılır ve dört şeyi bildirir: uyumsuz iletiye **uygulanacak
işlem**, işlemin iletilerin **hangi oranına** uygulanacağı, raporların **gönderileceği adres** ve
alt adlar için ayrı bir işlem tanımlanıp tanımlanmadığı. İlk ikisi bu dersin ölçtüğü iki eksendir;
üçüncüsü ölçümün kaynağıdır.

Bildirimin kapsamı da bir karardır. İşlem, yalnız **gönderen alanında bu ad yazan** iletilere
uygulanır; denetimlerin geçtiği ad ile gönderen alanındaki adın örtüşmesi aranır. Bu şart olmasa
bildirim işlemezdi: kendi adına düzgün imzalanmış bir ileti, gönderen alanında başka bir ad
taşıyarak denetimden geçmiş görünürdü. Örtüşme şartı, iki kaydın kapattığı yüzeyi bildirimin
kapsamına bağlayan halkadır.

Alt adlar için ayrı işlem tanımlayabilmenin nedeni, alt adların çoğunlukla ileti göndermemesidir.
Modeldeki bölgede on dört ad var ve bunlardan yalnız birkaçı gönderim yapıyor; gönderim yapmayan
alt adlar için doğrudan en sıkı işlem bildirilebilir, çünkü orada kaybedilecek meşru ileti yoktur.
Sıkılaştırmanın **ilk ve bedelsiz adımı** budur ve aşağıdaki sayımın dışında kalır.

#### Bir Dönem, Dört Aşama

**AK13.** Dönem bir aylıktır ve 414 kurgu iletiden oluşur; akış adetleri sabit alınır.
**AK14.** Uyum ölçütü, iki denetimden en az birinin gönderenin adıyla hizalı biçimde geçmesidir.
**AK15.** Karantinaya alınan meşru ileti teslim edilmiş sayılır; okunma olasılığı bu modelde
sayılmaz.

```javascript
// Model: bir dönemlik ileti akışı ve politika bildiriminin aşamaları. Akışlar,
// ileti sayıları ve rapor oranı kurgudur; uyum, iki denetimden en az birinin
// gönderenin adıyla hizalı biçimde geçmesidir.
const TOHUM = 7311;
const RAPOR_ORANI = 0.65;      // alıcı tarafların rapor gönderme oranı

function uretec(tohum) {
  let x = tohum % 2147483647;
  return () => { x = (x * 48271) % 2147483647; return (x - 1) / 2147483646; };
}

// kaynaklar: [adres, ileti adedi]; politika/imza alanları denetim sonucudur
const AKISLAR = [
  { ad: 'gecelik-ozet',        sinif: 'mesru', politika: true,  imza: true,  kaynaklar: [['198.51.100.11', 120]] },
  { ad: 'sapma-uyarisi',       sinif: 'mesru', politika: true,  imza: true,  kaynaklar: [['198.51.100.12', 60]] },
  { ad: 'donem-kapanisi',      sinif: 'mesru', politika: true,  imza: false, kaynaklar: [['198.51.100.13', 40]] },
  { ad: 'toplu-duyuru',        sinif: 'mesru', politika: true,  imza: true,  kaynaklar: [['203.0.113.40', 50], ['203.0.113.41', 40]] },
  { ad: 'esik-uyarisi',        sinif: 'mesru', politika: false, imza: false, kaynaklar: [['192.0.2.77', 25]] },
  { ad: 'yonlendirilen-emir',  sinif: 'mesru', politika: false, imza: false, kaynaklar: [['198.51.100.30', 18]] },
  { ad: 'taklit-faturalama',   sinif: 'sahte', politika: false, imza: false, kaynaklar: [['192.0.2.200', 30], ['198.18.0.5', 2]] },
  { ad: 'taklit-isemri',       sinif: 'sahte', politika: false, imza: false, kaynaklar: [['192.0.2.201', 15], ['198.18.0.9', 1], ['198.18.0.12', 1]] },
  { ad: 'blok-ici-taklit',     sinif: 'sahte', politika: true,  imza: false, kaynaklar: [['203.0.113.200', 12]] },
];

const uyumlu = (a) => a.politika || a.imza;
const adet = (a) => a.kaynaklar.reduce((t, [, n]) => t + n, 0);
const topla = (secim) => AKISLAR.filter(secim).reduce((t, a) => t + adet(a), 0);

const mesru = topla((a) => a.sinif === 'mesru');
const sahte = topla((a) => a.sinif === 'sahte');
console.log('donem toplami:', mesru + sahte, '| mesru:', mesru, '| sahte:', sahte);
console.log('uyumsuz mesru ileti:', topla((a) => a.sinif === 'mesru' && !uyumlu(a)),
  '| uyumlu sahte ileti:', topla((a) => a.sinif === 'sahte' && uyumlu(a)));

console.log('hazirliksiz mesru akis:',
  AKISLAR.filter((a) => a.sinif === 'mesru' && !uyumlu(a)).map((a) => `${a.ad}=${adet(a)}`).join(' '));

const ASAMALAR = ['bildirim yok', 'yalniz raporla', 'karantina', 'reddet'];
console.log('\nasama          gelen kutusu (mesru)  ayrilan mesru  gelen kutusu (sahte)  engellenen sahte');
for (const asama of ASAMALAR) {
  const ayir = asama === 'karantina' || asama === 'reddet';
  const mesruAyrilan = ayir ? topla((a) => a.sinif === 'mesru' && !uyumlu(a)) : 0;
  const sahteAyrilan = ayir ? topla((a) => a.sinif === 'sahte' && !uyumlu(a)) : 0;
  console.log(asama.padEnd(15) + String(mesru - mesruAyrilan).padEnd(22) +
    `${mesruAyrilan}${asama === 'reddet' ? ' (kayip)' : asama === 'karantina' ? ' (karantina)' : ''}`.padEnd(15) +
    String(sahte - sahteAyrilan).padEnd(22) + String(sahteAyrilan));
}

// Rapor akışı: her ileti bağımsız olarak RAPOR_ORANI olasılığıyla rapora girer.
// Bir kaynak, en az bir iletisi raporlandıysa bulunmuş sayılır.
const rast = uretec(TOHUM);
const yetkisiz = [];
for (const a of AKISLAR) {
  if (a.politika) continue;                       // politika kaydında zaten var
  for (const [adres, n] of a.kaynaklar) {
    let raporlanan = 0;
    for (let i = 0; i < n; i++) if (rast() < RAPOR_ORANI) raporlanan++;
    yetkisiz.push({ adres, akis: a.ad, sinif: a.sinif, n, bulundu: raporlanan > 0 });
  }
}
const bulunan = yetkisiz.filter((k) => k.bulundu);
console.log('\nrapor orani:', RAPOR_ORANI, '| tohum:', TOHUM);
console.log('yetkilendirilmemis kaynak:', yetkisiz.length, '| rapordan bulunan:', bulunan.length,
  `(${Math.round((bulunan.length / yetkisiz.length) * 100)}%)`);
for (const k of yetkisiz.filter((x) => !x.bulundu)) {
  console.log(`  kacan kaynak: ${k.adres.padEnd(15)} ${k.akis.padEnd(18)} ileti=${k.n}`);
}
console.log('bulunan kaynaklarin ileti payi:',
  `${bulunan.reduce((t, k) => t + k.n, 0)}/${yetkisiz.reduce((t, k) => t + k.n, 0)}`);

// Hazırlık: yeni servis politika kaydına eklenir, toplu iş imzalanır.
AKISLAR.find((a) => a.ad === 'esik-uyarisi').politika = true;
console.log('\nhazirlik sonrasi reddet asamasinda kaybedilen mesru ileti:',
  topla((a) => a.sinif === 'mesru' && !uyumlu(a)));
```

```
donem toplami: 414 | mesru: 353 | sahte: 61
uyumsuz mesru ileti: 43 | uyumlu sahte ileti: 12
hazirliksiz mesru akis: esik-uyarisi=25 yonlendirilen-emir=18

asama          gelen kutusu (mesru)  ayrilan mesru  gelen kutusu (sahte)  engellenen sahte
bildirim yok   353                   0              61                    0
yalniz raporla 353                   0              61                    0
karantina      310                   43 (karantina) 12                    49
reddet         310                   43 (kayip)     12                    49

rapor orani: 0.65 | tohum: 7311
yetkilendirilmemis kaynak: 7 | rapordan bulunan: 6 (86%)
  kacan kaynak: 198.18.0.12     taklit-isemri      ileti=1
bulunan kaynaklarin ileti payi: 91/92

hazirlik sonrasi reddet asamasinda kaybedilen mesru ileti: 18
```

#### Aşamaların Okunuşu

İlk iki satır aynı sayıları taşıyor ve bu bir hata değil. **Yalnız raporla** aşaması hiçbir
iletiyi engellemez; altmış bir sahte ileti gelen kutusuna ulaşmaya devam eder. Bu aşamanın
ürettiği tek şey rapordur ve rapor bir savunma değil, bir **ölçüm aracıdır**.

Sıkılaştırma **karantina** satırında başlıyor: kırk dokuz sahte ileti gelen kutusundan ayrılıyor,
karşılığında kırk üç meşru ileti de ayrılıyor. Oran neredeyse birebir — bu, açık kalemin
kapanmasının yanında **yanlış kapatmanın** aynı büyüklükte olduğu anlamına gelir. Aradaki tek
fark, karantinaya alınan meşru iletinin hâlâ bir yerde durmasıdır; alıcı ararsa bulur.

**Reddet** satırındaki sayılar karantinayla aynı, ama kolonun anlamı değişiyor: kırk üç meşru
ileti artık hiçbir yerde yok. Aynı sıkılıkta iki aşama, meşru ileti tarafında **geri
dönülebilirlik** bakımından ayrılıyor. Bu yüzden sıralama önemlidir: karantina, reddetmenin
provasıdır ve kaybı geri alınabilir kılar.

Son sütunda kapanmayan kalem duruyor. On iki sahte ileti her aşamada gelen kutusuna ulaşıyor,
çünkü bunlar politika kaydında yetkilendirilmiş ağ bloğunun içinden geliyor ve **uyumlu**
sayılıyorlar. Politika bildirimi uyumsuz iletiye ne yapılacağını söyler; uyumlu görünen taklidi
görmez. Önceki dersteki fazla geniş yetkilendirme, burada doğrudan bir kalem olarak geri dönüyor:
bloğu daraltmadan bildirim sıkılaştırmak bu on iki iletiye dokunmaz.

#### Raporun Değeri ve Sınırı

Rapor akışı, alıcı tarafların ad sahibine "bu adın adına şu kaynaktan ileti geldi, denetim şöyle
sonuçlandı" diye bildirmesidir. Değeri, önceki derste yalnız koşumda görünen kaymanın işletmede
görünür hale gelmesidir.

**AK16.** Alıcı tarafların bir bölümü rapor gönderir; her ileti bağımsız olarak 0,65 olasılıkla
rapora girer.
**AK17.** Rapor kaynağı gösterir, iletinin meşru mu sahte mi olduğunu göstermez.

Sayı iyi: yedi yetkilendirilmemiş kaynağın **altısı** bulunuyor, bulma oranı **%86** ve bulunan
kaynaklar iletilerin **91'ini** kapsıyor. Kaçan tek kaynak dönem boyunca bir tek ileti göndermiş.
Buradaki kural şudur: rapor akışı **hacimli** kaynağı neredeyse kesin bulur, seyrek kaynağı
kaçırır. Bu, hazırlık için doğru araç olduğu anlamına gelir — hazırlıksız düşecek meşru akışlar
tanım gereği düzenli ve hacimlidir.

Sınırı ise AK17'dedir. Rapor `192.0.2.77` adresinden 25 uyumsuz ileti geldiğini söyler; bunun
yeni kurulmuş bir eşik uyarısı servisi mi yoksa bir taklit mi olduğunu söylemez. Ayrımı yapan
şey rapor değil, envanterdir: gönderim yapan servislerin listesiyle karşılaştırma. Rapor akışı
soruyu üretir, yanıtı üretmez.

#### Reddetmenin Bedeli ve Hazırlık

Doğrudan reddetmeye geçmenin bedeli çıktıda adıyla yazılı: **esik-uyarisi 25 ileti**,
**yonlendirilen-emir 18 ileti**. İlki, kayda eklenmeyi bekleyen yeni bir servistir; kaybı bir
hazırlık eksiğidir. İkincisi saha ekiplerinin kendi adreslerine kurduğu yönlendirmedir ve ad
sahibinin denetiminde değildir.

Hazırlık adımı bu ayrımı sayıya çeviriyor: yeni servis politika kaydına eklendikten sonra reddet
aşamasında kaybedilen meşru ileti **43'ten 18'e** iniyor. Kalan 18 ileti ise kayıtla
kapatılamaz — yönlendirme iletiyi başka bir makineden çıkarır ve gövdesini değiştirir.

Hazırlığın ne kadar süreceği de rapordan çıkar. Tek dönemlik rapor yalnız o dönemde gönderim
yapan kaynakları gösterir; çeyrek başında çalışan bir kapanış işi ya da yılda bir gönderilen bir
bildirim, bir dönemlik pencerede hiç görünmez. Kaçan tek kaynağın dönem boyunca bir ileti
göndermiş olması bunun küçük örneğidir. Hazırlık penceresi, gönderim yapan en seyrek akışın
dönemini kapsamalıdır; kısa tutulduğunda sıkılaştırma o akışı **ilk çalıştığı gün** düşürür.

Bu, aşamalı sıkılaştırmanın gerekçesidir. Rapor aşamasında kaynaklar bulunur, kayıtlar
tamamlanır, geriye kalan kaybın büyüklüğü ölçülür; ancak ondan sonra karantinaya, sonra
reddetmeye geçilir. Sıra atlanırsa kayıp aynı büyüklükte olur, ama **önce yaşanır**, sonra
öğrenilir.

#### Yüzdeyle Sıkılaştırma

Aşama, tek bir anahtar değildir. Bildirim, işlemin iletilerin **bir yüzdesine** uygulanmasını da
söyleyebilir; sıkılaştırma böylece aşama içinde de kademelenir.

```javascript
// Model: bildirim, uyumsuz iletilerin yalnız bir yüzdesine uygulanabilir. Girdi,
// önceki koşumun sayılarıdır: iki hazırlıksız meşru akış ve 49 uyumsuz sahte ileti.
const TOHUM = 9013;
const MESRU_AKIS = [['esik-uyarisi', 25], ['yonlendirilen-emir', 18]];
const UYUMSUZ_SAHTE = 49;
const FARK_ESIGI = 10;         // bir akışta dönem başına bu kadar kayıp şikâyet üretir

function uretec(tohum) {
  let x = tohum % 2147483647;
  return () => { x = (x * 48271) % 2147483647; return (x - 1) / 2147483646; };
}

const say = (rast, n, oran) => {
  let k = 0;
  for (let i = 0; i < n; i++) if (rast() < oran) k++;
  return k;
};

console.log('tohum:', TOHUM, '| fark edilme esigi:', FARK_ESIGI, 'ileti/donem');
console.log('oran   esik-uyarisi  yonlendirilen-emir  toplam mesru kayip  engellenen sahte  esigi asan akis');
for (const oran of [0.05, 0.1, 0.25, 0.5, 1.0]) {
  const rast = uretec(TOHUM);
  const kayiplar = MESRU_AKIS.map(([, n]) => say(rast, n, oran));
  const sahteEngel = say(rast, UYUMSUZ_SAHTE, oran);
  console.log(
    `${Math.round(oran * 100)}%`.padEnd(7) +
    String(kayiplar[0]).padEnd(14) + String(kayiplar[1]).padEnd(20) +
    String(kayiplar[0] + kayiplar[1]).padEnd(20) + String(sahteEngel).padEnd(18) +
    String(kayiplar.filter((k) => k >= FARK_ESIGI).length),
  );
}
```

```
tohum: 9013 | fark edilme esigi: 10 ileti/donem
oran   esik-uyarisi  yonlendirilen-emir  toplam mesru kayip  engellenen sahte  esigi asan akis
5%     0             2                   2                   2                 0
10%    4             3                   7                   4                 0
25%    9             6                   15                  12                0
50%    14            12                  26                  26                2
100%   25            18                  43                  49                2
```

Tabloda iki şey aynı anda okunuyor. Birincisi, düşük oran **sahte iletiyi de düşük oranda**
engelliyor; yüzde onda kırk dokuz sahteden yalnız dördü durduruluyor. Yüzde, savunmayı değil
**riski** kademelendirir.

İkincisi ve asıl kullanışlı olanı son sütundur. Yüzde yirmi beşe kadar hiçbir akış fark edilme
eşiğini aşmıyor; kayıp var ama kimse şikâyet etmiyor. Bu, yüzdenin gerçek işlevini gösterir:
düşük oran bir savunma ayarı değil, **hazırlık eksiğini ucuza bulma** aracıdır. On beş iletilik
bir kayıp raporlarda görünür, saha ekibinde görünmez; aynı akış yüzde yüzde açıldığında yirmi
beş ileti birden kaybolur ve iş durur. Sıkılaştırmayı yüzdeyle yürütmenin bedeli, geçen her
dönemde sahte iletinin de aynı oranda geçmesidir.

#### Kalan Kalem ve Yeni Yüzey

**AK18.** Bu modelde bildirim tüm alıcılar tarafından aynı biçimde uygulanır.

Bu varsayım gerçeği aşar ve konunun **ölçülemeyen** kısmını gösterir: bildirim bir istektir,
zorlayıcı değildir. Alıcı taraf onu uygulamayabilir, kısmen uygulayabilir ya da kendi ölçütünü
üste koyabilir. Ad sahibi burada bir kararın **yalnız bildirimini** yapar; kararı uygulayan
başkasıdır ve uygulanıp uygulanmadığı ancak rapor akışından, o da eksik olarak görünür.

Kapatmanın getirdiği yeni yüzey rapor akışının kendisidir. Bölgeye bir adres yazılır ve o adrese
dış taraflardan sürekli veri gelir: hangi kaynaktan kaç ileti çıktığı, hangi denetimin düştüğü.
Bu, ölçüm ağının gönderim yapısını dışarıdan okunabilir kılan bir akıştır ve gideceği adres,
bölgede herkese açık yazar. Ayrıca bir hacim yüzeyidir: rapor adresi, dışarıdan gelen ve
işlenmesi gereken bir veri girişidir.

#### Özet

- Politika bildirimi, uyumsuz iletiye ne yapılacağı kararını alıcıdan ad sahibine taşır; bildirim
  yoksa aynı sahte ileti bir alıcıda gelen kutusuna, başkasında hiçbir yere gider.
- Yalnız raporla aşaması hiçbir iletiyi engellemez: 61 sahte ileti ulaşmayı sürdürür; bu aşama
  bir savunma değil ölçüm aracıdır.
- Karantina ve reddet aynı sayıları verir (49 sahte engellenir, 43 meşru ileti ayrılır); fark
  meşru iletinin geri döndürülebilirliğindedir.
- Yetkilendirilmiş ağ bloğunun içinden gelen 12 sahte ileti her aşamada gelen kutusuna ulaşır;
  bildirim uyumsuzu ayırır ama uyumlu görünen taklidi görmez.
- Rapor akışı yedi yetkilendirilmemiş kaynağın altısını bulur (%86) ve iletilerin 91'ini kapsar;
  kaçırdığı kaynak dönem boyunca tek ileti göndermiştir.
- Hazırlık, reddet aşamasındaki meşru kaybı 43'ten 18'e indirir; kalan 18 ileti yönlendirmeden
  gelir ve hiçbir kayıtla kapatılamaz.

#### Sonraki Adım

Ad artık kendi adına ileti gönderme iznini de tanımlıyor ve uyumsuz iletinin ne olacağını
bildiriyor. Bunların hepsi **gönderen tarafın** ölçüsüdür. Bir ileti bütün denetimlerden geçse
bile ulaşmayabilir: alıcı taraf, gönderenin geçmişine bakarak da karar verir — kaç iletisi geri
döndü, kaç kişi şikâyet etti, gönderim hacmi ani mi arttı. Sonraki ders teslim edilebilirliği bir
**oran** olarak modeller, bozan etkenleri ayrı ayrı sayar ve bir dönem koşturur: itibar
düştüğünde kaç ileti gecikir, kaçı hiç ulaşmaz ve toparlanma kaç dönem sürer.

### Posta Teslim Sorunları

Source: https://academia.sh/tr/kurslar/sunucu-ve-sertlestirme/posta-teslim-sorunlari

Teslim edilebilirliği bir oran olarak modellemek: geri dönen ileti, şikâyet, ani gönderim artışı ve doğrulama kaydı eksikliğini ayrı ayrı saymak, kara listeye girişin ve toparlanmanın kaç dönem sürdüğünü ölçmek.

Önceki üç ders adın nereyi gösterdiğini, kimin o adın adına ileti gönderebileceğini ve uyumsuz
iletiye ne yapılacağını kayıt düzeyinde kurdu. Üçü de **gönderen tarafın** ölçüleridir. Bu
dersin başladığı yerde iletiler artık uyumludur, imzalıdır ve politika bildirilmiştir — ve hâlâ
ulaşmayabilirler.

Alıcı taraf iletiyi yalnız kayıtlara bakarak kabul etmez. Gönderenin **geçmişine** de bakar: son
dönemde kaç iletisi geri döndü, kaç kişi şikâyet etti, hacmi ani mi arttı. Bu geçmişin özetine
**itibar** denir ve bir sayı gibi davranır: yüksekken görünmez, düştüğünde her şeyi belirler.
Bölgesel ölçüm ağının saha ekiplerine gönderdiği iş emri bildirimleri bu ölçünün altındadır ve
ağ kurgudur.

#### Teslim Edilebilirlik Bir Orandır

Bir ileti gönderildiğinde üç sonuçtan biri olur: gelen kutusuna ulaşır, geciktirilir ve daha
sonra teslim edilir, ya da hiç ulaşmaz. **Teslim edilebilirlik**, bu üç sonucun oranıdır — bir
evet/hayır değil.

Oranı bozan etkenler ayrı ayrı sayılabilir ve dördü birden aynı yöne çeker:

- **Geri dönen ileti oranı.** Var olmayan adrese gönderim, listenin bakımsız olduğunu gösterir.
- **Şikâyet oranı.** Alıcının iletiyi istenmeyen olarak işaretlemesi, en ağır tekil etkendir.
- **Ani gönderim artışı.** Aynı adresten çıkan hacmin birkaç katına çıkması, alışılmış davranıştan
  sapmadır.
- **Doğrulama kaydı eksikliği.** Önceki iki dersin kayıtları eksikse bir olay üretmez; yalnız
  ulaşılabilecek en yüksek itibarı düşürür.

Son madde bu konudaki halkadır: gönderen doğrulaması kurulmadığında ortaya çıkan zarar bir arıza
gibi görünmez, bir **tavan** gibi davranır.

#### Bir Dönem Koşumu

**AK19.** Dönem bir haftadır ve yirmi dönem koşturulur; hacim, oranlar ve eşikler kurgudur.
**AK20.** İtibar tek bir sayı olarak modellenir.
**AK21.** İtibar hızlı düşer, yavaş çıkar: bir dönemde en çok 35 puan iner, 5 puan çıkar.
**AK22.** Kara listeye giriş 35 puanın altında olur; çıkış için 55 puanın üstünde iki dönem
beklenir.

```javascript
// Model: teslim edilebilirlik bir orandır ve itibar üzerinden belirlenir. Dönemler,
// etkenler ve eşikler kurgudur; gerçek bir hizmetin ölçütü değildir.
const BASLANGIC_ITIBAR = 88;
const KARA_LISTE_GIRIS = 35;   // bu değerin altında gönderen adres listeye girer
const KARA_LISTE_CIKIS = 55;   // bu değerin üstünde iki dönem beklenir

// Dönem girdileri: hacim, geri dönen ileti oranı, şikâyet oranı, doğrulama kaydı eksik mi
const DONEMLER = [
  { d: 1,  hacim: 400,  geri: 0.012, sikayet: 0.0004, eksikKayit: true },
  { d: 2,  hacim: 410,  geri: 0.011, sikayet: 0.0005, eksikKayit: true },
  { d: 3,  hacim: 395,  geri: 0.013, sikayet: 0.0004, eksikKayit: true },
  { d: 4,  hacim: 420,  geri: 0.012, sikayet: 0.0006, eksikKayit: true },
  { d: 5,  hacim: 405,  geri: 0.010, sikayet: 0.0004, eksikKayit: true },
  { d: 6,  hacim: 3200, geri: 0.140, sikayet: 0.0040, eksikKayit: true },   // eski liste eklendi
  { d: 7,  hacim: 3100, geri: 0.135, sikayet: 0.0052, eksikKayit: true },
  { d: 8,  hacim: 2900, geri: 0.120, sikayet: 0.0048, eksikKayit: true },
  { d: 9,  hacim: 900,  geri: 0.040, sikayet: 0.0020, eksikKayit: false },  // liste temizlendi
  { d: 10, hacim: 450,  geri: 0.015, sikayet: 0.0008, eksikKayit: false },
  { d: 11, hacim: 430,  geri: 0.011, sikayet: 0.0005, eksikKayit: false },
  { d: 12, hacim: 425,  geri: 0.009, sikayet: 0.0004, eksikKayit: false },
  { d: 13, hacim: 415,  geri: 0.008, sikayet: 0.0003, eksikKayit: false },
  { d: 14, hacim: 420,  geri: 0.008, sikayet: 0.0003, eksikKayit: false },
  { d: 15, hacim: 430,  geri: 0.007, sikayet: 0.0002, eksikKayit: false },
  { d: 16, hacim: 425,  geri: 0.007, sikayet: 0.0002, eksikKayit: false },
  { d: 17, hacim: 440,  geri: 0.006, sikayet: 0.0002, eksikKayit: false },
  { d: 18, hacim: 435,  geri: 0.006, sikayet: 0.0002, eksikKayit: false },
  { d: 19, hacim: 430,  geri: 0.005, sikayet: 0.0001, eksikKayit: false },
  { d: 20, hacim: 445,  geri: 0.005, sikayet: 0.0001, eksikKayit: false },
];

// Bantlar: itibar aralığına göre [gelen kutusu, geciken, hic ulasmayan]
const BANTLAR = [
  [80, [0.98, 0.02, 0.00]],
  [60, [0.88, 0.10, 0.02]],
  [40, [0.65, 0.25, 0.10]],
  [20, [0.35, 0.35, 0.30]],
  [0,  [0.10, 0.30, 0.60]],
];
const KARA_LISTE_BANDI = [0.05, 0.15, 0.80];

const bant = (itibar) => BANTLAR.find(([esik]) => itibar >= esik)[1];
const kirp = (x) => Math.max(0, Math.min(100, x));

const DUSUS_HIZI = 35;         // bir dönemde inebileceği en fazla puan
const TOPARLANMA_HIZI = 5;     // bir dönemde çıkabileceği en fazla puan

let itibar = BASLANGIC_ITIBAR;
let karaListede = false;
let temizDonem = 0;
let onceki = DONEMLER[0].hacim;
const gecmis = [];

for (const g of DONEMLER) {
  const artis = g.hacim / onceki;
  let hedef = 100;
  hedef -= Math.max(0, g.geri - 0.02) * 300;        // geri dönen ileti oranı
  hedef -= Math.max(0, g.sikayet - 0.001) * 5000;   // şikâyet oranı
  hedef -= artis > 3 ? 20 : 0;                      // ani gönderim artışı
  hedef -= g.eksikKayit ? 12 : 0;                   // doğrulama kaydı eksikliği
  hedef = kirp(hedef);
  itibar = hedef > itibar
    ? Math.min(hedef, itibar + TOPARLANMA_HIZI)
    : Math.max(hedef, itibar - DUSUS_HIZI);

  if (!karaListede && itibar < KARA_LISTE_GIRIS) { karaListede = true; temizDonem = 0; }
  else if (karaListede) {
    if (itibar >= KARA_LISTE_CIKIS) temizDonem++; else temizDonem = 0;
    if (temizDonem >= 2) karaListede = false;
  }

  const [ik, gk, uk] = karaListede ? KARA_LISTE_BANDI : bant(itibar);
  gecmis.push({
    ...g, hedef: Math.round(hedef), itibar: Math.round(itibar), karaListede,
    gelen: Math.round(g.hacim * ik),
    geciken: Math.round(g.hacim * gk),
    ulasmayan: Math.round(g.hacim * uk),
  });
  onceki = g.hacim;
}

console.log('donem  hacim  geri%  sikayet%  itibar  kara  gelen  geciken  ulasmayan');
for (const s of gecmis) {
  console.log(
    `d${String(s.d).padStart(2, '0')}`.padEnd(7) + String(s.hacim).padEnd(7) +
    (s.geri * 100).toFixed(1).padEnd(7) + (s.sikayet * 100).toFixed(2).padEnd(10) +
    String(s.itibar).padEnd(8) + (s.karaListede ? 'evet' : '-').padEnd(6) +
    String(s.gelen).padEnd(7) + String(s.geciken).padEnd(9) + String(s.ulasmayan),
  );
}

const toplam = (alan) => gecmis.reduce((t, s) => t + s[alan], 0);
console.log('\ntoplam hacim:', toplam('hacim'), '| gelen kutusu:', toplam('gelen'),
  '| geciken:', toplam('geciken'), '| hic ulasmayan:', toplam('ulasmayan'));
console.log('teslim orani:', (toplam('gelen') / toplam('hacim') * 100).toFixed(1) + '%',
  '| kayip orani:', (toplam('ulasmayan') / toplam('hacim') * 100).toFixed(1) + '%');

const sonrasi = gecmis.filter((s) => s.d >= 10);
const say = (dizi, alan) => dizi.reduce((t, s) => t + s[alan], 0);
console.log('olay sonrasi (d10-d20) hacim:', say(sonrasi, 'hacim'),
  '| geciken:', say(sonrasi, 'geciken'), '| hic ulasmayan:', say(sonrasi, 'ulasmayan'));

const dusus = gecmis.find((s) => s.itibar < 80);
const dip = gecmis.reduce((a, b) => (b.itibar < a.itibar ? b : a));
const donus = gecmis.find((s) => s.d > dip.d && s.itibar >= 80);
console.log('\nitibar dusmeye basladi: d' + dusus.d, '| dip:', dip.itibar, '(d' + dip.d + ')',
  '| kara listede gecen donem:', gecmis.filter((s) => s.karaListede).length);
console.log('bozulma: 1 donem | 80 esigine donus: d' + donus.d,
  '| toparlanma:', donus.d - dip.d, 'donem');
```

```
donem  hacim  geri%  sikayet%  itibar  kara  gelen  geciken  ulasmayan
d01    400    1.2    0.04      88      -     392    8        0
d02    410    1.1    0.05      88      -     402    8        0
d03    395    1.3    0.04      88      -     387    8        0
d04    420    1.2    0.06      88      -     412    8        0
d05    405    1.0    0.04      88      -     397    8        0
d06    3200   14.0   0.40      53      -     2080   800      320
d07    3100   13.5   0.52      33      evet  155    465      2480
d08    2900   12.0   0.48      38      evet  145    435      2320
d09    900    4.0    0.20      43      evet  45     135      720
d10    450    1.5    0.08      48      evet  23     68       360
d11    430    1.1    0.05      53      evet  22     65       344
d12    425    0.9    0.04      58      evet  21     64       340
d13    415    0.8    0.03      63      -     365    42       8
d14    420    0.8    0.03      68      -     370    42       8
d15    430    0.7    0.02      73      -     378    43       9
d16    425    0.7    0.02      78      -     374    43       9
d17    440    0.6    0.02      83      -     431    9        0
d18    435    0.6    0.02      88      -     426    9        0
d19    430    0.5    0.01      93      -     421    9        0
d20    445    0.5    0.01      98      -     436    9        0

toplam hacim: 16875 | gelen kutusu: 7682 | geciken: 2278 | hic ulasmayan: 6918
teslim orani: 45.5% | kayip orani: 41.0%
olay sonrasi (d10-d20) hacim: 4745 | geciken: 403 | hic ulasmayan: 1078

itibar dusmeye basladi: d6 | dip: 33 (d7) | kara listede gecen donem: 6
bozulma: 1 donem | 80 esigine donus: d17 | toparlanma: 10 donem
```

#### Asimetri

Tek satır bu dersin bütün ağırlığını taşıyor: **bozulma bir dönem, toparlanma on dönem.**

Olay `d06`'da başlıyor. Saha listesine yıllar öncesinden kalma bir adres kümesi ekleniyor; hacim
sekiz katına çıkıyor, geri dönen ileti oranı %14'e fırlıyor, şikâyetler artıyor. Üç etken aynı
dönemde birden vuruyor ve itibar 88'den 53'e iniyor. Bir dönem sonra 33'e düşüp **kara listeye**
giriyor.

Buradan sonrası artık gönderim davranışıyla ilgili değil. `d09`'da liste temizleniyor, `d10`'da
hacim normale dönüyor ve oranlar iyi — ama itibar dönem başına yalnız beş puan çıkabiliyor.
Adres kara listede **altı dönem** kalıyor; listeden çıktıktan sonra da 80 eşiğine dönmek dört
dönem daha alıyor. Hatanın düzeltilmesi bir dönem sürdü; sonucunun silinmesi on. Bu asimetri kasıtlıdır ve alıcı
tarafın işine yarar: hızlı düşen bir ölçü kötüye kullanımı erken durdurur, yavaş çıkan bir ölçü
ise iyi davranışın birkaç dönem sürdürülmesini şart koşar.

İkinci sayı bunun bedelini gösteriyor. Olaydan sonraki on bir dönemde, yani gönderim tümüyle
normalken, **1.078 ileti hiç ulaşmıyor ve 403 ileti gecikiyor**. Bunlar saha ekibine giden iş
emri bildirimleridir ve içeriklerinde yanlış hiçbir şey yoktur; yalnız gönderenin geçmişi
yüzünden düşerler. Dönem toplamındaki %41'lik kayıp oranı yanıltıcıdır — kaybın büyük bölümü
zaten gönderilmemesi gereken iletilerdi. İşin gerçek bedeli, olaydan **sonra** kaybedilen
normal iletilerdir.

#### Etkenlerin Ayrı Sayılması

Dört etken aynı sayıya vuruyor ama katkıları eşit değil ve modeldeki ağırlıkları bunu gösteriyor.

Geri dönen ileti oranı en büyük tekil kalemdir: %14'te tek başına 36 puan götürür. Şikâyet oranı
daha küçük görünen bir sayıyla benzer ağırlık taşır — binde beş şikâyet 21 puan demektir; bu
etken az sayıda alıcının kararının çok ağır tartıldığı yerdir. Ani hacim artışı 20 puanlık sabit
bir cezadır ve içerikten bağımsızdır: aynı iletiler daha yavaş gönderilseydi bu kalem hiç
doğmayacaktı.

Dördüncüsü ötekilerden farklı davranıyor. Doğrulama kaydı eksikliği, ilk beş dönemde hiçbir olay
üretmiyor; teslim oranı %98, hiçbir şey görünmüyor. Yaptığı tek şey itibar tavanını **88'de**
tutmak. Bunun ne anlama geldiği `d19` ve `d20`'de ortaya çıkıyor: kayıt tamamlandıktan sonra
itibar 93'e, sonra 98'e çıkıyor. Yani kayıt eksikken sistem her zaman 12 puan daha alçakta
duruyordu ve bir olay geldiğinde kara liste eşiğine 12 puan **daha yakındı**. Önceki iki dersin
kayıtları burada bir savunma değil, bir **tampon** olarak ölçülüyor.

#### Akışları Ayırmak ve Getirdiği Yüzey

Koşumdaki bütün kayıp tek bir sayıdan geliyor. İtibar gönderen başına tutulur ve modelde tek bir
gönderen var: toplu duyuru da, iş emri bildirimi de aynı ad altından çıkıyor. Toplu listenin
bozduğu itibar, saha ekibine giden iş emrini de düşürüyor — iki akış arasında hiçbir bağ olmadığı
halde.

Bunun karşılığı akışları ayırmaktır: toplu ve isteğe bağlı gönderim ayrı bir alt ad altından yapılır
ve işleyişe ait bildirimler kendi adında kalır. Ayrım itibarı da ikiye böler; bir tarafta olan öbür
tarafı düşürmez. Modelin yapısı bunu doğrudan söyler, çünkü bantlar itibardan türer ve itibar tek
gönderene bağlıdır.

Ayrımın getirdiği yeni yüzey ise ilk üç dersin toplamıdır. Her yeni alt ad **kendi kayıt
kümesini** ister: adres kaydı, gönderen politikası kaydı, imza kaydı, kendi politika bildirimi ve
kendi rapor adresi. Bölgedeki kayıt sayısı artar, öksüz kayıt olasılığı artar, yaşam süresi
kararı bir kez daha verilir. Birinci derste sayılan envanter kayması, ikinci derste sayılan kayıt
eksikliği ve üçüncü derste sayılan hazırlıksız akış — üçü de yeni ad için sıfırdan doğar. Teslim
sorununu azaltan adım, bakım yüzeyini **iki katına** çıkarır ve bu bedel adı ayırma kararının
parçasıdır.

#### Ölçülemeyen Kısım

**AK23.** Bantlar itibar aralığını doğrudan teslim oranına çevirir.
**AK24.** Modelde gönderen taraf gelen kutusuna ulaşan ileti sayısını görür.

Son varsayım gerçekte tutmaz ve bu konunun ölçülemeyen kısmıdır. Gönderen taraf yalnız iki şeyi
bilir: iletinin alıcı tarafça kabul edilip edilmediği ve geri dönen iletiler. **Kabul edilmiş bir
iletinin gelen kutusuna mı, başka bir yere mi konduğu görünmez.** Yukarıdaki tabloda ayrı ayrı
sayılan "gelen" ve "geciken" sütunları, işletmede tek bir sütundur: kabul edildi.

İtibarın kendisi de yayınlanmaz. Bir sayı gibi modellenebilir ama okunamaz; her alıcı taraf
kendi ölçüsünü tutar ve bu ölçüler birbirinden farklıdır. Kara liste durumu kısmen sorgulanabilir,
ama listeye alma kararının hangi eşikle verildiği ve çıkışın ne kadar süreceği dışarıdan
bilinmez.

Bu yüzden ölçülebilen tek şey **dolaylı göstergelerdir**: geri dönen ileti oranı, şikâyet
bildirimleri, kendi kontrol adreslerine yapılan gönderimler ve önceki dersin rapor akışı. Dördü
de sonucu değil, sonucun gölgesini gösterir. Bir teslim sorununun ne zaman başladığı çoğu kez
bir alıcının "bildirim gelmiyor" demesiyle öğrenilir; bu, ölçüm değil ihbardır.

#### Özet

- Teslim edilebilirlik bir evet/hayır değil, üç sonucun oranıdır: gelen kutusu, gecikme, hiç
  ulaşmama.
- Dört etken ayrı ayrı sayılabilir; modelde geri dönen ileti oranı 36, şikâyet 21, ani hacim
  artışı 20 puan götürür, doğrulama kaydı eksikliği ise 12 puanlık bir tavan koyar.
- Bozulma bir dönem sürer, toparlanma on: itibar 88'den 53'e bir dönemde iner, kara listede altı
  dönem geçer ve 80 eşiğine dönüş dipten sonra on dönem alır.
- Olaydan sonra gönderim tümüyle normalken bile 1.078 ileti hiç ulaşmaz, 403 ileti gecikir;
  bunlar içeriğinde hiçbir sorun olmayan iş emri bildirimleridir.
- Doğrulama kayıtları bir olay engellemez, tavan yükseltir; eksikken sistem kara liste eşiğine
  sürekli 12 puan daha yakın durur.
- Ölçülemeyen kısım alıcının kararıdır: gönderen taraf kabul ile reddi görür, gelen kutusuna
  konup konmadığını görmez ve itibar hiçbir yerde yayınlanmaz.

#### Sonraki Adım

Bu konu adı kapattı. Ad artık nereyi gösterdiğini biliyor, o adın adına kimin ileti
gönderebileceği kayıtlı, uyumsuz iletiye ne yapılacağı bildirilmiş ve teslimin bozulduğu yer
ölçülebilir durumda. Dört derste kapatılan kalemlerin hepsi **adla** ilgiliydi.

Geriye adın gösterdiği şey kalıyor. Bölge dosyasındaki her adres kaydı bir makineye çıkıyor ve o
makine, bu konu boyunca hiç sorulmayan bir durumda duruyor: kurulduğu günden beri **her yerden
erişilebilir**. Hangi kapıların dinlendiği, yönetim erişiminin nereden açık olduğu, üzerinde kaç
kimlik bilgisinin süresiz durduğu sayılmadı. Sonraki konu ölçeği addan makineye taşır ve aynı
soruyu orada sorar: varsayılan kurulum kaç kalem açık bırakıyor?

## Sertleştirme ve Yedekleme

Varsayılan olarak açık kalan yüzeyin kapatılması ve geri dönüşün kanıtlanması: varsayılan reddet güvenlik duvarı politikası, anahtar tabanlı uzak erişim ve sıçrama sunucusu, merkezî sır deposu ile dinamik kimlik bilgisinin ömrü, yama penceresi ve otomasyonun açık pencere süresine etkisi, yedekleme kapsamı, sıklığı ve saklaması ile geri yükleme tatbikatının kanıt değeri.

### Güvenlik Duvarı Yapılandırması

Source: https://academia.sh/tr/kurslar/sunucu-ve-sertlestirme/guvenlik-duvari-yapilandirmasi

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.

Ö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.

```js
// 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

```js
// 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

```js
// 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.

```js
// 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.

### Uzak Erişim Sertleştirme

Source: https://academia.sh/tr/kurslar/sunucu-ve-sertlestirme/uzak-erisim-sertlestirme

Parola tabanlı erişimin deneme yüzeyi bir dönem boyunca sayılır, anahtar tabanlıya geçince kapanan ve açılan yüzey ayrı ayrı ölçülür, sıçrama sunucusu eklenince doğrudan erişilebilir makine sayısıyla doğan tek hedef karşılaştırılır.

Önceki ders güvenlik duvarını varsayılan reddede bıraktı: yönetim kabuğu artık yalnız iç ağdan,
yönetim düğümü ayrıca ofis ağından erişilebilir. Kapı daraldı. Kapıdan geçmenin neye bağlı olduğu
ise değişmedi — bağlanan taraf hâlâ bir parola yazıyor ve parola, izin verilen bölgelerdeki her
kaynaktan denenebiliyor. Bu dersin ölçüsü kapının genişliği değil, kapının arkasındaki kilittir.

- **ST7.** Altı makine, üç kabuk hesabı ve beş özne kurgusal bölgesel ölçüm ağına aittir. Gerçek
  bir erişim kurulmuyor; ölçülen şey `node` ile yazılan modeldir.
- **ST8.** Deneme kaydı, tohumu görünür bir üreteçle üretildi; her koşum aynı diziyi verir. Gerçek
  dağılım bölgeye ve döneme göre değişir, sayıların büyüklük sırası değişmez.
- **ST9.** Anahtar dizeleri ve parmak izleri kurgusaldır; gerçek anahtar yazılmadı. Parmak izi
  yalnız aynı anahtarın iki yerde durduğunu göstermek için var.
- **ST10.** Bir makinede yetkili anahtar dosyasını güncellemek dört dakika sayıldı. Gerçekte bu süre
  otomasyona göre değişir; iptalin toplamı yarıçapla orantılı kalır.
- **ST11.** Anahtarın ömrü yok, iptal edilene kadar geçerlidir. Süreli kimlik bilgisi bu dersin
  dışındadır.
- **ST12.** Sıçrama sunucusu tek makine olarak modellendi. İkincisi kullanılabilirlik kalemini
  düşürür, tek hedef kalemini ikiye çıkarır.

#### Parola Düzeninin Deneme Yüzeyi

Model üç şey tutuyor: güvenlik duvarının hangi kaynakların ulaşmasına izin verdiği, otuz günlük
dönemde gözlenen parola denemeleri ve anahtar tabanlıya geçildiğinde ortaya çıkacak kopya kümesi.
Deneme kaydı elle yazılmak yerine kendi yazdığımız üreteçle kuruluyor; tohum kodda görünüyor.

```js
// erisim.mjs — uzak erisim ozneleri, anahtar kopyalari ve deneme ureteci; model, gercek erisim degil
export const MAKINE = ['toplayici-1', 'toplayici-2', 'dogrulayici', 'faturalama', 'veri-deposu', 'yonetim'];
export const HESAP = ['isletim', 'dagitim', 'bakim'];   // her makinede acik olan kabuk hesaplari
export const ULASAN = { ic: 90, ofis: 40 };             // guvenlik duvarinin izin verdigi kaynak sayisi
export const PAYLASIM = { isletim: 6, dagitim: 6, bakim: 1 }; // ayni parolayi tasiyan makine sayisi
const TOHUM = 20260401;                                 // uretec tohumu; her kosum ayni diziyi verir
function* uretec(t = TOHUM) {                           // kendi yazdigimiz dogrusal esleme
  let x = t;
  for (;;) { x = (x * 1103515245 + 12345) % 2147483648; yield x / 2147483648; }
}
export function denemeler(n = 400) {                    // otuz gunluk parola denemesi kaydi
  const g = uretec(); const kayit = [];
  const s = (k) => Math.floor(g.next().value * k);
  for (let i = 0; i < n; i += 1) {
    const bolge = g.next().value < 0.7 ? 'ic' : 'ofis';
    const yogun = g.next().value < 0.04;               // kaynaklarin bir bolumu yogun deniyor
    kayit.push({ kaynak: `${bolge}-${s(ULASAN[bolge]) + 1}`, makine: MAKINE[s(6)], hesap: HESAP[s(3)],
      deneme: yogun ? 400 + s(900) : 1 + s(6) });
  }
  return kayit;
}
// Anahtar kopyalari; ozne, kopyanin durdugu yer ve kurgu parmak izi.
export const KOPYA = [
  ['op-a', 'dizustu', 'kz7f-11ac'], ['op-a', 'yedek-arsiv', 'kz7f-11ac'],
  ['op-b', 'dizustu', 'kz7f-2be0'], ['op-c', 'dizustu', 'kz7f-3d41'],
  ['dagitim', 'yapilandirma-araci', 'kz7f-5f92'], ['dagitim', 'tumlesim-kosucusu', 'kz7f-5f92'],
  ['bakim-dis', 'dis-makine', 'kz7f-6a08'],
].map(([ozne, yer, parmak]) => ({ ozne, yer, parmak, ad: `${ozne}/${yer}` }));
// Hangi ozne hangi makinede yetkili (yetkili anahtar dosyalari).
export const YETKI = {
  'op-a': MAKINE, 'op-b': MAKINE, 'op-c': ['yonetim', 'faturalama'],
  'dagitim': MAKINE, 'bakim-dis': ['veri-deposu', 'yonetim'],
};
export const DOKUNUS_DK = 4;                            // bir makinede yetkili anahtar dosyasini guncelleme suresi
export const yaricap = (k, y = YETKI) => y[k.ozne].length;
export const kalem = (y = YETKI) => KOPYA.reduce((a, k) => a + yaricap(k, y), 0);
```

```js
// kosum1.mjs — parola tabanli erisimin deneme yuzeyi otuz gunluk kayittan sayilir
import { MAKINE, HESAP, ULASAN, PAYLASIM, denemeler } from './erisim.mjs';

const kayit = denemeler();
const top = (l) => l.reduce((a, x) => a + x.deneme, 0);
const yogun = kayit.filter((x) => x.deneme >= 100);
const ulasan = ULASAN.ic + ULASAN.ofis;
for (const [ad, v, not = ''] of [
  ['parola denemesi', top(kayit)],
  ['deneyen ayri kaynak', new Set(kayit.map((x) => x.kaynak)).size, `${ulasan} kaynak ulasabiliyor`],
  ['hedef (makine x hesap)', MAKINE.length * HESAP.length],
  ['denenebilir uclu', ulasan * MAKINE.length * HESAP.length, 'ulasan kaynak x hedef'],
  ['yogun kaynak (>=100 deneme)', new Set(yogun.map((x) => x.kaynak)).size, `${top(yogun)} deneme uretiyor`],
  ['denenmemis hedef', MAKINE.length * HESAP.length - new Set(kayit.map((x) => `${x.makine}|${x.hesap}`)).size],
]) console.log(`${ad.padEnd(29)}${String(v).padStart(6)}  ${not}`.trimEnd());
console.log('\ntek parola sizarsa dusen makine:');
for (const h of HESAP) console.log(`  ${h.padEnd(10)} ${PAYLASIM[h]}`);
```

```
parola denemesi               16505
deneyen ayri kaynak             124  130 kaynak ulasabiliyor
hedef (makine x hesap)           18
denenebilir uclu               2340  ulasan kaynak x hedef
yogun kaynak (>=100 deneme)      17  15159 deneme uretiyor
denenmemis hedef                  0

tek parola sizarsa dusen makine:
  isletim    6
  dagitim    6
  bakim      1
```

Güvenlik duvarı dış bölgeyi kapattı, deneme yüzeyi buna rağmen sıfır değil: iç ağdan doksan, ofis
ağından kırk kaynak yönetim kabuğuna ulaşabiliyor. Dönemde bu kaynakların yüz yirmi dördü gerçekten
denedi ve on altı bin beş yüz beş deneme üretti. On yedi yoğun kaynak bunun on beş bin yüz elli
dokuzunu tek başına üretiyor; o on yedisi engellense geri kalan yüz yedi kaynak yerinde durur.
Ölçülmesi gereken sayı denemeyi yapanların sayısı değil, denemeyi yapabileceklerin sayısıdır: yüz
otuz kaynak çarpı on sekiz hedef, yani 2340 üçlü. On sekiz hedefin hepsi dönem içinde en az bir kez
denenmiş.

Alt blok yüzeyin ikinci boyutunu veriyor. İşletim ve dağıtım hesapları altı makinede aynı parolayı
taşıyor, çünkü makineler aynı kurulum adımıyla kuruldu. Tek bir parolanın sızması altı makine
demektir; bakım hesabı makineye özgü olduğu için orada sayı bir. Aynı düzende iki farklı yarıçap
yan yana duruyor ve aradaki fark bir güvenlik kararından değil, kurulum kolaylığından geliyor.

#### Anahtar Tabanlı Erişim

```js
// kosum2.mjs — anahtar tabanli erisime gecilir; kapanan yuzey ve acilan yeni yuzey ayri sayilir
import { MAKINE, HESAP, ULASAN, KOPYA, DOKUNUS_DK, denemeler, yaricap, kalem } from './erisim.mjs';

const kayit = denemeler();
console.log(`kapanan  ${kayit.reduce((a, x) => a + x.deneme, 0)} parola denemesi, ` +
  `${new Set(kayit.map((x) => x.kaynak)).size} kaynak -> 0`);
console.log(`acilan   ${KOPYA.length} kopya, ${new Set(KOPYA.map((k) => k.ozne)).size} ozne, ` +
  `${new Set(KOPYA.map((k) => k.parmak)).size} ayri anahtar, omur yok\n`);
console.log('kopya                          yer                  yetkili  iptal dk  ayni anahtari tasiyan yer');
for (const k of KOPYA) {
  const es = KOPYA.filter((x) => x.parmak === k.parmak && x.ad !== k.ad).map((x) => x.yer);
  console.log(`${k.ad.padEnd(30)} ${k.yer.padEnd(20)} ${String(yaricap(k)).padEnd(8)} ` +
    `${String(yaricap(k) * DOKUNUS_DK).padEnd(9)} ${es.join(', ') || '-'}`);
}
const uclu = (ULASAN.ic + ULASAN.ofis) * MAKINE.length * HESAP.length;
const toplam = kayit.reduce((a, x) => a + x.deneme, 0);
console.log('\nduzen                 kapanan deneme  denenebilir uclu  anahtar kalemi');
for (const [ad, kapanan, kalan, ak] of [['yalniz parola', 0, uclu, 0],
  ['parola + anahtar', 0, uclu, kalem()], ['yalniz anahtar', toplam, 0, kalem()]])
  console.log(`${ad.padEnd(21)} ${String(kapanan).padEnd(15)} ${String(kalan).padEnd(17)} ${ak}`);
const yer = [...new Set(KOPYA.map((k) => k.yer))];
console.log(`\n(kopya, makine) kalemi         ${kalem()}`);
console.log(`kopyanin durdugu ayri yer      ${yer.length}   ${yer.join(', ')}`);
console.log(`en genis kopyanin yaricapi     ${Math.max(...KOPYA.map((k) => yaricap(k)))}`);
console.log(`butun kopyalari iptal etmek    ${kalem() * DOKUNUS_DK} dk`);
```

```
kapanan  16505 parola denemesi, 124 kaynak -> 0
acilan   7 kopya, 5 ozne, 5 ayri anahtar, omur yok

kopya                          yer                  yetkili  iptal dk  ayni anahtari tasiyan yer
op-a/dizustu                   dizustu              6        24        yedek-arsiv
op-a/yedek-arsiv               yedek-arsiv          6        24        dizustu
op-b/dizustu                   dizustu              6        24        -
op-c/dizustu                   dizustu              2        8         -
dagitim/yapilandirma-araci     yapilandirma-araci   6        24        tumlesim-kosucusu
dagitim/tumlesim-kosucusu      tumlesim-kosucusu    6        24        yapilandirma-araci
bakim-dis/dis-makine           dis-makine           2        8         -

duzen                 kapanan deneme  denenebilir uclu  anahtar kalemi
yalniz parola         0               2340              0
parola + anahtar      0               2340              34
yalniz anahtar        16505           0                 34

(kopya, makine) kalemi         34
kopyanin durdugu ayri yer      5   dizustu, yedek-arsiv, yapilandirma-araci, tumlesim-kosucusu, dis-makine
en genis kopyanin yaricapi     6
butun kopyalari iptal etmek    136 dk
```

İlk satır kapanan yüzeydir: on altı bin beş yüz beş deneme sıfıra iner ve yüz yirmi dört kaynağın
hiçbiri artık deneyemez. Kapanan şey parola değil, tahmin edilebilirliktir — denenecek bir şey kalmaz.
İkinci satır aynı anda açılanı sayıyor: yedi kopya, beş özne, beş ayrı anahtar. Kopya sayısı özne
sayısından fazla, çünkü aynı anahtar iki ayrı yerde duruyor.

Tablo bu kopyaların nerede durduğunu ve ne kadar taşıdığını gösteriyor. Anahtar bir dizüstünde, bir
yedek arşivinde, bir yapılandırma aracında, bir tümleşim koşucusunda ve bir dış makinede duruyor —
beş ayrı yer, beşi de ayrı korunuyor. Yetkili sütunu her kopyanın yarıçapıdır: dört kopya altı
makinede birden geçerli. Toplam otuz dört `(kopya, makine)` kalemi var ve bunların her biri, o kopya
sızarsa açılan bir kapıdır. Parola düzeninde sayılan yüzey ortadan kalkmadı, biçim değiştirdi:
tahmin edilebilir yüz otuz kaynak yerine korunması gereken beş yer.

Ortadaki üç satırlık blok geçişin kendisini ölçüyor ve bu dersin en kolay atlanan sayısını veriyor.
Anahtar tabanlı erişimi açmak tek başına hiçbir şey kapatmıyor: parola girişi de açık kaldığı sürece
kapanan deneme sıfır, denenebilir üçlü 2340'ta duruyor. Buna karşılık otuz dört kalemlik
yeni yüzey açıldığı anda oradadır. Ara durum iki düzenin de yüzeyini birden taşır ve kurulumların
çoğu bu ara durumda haftalarca kalır, çünkü anahtar dağıtımı bitmeden parola girişini kapatmak
kimseyi dışarıda bırakma riski taşır. Kapatan adım anahtarın eklenmesi değil, parolanın
kaldırılmasıdır; ikisi ayrı sayılmadıkça birincisi ikincisinin yerine geçer.

İptal sütunu kararın maliyetini veriyor. Bir kopya sızarsa, o öznenin yetkili olduğu her makinede
yetkili anahtar dosyasına dokunmak gerekir: en geniş kopyada altı makine, yirmi dört dakika; bütün
kopyalar için yüz otuz altı dakika. Son sütun ise iptalin yan etkisidir. Yedek arşivindeki kopya
operatörün dizüstündeki kopyayla aynı anahtardır; birini iptal etmek ötekini de iptal eder. Sızıntının
hangi kopyadan geldiği bilinmeden yapılan bir iptal, operatörün kendi erişimini de kapatır.

İkinci satırın sonundaki "ömür yok" ise bu dersin kapatılamayan kalemidir. Parola denemesi görünen
bir şeydi: sayılıyordu, kaynağı biliniyordu, yoğunlaşması fark ediliyordu. Sızmış bir anahtarla
yapılan giriş meşru bir girişten ayırt edilemez ve anahtar iptal edilene kadar geçerlidir. Sızıntı
penceresini kapatan şey sürenin dolması değil, birinin fark etmesidir.

#### Sıçrama Sunucusu

```js
// kosum3.mjs — sicrama sunucusu eklenir; dogrudan erisim duser, tek bir hedef dogar
import { MAKINE, KOPYA, YETKI, DOKUNUS_DK, yaricap, kalem } from './erisim.mjs';

const SICRAMA = Object.fromEntries(Object.keys(YETKI).map((o) => [o, ['sicrama']]));
const IC_ANAHTAR = 1;                                   // sicrama sunucusunda duran, makinelere yetkili anahtar
const olc = (y) => [kalem(y), Math.max(...KOPYA.map((k) => yaricap(k, y))), kalem(y) * DOKUNUS_DK];
const [aK, aY, aD] = olc(YETKI), [bK, bY, bD] = olc(SICRAMA);
console.log('olcu                                dogrudan  sicrama sunuculu');
for (const [ad, x, y] of [
  ['dogrudan erisilebilir makine', MAKINE.length, 1],
  ['(kopya, makine) kalemi', aK, bK],
  ['bir kopya sizinca dusen makine', aY, bY],
  ['butun kopyalari iptal etmek (dk)', aD, bD],
  ['tek noktada duran ic anahtar', 0, IC_ANAHTAR],
  ['ic anahtarin yetkili oldugu makine', 0, MAKINE.length],
  ['toplam erisim kalemi', aK, bK + IC_ANAHTAR * MAKINE.length],
]) console.log(`${ad.padEnd(35)} ${String(x).padEnd(9)} ${y}`);
console.log('\nsicrama sunucusunun kendi yuzeyi (kalem kalem):');
for (const [ad, n] of [['dinlenen kapi', 3], ['yetkili ozne', Object.keys(SICRAMA).length],
  ['uzerinde duran ic anahtar', IC_ANAHTAR], ['oturum kaydi tutan tek nokta', 1],
  ['acil kacis yolu (dogrudan erisim)', 1], ['duserse erisilemeyen makine', MAKINE.length],
  ['ele gecirilirse ulasilan makine', MAKINE.length]]) console.log(`  ${ad.padEnd(35)}${n}`);
```

```
olcu                                dogrudan  sicrama sunuculu
dogrudan erisilebilir makine        6         1
(kopya, makine) kalemi              34        7
bir kopya sizinca dusen makine      6         1
butun kopyalari iptal etmek (dk)    136       28
tek noktada duran ic anahtar        0         1
ic anahtarin yetkili oldugu makine  0         6
toplam erisim kalemi                34        13

sicrama sunucusunun kendi yuzeyi (kalem kalem):
  dinlenen kapi                      3
  yetkili ozne                       5
  uzerinde duran ic anahtar          1
  oturum kaydi tutan tek nokta       1
  acil kacis yolu (dogrudan erisim)  1
  duserse erisilemeyen makine        6
  ele gecirilirse ulasilan makine    6
```

İlk dört satır adımı savunuyor: doğrudan erişilebilir makine altıdan bire, `(kopya, makine)` kalemi
otuz dörtten yediye, bir kopya sızınca düşen makine altıdan bire, bütün kopyaları iptal etme süresi
yüz otuz altı dakikadan yirmi sekize iniyor. Dört sütun da aynı yöne gidiyor. Anahtar kopyaları
artık yalnız tek bir makinede yetkili, dolayısıyla bir dizüstünün çalınması altı makine değil bir
makine demek.

Sonraki üç satır bedeli veriyor. Sıçrama sunucusunda, altı makinenin hepsinde yetkili bir iç anahtar
duruyor; onsuz sıçrama sunucusu bir işe yaramaz. Toplam erişim kalemi otuz dörtten on üçe iniyor —
sıfıra değil. Asıl değişen dağılımdır: otuz dört kalem beş ayrı yere dağılmıştı; on üç kalemin altısı
tek bir makinede toplandı. Yüzey küçüldü ve aynı anda yoğunlaştı; bu iki cümle birbirinin karşılığı
değil, ikisi birden doğrudur.

Alt blok sıçrama sunucusunun kendi yüzeyini kalem kalem sayıyor: üç dinlenen kapı, beş yetkili özne,
üzerinde duran bir iç anahtar, oturum kaydını tutan tek nokta. Son iki satır aynı makineyi iki
yönden okuyor. Sıçrama sunucusu düşerse altı makinenin hiçbirine yönetim erişimi kalmaz; bu yüzden
bir acil kaçış yolu bırakılır ve o kaçış yolu tam olarak kapatılmak istenen doğrudan erişimdir.
Ele geçirilirse yine altı makineye ulaşılır. Sıçrama sunucusu bir savunma değil, bir yoğunlaşma
noktasıdır: değeri, altı makinenin gözlenmesi yerine bir makinenin gözlenmesini yeterli kılmasından
gelir — o bir makine gerçekten gözlendiği sürece.

#### Özet

- Güvenlik duvarı dış bölgeyi kapattıktan sonra bile 130 kaynak yönetim kabuğuna ulaşabiliyor;
  dönemde 124'ü deneyip 16.505 deneme üretti, 17 yoğun kaynak bunun 15.159'unu tek başına üretiyor.
  Ölçülen yüzey denemeyi yapanlar değil, 130 × 18 = 2340 denenebilir üçlüdür.
- Aynı parolanın altı makinede paylaşılması ikinci bir yarıçap kalemidir: işletim ve dağıtım
  hesaplarında tek bir sızıntı 6 makine, makineye özgü bakım hesabında 1 makine demektir.
- Anahtar tabanlıya geçmek 16.505 denemeyi ve 124 kaynağı tümüyle kapatıyor; karşılığında 7 kopya,
  5 ayrı yer ve 34 `(kopya, makine)` kalemi açıyor. Yüzey kaybolmuyor, biçim değiştiriyor.
- İptal maliyeti yarıçapla orantılıdır: en geniş kopya 6 makine ve 24 dakika, bütün kopyalar 136
  dakika. Aynı anahtarın iki yerde durması iptali yan etkili yapar — bir kopyayı iptal etmek
  ötekini de kapatır.
- Anahtarın ömrü yok: sızmış bir anahtarla yapılan giriş meşru girişten ayırt edilemez ve pencere
  ancak biri fark edince kapanır. Parola denemesi sayılabiliyordu, bu sayılamıyor.
- Sıçrama sunucusu doğrudan erişilebilir makineyi 6'dan 1'e, kalemi 34'ten 7'ye, iptal süresini
  136 dakikadan 28'e indiriyor; karşılığında 6 makinede yetkili bir iç anahtar tek bir makinede
  toplanıyor, toplam kalem 13'te kalıyor ve düşerse 6 makineye erişim, ele geçirilirse yine 6
  makine söz konusu olur.

#### Sonraki Adım

Bu dersin anahtarı iptal edilene kadar geçerli. Aynı şey uygulamaların taşıdığı kimlik bilgileri
için de doğrudur: veri deposu parolası, kuyruk anahtarı ve posta geçidi belirteci bir kez yazılır ve
kimse ne zaman değişeceğini söylemez. Sonraki dersin ekseni bu yüzden ömürdür. Ömrü olmayan bir
sırda sızıntı penceresi sonsuzdur; ömrü belli bir kimlik bilgisinde pencere ömür kadardır. Ömür
taranacak: kısa ömür pencereyi düşürür ama yenileme yükünü ve merkezî depoya bağımlılığı artırır,
depo düştüğünde kaç servisin kaç dakika sonra çalışamaz hâle geldiği sayılır. Merkezî deponun
kendisi de bir yüzeydir ve kaç öznenin kaç sırra erişebildiğiyle ölçülür.

### Sır Yönetimi Sistemleri

Source: https://academia.sh/tr/kurslar/sunucu-ve-sertlestirme/sir-yonetimi-sistemleri

Sırrın ekseni ömürdür: statik sırda sızıntı penceresi sonsuzdur, ömrü belli kimlik bilgisinde ömür kadardır. Ömür taranır, yenileme yükü ve depo kesintisine dayanma sayılır, merkezî deponun kendi erişim yüzeyi kalem kalem çıkarılır.

Önceki dersin anahtarı iptal edilene kadar geçerliydi; ölçülemeyen tek kalem buydu. Uygulamaların
taşıdığı kimlik bilgileri için de aynısı geçerlidir: veri deposu kimliği, kuyruk anahtarı ve posta
geçidi belirteci kurulum günü yazılır ve ne zaman değişecekleri hiçbir yerde yazmaz. Sırların
üretimde nasıl saklandığı M22/K01'de, dağıtım hattının sırlara nasıl eriştiği M22/K04'te ölçüldü;
ikisi de burada tekrarlanmıyor. Buranın tek ekseni ömürdür — bir kimlik bilgisi ne kadar süre
geçerli kalıyor ve sızarsa pencere ne kadar açık duruyor.

- **ST13.** Beş sır, altı servis ve üç ortam kurgusal bölgesel ölçüm ağına aittir. Gerçek sır
  yazılmadı, adlar kurgusaldır; ölçülen şey `node` ile yazılan modeldir.
- **ST14.** Dönem otuz gün, yani 43.200 dakika sayıldı.
- **ST15.** Depo kesintisinde örneklerin kalan ömrü, ömür aralığına eşit aralıklarla dağıtıldı;
  rastgelelik yok. Gerçekte dağılım yenileme zamanlamasına bağlıdır, sonucun yönü değişmez.
- **ST16.** Bir kimlik bilgisi ya geçerlidir ya değil. Kısmi yetki, yenileme başarısızlığında
  yeniden deneme ve önbelleğe alınmış oturum modellenmiyor.
- **ST17.** Sırrın içeriği, üretilme biçimi ve şifrelenmesi ölçülmüyor. Ölçülen tek şey ömür ve
  erişim kalemidir.
- **ST18.** Merkezî depo tek bir yer olarak modellendi. Çoğaltılmış bir depo kesinti kalemini
  düşürür, erişim kalemini düşürmez.

#### Statik Sır Düzeni

Model beş sırrı, sırlara ihtiyaç duyan altı servisi, üç ortamı ve statik düzende sırrın durduğu
yerleri tutuyor. Ömür listesi taranacak değerleri veriyor; `null` ömrü olmayan, yani statik sırrı
gösteriyor.

```js
// sir.mjs — sir kumesi, erisim matrisi ve omur modeli; gercek sir yok, adlar kurgusaldir
export const SIR = ['veri-deposu-kimligi', 'kuyruk-anahtari', 'posta-gecidi-belirteci',
  'olcut-yazma-anahtari', 'arsiv-anahtari'];
export const SERVIS = {                                  // servis -> ihtiyac duydugu sirlar
  'okuma-toplayici': ['veri-deposu-kimligi', 'kuyruk-anahtari'],
  'dogrulayici': ['veri-deposu-kimligi', 'kuyruk-anahtari'],
  'faturalama': ['veri-deposu-kimligi', 'posta-gecidi-belirteci'],
  'is-emri': ['veri-deposu-kimligi', 'kuyruk-anahtari', 'posta-gecidi-belirteci'],
  'gecelik-toplu-is': ['veri-deposu-kimligi', 'arsiv-anahtari'],
  'olcut-toplayici': ['olcut-yazma-anahtari'],
};
export const ORTAM = ['gelistirme', 'hazirlik', 'uretim'];
export const ORNEK = Object.keys(SERVIS).flatMap((s) => ORTAM.map((o) => ({ servis: s, ortam: o })));
export const STATIK_YER = ['yapilandirma-deposu', 'ortam-degiskeni', 'yedek-goruntusu', 'gelistirici-dizustu'];
export const DONEM_DK = 30 * 24 * 60;                    // otuz gunluk donem
export const OMUR = [5, 15, 60, 480, 1440, null];        // dakika; null = statik, omur yok
// Insan ve otomasyon ozneleri; hangi sirlara erisebildikleri.
export const OZNE = {
  'op-a': SIR, 'op-b': ['veri-deposu-kimligi', 'kuyruk-anahtari', 'arsiv-anahtari'],
  'op-c': ['posta-gecidi-belirteci'], 'dagitim': SIR, 'gozlem': ['olcut-yazma-anahtari'],
};
// Her sir dinamik uretilemez; ikinci alan gerekcedir.
export const DINAMIK = {
  'veri-deposu-kimligi': [true, 'depo hesabi istege gore acilip kapatilabilir'],
  'kuyruk-anahtari': [true, 'kuyruk gecici yetki verebiliyor'],
  'olcut-yazma-anahtari': [true, 'yazma yetkisi kisa sureli verilebilir'],
  'posta-gecidi-belirteci': [false, 'dis tarafca veriliyor, bizde uretilemez'],
  'arsiv-anahtari': [false, 'sifreleme anahtari; dondurulurse eski arsiv okunamaz'],
};
export const ornekKalem = () => ORNEK.reduce((a, o) => a + SERVIS[o.servis].length, 0);
export const ozneKalem = () => Object.values(OZNE).reduce((a, s) => a + s.length, 0);
export const dondurmeEtkisi = (s) => ORNEK.filter((o) => SERVIS[o.servis].includes(s)).length;
// Depo kesintisinde her ornegin kalan omru: aralik esit araliklarla bolundu, rastgelelik yok.
export const kalanOmur = (omur, n = ORNEK.length) =>
  Array.from({ length: n }, (_, i) => (omur * (i + 0.5)) / n);
```

```js
// kosum1.mjs — statik sir duzeninde kalemler ve dondurme maliyeti sayilir
import { SIR, SERVIS, ORTAM, ORNEK, STATIK_YER, ornekKalem, dondurmeEtkisi } from './sir.mjs';

for (const [ad, v, not = ''] of [
  ['sir', SIR.length],
  ['servis x ortam = ornek', ORNEK.length, `${Object.keys(SERVIS).length} servis, ${ORTAM.length} ortam`],
  ['(ornek, sir) kalemi', ornekKalem()],
  ['sirrin durdugu ayri yer', STATIK_YER.length, STATIK_YER.join(', ')],
  ['sir kopyasi (sir x yer)', SIR.length * STATIK_YER.length],
  ['sirrin omru', 'yok', 'kurulumdan beri degismedi'],
]) console.log(`${ad.padEnd(26)}${String(v).padStart(4)}  ${not}`.trimEnd());
console.log('\nbir sirri dondurmek kac ornegi yeniden baslatir:');
for (const s of SIR) console.log(`  ${s.padEnd(24)} ${dondurmeEtkisi(s)}`);
```

```
sir                          5
servis x ortam = ornek      18  6 servis, 3 ortam
(ornek, sir) kalemi         36
sirrin durdugu ayri yer      4  yapilandirma-deposu, ortam-degiskeni, yedek-goruntusu, gelistirici-dizustu
sir kopyasi (sir x yer)     20
sirrin omru                yok  kurulumdan beri degismedi

bir sirri dondurmek kac ornegi yeniden baslatir:
  veri-deposu-kimligi      15
  kuyruk-anahtari          9
  posta-gecidi-belirteci   6
  olcut-yazma-anahtari     3
  arsiv-anahtari           3
```

Beş sır, on sekiz servis örneğine dağıldığında otuz altı `(örnek, sır)` kalemi ediyor. Bunun
üstüne sırrın dört ayrı yerde durması geliyor: yapılandırma deposunda, çalışan sürecin ortam
değişkeninde, yedek görüntüsünde ve geliştirici dizüstünde. Beş sır çarpı dört yer, yirmi kopya.
Bu yerlerin ikisi — yedek görüntüsü ve dizüstü — erişim kaydı tutmaz; oradan okunan bir sırrın
okunduğu hiçbir yerde görünmez.

Alt blok döndürmenin neden yapılmadığını sayıyla veriyor. Veri deposu kimliği on beş örnekte
kullanılıyor; onu değiştirmek on beş örneği yeniden başlatmak demek ve bu on beş örnek üç ayrı
ortama yayılmış durumda. Döndürmenin maliyeti tam olarak döndürmemenin nedenidir. Sonuç, tabloda
"ömür: yok" satırıdır — sır kurulumdan beri aynıdır, dolayısıyla sızmışsa sızdığı günden beri
geçerlidir. Sızıntı penceresi burada bir süre değil, bir durumdur: birileri fark edene kadar açık.

#### Ömür Taraması

```js
// kosum2.mjs — omur taranir: sizinti penceresi, yenileme yuku ve depo kesintisine dayanma
import { ORNEK, DONEM_DK, OMUR, kalanOmur } from './sir.mjs';

const d1 = (x) => (Math.round(x * 10) / 10).toFixed(1);
console.log('omur      sizinti penceresi  donemde     depo kesintisinde     30 dk kesintide');
console.log('(dk)      (ort. dk)          yenileme    ilk dusme / hepsi(dk) calisamayan ornek');
for (const omur of OMUR) {
  if (omur === null) {
    console.log(`${'statik'.padEnd(9)} ${'sonsuz'.padEnd(18)} ${String(0).padEnd(11)} ` +
      `${'-'.padEnd(21)} 0`);
    continue;
  }
  const kalan = kalanOmur(omur);
  console.log(`${String(omur).padEnd(9)} ${d1(omur / 2).padEnd(18)} ` +
    `${String(ORNEK.length * Math.round(DONEM_DK / omur)).padEnd(11)} ` +
    `${`${d1(kalan[0])} / ${d1(kalan[kalan.length - 1])}`.padEnd(21)} ${kalan.filter((k) => k < 30).length}`);
}
```

```
omur      sizinti penceresi  donemde     depo kesintisinde     30 dk kesintide
(dk)      (ort. dk)          yenileme    ilk dusme / hepsi(dk) calisamayan ornek
5         2.5                155520      0.1 / 4.9             18
15        7.5                51840       0.4 / 14.6            18
60        30.0               12960       1.7 / 58.3            9
480       240.0              1620        13.3 / 466.7          1
1440      720.0              540         40.0 / 1400.0         0
statik    sonsuz             0           -                     0
```

Tablo tek bir kararın üç ayrı sonucunu yan yana koyuyor. Beş dakikalık ömürde sızıntı penceresi
ortalama iki buçuk dakikaya iniyor — sızmış bir kimlik bilgisi neredeyse hiçbir işe yaramaz. Bedeli
sağdaki iki sütunda: dönemde yüz elli beş bin beş yüz yirmi yenileme ve depoda kesinti başladığında
ilk örneğin altı saniye içinde, hepsinin beş dakika içinde çalışamaz hâle gelmesi. Statik satırı
tam tersidir: sıfır yenileme, kesintiden hiç etkilenmeme ve sonsuz pencere.

Aradaki satırlar kararın gerçekten alındığı yerdir. Altmış dakikalık ömürde pencere yarım saate
iniyor, yenileme on iki bin dokuz yüz altmışa düşüyor, ama otuz dakikalık bir depo kesintisinde on
sekiz örneğin dokuzu çalışamaz hâle geliyor. Sekiz saatlik ömürde aynı kesintide yalnız bir örnek
düşüyor ve pencere dört saate çıkıyor. Yirmi dört saatlik ömürde kesinti hiçbir örneği düşürmüyor,
pencere on iki saat.

Sağdan ikinci sütun bu tablonun asıl bulgusudur: ömür, deponun kabul edilebilir kesinti süresini
belirliyor. Kesinti seçilen ömrün altında kaldığı sürece örneklerin çoğu ayakta kalır; kesinti ömrü
aştığında hepsi düşer. Yani "sızıntı penceresini kısaltalım" kararı, farkında olunmadan "deponun
kesintisiz çalışması gerekiyor" kararıdır. Beş dakikalık ömür seçildiğinde depo, on sekiz örneğin
hepsi için beş dakikadan uzun süre kaybolamayan bir bağımlılıktır — ve bu, hiçbir sırrın taşımadığı
yeni bir kullanılabilirlik kalemi getirir.

#### Ömrü Kısaltılamayan Sırlar

Ömür taraması bütün sırların ömrünün seçilebildiğini varsayıyor. Beş sırdan kaçının ömrü gerçekten
seçilebilir, ayrı bir sayıdır.

```js
// kosum4.mjs — her sir dinamik uretilemez; omur ekseninin disinda kalan kalemler sayilir
import { SIR, SERVIS, ORNEK, DINAMIK, ornekKalem } from './sir.mjs';

console.log('sir                       dinamik  gerekce');
for (const s of SIR) console.log(`  ${s.padEnd(24)} ${(DINAMIK[s][0] ? 'evet' : 'hayir').padEnd(8)} ${DINAMIK[s][1]}`);
const statik = (s) => !DINAMIK[s][0];
const kalem = ORNEK.reduce((a, o) => a + SERVIS[o.servis].filter(statik).length, 0);
const ornek = ORNEK.filter((o) => SERVIS[o.servis].some(statik));
console.log('');
for (const [ad, v] of [
  ['omru kisaltilabilen sir', `${SIR.filter((s) => !statik(s)).length} / ${SIR.length}`],
  ['statik kalmak zorunda olan sir', `${SIR.filter(statik).length} / ${SIR.length}`],
  ['statik kalan (ornek, sir) kalemi', `${kalem} / ${ornekKalem()}`],
  ['en az bir statik sir tasiyan ornek', `${ornek.length} / ${ORNEK.length}`],
  ['bu orneklerde sizinti penceresi', 'sonsuz'],
]) console.log(`${ad.padEnd(36)}${v}`);
console.log(`\ntasiyan servisler: ${[...new Set(ornek.map((o) => o.servis))].join(', ')}`);
```

```
sir                       dinamik  gerekce
  veri-deposu-kimligi      evet     depo hesabi istege gore acilip kapatilabilir
  kuyruk-anahtari          evet     kuyruk gecici yetki verebiliyor
  posta-gecidi-belirteci   hayir    dis tarafca veriliyor, bizde uretilemez
  olcut-yazma-anahtari     evet     yazma yetkisi kisa sureli verilebilir
  arsiv-anahtari           hayir    sifreleme anahtari; dondurulurse eski arsiv okunamaz

omru kisaltilabilen sir             3 / 5
statik kalmak zorunda olan sir      2 / 5
statik kalan (ornek, sir) kalemi    9 / 36
en az bir statik sir tasiyan ornek  9 / 18
bu orneklerde sizinti penceresi     sonsuz

tasiyan servisler: faturalama, is-emri, gecelik-toplu-is
```

Üç sır için dinamik üretim mümkün: veri deposu hesabı istek üzerine açılıp kapatılabiliyor, kuyruk
geçici yetki verebiliyor, ölçüt yazma yetkisi kısa süreli tanımlanabiliyor. İki sır için mümkün
değil ve gerekçeleri farklı türden. Posta geçidi belirteci dış bir tarafça veriliyor; ömrünü
belirleyen taraf biz değiliz, dolayısıyla ömür ekseninde yapılabilecek bir şey yok. Arşiv anahtarı
ise bir şifreleme anahtarıdır; döndürüldüğünde eski arşiv okunamaz hâle gelir, yani ömrünü kısaltmak
sırrın işlevini bozar.

Sayılar tarama tablosunun kapsamını daraltıyor. Otuz altı `(örnek, sır)` kaleminin dokuzu ömür
ekseninin dışında kalıyor ve on sekiz örneğin dokuzu — faturalama, iş emri ve gecelik toplu iş — en
az bir statik sır taşımaya devam ediyor. Bu dokuz örnek için önceki bölümün bütün sütunları
geçersizdir: sızıntı penceresi ömür kadar değil, sonsuzdur. Beş dakikalık ömür seçilse bile sistemin
yarısı statik sır taşır. Ömür ekseni gerçek bir eksendir ama her sırra uygulanamaz ve
uygulanamayanlar tam olarak dışarıya bakan iki sırdır: posta geçidine giden belirteç ve arşivi açan
anahtar.

#### Merkezî Deponun Kendi Yüzeyi

```js
// kosum3.mjs — merkezi deponun kendi yuzeyi: kac ozne kac sirra erisebiliyor
import { SIR, ORNEK, STATIK_YER, OZNE, ornekKalem, ozneKalem } from './sir.mjs';

console.log('ozne         erisebildigi sir');
for (const [o, s] of Object.entries(OZNE))
  console.log(`  ${o.padEnd(10)} ${String(s.length).padEnd(3)} ${s.length === SIR.length ? '(hepsi)' : s.join(', ')}`);
console.log(`  ${'servis'.padEnd(10)} ${ornekKalem()}  (${ORNEK.length} ornek, ortalama ${ornekKalem() / ORNEK.length} sir)`);
const toplam = ozneKalem() + ornekKalem();
console.log(`\nolcu                                 statik   merkezi depo`);
for (const [ad, a, b] of [
  ['sirrin durdugu ayri yer', STATIK_YER.length, 1],
  ['sir kopyasi', SIR.length * STATIK_YER.length, SIR.length],
  ['butun sirlari tasiyan nokta', STATIK_YER.length, 1],
  ['(ozne, sir) kalemi', toplam, toplam],
  ['kaydi tutulan ve iptal edilebilen', 0, toplam],
  ['butun sirlara erisen ozne', Object.values(OZNE).filter((s) => s.length === SIR.length).length,
    Object.values(OZNE).filter((s) => s.length === SIR.length).length],
  ['depo dustugunde yenileyemeyen ornek', 0, ORNEK.length],
]) console.log(`${ad.padEnd(36)} ${String(a).padEnd(8)} ${b}`);
```

```
ozne         erisebildigi sir
  op-a       5   (hepsi)
  op-b       3   veri-deposu-kimligi, kuyruk-anahtari, arsiv-anahtari
  op-c       1   posta-gecidi-belirteci
  dagitim    5   (hepsi)
  gozlem     1   olcut-yazma-anahtari
  servis     36  (18 ornek, ortalama 2 sir)

olcu                                 statik   merkezi depo
sirrin durdugu ayri yer              4        1
sir kopyasi                          20       5
butun sirlari tasiyan nokta          4        1
(ozne, sir) kalemi                   51       51
kaydi tutulan ve iptal edilebilen    0        51
butun sirlara erisen ozne            2        2
depo dustugunde yenileyemeyen ornek  0        18
```

Üst blok deponun kendi erişim yüzeyidir. Beş öznenin ikisi beş sırrın beşine birden erişebiliyor:
bir operatör ve dağıtım otomasyonu. Matris yazılmış, üç özne için gerçekten daraltılmış, ikisi için
hiç daraltılmamış. Servis örnekleri otuz altı kalem ekliyor ve ortalaması iki — servisler dar,
insanlar geniş. Toplam elli bir `(özne, sır)` kalemi var ve her biri, o özne ele geçirilirse açılan
bir sırdır.

Alt tablo iki düzeni yan yana koyuyor ve ilk üç satır merkezî deponun kazancıdır: sırrın durduğu yer
dörtten bire, kopya yirmiden beşe, bütün sırları taşıyan nokta dörtten bire iniyor. Dördüncü satır
ise kazanç değil: `(özne, sır)` kalemi elli birde kalıyor. Merkezî depo erişim sayısını azaltmıyor.
Statik düzende de aynı elli bir erişim vardı; farkı, hiçbirinin bir yerde yazılı olmamasıydı.

Beşinci satır bu dersin gerçek kazancıdır. Statik düzende kaydı tutulan ve iptal edilebilen erişim
sıfırdı — yedek görüntüsünden okunan bir sır için ne kayıt vardı ne de tek tek geri alınabilirdi.
Merkezî depoda elli bir erişimin elli biri hem kaydedilebilir hem iptal edilebilir. Merkezî deponun
verdiği şey daha az erişim değil, sayılabilir ve geri alınabilir erişimdir.

Son satır bedeli tekrarlıyor: depo düştüğünde on sekiz örnek yenileyemez; statik düzende ise sıfır örnek
etkilenirdi. Kapatılamayan kalem de burada duruyor — bütün sırları taşıyan tek nokta. Statik düzende
bu noktadan dört tane vardı, merkezî depoda bir tane var. Dörtten bire inmek gerçek bir kazançtır,
ama sıfır olmuyor ve o tek nokta artık hem bütün sırları hem bütün servislerin çalışabilirliğini
taşıyor.

#### Özet

- Statik düzende 5 sır 18 örneğe dağılıp 36 `(örnek, sır)` kalemi ediyor ve 4 ayrı yerde toplam 20
  kopya hâlinde duruyor; bu yerlerin ikisi erişim kaydı tutmuyor. Döndürme maliyeti döndürmemenin
  nedenidir: en çok paylaşılan sırrı değiştirmek 15 örneği yeniden başlatmayı gerektiriyor, bu
  yüzden sır kurulumdan beri aynı ve sızıntı penceresi bir süre değil bir durum — biri fark edene
  kadar açık.
- Ömür taraması üç sonucu birlikte veriyor: 5 dakikalık ömürde pencere 2,5 dakika ama dönemde
  155.520 yenileme ve kesintide 5 dakika içinde 18 örneğin hepsi düşüyor; statikte pencere sonsuz,
  yenileme 0 ve kesintinin hiç etkisi yok.
- Ömür, deponun kabul edilebilir kesinti süresini belirliyor: 60 dakikalık ömürde 30 dakikalık bir
  kesinti 18 örneğin 9'unu, 480 dakikalık ömürde 1'ini, 1440 dakikalık ömürde hiçbirini düşürüyor.
- Ömür ekseni her sırra uygulanamıyor: 5 sırdan 2'si statik kalmak zorunda (biri dış tarafça
  veriliyor, öteki şifreleme anahtarı) ve 36 kalemin 9'u, 18 örneğin 9'u ömür ekseninin dışında
  kalıp sonsuz pencereyi koruyor.
- Merkezî depo sırrın durduğu yeri 4'ten 1'e, kopyayı 20'den 5'e indiriyor ama `(özne, sır)` kalemi
  51'de kalıyor; 5 öznenin 2'si bütün sırlara erişiyor. Kazanç erişimin azalması değil, 0 olan
  kaydedilebilir ve iptal edilebilir erişimin 51 olmasıdır.
- Kapatılamayan kalem, bütün sırları taşıyan tek noktadır: statik düzende 4 taneydi, merkezî depoda
  1 tane — ama o tek nokta artık 18 örneğin çalışabilirliğini de taşıyor.

#### Sonraki Adım

Bu üç ders üç ayrı yoğunlaşma noktası bıraktı: dışarıya bakan yönetim düğümü, bütün erişimin
geçtiği sıçrama sunucusu ve bütün sırları taşıyan depo. Üçünün de ortak bir özelliği var — üçü de
yazılımdır ve üçünün de yazılımı eskiyor. Bir sertleştirme adımı, koştuğu kodun bilinen bir açığı
kalmadığı sürece geçerlidir. Sonraki dersin sorusu bu yüzden yamalardır: bir düzeltme yayımlandığı
anla makinelere uygulandığı an arasında kaç makine ne kadar süre açık kalıyor, yama penceresini
daraltmak kaç yeniden başlatma ve kaç kesinti dakikası istiyor, otomatik uygulanan yama ile
onaylanarak uygulanan yama arasındaki fark kaç gün ve kaç makine ediyor.

### Yama Yönetimi

Source: https://academia.sh/tr/kurslar/sunucu-ve-sertlestirme/yama-yonetimi

Kusur duyurusundan yamanın uygulanmasına kadar geçen açık pencerenin dört parçaya ayrılması: beş pencere düzeninde ortalama açık pencere, kesinti ve geri alma sayısının karşılaştırılması, otomatik yamanın kazandırdığı günün ürettiği sınanmamış yama riskiyle aynı tabloda okunması ve yamalanamayan kalemin adıyla yazılması.

Önceki ders erişimi daralttı ve sırların ömrünü kısalttı. Ama o kimlik bilgisini kullanan yazılımın
kendisi — çekirdek, sistem kitaplığı, dil çalışma zamanı, ters vekil — durduğu yerde eskiyor. Bir
kusur duyurusu yapıldığı anda, o bileşenin kurulu olduğu **her makine** bir açık yüzey kalemine
dönüşür ve kalem, yama uygulanana kadar açık kalır. Varsayılanın burada bıraktığı bir ayar değil, bir
**boşluktur**: hangi makinede hangi sürümün koştuğunu kimse bilmez ve yama, bir şey bozulduğunda
uygulanır. Ölçü **açık pencere**dir — duyuru ile uygulama arasında geçen süre; kaç kalemin ne kadar
süre açık kaldığı ise **açık kalem-günü**dür.

#### Açık Pencere Dört Parçadır

Açık pencere tek bir sayı değil, bağımsız dört parçanın toplamıdır; kusurlu bir yamada yeniden
deneme süresi de bu dördün üstüne biner ve tablodaki toplam sütunu bu yüzden dördün toplamından
büyüktür. **Fark etme**, duyuruyla o bileşenin filoda kurulu olduğunun görülmesi arasındaki
süredir ve envanter tarama aralığına bağlıdır. **Sınama**, yamanın üretim dışı bir ortamda
denenmesidir. **Pencere bekleme**, hazır yamanın bir sonraki bakım aralığını beklemesidir.
**Uygulama**, kurulum ve yeniden başlatmadır.

Aşağıdaki düzenek bir **modeldir**. Kurgu bölgesel ölçüm ağının makineleri ve bileşenleri veri
yapısı olarak yazılır; gerçek bir filo taranmaz.

- **ST19** — Filo kurgudur: on iki makine, sekiz bileşen ve altmış (makine, bileşen) kalemi.
- **ST20** — Doksan günlük pencerede on dört duyuru yapılıyor; günleri ve bileşenleri modelde
  yazılıdır.
- **ST21** — Envanter tarama aralığı fark etmeyi belirler: duyuru bir sonraki taramada görülür.
- **ST22** — Bakım penceresi sabit aralıklı ve sabit saatlidir; `pencere: 0` beklemesiz düzendir.
- **ST23** — Yamanın kusurlu olup olmadığı kendi yazdığımız üreteçle belirlenir, tohum görünürdür.
  Sınama kusuru yakalarsa düzeltilmiş yama üç gün sonra gelir; yakalayamazsa yama üretime gider,
  yarım gün sonra görülür ve geri alınır.
- **ST24** — Üç kalem hiçbir düzende yamalanamaz; gerekçeleri modelde yazılıdır.

```js
// yama/model.mjs — yama akisi MODELIDIR: on iki kurgu makine, sekiz bilesen, on dort duyuru.
// Gercek bir filo taranmaz, gercek bir yama indirilmez; butun sayilar bu dosyadan turer.
const GRUP = { toplayici: 3, dogrulayici: 2, faturalama: 1, "is-emri": 1, veri: 2, gecit: 2, kuyruk: 1 };
export const MAKINELER = Object.entries(GRUP).flatMap(([a, n]) =>
  Array.from({ length: n }, (_, i) => `${a}-${i + 1}`));

export const BILESEN = {                          // sinama ve uygulama sureleri gun cinsinden
  cekirdek:              { sinama: 2.0, uygulama: 0.20, grup: "hepsi" },
  "sistem-kitapligi":    { sinama: 1.0, uygulama: 0.15, grup: "hepsi" },
  "gozetim-ajani":       { sinama: 0.25, uygulama: 0.05, grup: "hepsi" },
  zamanlayici:           { sinama: 0.25, uygulama: 0.05, grup: "hepsi" },
  "dil-calisma-zamani":  { sinama: 1.5, uygulama: 0.10, grup: ["toplayici", "dogrulayici", "faturalama", "is-emri"] },
  "veritabani-sunucusu": { sinama: 2.0, uygulama: 0.25, grup: ["veri"] },
  "ters-vekil":          { sinama: 0.5, uygulama: 0.05, grup: ["gecit"] },
  "mesaj-kuyrugu":       { sinama: 1.0, uygulama: 0.10, grup: ["kuyruk"] },
};
export const makineleri = (b) => (BILESEN[b].grup === "hepsi" ? MAKINELER
  : MAKINELER.filter((m) => BILESEN[b].grup.includes(m.slice(0, m.lastIndexOf("-")))));
export const KALEM = Object.keys(BILESEN).reduce((a, b) => a + makineleri(b).length, 0);

export const YAMALANAMAZ = [                      // kalem = (makine, bilesen); gerekce adiyla yazilir
  ["faturalama-1", "dil-calisma-zamani", "uygulama uyumlulugu"],
  ["veri-1", "veritabani-sunucusu", "surekli calismasi gereken servis"],
  ["kuyruk-1", "mesaj-kuyrugu", "tek kopya, bosaltilamayan kuyruk"],
];
export const yamalanabilir = (b) =>
  makineleri(b).filter((m) => !YAMALANAMAZ.some((k) => k[0] === m && k[1] === b));

export const DUYURU = [                           // 90 gunluk pencerede on dort kusur duyurusu
  [3.2, "sistem-kitapligi"], [8.6, "dil-calisma-zamani"], [12.1, "cekirdek"], [19.4, "gozetim-ajani"],
  [23.0, "ters-vekil"], [27.8, "sistem-kitapligi"], [34.5, "veritabani-sunucusu"], [39.9, "zamanlayici"],
  [45.3, "cekirdek"], [51.7, "mesaj-kuyrugu"], [58.2, "dil-calisma-zamani"], [63.5, "sistem-kitapligi"],
  [71.1, "gozetim-ajani"], [78.4, "cekirdek"],
];
export const UFUK = 90, YENIDEN = 3.0, GORULME = 0.5, TOHUM = 4127;

export function uretec(tohum) {                   // ureteci kendimiz yaziyoruz, tohum gorunur
  let x = tohum >>> 0;
  return () => { x = (Math.imul(x, 1103515245) + 12345) >>> 0; return x / 4294967296; };
}
const r = uretec(TOHUM);                          // cekilis duzenden bagimsiz: hepsi ayni yamalari gorur
export const KUSURLU = DUYURU.map(() => r() < 0.20);
export const YAKALANIR = DUYURU.map(() => r() < 0.75);

export const DUZEN = {                            // tarama = envanter araligi, pencere = bakim araligi
  varsayilan: { tarama: 30, sinama: false, pencere: 30, ofs: 5.0 },
  haftalik: { tarama: 1, sinama: true, pencere: 7, ofs: 2.0 },
  gecelik: { tarama: 1, sinama: true, pencere: 1, ofs: 2 / 24 },
  surekli: { tarama: 0.25, sinama: true, pencere: 0, ofs: 0 },
  otomatik: { tarama: 0.25, sinama: false, pencere: 0, ofs: 0 },
};
const ilkPencere = (d, hazir) => (d.pencere === 0 ? hazir
  : Math.ceil((hazir - d.ofs) / d.pencere) * d.pencere + d.ofs);

// Bir duyurunun akisi: fark etme, sinama, pencere bekleme, uygulama.
export function akis(i, adi, kusurlu = KUSURLU[i]) {
  const d = DUZEN[adi], [gun, b] = DUYURU[i], bil = BILESEN[b], olay = [];
  const fark = Math.ceil(gun / d.tarama) * d.tarama;
  const sinama = d.sinama ? bil.sinama : 0;
  let hazir = fark + sinama, geriAlma = 0;
  if (kusurlu && d.sinama && YAKALANIR[i]) hazir += YENIDEN;    // sinama yakaladi: yama gecikir
  else if (kusurlu) {                                          // sinanmadi ya da kacti: uretime gitti
    const ilk = ilkPencere(d, hazir);
    olay.push(ilk, ilk + GORULME);                             // uygulama ve ardindan geri alma
    geriAlma = 1;
    hazir = ilk + GORULME + YENIDEN;
  }
  const uygula = ilkPencere(d, hazir);
  olay.push(uygula);
  return { fark: fark - gun, sinama, bekleme: uygula - hazir, uygulama: bil.uygulama,
    kapanis: uygula + bil.uygulama, pencere: uygula + bil.uygulama - gun, geriAlma, olay };
}

export function tara(adi, kusurluMu = null) {
  const kesinti = new Set();
  let ort = 0, geriAlma = 0, kalemGun = 0, acik = 0;
  for (let i = 0; i < DUYURU.length; i += 1) {
    const a = akis(i, adi, kusurluMu === null ? KUSURLU[i] : kusurluMu);
    const yb = yamalanabilir(DUYURU[i][1]);
    ort += a.pencere / DUYURU.length;
    geriAlma += a.geriAlma;
    kalemGun += a.pencere * yb.length;
    if (a.kapanis > UFUK) acik += yb.length;
    for (const an of a.olay) for (const m of yb) kesinti.add(`${m}@${an.toFixed(4)}`);
  }
  return { ort, geriAlma, kalemGun, kesinti: kesinti.size,
    acik: acik + YAMALANAMAZ.length };
}
```

#### Beş Düzen Taranıyor

```js
// yama/pencere.mjs — bes pencere duzeninde acik pencerenin dort parcasi ve bedelleri
import { DUYURU, DUZEN, MAKINELER, BILESEN, KALEM, KUSURLU, TOHUM, akis, tara } from "./model.mjs";

const g = (x, n, d = 2) => x.toFixed(d).padStart(n);
console.log(`${MAKINELER.length} makine, ${Object.keys(BILESEN).length} bilesen, ${KALEM} kalem; ` +
  `90 gunde ${DUYURU.length} duyuru, ${KUSURLU.filter(Boolean).length} kusurlu yama (tohum ${TOHUM}).`);
console.log("\nduzen      | tarama | sinama | pencere | ort. acik | acik kalem | kesinti | geri alma");
console.log("-----------|--------|--------|---------|-----------|------------|---------|----------");
for (const [ad, d] of Object.entries(DUZEN)) {
  const t = tara(ad);
  console.log(`${ad.padEnd(10)} | ${g(d.tarama, 6)} | ${(d.sinama ? "var" : "yok").padStart(6)}` +
    ` | ${(d.pencere ? d.pencere + " gun" : "yok").padStart(7)} | ${g(t.ort, 9)}` +
    ` | ${String(t.acik).padStart(10)} | ${String(t.kesinti).padStart(7)} | ${String(t.geriAlma).padStart(8)}`);
}

console.log("\nAcik pencerenin dort parcasi (gun), on dort duyurunun ortalamasi:");
console.log("duzen      | fark etme | sinama | pencere bekleme | uygulama | toplam");
console.log("-----------|-----------|--------|-----------------|----------|-------");
for (const ad of Object.keys(DUZEN)) {
  const p = { fark: 0, sinama: 0, bekleme: 0, uygulama: 0, pencere: 0 };
  for (let i = 0; i < DUYURU.length; i += 1)
    for (const k of Object.keys(p)) p[k] += akis(i, ad)[k] / DUYURU.length;
  console.log(`${ad.padEnd(10)} | ${g(p.fark, 9)} | ${g(p.sinama, 6)} | ${g(p.bekleme, 15)}` +
    ` | ${g(p.uygulama, 8)} | ${g(p.pencere, 6)}`);
}
```

```
12 makine, 8 bilesen, 60 kalem; 90 gunde 14 duyuru, 4 kusurlu yama (tohum 4127).

duzen      | tarama | sinama | pencere | ort. acik | acik kalem | kesinti | geri alma
-----------|--------|--------|---------|-----------|------------|---------|----------
varsayilan |  30.00 |    yok |  30 gun |     28.94 |         45 |      54 |        4
haftalik   |   1.00 |    var |   7 gun |      6.79 |          3 |     126 |        1
gecelik    |   1.00 |    var |   1 gun |      3.09 |          3 |     147 |        1
surekli    |   0.25 |    var |     yok |      2.28 |          3 |     147 |        1
otomatik   |   0.25 |    yok |     yok |      1.22 |          3 |     205 |        4

Acik pencerenin dort parcasi (gun), on dort duyurunun ortalamasi:
duzen      | fark etme | sinama | pencere bekleme | uygulama | toplam
-----------|-----------|--------|-----------------|----------|-------
varsayilan |     15.24 |   0.00 |           11.14 |     0.13 |  28.94
haftalik   |      0.52 |   1.16 |            3.89 |     0.13 |   6.79
gecelik    |      0.52 |   1.16 |            0.33 |     0.13 |   3.09
surekli    |      0.09 |   1.16 |            0.00 |     0.13 |   2.28
otomatik   |      0.09 |   0.00 |            0.00 |     0.13 |   1.22
```

İkinci tablo varsayılanın nerede kaybettiğini gösteriyor: 28,94 günün 15,24'ü **fark etmedir**. Bu
sürenin yamayla ya da kesinti korkusuyla ilgisi yok; tek nedeni hangi sürümün nerede koştuğunu tutan
bir kaydın bulunmamasıdır. Envanter taraması günlüğe çekildiğinde bu parça 0,52 güne iniyor — tek
adımda 14,72 gün, üstelik hiçbir makine yeniden başlatılmadan.

Sınama ters yönde çalışan tek kalemdir: yoktan 1,16 güne çıkar, yani pencereyi **uzatır**. Karşılığı
geri alma sütunundadır: on dört yamanın dördü kusurlu; sınama yapılan üç düzende bunların üçü
üretime ulaşmadan yakalandı ve geri alma 4 yerine 1 oldu.

Kesinti ise pencere aralığıyla ters çalışır. Varsayılan düzen 54 kesintiyle en sessiz olanıdır,
çünkü aylık pencerede biriken yamalar tek yeniden başlatmada toplanır — ve aynı toplanma pencereyi
28,94 güne çıkaran şeydir. Gecelik düzende kesinti 126'dan 147'ye çıkar, bekleme 3,89 günden 0,33
güne iner. **Kesinti sayısı ile açık pencere aynı kaldıracın iki ucudur.** Doksanıncı gün sayımı
sonuçtur: varsayılan düzende 45 kalem açık, öteki dört düzende 3.

#### Otomasyonun Kazandırdığı Gün ve Ürettiği Risk

```js
// yama/otomasyon.mjs — otomasyonun kazandirdigi gun, urettigi risk ve getirdigi yeni yuzey
import { DUYURU, DUZEN, MAKINELER, YAMALANAMAZ, KALEM, UFUK, KUSURLU, tara } from "./model.mjs";

const g = (x, n, d = 2) => x.toFixed(d).padStart(n);
const taban = tara("haftalik");
console.log("duzen      | ort. acik | haftaliga gore | sinanmadan | uretimde  | geri almanin | ek");
console.log("           |     (gun) |  kazanc  (gun) |  uygulanan | geri alma | ekledigi gun | kesinti");
console.log("-----------|-----------|----------------|------------|-----------|--------------|--------");
for (const ad of Object.keys(DUZEN)) {
  const t = tara(ad), s = tara(ad, false);          // s: hicbir yama kusurlu degilse
  console.log(`${ad.padEnd(10)} | ${g(t.ort, 9)} | ${g(taban.ort - t.ort, 14)}` +
    ` | ${String(DUZEN[ad].sinama ? 0 : DUYURU.length).padStart(10)} | ${String(t.geriAlma).padStart(9)}` +
    ` | ${g(t.ort - s.ort, 12)} | ${String(t.kesinti - s.kesinti).padStart(7)}`);
}

console.log("\nYamalanamayan kalemler (duyuru gelir, uygulama hicbir duzende olmaz):");
let yamalanamazGun = 0;
for (const [m, b, gerekce] of YAMALANAMAZ) {
  const ilk = DUYURU.find(([, x]) => x === b)[0];
  yamalanamazGun += UFUK - ilk;
  console.log(`${(m + " / " + b).padEnd(34)} | ${gerekce.padEnd(32)} | duyuru ${g(ilk, 4, 1)}. gun` +
    ` | ${g(UFUK - ilk, 5, 1)} gun acik`);
}
const kalemGun = tara("gecelik").kalemGun;
console.log(`gecelik duzende yamalanabilir ${KALEM - YAMALANAMAZ.length} kalem : ${g(kalemGun, 7)} kalem-gunu`);
console.log(`yamalanamayan ${YAMALANAMAZ.length} kalem${" ".repeat(24)} : ${g(yamalanamazGun, 7)} kalem-gunu ` +
  `(toplamin %${g(100 * yamalanamazGun / (kalemGun + yamalanamazGun), 5)}'i)`);

// kapatmanin getirdigi yeni yuzey: her makinede bir yama ajani, bir paket kaynagi, bir envanter kaydi
const yeni = MAKINELER.length + 3;
console.log(`\nyeni yuzey: ${MAKINELER.length} yama ajani + paket kaynagi + envanter kaydi + bakim penceresi`);
console.log(`${KALEM} kalem -> ${KALEM + yeni} kalem (+${yeni}); acik pencere ` +
  `${g(tara("varsayilan").ort, 5)} gunden ${g(tara("otomatik").ort, 5)} gune indi, ` +
  `geri alma ${taban.geriAlma} yerine ${tara("otomatik").geriAlma}, ` +
  `kesinti ${taban.kesinti} yerine ${tara("otomatik").kesinti}.`);
console.log(`kusurlu yama ${KUSURLU.filter(Boolean).length}/${DUYURU.length}; ` +
  `sinama bunlarin ${KUSURLU.filter(Boolean).length - taban.geriAlma} tanesini uretimden once yakaladi.`);
```

```
duzen      | ort. acik | haftaliga gore | sinanmadan | uretimde  | geri almanin | ek
           |     (gun) |  kazanc  (gun) |  uygulanan | geri alma | ekledigi gun | kesinti
-----------|-----------|----------------|------------|-----------|--------------|--------
varsayilan |     28.94 |         -22.14 |         14 |         4 |         8.57 |      18
haftalik   |      6.79 |           0.00 |          0 |         1 |         1.50 |      17
gecelik    |      3.09 |           3.70 |          0 |         1 |         0.93 |      24
surekli    |      2.28 |           4.52 |          0 |         1 |         0.89 |      24
otomatik   |      1.22 |           5.57 |         14 |         4 |         1.00 |      82

Yamalanamayan kalemler (duyuru gelir, uygulama hicbir duzende olmaz):
faturalama-1 / dil-calisma-zamani  | uygulama uyumlulugu              | duyuru  8.6. gun |  81.4 gun acik
veri-1 / veritabani-sunucusu       | surekli calismasi gereken servis | duyuru 34.5. gun |  55.5 gun acik
kuyruk-1 / mesaj-kuyrugu           | tek kopya, bosaltilamayan kuyruk | duyuru 51.7. gun |  38.3 gun acik
gecelik duzende yamalanabilir 57 kalem :  407.50 kalem-gunu
yamalanamayan 3 kalem                         :  175.20 kalem-gunu (toplamin %30.07'i)

yeni yuzey: 12 yama ajani + paket kaynagi + envanter kaydi + bakim penceresi
60 kalem -> 75 kalem (+15); acik pencere 28.94 gunden  1.22 gune indi, geri alma 1 yerine 4, kesinti 126 yerine 205.
kusurlu yama 4/14; sinama bunlarin 3 tanesini uretimden once yakaladi.
```

Otomatik düzen haftalığa göre 5,57 gün kazandırıyor ve en kısa pencereye sahip. Aynı satırda üç sayı
daha var: on dört yamanın on dördü sınanmadan uygulandı, dördü üretimde geri alındı ve geri alma 82
fazladan kesinti üretti. Sürekli düzen ise 4,52 gün kazandırıyor — kazancın yüzde 81'i — ama
sınanmadan uygulanan yama sıfır ve ek kesinti 24. Aradaki fark 1,06 gündür. **Tartışma otomasyonun
kendisi değil, sınamanın atlanıp atlanmadığıdır.** Geri almanın eklediği gün sütunu ise kusurlu
yamanın kendi penceresini uzattığını gösteriyor: otomatik düzende 1,00 gün, varsayılan düzende 8,57
gün — çünkü düzeltilmiş sürüm bir sonraki aylık pencereyi bekler.

İkinci tablo kapatılamayan kalemi adıyla yazıyor. Faturalama makinesindeki dil çalışma zamanı, gün
sonu toplu işi eski sürüme bağlı olduğu için yükseltilemez; birincil veri makinesindeki veritabanı
sunucusu, gecelik toplu iş penceresinde yazma kesintisine yer olmadığı için yeniden başlatılamaz;
tek kopya kuyruk boşaltılamadığı için durdurulamaz. Bu üç kalem 175,20 kalem-günü taşıyor — altmış
kalemin yüzde 5'i, açık kalem-gününün **yüzde 30,07'si**.

Kapatmanın kendisi de yüzey getiriyor. Yama otomasyonu on iki makinenin her birine yükseltilmiş
yetkiyle kod çalıştıran bir süreç koyar; paket kaynağı dışarıdan gelen ikili dosyanın tek güven
noktasıdır; envanter kaydı okuyabilen biri için filonun tam bir kusur haritasıdır; bakım penceresi
her gece aynı saatte tekrarlanan, önceden bilinen bir bozulma aralığıdır.

#### Özet

- Açık pencere dört parçadır: fark etme, sınama, pencere bekleme, uygulama. Varsayılan düzende
  28,94 günün 15,24'ü tek başına fark etmedir ve envanter taraması bunu 0,52 güne indirir.
- Sınama pencereyi 1,16 gün uzatır, karşılığında üretimde geri alınan yamayı 4'ten 1'e düşürür.
- Kesinti sayısı ile açık pencere ters çalışır: aylık pencerede 54 kesinti ve 28,94 gün, gecelikte
  147 kesinti ve 3,09 gün. Doksanıncı günde açık kalem 45'ten 3'e iner.
- Otomatik yama 5,57 gün kazandırır ama on dört yamanın hepsini sınanmadan uygular, geri almayı 4'e
  çıkarır ve 82 fazladan kesinti üretir; sürekli düzen kazancın yüzde 81'ini sınamayı bırakmadan
  verir.
- Yamalanamayan üç kalem — uygulama uyumluluğu, sürekli çalışması gereken servis, tek kopya kuyruk —
  altmış kalemin yüzde 5'i olduğu hâlde açık kalem-gününün yüzde 30,07'sini taşır.
- Kapatmanın getirdiği yeni yüzey on beş kalemdir: yama ajanı, paket kaynağı, envanter kaydı ve
  bakım penceresi; toplam 60'tan 75'e çıkar.

#### Sonraki Adım

Bu ders bir varsayımı hiç sınamadı: yama geri alındığında geri dönülecek bir **önceki durumun** var
olduğu. Yamalanamayan kalemlerin çözümü de aynı varsayıma yaslanıyordu. Kurtarma hedefleri
Dayanıklılık Kalıpları kursunda ölçüldü ve burada girdi olarak alınır; sonraki ders hedefleri değil
**yedeğin kendisini** ölçer: üretimdeki kalemlerden kaçı gerçekten yedekleniyor, hangi kalem adıyla
dışarıda kalıyor, sıklık ile veri kaybı penceresi ve saklama ile geriye gidilebilen nokta nerede
kesişiyor. Yedeğin kendisi de bir yüzeydir: kaç kopya, nerede, kim okuyabiliyor.

### Yedekleme Stratejisi

Source: https://academia.sh/tr/kurslar/sunucu-ve-sertlestirme/yedekleme-stratejisi

Yedeğin kendisinin ölçülmesi: kapsam boşluğunun kalem kalem sayılması ve yedeklenmeyen kalemin adıyla yazılması, sıklık ile veri kaybı penceresinin ve saklama ile geriye gidilebilen noktanın depolama maliyetiyle birlikte taranması, yedek kopyalarının kaç kimlik tarafından okunabildiğinin sayılması ve şifreleme anahtarının getirdiği yeni tek noktanın gösterilmesi.

Önceki ders bir varsayımla bitti: yama geri alındığında geri dönülecek bir önceki durum vardır. Aynı
varsayım her kurtarma planının altında durur. Kurtarma süresi ve veri kaybı hedefleri Dayanıklılık
Kalıpları kursunda ölçüldü; burada girdi olarak alınır. Ölçülen şey **yedeğin kendisidir**.

Varsayılanın bıraktığı kalem burada da bir boşluktur: kurulum sonrası akla gelen tek yedek
veritabanının gecelik dökümüdür. Geri kalanı — yapılandırma, sır, nesne deposu, dış hizmetteki veri
— kimsenin karar vermediği bir şekilde plan dışında kalır. Ölçü **kapsam boşluğu**dur: üretimde var
olup yedek kümesinde bulunmayan kalem sayısı.

#### Kapsam Boşluğu Kalem Kalem

- **ST25** — Üretim envanteri kurgudur: on altı kalem; türü, boyutu ve günlük değişimi modelde
  yazılıdır.
- **ST26** — Dört servisin gerektirdiği kalem kümesi modelde yazılıdır; bir kalem eksikse o servis
  geri yüklenemez.
- **ST27** — Üç kalemin yedeği alınamaz; gerekçe kalemin türündedir.

- **ST28** — Sıkıştırma oranı 0,42; artımlı yedek günlük değişimin aralık payıdır, her noktanın
  0,02 GiB üst verisi vardır.
- **ST29** — Veri kaybı penceresi ortalamada aralığın yarısı, en kötüde aralığın kendisidir.
- **ST30** — Şifreleme bölümü gerçekten koşar; süre ölçülür ama basılmaz, bant denetiminden
  geçirilir.

```js
// yedek/model.mjs — uretim envanteri MODELIDIR: on alti kalem, dort servis. Gercek yedek alinmaz.
const K = (ad, tur, gib, degisim, alinabilir = true) => ({ ad, tur, gib, degisim, alinabilir });
export const ENVANTER = [
  K("okuma-veritabani", "veritabani", 420, 6.0), K("tarife-veritabani", "veritabani", 4, 0.02),
  K("is-emri-veritabani", "veritabani", 18, 0.6), K("fatura-belge-deposu", "nesne deposu", 260, 1.4),
  K("saha-foto-deposu", "nesne deposu", 610, 3.1), K("servis-yapilandirmasi", "yapilandirma", 0.02, 0.001),
  K("guvenlik-duvari-kurallari", "yapilandirma", 0.001, 0.0002),
  K("ad-bolge-dosyasi", "yapilandirma", 0.0005, 0.0001),
  K("dagitim-yapilandirmasi", "yapilandirma", 0.05, 0.01),
  K("sir-deposu-icerigi", "sir", 0.002, 0.0005), K("sertifika-ozel-anahtarlari", "sir", 0.0004, 0.00005),
  K("gozetim-olcum-serisi", "olcum", 95, 4.2), K("denetim-gunlugu", "gunluk", 140, 2.8),
  K("mesaj-kuyrugu-durumu", "kuyruk", 2.5, 2.5, false),
  K("dis-fatura-hizmeti-verisi", "dis hizmet", 12, 0.3, false),
  K("dis-bildirim-listeleri", "dis hizmet", 0.8, 0.05, false),
];
// Servis ancak gereken kalemlerin hepsi yedekteyse geri yuklenebilir.
export const SERVIS = {
  toplayici: ["okuma-veritabani", "servis-yapilandirmasi", "sir-deposu-icerigi", "dagitim-yapilandirmasi"],
  dogrulayici: ["okuma-veritabani", "servis-yapilandirmasi", "sir-deposu-icerigi", "mesaj-kuyrugu-durumu"],
  faturalama: ["okuma-veritabani", "tarife-veritabani", "fatura-belge-deposu", "servis-yapilandirmasi",
    "sir-deposu-icerigi", "dis-fatura-hizmeti-verisi"],
  "is-emri": ["is-emri-veritabani", "saha-foto-deposu", "servis-yapilandirmasi",
    "sertifika-ozel-anahtarlari", "ad-bolge-dosyasi"],
};
export const PLAN = {                             // hangi turler yedek kumesine giriyor
  varsayilan: ["veritabani"],
  "veri-ve-nesne": ["veritabani", "nesne deposu"],
  "yapilandirma-eklendi": ["veritabani", "nesne deposu", "yapilandirma"],
  "sir-eklendi": ["veritabani", "nesne deposu", "yapilandirma", "sir"],
  tam: ["veritabani", "nesne deposu", "yapilandirma", "sir", "olcum", "gunluk", "kuyruk", "dis hizmet"],
};
export const kapsanan = (p) =>
  ENVANTER.filter((k) => PLAN[p].includes(k.tur) && k.alinabilir);
```

```js
// yedek/kapsam.mjs — kapsam boslugunu kalem kalem sayar ve geri yuklenebilir servisi olcer
import { ENVANTER, SERVIS, PLAN, kapsanan } from "./model.mjs";

const TOPLAM_GIB = ENVANTER.reduce((a, k) => a + k.gib, 0);
const g = (x, n, d = 2) => x.toFixed(d).padStart(n);
console.log(`${ENVANTER.length} uretim kalemi, ${g(TOPLAM_GIB, 0, 1)} GiB, ${Object.keys(SERVIS).length} servis; ` +
  `${ENVANTER.filter((k) => !k.alinabilir).length} kalem yedegi alinamiyor.`);
console.log("\nplan                 | kapsanan | bosluk | yedeklenen GiB | bayt orani | geri yuklenebilir");
console.log("---------------------|----------|--------|----------------|------------|------------------");
for (const p of Object.keys(PLAN)) {
  const ic = kapsanan(p), ad = new Set(ic.map((k) => k.ad));
  const gib = ic.reduce((a, k) => a + k.gib, 0);
  const servis = Object.entries(SERVIS).filter(([, ger]) => ger.every((x) => ad.has(x)));
  console.log(`${p.padEnd(20)} | ${String(ic.length).padStart(8)} | ` +
    `${String(ENVANTER.length - ic.length).padStart(6)} | ${g(gib, 14, 1)} | ` +
    `%${g(100 * gib / TOPLAM_GIB, 9)} | ${(servis.length + "/" + Object.keys(SERVIS).length).padStart(18)}`);
}

console.log("\nKapsam boslugu kalem kalem (yapilandirma-eklendi planinda disarida kalanlar):");
const icinde = new Set(kapsanan("yapilandirma-eklendi").map((k) => k.ad));
for (const k of ENVANTER.filter((x) => !icinde.has(x.ad)))
  console.log(`${k.ad.padEnd(26)} | ${k.tur.padEnd(11)} | ${g(k.gib, 7, 3)} GiB | ` +
    `${k.alinabilir ? "plan disi" : "ALINAMIYOR"}`);

const engelli = ENVANTER.map((k) => ({ k, e: Object.keys(SERVIS).filter((s) => SERVIS[s].includes(k.ad)) }))
  .filter((x) => x.e.length > 0).sort((a, b) => a.k.gib - b.k.gib).slice(0, 4);
const kucuk = engelli.reduce((a, x) => a + x.k.gib, 0);
console.log(`\nen kucuk dort servis engelleyen kalem: ${engelli.map((x) => x.k.ad).join(", ")}`);
console.log(`toplam ${g(kucuk * 1024, 6)} MiB = uretim baytlarinin %${g(100 * kucuk / TOPLAM_GIB, 6, 4)}'i; ` +
  `birlikte ${new Set(engelli.flatMap((x) => x.e)).size}/${Object.keys(SERVIS).length} servisi engelliyor.`);
```

```
16 uretim kalemi, 1562.4 GiB, 4 servis; 3 kalem yedegi alinamiyor.

plan                 | kapsanan | bosluk | yedeklenen GiB | bayt orani | geri yuklenebilir
---------------------|----------|--------|----------------|------------|------------------
varsayilan           |        3 |     13 |          442.0 | %    28.29 |                0/4
veri-ve-nesne        |        5 |     11 |         1312.0 | %    83.97 |                0/4
yapilandirma-eklendi |        9 |      7 |         1312.1 | %    83.98 |                0/4
sir-eklendi          |       11 |      5 |         1312.1 | %    83.98 |                2/4
tam                  |       13 |      3 |         1547.1 | %    99.02 |                2/4

Kapsam boslugu kalem kalem (yapilandirma-eklendi planinda disarida kalanlar):
sir-deposu-icerigi         | sir         |   0.002 GiB | plan disi
sertifika-ozel-anahtarlari | sir         |   0.000 GiB | plan disi
gozetim-olcum-serisi       | olcum       |  95.000 GiB | plan disi
denetim-gunlugu            | gunluk      | 140.000 GiB | plan disi
mesaj-kuyrugu-durumu       | kuyruk      |   2.500 GiB | ALINAMIYOR
dis-fatura-hizmeti-verisi  | dis hizmet  |  12.000 GiB | ALINAMIYOR
dis-bildirim-listeleri     | dis hizmet  |   0.800 GiB | ALINAMIYOR

en kucuk dort servis engelleyen kalem: sertifika-ozel-anahtarlari, ad-bolge-dosyasi, sir-deposu-icerigi, servis-yapilandirmasi
toplam  23.45 MiB = uretim baytlarinin %0.0015'i; birlikte 4/4 servisi engelliyor.
```

Varsayılan plan on altı kalemin üçünü kapsıyor, kapsam boşluğu 13. Nesne deposu eklendiğinde bayt
oranı yüzde 28,29'dan yüzde 83,97'ye fırlıyor ve plan tamamlanmış görünüyor — ama geri yüklenebilir
servis hâlâ 0/4. Yapılandırma eklendiğinde bayt oranı 0,01 puan artıyor, servis yine 0/4. Sır
eklendiğinde bayt oranı **hiç değişmiyor**, servis ise 0'dan 2'ye çıkıyor. **Bayt oranı kapsamı
ölçmez.** Son iki satır nedenini veriyor: en küçük dört engelleyici kalem toplam 23,45 MiB, üretim
baytlarının yüzde 0,0015'i, ama dört servisi de engelliyor.

Tam planda bile servis 2/4'te kalıyor: mesaj kuyruğu durumunun tutarlı anlık görüntüsü alınamıyor,
dış fatura hizmetindeki veri ile dış bildirim listelerinin dışa aktarım arayüzü yok. Doğrulayıcı
birinciye, faturalama ikinciye bağlı; ikisi de geri yüklenemez. Bu kalemler için yedekleme kararı
yoktur — karar, kalemi yedeklenebilir bir yere taşımaktır.

#### Sıklık, Saklama ve Depolama

```js
// yedek/siklik.mjs — siklik, saklama, nokta sayisi ve depolama birlikte taranir (MODELDIR)
import { ENVANTER, kapsanan } from "./model.mjs";

const SIKISTIRMA = 0.42, UST_VERI = 0.02;         // nokta basina ust veri, GiB
const ic = kapsanan("tam");
const TAM = ic.reduce((a, k) => a + k.gib, 0) * SIKISTIRMA;
const GUNLUK = ic.reduce((a, k) => a + k.degisim, 0) * SIKISTIRMA;
const URETIM = ENVANTER.reduce((a, k) => a + k.gib, 0);
const DUZEN = {                                   // tam: gun, art: saat (null = artimli yok)
  "haftalik-tam": { tam: 7, art: null }, "gecelik-tam": { tam: 1, art: null },
  "gecelik+6s": { tam: 1, art: 6 }, "haftalik+1s": { tam: 7, art: 1 },
  "haftalik+5dk": { tam: 7, art: 1 / 12 },
};
const nokta = (d, R) => Math.floor(R / d.tam) + 1 + (d.art ? Math.floor(R * 24 / d.art) : 0);
const depo = (d, R) => (Math.floor(R / d.tam) + 1) * TAM + (d.art ? R * GUNLUK : 0)
  + nokta(d, R) * UST_VERI;
const g = (x, n, d = 2) => x.toFixed(d).padStart(n);

console.log(`yedeklenen ${ic.length} kalem: tam yedek ${g(TAM, 0, 1)} GiB (sikistirma ${SIKISTIRMA}), ` +
  `gunluk degisim ${g(GUNLUK, 0, 2)} GiB, nokta basina ust veri ${UST_VERI} GiB.`);
console.log("\nduzen        | tam yedek | artimli | ort. veri kaybi (dk) | en kotu (dk) | gunluk yazilan GiB");
console.log("-------------|-----------|---------|----------------------|--------------|-------------------");
for (const [ad, d] of Object.entries(DUZEN)) {
  const dk = (d.art ?? d.tam * 24) * 60;
  console.log(`${ad.padEnd(12)} | ${(d.tam + " gun").padStart(9)} | ` +
    `${(d.art ? (d.art < 1 ? d.art * 60 + " dk" : d.art + " saat") : "yok").padStart(7)} | ` +
    `${g(dk / 2, 20, 1)} | ${g(dk, 12, 1)} | ${g(TAM / d.tam + (d.art ? GUNLUK : 0), 18)}`);
}

const SAKLAMA = [7, 30, 90, 365];        // saklama = geriye gidilebilen en eski nokta
console.log("\ndepolanan GiB (saklama gunune gore) ve 30 gunde geri donulebilen nokta:");
console.log(`duzen        |${SAKLAMA.map((R) => (R + " gun").padStart(11)).join(" |")} | 30g nokta`);
console.log("-------------|------------|------------|------------|------------|----------");
for (const [ad, d] of Object.entries(DUZEN))
  console.log(`${ad.padEnd(12)} |${SAKLAMA.map((R) => g(depo(d, R), 11, 1)).join(" |")} | ` +
    `${String(nokta(d, 30)).padStart(9)}`);
console.log(`uretim verisi ${g(URETIM, 0, 1)} GiB; haftalik+1s duzeninde depolanan, saklama 7 gunde ` +
  `${g(depo(DUZEN["haftalik+1s"], 7) / URETIM, 0)} kati, 365 gunde ${g(depo(DUZEN["haftalik+1s"], 365) / URETIM, 0)} kati.`);
```

```
yedeklenen 13 kalem: tam yedek 649.8 GiB (sikistirma 0.42), gunluk degisim 7.62 GiB, nokta basina ust veri 0.02 GiB.

duzen        | tam yedek | artimli | ort. veri kaybi (dk) | en kotu (dk) | gunluk yazilan GiB
-------------|-----------|---------|----------------------|--------------|-------------------
haftalik-tam |     7 gun |     yok |               5040.0 |      10080.0 |              92.82
gecelik-tam  |     1 gun |     yok |                720.0 |       1440.0 |             649.77
gecelik+6s   |     1 gun |  6 saat |                180.0 |        360.0 |             657.39
haftalik+1s  |     7 gun |  1 saat |                 30.0 |         60.0 |             100.44
haftalik+5dk |     7 gun |    5 dk |                  2.5 |          5.0 |             100.44

depolanan GiB (saklama gunune gore) ve 30 gunde geri donulebilen nokta:
duzen        |      7 gun |     30 gun |     90 gun |    365 gun | 30g nokta
-------------|------------|------------|------------|------------|----------
haftalik-tam |     1299.6 |     3249.0 |     8447.3 |    34438.9 |         5
gecelik-tam  |     5198.3 |    20143.5 |    59131.0 |   237823.5 |        31
gecelik+6s   |     5252.2 |    20374.4 |    59823.6 |   240632.3 |       151
haftalik+1s  |     1356.2 |     3491.8 |     9175.9 |    37393.7 |       725
haftalik+5dk |     1393.2 |     3650.2 |     9651.1 |    39320.9 |      8645
uretim verisi 1562.4 GiB; haftalik+1s duzeninde depolanan, saklama 7 gunde 0.87 kati, 365 gunde 23.93 kati.
```

Gecelik tam yedek en yaygın varsayılan alışkanlıktır ve iki ucu da kaybeder: günde 649,77 GiB yazar,
otuz günde 20.143,5 GiB depolar, penceresi 720 dakikadır, 31 nokta bırakır. Haftalık tam
yedek üstüne saatlik artımlı düzen günde 100,44 GiB yazar, otuz günde 3.491,8 GiB depolar, pencereyi
30 dakikaya indirir ve 725 nokta bırakır — altı kat az yazma, beş kat az depolama, yirmi dört kat
küçük pencere.

Sıklığı artırmanın depolamaya etkisi neredeyse yoktur: artımlı aralık beş dakikaya inince otuz
günlük depolama 3.491,8 GiB'den 3.650,2 GiB'ye çıkıyor — yüzde 4,5 — ve kayıp penceresi 2,5
dakikaya iner. Artan şey depolanan veri değil, nokta sayısı ve üst veridir. **Pahalı
olan sıklık değil saklamadır:** saklama 7 günden 365 güne çıkınca depolanan 1.356,2 GiB'den 37.393,7
GiB'ye, üretim verisinin 0,87 katından 23,93 katına çıkıyor.

Saklama aynı zamanda geriye gidilebilen en eski noktadır ve sessiz bozulmanın fark edilme süresiyle
karşılaştırılmadıkça bir sayı değildir: yedi günlük saklamada sekizinci günde fark edilen bozulma
için temiz nokta yoktur, 725 noktanın hepsi bozulmadan sonrasına aittir.

#### Yedeğin Kendisi Bir Yüzeydir

Kopya yerleşimi de bir modeldir. Tek olayda kaybolan kopya, kopya/bölge oranının yukarı
yuvarlanmışıdır; **okunabilir yüzey** kopya sayısı ile okuyan kimlik sayısının çarpımıdır.

| yerleşim | kopya | bölge | okuyan kimlik | silebilen | şifreli | tek olayda kaybolan | okunabilir yüzey |
|---|---|---|---|---|---|---|---|
| varsayılan | 1 | 1 | 9 | 9 | hayır | 1 | 9 |
| iki-kopya | 2 | 1 | 9 | 9 | hayır | 2 | 18 |
| ayrı-bölge | 3 | 2 | 5 | 5 | evet | 2 | 15 |
| daraltılmış | 3 | 2 | 2 | 2 | evet | 2 | 6 |
| değiştirilemez | 4 | 2 | 2 | 0 | evet | 2 | 8 |

```js
// yedek/anahtar.mjs — sifreleme bolumu GERCEKTEN kosar: dogru ve yanlis anahtarla geri donus
// denenir. Sure olculur ama HAM OLCUM BASILMAZ, yalniz bant denetimi yazilir.
import { createCipheriv, createDecipheriv, scryptSync } from "node:crypto";

const TOHUM = 90211, MIB = 24;           // veri kendi uretecimizden, tohum gorunur: kurgudur
let x = TOHUM >>> 0;
const sonraki = () => { x = (Math.imul(x, 1103515245) + 12345) >>> 0; return x; };
const duz = Buffer.allocUnsafe(MIB * 1024 * 1024);
for (let i = 0; i < duz.length; i += 4) duz.writeUInt32LE(sonraki(), i);
const iv = Buffer.allocUnsafe(12);       // baslatma vektoru de ayni uretecten: rastgelelik yok
for (let i = 0; i < 12; i += 4) iv.writeUInt32LE(sonraki(), i);
const tuz = Buffer.from("kurgu-tuz-ornek-gecersiz");   // gercek sir ya da anahtar yazilmaz
const anahtar = scryptSync("kurgu-parola-ornek-gecersiz", tuz, 32);
const baska = scryptSync("kurgu-baska-parola-ornek-gecersiz", tuz, 32);

const t0 = process.hrtime.bigint();
const s = createCipheriv("aes-256-gcm", anahtar, iv);
const kapali = Buffer.concat([s.update(duz), s.final()]), etiket = s.getAuthTag();
const coz = (a) => {                     // yanlis anahtarda butunluk etiketi tutmaz
  try {
    const d = createDecipheriv("aes-256-gcm", a, iv).setAuthTag(etiket);
    return Buffer.concat([d.update(kapali), d.final()]);
  } catch { return null; }
};
const geri = coz(anahtar), yanlis = coz(baska);
const sn = Number(process.hrtime.bigint() - t0) / 1e9;

const [ALT, UST] = [5, 40000];           // MiB/s bandi; olculen deger degil denetim sonucu basilir
const yaz = (e, d) => console.log(`${e.padEnd(44)}: ${d}`);
console.log(`\nkurgu yedek kumesi ${MIB} MiB (tohum ${TOHUM}), sifreli boyut ${kapali.length} bayt`);
yaz("dogru anahtarla girdinin aynisina donuldu", geri && geri.equals(duz) ? "evet" : "hayir");
yaz("baska anahtarla geri donulebildi", yanlis ? "evet" : "hayir");
yaz(`hiz ${ALT}-${UST} MiB/s bandinda`, MIB / sn >= ALT && MIB / sn <= UST ? "evet" : "hayir");
```

```

kurgu yedek kumesi 24 MiB (tohum 90211), sifreli boyut 25165824 bayt
dogru anahtarla girdinin aynisina donuldu   : evet
baska anahtarla geri donulebildi            : hayir
hiz 5-40000 MiB/s bandinda                  : evet
```

Varsayılan yerleşim üretim verisinin tam kopyasını üretimle aynı yerde, aynı dokuz kimliğin
okuyabildiği ve şifresiz biçimde tutar: okunabilir yüzey 9, tek olayda kopyanın tamamı gidiyor.
İkinci kopya dayanıklılığı artırırken yüzeyi 18'e çıkarıyor — **yedek almak, veriyi ikinci kez açığa
çıkarmaktır**. Erişim daraltıldığında üç kopyayla yüzey 6'ya iniyor: kopya üç kat artarken yüzey
üçte birine düşüyor. Değiştirilemez dördüncü kopya silebilen kimliği sıfırlıyor.

Şifrelemenin getirdiği kalem koşumda görünüyor: doğru anahtarla girdinin aynısına dönülüyor, başka
bir anahtarla dönülemiyor. Bu, yeni tek noktanın da tanımıdır — anahtar kaybolursa yedek de
kaybolur. Anahtar bir sırdır ve sır deposunda durur; sır
deposu içeriği ise yedeklenmesi gereken kalemlerden biridir: **yedeğin anahtarı yedeğin içinde
saklanamaz.**

#### Özet

- Kapsam boşluğu bayt oranıyla ölçülmez: nesne deposu eklendiğinde bayt oranı yüzde 83,97'ye
  çıkarken geri yüklenebilir servis 0/4'te kalıyor; sır eklendiğinde bayt oranı hiç değişmeden
  servis 2/4'e çıkıyor.
- Dört küçük kalem — sertifika özel anahtarları, ad bölge dosyası, sır deposu içeriği, servis
  yapılandırması — toplam 23,45 MiB, üretim baytlarının yüzde 0,0015'i, ama dört servisi de
  engelliyor.
- Yedeklenemeyen üç kalem adıyla yazılır: anlık kuyruk durumu, dış fatura hizmetindeki veri, dış
  bildirim listeleri. Tam planda bile servis 2/4'te kalır.
- Sıklık ucuz, saklama pahalıdır: artımlı aralığı beş dakikaya indirmek otuz günlük depolamayı yüzde
  4,5 artırır, saklamayı 365 güne çıkarmak 1.356,2 GiB'den 37.393,7 GiB'ye taşır.
- Yedeğin kendisi bir yüzeydir: okunabilir yüzey varsayılanda 9, iki kopyada 18, erişimi daraltılmış
  üç kopyada 6. Şifreleme anahtarı yeni bir tek noktadır ve yedeğin içinde saklanamaz.

#### Sonraki Adım

Bu dersin bütün sayıları bir yedek **kümesinden** çıktı; hiçbiri bir geri yükleme yapılarak elde
edilmedi. Kapsam tablosu bir kalemin yedek kümesinde bulunduğunu söyler, okunabilir olduğunu değil;
nokta sayısı bir noktaya dönülebileceğini söyler, dönüşün ne kadar süreceğini değil. Sonraki ders
bunu denetimli bir tatbikatla sınar: gerçek dosyalar yedeklenip geri yüklenir ve geri gelenin
gidenle **birebir aynı** olduğu doğrulanır. Ölçülecek üç şey var — tatbikatta geçen gerçek süre,
kapsam tablosunun doğru saydığı kalem sayısı ve tatbikatsız bir düzende ilk geri yüklemenin hangi
varsayımları birden kırdığı.

### Geri Yükleme Tatbikatı

Source: https://academia.sh/tr/kurslar/sunucu-ve-sertlestirme/geri-yukleme-tatbikati

Yedeğin çalıştığının kanıtlanması: gerçek dosyaların yedeklenip silinmesi ve geri yüklenmesi, birebir aynı olduğunun özetle doğrulanması, yalnız tatbikatla görülen beş kusurun sayılması, geri yükleme süresinin beş bileşene ayrılıp kurtarma hedefiyle karşılaştırılması ve tatbikat sıklığının biriken belirsizlikle birlikte taranması.

Önceki ders yedeğin kapsamını, sıklığını ve saklamasını sayıya bağladı; o sayılar bir yedek
**kümesinden** okundu. Varsayılanın bıraktığı kalem en sessiz olanıdır: **yedek alma adımı
başarılı döner.** Arşiv üretilir, boyutu yazılır, kayıt tutulur — ve o kayıt yedeğin geri
yüklenebildiğine dair hiçbir şey söylemez. Ölçü geri döndürülebilirliğin **kanıtıdır**: üretimdeki
bayt ile geri gelen baytı karşılaştıran bir özet.

#### Tatbikat Gerçekten Koşuyor

- **ST31** — Kurgu bölgesel ölçüm ağının üretim ağacı gerçekten diske yazılıyor: beş kalem,
  içerikleri kendi üretecimizden, tohum 51703; geçici dizin koşum sonunda siliniyor.
- **ST32** — Arşiv kabı kendi biçimimizdir; parola ve tuz kurgudur.
- **ST33** — Beş kusurun üçü gerçekten enjekte edilir (kapsam dışı kalem, çevrilmiş bayt,
  başka anahtar); yanlış sıra ile eksik yetki modeldir.
- **ST34** — Kurtarma süresi hedefi Dayanıklılık Kalıpları kursundan girdidir: 240 dakika. İndirme
  süresi önceki dersin 649,8 GiB tam yedeğinden ve 80 MiB/s'lik kurgu bir hattan türer; öteki dört
  bileşen modeldir.
- **ST35** — Üretim kümesi ayda üç yapılandırma değişikliği ve çeyrekte bir kalem alır; bir tatbikat
  bir kişinin altı saatidir, ayrı bir geri yükleme ortamında koşar.
- **ST36** — Süre ölçülür ama basılmaz; yalnız bant denetiminden geçirilir.

```js
// tatbikat/kap.mjs — arsiv kabi kendi bicimimizdir: bildirim + ardisik icerikler.
// Parola ve tuz kurgudur, gercek sir yazilmaz.
import { readFileSync, writeFileSync, readdirSync, mkdirSync } from "node:fs";
import { join } from "node:path";
import { gzipSync, gunzipSync } from "node:zlib";
import { createCipheriv, createDecipheriv, createHash, scryptSync } from "node:crypto";

export const TOHUM = 51703;              // ureteci kendimiz yaziyoruz, tohum gorunur
let x = TOHUM >>> 0;
export const uret = (n) => {
  const b = Buffer.allocUnsafe(n);
  for (let i = 0; i < n; i += 4) { x = (Math.imul(x, 1103515245) + 12345) >>> 0; b.writeUInt32LE(x, i); }
  return b;
};
export const ozet = (b) => createHash("sha256").update(b).digest("hex");
const tuz = Buffer.from("kurgu-tuz-ornek-gecersiz");
export const ANAHTAR = scryptSync("kurgu-yedek-parolasi-ornek-gecersiz", tuz, 32);
export const BASKA = scryptSync("kurgu-baska-parola-ornek-gecersiz", tuz, 32);
const IV = Buffer.from("kurgu-iv-12b");  // 12 bayt, sabit ve kurgu

export function paketle(dizin, atla = []) {       // atla: plan disi birakilan kalem
  const adlar = readdirSync(dizin).sort().filter((a) => !atla.includes(a));
  const govde = adlar.map((a) => readFileSync(join(dizin, a)));
  const bildirim = Buffer.from(JSON.stringify(adlar.map((a, i) => [a, govde[i].length])));
  const bas = Buffer.allocUnsafe(4);
  bas.writeUInt32LE(bildirim.length, 0);
  return Buffer.concat([bas, bildirim, ...govde]);
}
export function ac(kap, dizin) {
  const n = kap.readUInt32LE(0);
  let p = 4 + n;
  mkdirSync(dizin, { recursive: true });
  for (const [ad, boy] of JSON.parse(kap.subarray(4, 4 + n).toString())) {
    writeFileSync(join(dizin, ad), kap.subarray(p, p + boy));
    p += boy;
  }
}
export function sifrele(kap) {
  const s = createCipheriv("aes-256-gcm", ANAHTAR, IV);
  return { govde: Buffer.concat([s.update(gzipSync(kap)), s.final()]), etiket: s.getAuthTag() };
}
export function coz({ govde, etiket }, anahtar = ANAHTAR) {
  try {                                  // bozuk arsiv ya da yanlis anahtar duser
    const d = createDecipheriv("aes-256-gcm", anahtar, IV).setAuthTag(etiket);
    return gunzipSync(Buffer.concat([d.update(govde), d.final()]));
  } catch { return null; }
}
```

```js
// tatbikat/tatbikat.mjs — GERCEKTEN kosar: kurgu uretim agaci diske yazilir, arsivlenir,
// SILINIR ve geri yuklenir; birebir ayni oldugu ozetle dogrulanir. Sure basilmaz.
import { mkdtempSync, mkdirSync, writeFileSync, readFileSync, readdirSync, rmSync } from "node:fs";
import { join } from "node:path";
import { tmpdir } from "node:os";
import { TOHUM, uret, ozet, paketle, ac, sifrele, coz, BASKA } from "./kap.mjs";

const KALEM = [["olcum.veri", 262144], ["is-emri.veri", 131072], ["tarife.veri", 65536],
  ["servis.yapilandirma", 2048], ["ad-bolge.kayit", 1024]];   // kurgu olcum agi agaci
const ICERIK = KALEM.map(([ad, n]) => [ad, uret(n)]);
const kok = mkdtempSync(join(tmpdir(), "tatbikat-"));
const uretim = join(kok, "uretim");
const durum = () => readdirSync(uretim).sort().map((a) => [a, ozet(readFileSync(join(uretim, a)))]);

function kos({ atla = [], boz = false, anahtar = undefined }) {
  rmSync(uretim, { recursive: true, force: true });
  mkdirSync(uretim, { recursive: true });
  for (const [ad, b] of ICERIK) writeFileSync(join(uretim, ad), b);
  const oncesi = durum();
  let a = sifrele(paketle(uretim, atla));
  if (boz) a = { ...a, govde: Buffer.concat([a.govde.subarray(0, 64),         // tek bayt cevrilir
    Buffer.from([a.govde[64] ^ 1]), a.govde.subarray(65)]) };
  rmSync(uretim, { recursive: true });                  // uretim silindi: donus arsivden
  const kap = coz(a, anahtar);
  if (kap) ac(kap, uretim);
  const m = new Map(kap ? durum() : []);
  return { oncesi, acildi: !!kap, arsiv: a.govde.length,
    ayni: oncesi.filter(([ad, o]) => m.get(ad) === o).length };
}

const t0 = process.hrtime.bigint();
const saglikli = kos({});
const sn = Number(process.hrtime.bigint() - t0) / 1e9;
const bayt = ICERIK.reduce((a, [, b]) => a + b.length, 0);
const geri = new Map(durum());
console.log(`${KALEM.length} kalem, ${bayt} bayt (tohum ${TOHUM}); arsiv ${saglikli.arsiv} bayt`);
console.log("kalem               | uretimdeki ozet (ilk 16) | geri gelen ayni");
console.log("--------------------|--------------------------|----------------");
for (const [ad, o] of saglikli.oncesi)
  console.log(`${ad.padEnd(19)} | ${o.slice(0, 16).padStart(24)} | ` +
    `${(geri.get(ad) === o ? "evet" : "hayir").padStart(15)}`);

// MODEL: sira bozulunca kac adim bos veriyle acilir
const BAGLI = { sir: [], veri: ["sir"], yapilandirma: [], servis: ["veri", "yapilandirma"] };
const YANLIS = ["servis", "veri", "yapilandirma", "sir"];
const bos = YANLIS.filter((a, i) => BAGLI[a].some((b) => YANLIS.indexOf(b) > i)).length;
// MODEL: geri yukleme kimliginin gereken/verilen yetkileri
const GEREKEN = { "yedek-deposu": "oku", "nesne-deposu": "yaz", "sir-deposu": "oku", "servis-yoneticisi": "baslat" };
const VERILEN = { "yedek-deposu": "oku", "sir-deposu": "oku" };
const yetki = Object.keys(GEREKEN).filter((k) => VERILEN[k] !== GEREKEN[k]);

console.log("\ndeneme                     | acildi | birebir | eksik | yedek alma adimi");
console.log("---------------------------|--------|---------|-------|------------------");
let bulunan = 2;                                        // iki MODEL kusuru bastan
for (const [ad, secenek] of [["saglikli tatbikat", {}],
  ["eksik kalem (yapilandirma)", { atla: ["servis.yapilandirma"] }],
  ["bozuk arsiv (tek bayt)", { boz: true }], ["cozulemeyen sifre", { anahtar: BASKA }]]) {
  const r = kos(secenek), n = r.oncesi.length;
  if (r.ayni < n) bulunan += 1;
  console.log(`${ad.padEnd(26)} | ${(r.acildi ? "evet" : "hayir").padStart(6)} | ` +
    `${(r.ayni + "/" + n).padStart(7)} | ${String(n - r.ayni).padStart(5)} | ` +
    `${(r.ayni < n ? "basarili gorundu" : "basarili").padStart(16)}`);
}
console.log(`yanlis sira (MODEL)        | ${bos}/${YANLIS.length} adim bos veriyle aciliyor` +
  `${" ".repeat(11)}| basarili gorundu`);
console.log(`eksik yetki (MODEL)        | ${yetki.length} kalem: ${yetki.join(", ")} | basarili gorundu`);
console.log(`\ntatbikatin buldugu kusur ${bulunan}; yedek alma adiminda gorulen 0`);
const mib = bayt / 1024 / 1024, [ALT, UST] = [0.5, 20000];   // MiB/s bandi; ham olcum basilmaz
console.log(`yedekle+sil+geri yukle hizi ${ALT}-${UST} MiB/s bandinda: ` +
  `${mib / sn >= ALT && mib / sn <= UST ? "evet" : "hayir"}`);
rmSync(kok, { recursive: true, force: true });               // gecici agac silinir
```

```
5 kalem, 461824 bayt (tohum 51703); arsiv 462113 bayt
kalem               | uretimdeki ozet (ilk 16) | geri gelen ayni
--------------------|--------------------------|----------------
ad-bolge.kayit      |         b7c0e693cd032524 |            evet
is-emri.veri        |         5c4512d9a8016d51 |            evet
olcum.veri          |         3edf42c01d4f883f |            evet
servis.yapilandirma |         4ead0d5566a44d75 |            evet
tarife.veri         |         434443d05cecee54 |            evet

deneme                     | acildi | birebir | eksik | yedek alma adimi
---------------------------|--------|---------|-------|------------------
saglikli tatbikat          |   evet |     5/5 |     0 |         basarili
eksik kalem (yapilandirma) |   evet |     4/5 |     1 | basarili gorundu
bozuk arsiv (tek bayt)     |  hayir |     0/5 |     5 | basarili gorundu
cozulemeyen sifre          |  hayir |     0/5 |     5 | basarili gorundu
yanlis sira (MODEL)        | 2/4 adim bos veriyle aciliyor           | basarili gorundu
eksik yetki (MODEL)        | 2 kalem: nesne-deposu, servis-yoneticisi | basarili gorundu

tatbikatin buldugu kusur 5; yedek alma adiminda gorulen 0
yedekle+sil+geri yukle hizi 0.5-20000 MiB/s bandinda: evet
```

Birinci tablo bu dersin kanıtıdır: üretim ağacı yazıldı, arşivlendi, **silindi** ve yalnız arşivden
geri getirildi; beş kalemin beşinde özetler aynı çıktı. Bir cümle değil, beş karşılaştırma.

İkinci tablonun son sütunu bulgudur. Kapsam dışı bırakılan yapılandırma geri gelmiyor ama arşiv
açılıyor; tek baytı çevrilmiş arşiv ile başka anahtarla şifrelenmiş arşiv hiç açılmıyor ve beş kalem
birden gidiyor. Yanlış sırada dört adımın ikisi boş veriyle açılıyor ve kimlikte iki yetki eksik.
**Beş kusurun beşi de yedek alma adımında görünmedi.**

#### Süre Bileşenlere Ayrılıyor

```js
// tatbikat/sure.mjs — geri yukleme suresi bilesenlerine ayrilir, hedefle karsilastirilir ve
// tatbikat sikligi taranir. MODELDIR; indirme suresi 05'in tam yedek boyutundan turer.
const HEDEF = 240;                       // dakika; onceki kurstan girdi
const TAM_GIB = 649.8, HAT_MIBS = 80;    // tam yedek boyutu; hat hizi kurgudur
const INDIRME = (TAM_GIB * 1024) / HAT_MIBS / 60;
const BILESEN = {                        // [tatbikatsiz, tatbikatli] dakika
  bulma: [95, 12], indirme: [INDIRME, INDIRME], acma: [65, 38],
  dogrulama: [40, 15], "servisi acma": [85, 22],
};
const g = (x, n, d = 1) => x.toFixed(d).padStart(n);
const topla = (i) => Object.values(BILESEN).reduce((a, b) => a + b[i], 0);
const PAY = HEDEF / Object.keys(BILESEN).length;         // esit pay

console.log(`hedef ${HEDEF} dk; tam yedek ${TAM_GIB} GiB, hat ${HAT_MIBS} MiB/s, esit pay ${PAY} dk.`);
console.log("\nbilesen      | tatbikatsiz | tatbikatli | hedefin yuzdesi");
console.log("-------------|-------------|------------|----------------");
for (const [ad, [y, t]] of Object.entries(BILESEN))
  console.log(`${ad.padEnd(12)} | ${g(y, 11)} | ${g(t, 10)} | ${("%" + g((100 * t) / HEDEF, 6)).padStart(15)}`);
console.log(`${"toplam".padEnd(12)} | ${g(topla(0), 11)} | ${g(topla(1), 10)} | ` +
  `${("%" + g((100 * topla(1)) / HEDEF, 6)).padStart(15)}`);
const asan = Object.entries(BILESEN).filter(([, [, t]]) => t > PAY).map(([a]) => a);
console.log(`tatbikatli surede esit payi asan ${asan.length} bilesen: ${asan.join(", ")}`);

const DEGISIM = 3 / 30 + 1 / 90;         // gunluk degisim: ayda 3 yapilandirma, ceyrekte 1 kalem
const KALEM = 16, SAAT = 6;              // envanter; bir tatbikat alti saat
console.log("\nsiklik    | yilda | yillik saat | dogrulanmamis degisiklik | geri yukleme | hedef");
console.log("----------|-------|-------------|--------------------------|--------------|-------");
for (const gun of [90, 180, 365, null]) {
  const n = gun ? Math.floor(365 / gun) : 0;
  const belirsiz = gun ? gun * DEGISIM : 365 * DEGISIM + KALEM;
  const sure = gun ? topla(1) : topla(0);
  console.log(`${(gun ? gun + " gunde" : "hic").padEnd(9)} | ${String(n).padStart(5)} | ` +
    `${String(n * SAAT).padStart(11)} | ${(g(belirsiz, 4) + (gun ? " kalem" : " kalem+kume")).padStart(24)}` +
    ` | ${g(sure, 12)} | ${(sure > HEDEF ? "asildi" : "tuttu").padStart(6)}`);
}
```

```
hedef 240 dk; tam yedek 649.8 GiB, hat 80 MiB/s, esit pay 48 dk.

bilesen      | tatbikatsiz | tatbikatli | hedefin yuzdesi
-------------|-------------|------------|----------------
bulma        |        95.0 |       12.0 |         %   5.0
indirme      |       138.6 |      138.6 |         %  57.8
acma         |        65.0 |       38.0 |         %  15.8
dogrulama    |        40.0 |       15.0 |         %   6.3
servisi acma |        85.0 |       22.0 |         %   9.2
toplam       |       423.6 |      225.6 |         %  94.0
tatbikatli surede esit payi asan 1 bilesen: indirme

siklik    | yilda | yillik saat | dogrulanmamis degisiklik | geri yukleme | hedef
----------|-------|-------------|--------------------------|--------------|-------
90 gunde  |     4 |          24 |               10.0 kalem |        225.6 |  tuttu
180 gunde |     2 |          12 |               20.0 kalem |        225.6 |  tuttu
365 gunde |     1 |           6 |               40.6 kalem |        225.6 |  tuttu
hic       |     0 |           0 |          56.6 kalem+kume |        423.6 | asildi
```

Tatbikatsız düzende geri yükleme 423,6 dakika sürüyor, hedefi 183,6 dakika aşıyor; tatbikatlı
düzende 225,6 dakikaya iniyor ve hedef 14,4 dakikalık payla tutuyor. Tatbikatın kısalttığı şey
bilgidir: doğru noktayı bulma 95 dakikadan 12'ye, servisleri açma 85'ten 22'ye iniyor — prova
edilmiş adımlar.

İndirme sütunu hiç değişmiyor: 138,6 dakika, hedefin yüzde 57,8'i ve eşit payı aşan tek bileşen. Bu
süre bilgi eksikliğinden değil, 649,8 GiB'i 80 MiB/s'lik bir hattan geçirmekten geliyor; tatbikat
ölçer ama kısaltmaz. **Hedefi tutturmanın yolu daha çok tatbikattan değil, yedeği geri
yükleneceği yere yaklaştırmaktan geçiyor.** Sıklık taraması bedeli ve alternatifini yan yana
koyuyor: doksan günde bir tatbikat yılda yirmi dört saat ve 10 kalemlik belirsizlik, yılda bir
tatbikat altı saat ve 40,6 kalem. Hiç yapılmadığında bedel sıfır, belirsizlik on altı kalemin
tamamı ve süre hedefi aşıyor.

#### Özet

- Yedek alma adımı beş kusurun beşinde de başarılı döndü; hepsi yalnız tatbikatta görüldü: kapsam
  dışı kalem, bozuk arşiv, çözülemeyen şifre, yanlış sıra, eksik yetki.
- Kanıt bir özet karşılaştırmasıdır: beş kalem yazıldı, arşivlendi, silindi, geri yüklendi ve özetler
  aynı çıktı.
- Geri yükleme süresi tatbikatsız 423,6, tatbikatlı 225,6 dakikadır; hedef yüzde 94 doluluğla
  tutar. Tatbikat dört bileşeni kısaltır, indirmeye dokunmaz: 138,6 dakika hedefin yüzde 57,8'i ve
  eşit payı aşan tek bileşendir.
- Tatbikat sıklığı bir bedel-belirsizlik takasıdır: doksan günde bir yılda 24 saat ve 10 kalem,
  hiç yapılmadığında 0 saat ve on altı kalemin tamamı.

#### Kurs Kapanışı

| Ders | Varsayılanın açık bıraktığı | Kapatılan / yanlış kapatılan | Kapatmanın getirdiği yeni yüzey |
|---|---|---|---|
| Web sunucusu rolleri | 18 kalem | 13 kapandı / 4 meşru iş | 3 yeni kalem |
| Ters vekil yapılandırması | 4 kayıp bilgi | 4 çözüldü / 2 kalem gizlendi | sahte başlık, 4 istek |
| Taşıma katmanı sonlandırma | 19 zayıf kalem | 19 kapandı / 65 cihaz | sertifika 6 noktada |
| Sertifika otomasyonu | 1.700 saat pencere | 0 saat / 12 gereksiz yenileme | 4 yeni kalem |
| Önbellek sunucusu | 179 sızan istek | 0 sızıntı / 2 kat yük | kaçan yayın, sessiz pencere |
| Servis ağı | 40 servise 40 dokunuş | 508 iş kalemi / 3 serviste pahalı | 162 yan araba kalemi |
| DNS yönetimi | 4 ölü, 2 devralınabilir kayıt | 5 dakikaya / 288 kat sorgu | bölgeye yazan kimlik |
| Gönderen doğrulama kayıtları | sahipsiz gönderim serbest | 5/6 sahte / 2 meşru düştü | 254 fazla yetkili adres |
| Alan adı politika kaydı | 61 sahte ulaşıyor | 49 engellendi / 43 meşru ayrıldı | 12 uyumlu taklit |
| Posta teslim sorunları | 12 puan tavan | tavan kalktı / 1.078 ileti kayıp | alıcı kararı ölçülemez |
| Güvenlik duvarı yapılandırması | 100 kalem, 107.265 deneme | 10 satır hepsi / 2 akış | dış satır, 20.650 deneme |
| Uzak erişim sertleştirme | 2.340 üçlü, 16.505 deneme | 16.505 kapandı / 0 meşru | 34 anahtar kopyası |
| Sır yönetimi sistemleri | 36 kalem, sonsuz pencere | 2,5 dakika / 9 kalem ömürsüz | tek nokta, 18 örnek |
| Yama yönetimi | 60 kalem, 28,94 gün | 1,22 güne / 4 geri alma, 82 kesinti | 15 kalem, yama ajanı |
| Yedekleme stratejisi | 13 kalem kapsam dışı | 3 kaleme / servis yine 2/4 | okunabilir yüzey iki katı |
| Geri yükleme tatbikatı | 5 kusur görünmez, 423,6 dk | 5 bulundu / 225,6 dk | 24 saat, 2 eksik yetki |

İkinci sütunda hiçbir satırda bir kararın izi yok: **varsayılan bir karar değildir, kimsenin
vermediği karardır.** Üçüncü sütunda yanlış kapatma on altı satırın on dördünde doludur: hiçbir
adım bedava değil. Dördüncü sütunda üç yüzey türü tekrar ediyor: **yeni bir kimlik ya da yazma
yetkisi** beş derste, **bütün yükü taşıyan tek nokta** dört derste, **kendisi yapılandırılması
gereken yeni bir katman** dört derste. Her savunma kendi yüzeyini getirir — kapatılan kalem yok
olmaz, biçim değiştirir.

Yedi kurstur her katman ayrı ayrı kuruldu ve sertleştirildi. Tablodaki her satır bir kararlar
dizisidir: hangi kapı, hangi eşik, hangi kalem. Ama bunların hepsini **her ekibin yeniden
kurması** mı gerekiyor? Platform Mühendisliği bu soruyla başlıyor.

