Ders 07 / 15
Kısa Ömürlü Kimlik Bilgileri
Bir sır sızdığı andan kendiliğinden geçersizleştiği ana kadar geçen süre ölçülür: 31 kalemin 16'sında açık pencere 90 günden 64 dakikaya, yani 2.033 kata iniyor; kalan 15 kalemde hiç kısalmıyor ve geçişten sonra toplam maruziyetin %99,96'sı orada toplanıyor. Bedeli depo isteğinin toplamı değil dağılımıdır — üç uygulamanın yükü 6 ile 14 kat artıyor, hedef sistemlerde günde 1.073 geçici kimlik bilgisi doğup ölüyor ve iki saatlik bir depo kesintisinde duran uygulama dörtten sekize çıkıyor.
İçindekiler
Önceki ders erişim matrisini daralttı: yetmiş dokuz (uygulama, sır) kaleminden otuz biri
gerçekten okunuyordu, kırk sekizi karşılıksızdı. Kalan otuz bir kalemin her birinde duran şeye
ise hiç bakılmadı. O şey ömrü olmayan bir değerdir: kurulum günü yazılmış, o gün bu gündür
aynı. Bu ders o değeri tek bir eksende ölçer — sır sızarsa ne kadar süre çalışır.
Sır saklama servisinin mimarisi ve dinamik kimlik bilgisi üretecinin servis olarak nasıl kurulduğu daha önceki kurslarda ölçüldü; burada tekrarlanmıyor. Buranın ölçüsü tek bir süredir: açık pencere. Statik bir sır için bu süre bir sonraki planlı döndürmeye kadardır; istek üzerine üretilen kısa ömürlü bir kimlik bilgisi için kalan jeton ömrüdür. İkisi arasındaki fark bu dersin konusudur — ve o farkın hangi kalemlerde hiç oluşmadığı da.
- SR7. Önceki dersin modeli sürüyor: dokuz uygulama, bir sır deposu, otuz bir okunan kalem
ve on yedi ayrı sır. Ortam kurgudur, ölçülen şey
nodeile yazılmış bir modeldir ve gerçek sır değeri taşımaz. - SR8. Açık pencere sızıntının fark edilmesini içermez. Fark etme ve iptal akışı bu konunun son dersinde ayrıca ölçülür; burada sır kendiliğinden geçersizleşene kadar geçen süre sayılır.
- SR9. Statik sır için modelde planlı döndürme zamanında yapılır. Gecikmiş döndürme ve döndürme sırasında olan biten bir sonraki dersin konusudur.
- SR10. Sızıntı anı pencere içinde rastgele varsayılır: ortalama açık pencere döndürme periyodunun yarısı, en kötü durumda tamamıdır. Aynı kural jeton ömrü için de geçerlidir.
- SR11. Bir hedef sistemin istek üzerine kimlik bilgisi üretip üretemediği model tablosunda verilir. İmza anahtarı üretilebilir sayılmaz: imzayı doğrulayan tarafın da aynı anahtarı bilmesi gerekir, dolayısıyla anahtar istek başına değiştirilemez.
- SR12. Rastgelelik yok; bütün sayılar model tablolarından türetiliyor ve çıktı koşumdan koşuma aynı.
Pencere Kaç Kata İniyor
// omur.mjs — 31 (uygulama, sir) kalemi ve her kalemin acik penceresi. MODELDIR. // Bolgesel olcum aginin uretim ortami KURGUDUR: dokuz uygulama, bir sir deposu. // GERCEK SIR DEGERI YOKTUR: yalniz sir yollari, dondurme periyodu ve jeton omru modellenir. export const OKUR = { "portal-onyuz": ["imza/oturum-imzalama"], "portal-api": ["veri/portal-birincil", "veri/portal-okuma", "imza/oturum-imzalama", "imza/ic-cagri-imzalama", "altyapi/onbellek", "altyapi/gunluk-yazma"], "abone-kayit": ["veri/portal-birincil", "dis/eposta-gecidi", "dis/kisa-mesaj-gecidi"], "fatura-servisi": ["veri/fatura-birincil", "veri/portal-okuma", "veri/arsiv", "dis/odeme-gecidi", "imza/belge-imzalama"], "odeme-koprusu": ["dis/odeme-gecidi"], "saha-api": ["veri/saha-birincil", "kuyruk/is-emri-kuyrugu", "dis/harita-servisi", "imza/ic-cagri-imzalama"], "is-emri": ["veri/saha-birincil", "kuyruk/is-emri-kuyrugu", "kuyruk/bildirim-kuyrugu", "dis/harita-servisi"], "bildirim": ["kuyruk/bildirim-kuyrugu", "dis/eposta-gecidi", "dis/kisa-mesaj-gecidi"], "rapor-uretici": ["veri/portal-okuma", "veri/arsiv", "altyapi/nesne-deposu", "dis/eposta-gecidi"], }; // alan varsayilani [dondurme(gun), uretir, jeton omru(dk)]; uretir = hedef sistem istek // uzerine kisa omurlu kimlik bilgisi uretebiliyor mu. Istisnalar ayrica yaziliyor. const ALANVAR = { veri: [180, true, 60], kuyruk: [180, true, 120], altyapi: [180, true, 240], imza: [90, false, 0], dis: [365, false, 0] }; const ISTISNA = { "altyapi/gunluk-yazma": [180, true, 720], "altyapi/onbellek": [180, false, 0], "dis/odeme-gecidi": [90, false, 0] }; export const SIR = Object.fromEntries([...new Set(Object.values(OKUR).flat())].map((s) => { const [dondurme, uretir, omur] = ISTISNA[s] || ALANVAR[s.split("/")[0]]; return [s, { dondurme, uretir, omur }]; })); // bicim/omur: sirrin bugun nasil alindigi. ornek: calisan ornek sayisi. // yb: gunde kac yeniden baslatma. istek: gunluk istek (kurgu birim). export const UYG = { "portal-onyuz": { bicim: "baslangicta", omur: 0, ornek: 4, yb: 6, istek: 84000 }, "portal-api": { bicim: "onbellekli", omur: 60, ornek: 8, yb: 12, istek: 96000 }, "abone-kayit": { bicim: "baslangicta", omur: 0, ornek: 2, yb: 3, istek: 1400 }, "fatura-servisi": { bicim: "onbellekli", omur: 240, ornek: 2, yb: 2, istek: 6200 }, "odeme-koprusu": { bicim: "her-istekte", omur: -1, ornek: 3, yb: 2, istek: 3400 }, "saha-api": { bicim: "onbellekli", omur: 60, ornek: 5, yb: 8, istek: 42000 }, "is-emri": { bicim: "baslangicta", omur: 0, ornek: 3, yb: 4, istek: 9600 }, "bildirim": { bicim: "onbellekli", omur: 15, ornek: 2, yb: 3, istek: 12000 }, "rapor-uretici": { bicim: "baslangicta", omur: 0, ornek: 1, yb: 1, istek: 320 }, }; export const AD = Object.keys(UYG); export const KALEM = AD.flatMap((a) => OKUR[a].map((s) => [a, s])); export const ALAN = ["veri", "kuyruk", "altyapi", "imza", "dis"]; // acik pencere: sir sizdiginda kendiliginden gecersizlesene kadar gecen sure (dk). export const pencere = (s, kisa) => kisa && SIR[s].uretir ? SIR[s].omur : SIR[s].dondurme * 1440; export const gen = (B) => (h) => h.map((v, j) => j ? String(v).padStart(B[j]) : String(v).padEnd(B[0])).join(""); export const sure = (dk) => dk < 1440 ? `${Math.round(dk)} dk` : `${(dk / 1440).toFixed(1)} gun`; export const ort = (k, kisa) => k.reduce((t, [, s]) => t + pencere(s, kisa) / 2, 0) / k.length; if (import.meta.url === `file://${process.argv[1]}`) { const yz = gen([10, 8, 15, 16, 18, 7]); const D = KALEM.filter(([, s]) => SIR[s].uretir), S = KALEM.filter(([, s]) => !SIR[s].uretir); console.log(`model: ${KALEM.length} (uygulama, sir) kalemi, ${Object.keys(SIR).length} okunan ` + `sir, ${AD.length} uygulama (kurgu uretim ortami)\n`); console.log(yz(["alan", "kalem", "kisaltilabilir", "bugun pencere", "kisa omur pencere", "kat"])); for (const al of ALAN) { const k = KALEM.filter(([, s]) => s.startsWith(al + "/")); console.log(yz([al, k.length, k.filter(([, s]) => SIR[s].uretir).length, sure(ort(k, false)), sure(ort(k, true)), (ort(k, false) / ort(k, true)).toFixed(0)])); } console.log(yz(["toplam", KALEM.length, D.length, sure(ort(KALEM, false)), sure(ort(KALEM, true)), (ort(KALEM, false) / ort(KALEM, true)).toFixed(1)])); console.log(`\nyalniz kisaltilabilen ${D.length} kalem: ortalama pencere ` + `${sure(ort(D, false))} -> ${sure(ort(D, true))}, ` + `${Math.round(ort(D, false) / ort(D, true))} kat`); console.log(`geriye kalan ${S.length} kalem: ortalama pencere ${sure(ort(S, false))}, degismedi`); console.log(`kisa omre gecildikten sonra toplam maruziyet payi — ` + `${S.length} statik kalem: %${(100 * ort(S, true) * S.length / (ort(KALEM, true) * KALEM.length)).toFixed(2)}`); const kalan = [...new Set(S.map(([, s]) => s))].sort((x, y) => SIR[y].dondurme - SIR[x].dondurme); console.log(`kisa omre hic gecemeyen ${kalan.length} sir: ` + kalan.map((s) => `${s.split("/")[1]}(${SIR[s].dondurme}g)`).join(" ")); }
model: 31 (uygulama, sir) kalemi, 17 okunan sir, 9 uygulama (kurgu uretim ortami) alan kalem kisaltilabilir bugun pencere kisa omur pencere kat veri 10 10 90.0 gun 30 dk 4320 kuyruk 4 4 90.0 gun 60 dk 2160 altyapi 3 2 90.0 gun 30.1 gun 3 imza 5 0 45.0 gun 45.0 gun 1 dis 9 0 151.9 gun 151.9 gun 1 toplam 31 16 100.7 gun 54.3 gun 1.9 yalniz kisaltilabilen 16 kalem: ortalama pencere 90.0 gun -> 64 dk, 2033 kat geriye kalan 15 kalem: ortalama pencere 112.2 gun, degismedi kisa omre gecildikten sonra toplam maruziyet payi — 15 statik kalem: %99.96 kisa omre hic gecemeyen 8 sir: eposta-gecidi(365g) kisa-mesaj-gecidi(365g) harita-servisi(365g) onbellek(180g) oturum-imzalama(90g) ic-cagri-imzalama(90g) odeme-gecidi(90g) belge-imzalama(90g)
Tablonun ilk iki satırı kısa ömürlü kimlik bilgisinin gerçek büyüklüğünü veriyor. Veri tabanı kalemlerinde açık pencere doksan günden otuz dakikaya iniyor; oran dört bin üç yüz yirmi kat. Kuyruk kalemlerinde iki bin yüz altmış kat. Çoğu savunma bir kalemi yüzde otuz, yüzde elli iyileştirir; burada aynı kalem üç basamak birden değişiyor — doksan gün ile otuz dakika arasında zaten dört basamak vardır.
Son satır aynı tabloyu bütün küme üzerinden okuyor ve rakam çöküyor. Otuz bir kalemin ortalaması yüz virgül yedi günden elli dört virgül üç güne iniyor: yalnız bir virgül dokuz kat. Aynı değişiklik, aynı koşumda, iki bin katla iki katı yan yana veriyor. Aradaki fark tablonun üçüncü sütununda: otuz bir kalemin on altısı kısaltılabiliyor, on beşi kısaltılamıyor.
Kısaltılamayan on beş kalem üç sınıfa ayrılıyor. İmza anahtarları (beş kalem) istek başına değiştirilemez, çünkü imzayı doğrulayan tarafın da aynı anahtarı bilmesi gerekir; anahtarın ömrünü kısaltmak doğrulama tarafını kırar. Dış geçit anahtarları (dokuz kalem) sağlayıcının ne verdiğine bağlıdır ve bu modelde dördü de sabit anahtar veriyor — ödeme, harita, e-posta ve kısa mesaj geçitleri. Önbellek sunucusu (bir kalem) istek üzerine kullanıcı üretmiyor.
Dördüncü satırdan sonraki iki satır ise kararın kendisidir. Geçişten sonra toplam maruziyetin yüzde 99,96’sı kısaltılamayan on beş kalemde toplanıyor. Yani kısa ömre geçmek, riskin neredeyse tamamını taşıyan kalemleri hiç etkilemeden, riskin yüzde sıfır virgül sıfır dördünü üç basamak küçültüyor. Bu, yapılan işin değersiz olduğu anlamına gelmez — veri tabanı kimlik bilgisi sızdığında ele geçen şey abone verisidir ve pencerenin doksan günden otuz dakikaya inmesi gerçek bir kazançtır. Anlamı şudur: ortalama açık pencere yanlış göstergedir. Doğru gösterge, kısaltılamayan kalemin listesidir ve o liste sekiz sırdan oluşuyor.
Yenilemenin Bedeli
Jeton ömrü kısaldıkça yenileme sıklaşır; ve yenilemenin gittiği yer, önceki dersin ölçtüğü tek noktadır.
// yuk.mjs — kisa omre gecisin bedeli: depo istegi, hedef sistemde uretim, kesinti dayanikliligi import { AD, OKUR, SIR, UYG, KALEM, gen } from "./omur.mjs"; // bir kalemin gunluk depo istegi. kisa omurlude kalem kendi jeton omruyle yenilenir; // statik kalem uygulamanin bugunku okuma bicimini korur. const istekSay = (a, s, kisa) => { const u = UYG[a]; if (kisa && SIR[s].uretir) return Math.round(1440 / SIR[s].omur) * u.ornek + u.yb; if (u.bicim === "her-istekte") return u.istek; if (u.bicim === "onbellekli") return Math.round(1440 / u.omur) * u.ornek + u.yb; return u.yb; }; // depo kesintisinde uygulamanin dayandigi sure: her istekte okuyan 0, onbellekli omru kadar, // baslangicta okuyan sinirsiz. kisa omurlude en kisa jeton omru de tavan koyar. const dayanma = (a, kisa) => Math.min( UYG[a].bicim === "her-istekte" ? 0 : UYG[a].bicim === "onbellekli" ? UYG[a].omur : Infinity, ...(kisa ? OKUR[a].filter((s) => SIR[s].uretir).map((s) => SIR[s].omur) : [])); const yz = gen([16, 8, 13, 13, 11, 6]); console.log(yz(["uygulama", "kalem", "bugun istek", "kisa omurlu", "uretim", "kat"])); for (const a of AD) { const b = OKUR[a].reduce((t, s) => t + istekSay(a, s, false), 0); const k = OKUR[a].reduce((t, s) => t + istekSay(a, s, true), 0); const u = OKUR[a].filter((s) => SIR[s].uretir).reduce((t, s) => t + istekSay(a, s, true), 0); console.log(yz([a, OKUR[a].length, b, k, u, (k / b).toFixed(1)])); } const T = (kisa, f = () => true) => KALEM.filter(([, s]) => f(s)) .reduce((t, [a, s]) => t + istekSay(a, s, kisa), 0); console.log(yz(["toplam", KALEM.length, T(false), T(true), T(true, (s) => SIR[s].uretir), (T(true) / T(false)).toFixed(1)])); console.log(`\nhedef sistemde gunluk gecici kimlik bilgisi (olusturma, sonra suresi dolan):`); for (const al of ["veri", "kuyruk", "altyapi"]) console.log(` ${al.padEnd(9)}${String(KALEM.filter(([, s]) => s.startsWith(al + "/") && SIR[s].uretir).reduce((t, [a, s]) => t + istekSay(a, s, true), 0)).padStart(5)}`); const yz2 = gen([13, 22, 20]); console.log(`\n${yz2(["kesinti(dk)", "bugun duran uygulama", "kisa omurlu duran"])}`); for (const D of [15, 60, 120, 240, 1440]) console.log(yz2([D, AD.filter((a) => dayanma(a, false) < D).length, AD.filter((a) => dayanma(a, true) < D).length])); const saglam = AD.filter((a) => dayanma(a, true) === Infinity); console.log(`\ndepo kesintisinde suresiz calisabilen uygulama: bugun ` + `${AD.filter((a) => dayanma(a, false) === Infinity).length}, kisa omurlu ${saglam.length}` + `${saglam.length ? ` (${saglam.join(", ")})` : ""}`);
uygulama kalem bugun istek kisa omurlu uretim kat portal-onyuz 1 6 6 0 1.0 portal-api 6 1224 1048 436 0.9 abone-kayit 3 9 57 51 6.3 fatura-servisi 5 70 178 150 2.5 odeme-koprusu 1 3400 3400 0 1.0 saha-api 4 512 452 196 0.9 is-emri 4 16 160 156 10.0 bildirim 3 585 417 27 0.7 rapor-uretici 4 4 58 57 14.5 toplam 31 5826 5776 1073 1.0 hedef sistemde gunluk gecici kimlik bilgisi (olusturma, sonra suresi dolan): veri 863 kuyruk 175 altyapi 35 kesinti(dk) bugun duran uygulama kisa omurlu duran 15 1 1 60 2 2 120 4 8 240 4 8 1440 5 8 depo kesintisinde suresiz calisabilen uygulama: bugun 4, kisa omurlu 1 (portal-onyuz)
Toplam satırı ilk bakışta beklenenin tersini söylüyor: günlük depo isteği beş bin sekiz yüz yirmi altıdan beş bin yedi yüz yetmiş altıya iniyor, yani hiç değişmiyor. Kısa ömre geçmenin depoya ek yük getirmediği sonucu çıkarılamaz; toplam, birbirini götüren iki hareketi gizliyor.
Uygulama satırları o iki hareketi ayırıyor. Yükü artan üç uygulama var ve üçü de sırrını bugün yalnız başlangıçta okuyanlardır: rapor üreticisi on dört buçuk kat, iş emri servisi on kat, abone kaydı altı virgül üç kat. Bunlar bugün günde dört, on altı ve dokuz istek yapıyor; kısa ömre geçtiklerinde elli sekiz, yüz altmış ve elli yedi. Ömrü olmayan bir değer bir kez okunur, ömrü olan bir değer sürekli yenilenir. Yükü azalan iki uygulama ise ters sebepten: portal ve saha uygulama arayüzleri önbelleklerini zaten altmış dakikada bir tazeliyor, jeton ömrü de altmış dakika; değişen tek şey günlük yazma anahtarının on iki saatlik ömre geçmesi ve o kalemin isteğinin iki yüz dörtten yirmi sekize düşmesi.
İkinci tablo asıl yeni maliyeti gösteriyor. Bin yetmiş üç isteğin karşılığı bir okuma değil, bir üretimdir: hedef sistemde günde sekiz yüz altmış üç veri tabanı kullanıcısı, yüz yetmiş beş kuyruk ve otuz beş altyapı kimlik bilgisi yaratılıyor ve süresi dolduğunda temizleniyor. Bu, sır deposunun değil veri tabanının yüküdür ve sır yönetimi hesabında sık sık unutulur; yaratmayı beceren ama silmeyi beceremeyen bir akış günde sekiz yüz altmış üç kalemlik birikim üretir.
Üçüncü tablo bedelin en pahalı kalemidir ve önceki dersin bulgusunu doğrudan kötüleştiriyor. Depo kesintisinde iki saat dayanabilen uygulama sayısı bugün dört; kısa ömre geçildiğinde bu sayı sekize çıkıyor, yani dokuz uygulamanın sekizi iki saatlik bir depo kesintisinde duruyor. Kesintiye süresiz dayanabilen uygulama dörtten bire iniyor ve o bir uygulama, hiç kısaltılabilir kalemi olmayan portal ön yüzüdür. Açık pencereyi doksan günden otuz dakikaya indirmek, uygulamanın depoya olan bağımlılığını da doksan günden otuz dakikaya indirmek demektir; ikisi aynı ayarın iki yüzüdür ve ayrı ayrı seçilemez.
Daha Ucuz Aşama
Otuz dakikalık pencere çalışma zamanında kuruluyor, ama pencerenin kısaltılabilir olup olmadığı çalışma zamanında kararlaşmıyor. Kısaltılamayan sekiz sırrın her biri daha erken bir aşamada seçildi: e-posta ve kısa mesaj geçitleri tedarikçi seçimi aşamasında, imza anahtarları tasarım aşamasında, önbellek sunucusu altyapı seçiminde. Bir dış sağlayıcı seçilirken “istek üzerine kısa ömürlü kimlik bilgisi üretiyor mu” sorusu sorulmadıysa, o sağlayıcının anahtarı sistemin ömrü boyunca statik kalır; bu ders o anahtarı ölçebilir, kısaltamaz. Dokuz dış kalemin tamamı bu yolla doğdu ve bugün toplam maruziyetin en büyük payını taşıyor.
Çalışma zamanına gerçekten ait olan tek karar, kısaltılabilen on altı kalemde jeton ömrünün seçilmesidir. O seçim de tek yönlü değildir: ömrü altmış dakikadan on beş dakikaya indirmek pencereyi dörde böler, depo isteğini dörtle çarpar ve kesintiye dayanma süresini dörde böler. Üçü aynı sayıdır.
Özet
- Açık pencere, sır sızdığı andan kendiliğinden geçersizleştiği ana kadar geçen süredir. Statik sırda bir sonraki planlı döndürmeye kadar, kısa ömürlü kimlik bilgisinde kalan jeton ömrü.
- Kısaltılabilen 16 kalemde pencere ortalama 90 günden 64 dakikaya, yani 2.033 kata iniyor; veri tabanı kalemlerinde oran 4.320 kat.
- Otuz bir kalemin tamamında ortalama yalnız 1,9 kat daralıyor. Geçişten sonra toplam maruziyetin %99,96’sı kısaltılamayan 15 kalemde toplanıyor. Ortalama açık pencere bu yüzden yanlış göstergedir; doğru gösterge sekiz sırlık kısaltılamayanlar listesidir.
- Depoya günlük istek 5.826’dan 5.776’ya, yani hiç değişmiyor; ama 1.073’ü artık okuma değil üretimdir ve hedef sistemlerde günde 863 veri tabanı kullanıcısı doğup ölüyor. Sırrını yalnız başlangıçta okuyan üç uygulamanın yükü 6,3, 10 ve 14,5 kat artıyor.
- Bedelin en pahalı kalemi kesinti dayanıklılığıdır: iki saatlik depo kesintisinde duran uygulama 4’ten 8’e çıkıyor, süresiz dayanabilen 4’ten 1’e iniyor. Pencereyi kısaltmakla depo bağımlılığını sıkılaştırmak aynı ayardır.
- Kısaltılamayan sekiz sır tedarikçi ve tasarım seçimi aşamasında belirlendi; çalışma zamanı onları ölçer, kısaltamaz.
Sonraki Adım
Bu ders on beş kalemde ömrün kısaltılamadığını gösterdi. O kalemler için geriye tek bir araç kalıyor: döndürme. Sır kısalmıyorsa belirli aralıklarla değiştirilir ve açık pencere döndürme periyoduyla sınırlanır. Ama döndürme bir anda olan bir iş değildir. Yeni değeri okuyacak her uygulamanın geçmesi gerekir ve uygulamalar aynı hızda geçmez: birisi altmış dakikada, birisi ancak yeniden başladığında. O geçiş süresi boyunca iki sır birlikte geçerli kalmak zorundadır, yoksa geçmemiş olan kesilir. Sonraki ders o süreyi hesaplar: on yedi sır için asgari örtüşme kaç dakika, süre kısa tutulduğunda kaç istemci yeni değeri kaçırıyor ve kaç meşru istek kesiliyor.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.