İçeriğe geç
academia.sh

Ders 10 / 13

Tünelleme ve Sıçrama Sunucusu

Yolun ikiye bölünmesiyle aday neden kümesi ona çıkar; uçtan uca tek deneme sekiz aday eler ve iki durak arasında üç ayrılamayan öbek bırakır, duraktan yapılan sınama dokuz eler, tünel ağzının bağ adresi dolaylı erişimi sıfırdan yetmiş ikiye çıkarır.

İçindekiler

Önceki dersin en keskin sonucu şuydu: eleme gücünün tamamı sunucudadır ve sunucuya girmenin yolu kapalıdır. Dışarıdan yapılabilen dört sınama dört üyeli bir öbeği ayıramadan bırakıyordu. Bu tıkanmanın olağan çözümü, doğrudan erişilemeyen makineye erişilebilen bir başka makinenin üzerinden gitmektir.

Çözüm bir bedelle gelir ve bu ders o bedeli sayar. Yol ikiye bölününce aday neden kümesi de ikiye bölünür: arıza artık iki makineden birinde, aradaki iki bacaktan birinde ya da istemcinin kendisinde olabilir. Uçtan uca yapılan tek bir deneme, bu genişlemiş kümenin kaçını eliyor.

Yolun İki Durağı

Sıçrama sunucusu (jump host), iki ağ arasında tek geçit olarak duran makinedir. İstemci ona bağlanır, o da hedefe bağlanır. İki yerleşim biçimi vardır ve ikisi farklı aday neden üretir.

Birincisinde istemci makinesinde bir yerel bağlantı noktası açılır ve o noktaya gelen trafik şifreli oturumun içinden geçirilip hedefe iletilir. Buna tünel (tunnel) denir. İkincisinde sıçrama sunucusu yalnız taşıyıcıdır: oturum doğrudan hedefte açılır, sıçrama sunucusunda kabuk çalışmaz. Aşağıdaki döküm çalıştırılmamıştır; iki biçimin yazımını göstermek içindir:

# ornek dokum , calistirilmamistir
# yerel yonlendirme: agiz istemcide acilir , trafik sicrama uzerinden hedefe gider
ssh -L 127.0.0.1:<yerel-nokta>:<hedef-konak>:<hedef-nokta> <kullanici>@<sicrama>

# durak olarak kullanma: oturum hedefte acilir , sicrama yalnizca tasir
ssh -J <kullanici>@<sicrama> <kullanici>@<hedef-konak>

İki biçimin ortak ayrıntısı, tanının yarısını belirler: <hedef-konak> adı sıçrama sunucusunda çözülür, istemcide değil. Hedefin adı yalnız uzak ağın çözücüsünde tanımlıysa bu iki yazım çalışır. Aynı ad istemcinin kendi yapılandırmasında bir takma ad olarak yazılmışsa istemci onu çözmeye çalışır ve çözemez. Ortaya çıkan hata iletisi ad çözümlemeyi işaret eder, oysa ad sunucuda gayet iyi çözülmektedir. Adın hangi tarafta çözüldüğü, bu konunun kendine özgü aday nedenidir.

Sıçrama sunucusunun doğrudan erişilebilir makine sayısını nasıl daralttığı DevOps ve Platform Mühendisliği müfredatının uzak erişim sertleştirme dersinde, güven bölgeleri arasındaki yerleşimi ise Siber Güvenlik müfredatının çevre savunması konusunda sayıldı. Burada ölçülen şey başkadır: aynı yerleşimin tanıya ne yaptığı.

Tünelin Ağzı Nereye Bağlanır

Tünel istemci makinesinde bir bağlantı noktası açar ve o noktanın bağ adresi bir seçimdir. Geri döngü adresine bağlandığında yalnız o makinenin üzerindeki süreçler tüneli kullanabilir. Bütün arayüzlere bağlandığında istemcinin bulunduğu ağ bölütündeki her konak da kullanabilir — ve tünelin öteki ucunda, o konakların doğrudan erişemediği bir hedef vardır.

Bu, açık yüzeyin sayılabilir bir büyümesidir. Kurguda istemcinin bölütünde başka 24 konak bulunur ve 3 tünel açıktır. Geri döngüye bağlı tünellerde tünel ağzına ulaşabilen başka konak 0, dolaylı olarak erişilebilir hâle gelen (konak, hedef servis) çifti 0. Bütün arayüzlere bağlandığında bu iki sayı 24 ve 72 olur. Aradaki fark bir yapılandırma alanıdır ve varsayılanı bilmeden yazılan bir tünel, kapalı sanılan bir yolu yirmi dört konağa açar.

On Aday Neden

Kurgu şudur: istemci, sıçrama sunucusu üzerinden hedefteki bir servise ulaşmayı deniyor ve ulaşamıyor. Sağlam durumun tek bir alanını bozan on aday neden var.

  • EF11 — Aday neden listesi on maddedir ve tüketicidir. İki maddesi istemcide, ikisi ilk bacakta, biri sıçrama sunucusunun yapılandırmasında, dördü hedefte, biri ad çözümlemenin yerindedir.
  • EF12 — Kâhin hedef-duvar-dusuruyor seçilmiştir: hedefin süzgeci paketi sessizce düşürür.
  • EF13 — Altı sınama tanımlıdır. Üçü istemcide yapılabilir, ikisi sıçrama sunucusunda oturum açmayı gerektirir, biri iki tarafı karşılaştırır.
  • EF14 — Sıçrama sunucusunda çalışan sınamalar ilk bacak bozuksa yapılamaz ve bunu ayrı bir yanıtla bildirirler; bu bir bağımlılıktır, ölçünün parçasıdır.
  • EF15 — Uçtan uca deneme, tüneli açıp içinden bir oturum denemesini birlikte kapsar; bu yüzden hedefteki kimlik doğrulama sonucunu da görebilir.
  • EF16 — Katmanlı sıra istemciden hedefe doğru ilerler; ikinci sıra uçtan uca denemeyi başa alır. İkisi de kâhin bilinmeden uygulanabilir.
  • EF17 — Tünel ağzı ölçümünde bölütte 24 başka konak ve 3 açık tünel varsayılır.
  • EF18 — Aday kümesi süpürmesi dokuz, on ve on bir adaylı listelerle yapılır.
  • EF19 — On bir adaylı listeye eklenen sicrama-oturum-sinirinda, sıçrama sunucusunun yönlendirmeyi oturum düzeyinde engellemesidir ve yonlendirme-kapali ile aynı yanıtı verir.
  • EF20 — Bütün sayılar tam sayımdır; rastgelelik ve tohum yoktur.
"""Iki durakli yol: istemci -> sicrama sunucusu -> hedef. On aday , alti sinama."""
ADAY = ("yerel-bag-noktasi-dolu", "yerel-adres-yanlis", "sicrama-erisilemez",
        "sicrama-kimlik-reddetti", "yonlendirme-kapali", "hedef-erisilemez",
        "hedef-duvar-dusuruyor", "hedef-dinlemiyor", "hedef-kimlik-reddetti",
        "ad-yalniz-uzakta-cozuluyor")
SAGLAM = {"yerel_bagli": True, "yerel_adres_dogru": True, "sicrama_erisilir": True,
          "sicrama_kimlik": True, "yonlendirme_izinli": True, "hedef_erisilir": True,
          "hedef_duvar_gecirir": True, "hedef_dinliyor": True,
          "hedef_kimlik": True, "ad_yerelde_cozulur": True}
BOZUK = {
    "yerel-bag-noktasi-dolu": {"yerel_bagli": False},
    "yerel-adres-yanlis": {"yerel_adres_dogru": False},
    "sicrama-erisilemez": {"sicrama_erisilir": False},
    "sicrama-kimlik-reddetti": {"sicrama_kimlik": False},
    "yonlendirme-kapali": {"yonlendirme_izinli": False},
    "hedef-erisilemez": {"hedef_erisilir": False},
    "hedef-duvar-dusuruyor": {"hedef_duvar_gecirir": False},
    "hedef-dinlemiyor": {"hedef_dinliyor": False},
    "hedef-kimlik-reddetti": {"hedef_kimlik": False},
    "ad-yalniz-uzakta-cozuluyor": {"ad_yerelde_cozulur": False},
}


def durum(a=None):
    d = dict(SAGLAM)
    if a:
        d.update(BOZUK[a])
    return d


def t_uctan_uca(d):
    if not d["yerel_bagli"] or not d["yerel_adres_dogru"]:
        return "yerel-baglanti-reddedildi"
    if not d["ad_yerelde_cozulur"]:
        return "ad-cozulemedi"
    if not d["sicrama_erisilir"] or not d["sicrama_kimlik"]:
        return "durak-acilmadi"
    if not d["yonlendirme_izinli"]:
        return "kanal-yasak"
    if not d["hedef_erisilir"] or not d["hedef_duvar_gecirir"]:
        return "kanal-zaman-asimi"
    if not d["hedef_dinliyor"]:
        return "kanal-reddedildi"
    return "kuruldu" if d["hedef_kimlik"] else "hedefte-izin-reddedildi"


def t_sicrama_oturumu(d):
    if not d["sicrama_erisilir"]:
        return "erisilemez"
    return "acildi" if d["sicrama_kimlik"] else "izin-reddedildi"


def t_yerel_dinleyen(d):
    if not d["yerel_bagli"]:
        return "bagli-degil"
    return "beklenen-adres" if d["yerel_adres_dogru"] else "baska-adres"


def t_sicramadan_hedefe(d):
    if not d["sicrama_erisilir"] or not d["sicrama_kimlik"]:
        return "yapilamadi"
    if not d["hedef_erisilir"]:
        return "ulasilamaz"
    if not d["hedef_duvar_gecirir"]:
        return "zaman-asimi"
    return "kuruldu" if d["hedef_dinliyor"] else "reddedildi"


def t_yonlendirme_ayari(d):
    if not d["sicrama_erisilir"] or not d["sicrama_kimlik"]:
        return "okunamadi"
    return "izinli" if d["yonlendirme_izinli"] else "kapali"


SINAMA = {"uctan-uca": t_uctan_uca, "yerel-dinleyen": t_yerel_dinleyen,
          "sicrama-oturumu": t_sicrama_oturumu,
          "yonlendirme-ayari": t_yonlendirme_ayari,
          "sicramadan-hedefe": t_sicramadan_hedefe,
          "ad-yeri": lambda d: ("iki-tarafta" if d["ad_yerelde_cozulur"]
                                else "yalniz-uzakta")}
KATMANLI = ["yerel-dinleyen", "ad-yeri", "sicrama-oturumu", "yonlendirme-ayari",
            "sicramadan-hedefe", "uctan-uca"]
UCTAN_ONCE = ["uctan-uca"] + KATMANLI[:-1]


def ele(adaylar, s, yanit):
    return tuple(a for a in adaylar if SINAMA[s](durum(a)) == yanit)


def obek(sinamalar, adaylar=ADAY):
    o = {}
    for a in adaylar:
        o.setdefault(tuple(SINAMA[s](durum(a)) for s in sinamalar), []).append(a)
    return [sorted(v) for v in o.values() if len(v) > 1]


def sira_adimi(sira, gercek, adaylar=ADAY):
    kalan, adim = tuple(adaylar), 0
    for s in sira:
        if len(kalan) <= 1:
            break
        adim += 1
        kalan = ele(kalan, s, SINAMA[s](durum(gercek)))
    return adim, len(kalan)


KAHIN = "hedef-duvar-dusuruyor"
print("aday neden:", len(ADAY), "| sinama:", len(SINAMA), "| kahin:", KAHIN)
print()
print("sinama              ayri yanit  en kotu kalan  elenen  kalan")
for s in SINAMA:
    o = {}
    for a in ADAY:
        o.setdefault(SINAMA[s](durum(a)), []).append(a)
    kalan = len(ele(ADAY, s, SINAMA[s](durum(KAHIN))))
    print(f"  {s:18s} {len(o):11d} {max(len(v) for v in o.values()):14d}"
          f" {len(ADAY) - kalan:7d} {kalan:6d}")
print()
print("ariza                        katmanli  uctan-once  yalniz uctan uca kalan")
tk = tu = 0
for a in ADAY:
    k, _ = sira_adimi(KATMANLI, a)
    u, _ = sira_adimi(UCTAN_ONCE, a)
    _, y = sira_adimi(["uctan-uca"], a)
    tk += k
    tu += u
    print(f"  {a:26s} {k:8d} {u:11d} {y:22d}")
print(f"  {'toplam':26s} {tk:8d} {tu:11d}")
print()
print("arac kumesi                          ayrilamayan obek")
for ad, k in (("yalniz uctan uca", ["uctan-uca"]),
              ("uctan uca + sicrama oturumu", ["uctan-uca", "sicrama-oturumu"]),
              ("uctan uca + sicramadan hedefe",
               ["uctan-uca", "sicramadan-hedefe"]),
              ("yerelde calisan uc sinama",
               ["uctan-uca", "yerel-dinleyen", "ad-yeri"]),
              ("alti sinama", list(SINAMA))):
    o = obek(k)
    print(f"  {ad:35s} {len(o):8d}", o if o else "")
print()
KOMSU, TUNEL = 24, 3
print(f"tunel agzinin bag adresi (bolutte {KOMSU} baska konak , {TUNEL} tunel acik)")
for ad, ulasan in (("geri-dongu", 0), ("tum arayuzler", KOMSU)):
    print(f"  {ad:14s} tunel agzina ulasabilen baska konak {ulasan:3d}"
          f" | dolayli (konak , hedef servis) cifti {ulasan * TUNEL:3d}")
print()
print("aday kumesi supurmesi")
BOZUK["sicrama-oturum-sinirinda"] = {"yonlendirme_izinli": False}
for ad, k in (("9 aday: hedef-kimlik-reddetti yok",
               tuple(a for a in ADAY if a != "hedef-kimlik-reddetti")),
              ("10 aday: temel liste", ADAY),
              ("11 aday: sicrama-oturum-sinirinda eklendi",
               ADAY + ("sicrama-oturum-sinirinda",))):
    kalan = len(ele(k, "uctan-uca", SINAMA["uctan-uca"](durum(KAHIN))))
    o = obek(list(SINAMA), k)
    print(f"  {ad:42s} uctan uca elenen {len(k) - kalan:2d} kalan {kalan:2d}"
          f" | ayrilamayan obek {len(o)}"
          f" en buyuk {max((len(x) for x in o), default=0)}")
aday neden: 10 | sinama: 6 | kahin: hedef-duvar-dusuruyor

sinama              ayri yanit  en kotu kalan  elenen  kalan
  uctan-uca                    7              2       8      2
  yerel-dinleyen               3              8       2      8
  sicrama-oturumu              3              8       2      8
  yonlendirme-ayari            3              7       3      7
  sicramadan-hedefe            5              5       9      1
  ad-yeri                      2              9       1      9

ariza                        katmanli  uctan-once  yalniz uctan uca kalan
  yerel-bag-noktasi-dolu            1           2                      2
  yerel-adres-yanlis                1           2                      2
  sicrama-erisilemez                3           4                      2
  sicrama-kimlik-reddetti           3           4                      2
  yonlendirme-kapali                4           1                      1
  hedef-erisilemez                  5           6                      2
  hedef-duvar-dusuruyor             5           6                      2
  hedef-dinlemiyor                  5           1                      1
  hedef-kimlik-reddetti             5           1                      1
  ad-yalniz-uzakta-cozuluyor        2           1                      1
  toplam                           34          28

arac kumesi                          ayrilamayan obek
  yalniz uctan uca                           3 [['yerel-adres-yanlis', 'yerel-bag-noktasi-dolu'], ['sicrama-erisilemez', 'sicrama-kimlik-reddetti'], ['hedef-duvar-dusuruyor', 'hedef-erisilemez']]
  uctan uca + sicrama oturumu                2 [['yerel-adres-yanlis', 'yerel-bag-noktasi-dolu'], ['hedef-duvar-dusuruyor', 'hedef-erisilemez']]
  uctan uca + sicramadan hedefe              2 [['yerel-adres-yanlis', 'yerel-bag-noktasi-dolu'], ['sicrama-erisilemez', 'sicrama-kimlik-reddetti']]
  yerelde calisan uc sinama                  2 [['sicrama-erisilemez', 'sicrama-kimlik-reddetti'], ['hedef-duvar-dusuruyor', 'hedef-erisilemez']]
  alti sinama                                0 

tunel agzinin bag adresi (bolutte 24 baska konak , 3 tunel acik)
  geri-dongu     tunel agzina ulasabilen baska konak   0 | dolayli (konak , hedef servis) cifti   0
  tum arayuzler  tunel agzina ulasabilen baska konak  24 | dolayli (konak , hedef servis) cifti  72

aday kumesi supurmesi
  9 aday: hedef-kimlik-reddetti yok          uctan uca elenen  7 kalan  2 | ayrilamayan obek 0 en buyuk 0
  10 aday: temel liste                       uctan uca elenen  8 kalan  2 | ayrilamayan obek 0 en buyuk 0
  11 aday: sicrama-oturum-sinirinda eklendi  uctan uca elenen  9 kalan  2 | ayrilamayan obek 1 en buyuk 2

Üç Sayı

Kâhin: gerçek neden hedef-duvar-dusuruyor — hedefin süzgeci paketi sessizce düşürüyor. Sınama: uçtan uca deneme “kanal zaman aşımına uğradı” diyor; sıçrama sunucusundan hedefe yapılan deneme “zaman aşımı” diyor; yerel dinleyen listesi tünelin beklenen adrese bağlı olduğunu söylüyor. Elenen aday: uçtan uca 8, duraktan hedefe 9, yerel dinleyen 2, ad yeri 1.

Uçtan uca deneme bu kurgunun en güçlü tek sınamasıdır: yedi ayrı yanıt üretiyor ve en kötü durumda geriye yalnız iki aday bırakıyor. Yine de kâhini tek başına bulamıyor, çünkü hedefe ulaşamamak ile hedefin süzgecinin düşürmesi tünelin içinden aynı görünüyor. İkisini ayıran şey, sıçrama sunucusundan yapılan denemedir: orada “ulaşılamaz” ile “zaman aşımı” farklı yanıtlardır ve o sınama tek başına dokuz aday eliyor.

Buradan çıkan yerleşim kuralı şudur: sıçrama sunucusu bir geçit olduğu kadar bir gözlem noktasıdır. Hedefe en yakın yerde durur ve orada yapılan deneme, aradaki bütün bacakları denklemden çıkarır. Bir sıçrama sunucusuna oturum açabilmek, tanıda dokuz adaylık bir eleme demektir.

Sıra ve Ayrılamayan Öbekler

İkinci tablo iki sabit sırayı karşılaştırıyor. Katmanlı sıra istemciden hedefe doğru ilerliyor ve on arıza için toplam 34 adım harcıyor. Uçtan uca denemeyi başa alan sıra 28 adımda bitiriyor. İkisi de kâhin bilinmeden uygulanabilir; aradaki altı adımlık fark, uçtan uca denemenin yedi ayrı yanıt üretmesinden geliyor.

Bu sonuç, tek makinede ölçülen katmanlı yöntemle çelişmez. Orada bağlantı denemesi dört ayrı yanıt veriyordu; burada tünelin içinden yapılan deneme yediye çıkıyor, çünkü tünel yolun her durağındaki başarısızlığı ayrı bir ileti olarak geri taşıyor. Sınamanın gücü aracın adında değil, kaç ayrı yanıt ürettiğindedir.

Üçüncü tablo eleme gücünün nerede tükendiğini gösteriyor. Yalnız uçtan uca bakıldığında üç öbek ayrılamıyor: iki yerel arıza, iki ilk bacak arızası ve hedefin iki sessiz arızası. Sıçrama oturumu eklendiğinde ikinci öbek çözülüyor, duraktan hedefe denemesi eklendiğinde üçüncüsü. Yerel üç sınama ise iki öbek bırakıyor; içlerinden hiçbiri istemcinin dışına çıkamıyor. Altı sınama birlikte kullanıldığında ayrılamayan öbek 0.

Aday Kümesi Süpürmesi

Alt tablo aday listesini üç boyda deniyor. hedef-kimlik-reddetti çıkarıldığında uçtan uca denemenin elediği aday sekizden yediye iniyor ve kalan yine iki. Listeye sicrama-oturum-sinirinda eklendiğinde elenen dokuza çıkıyor ve kalan yine iki; buna karşılık altı sınamanın hepsiyle bile ayrılamayan bir öbek doğuyor, çünkü yeni aday yonlendirme-kapali ile bütün sınamalarda aynı yanıtı veriyor.

Bir ayrıntı bu ölçümün dışında kalır ve yazılması gerekir. Tünelin kanal hatası istemcinin uçbiriminde bir kez görünür ve hiçbir yere yazılmaz. Tünel arka planda açılmışsa o tek satır da görünmez; geriye yalnız çalışmayan bir bağlantı kalır. Duraktaki oturumun kaydı sıçrama sunucusunun günlüğündedir, kanalın açılıp kapandığı ise oradaki ayrıntı düzeyine bağlıdır. Kanıt beklemez: kanal hatasını sonradan aramak, ayrıntı düzeyi arıza anında yeterliyse sonuç verir.

Bu üç satır, önceki dersin kuralını başka bir yönden gösteriyor. Orada eleme sayısı sabit kalırken kalan büyümüştü; burada eleme sayısı büyürken ayırt edilebilirlik düşüyor. İki durumda da elemenin kendisi bir başarı ölçüsü değildir. Bir aday kümesi ancak sınamaların yanıt desenleri onu tek tek ayırabiliyorsa çözülmüş sayılır ve bunun ölçüsü, ayrılamayan öbek sayısıdır.

Özet

  • Sıçrama sunucusu yolu ikiye böler: tünel biçiminde istemcide bir ağız açılır, durak biçiminde oturum doğrudan hedefte açılır ve sıçrama sunucusu yalnız taşır.
  • Hedefin adı sıçrama sunucusunda çözülür; aynı ad istemcinin yapılandırmasında yazılıysa istemci onu çözmeye çalışır ve ortaya sunucuda var olmayan bir ad çözümleme arızası çıkar.
  • Tünel ağzının bağ adresi açık yüzeyi belirler: geri döngüde dolaylı erişilebilir çift 0, bütün arayüzlerde bölütteki 24 konak ve 3 tünel için 72.
  • On aday nedende uçtan uca deneme yedi ayrı yanıt verip 8 aday eliyor, sıçrama sunucusundan hedefe yapılan deneme 9 eliyor ve tek başına çözüyor; ad çözümlemenin yeri yalnız 1 eliyor.
  • Katmanlı sıra 34, uçtan uca denemeyi başa alan sıra 28 adım harcıyor; ikisi de kâhin bilinmeden uygulanabilir.
  • Aday listesine bir madde eklendiğinde elenen sayısı sekizden dokuza çıkarken ayrılamayan öbek sıfırdan bire yükseliyor; ölçü eleme değil, ayırt edilebilirliktir.

Sonraki Adım

Bu dersin kâhini hedefin süzgeciydi ve tünelin içinden bakıldığında o süzgeç, hedefe hiç ulaşılamamasından ayırt edilemiyordu. Sessizce düşürülen paket bu kursun en zor izlenen olayıdır, çünkü geriye hiçbir şey göndermez. Sonraki ders o süzgecin içine girer: paketin bir makinenin içinde hangi duraklardan geçtiğini, kuralların hangi sırayla değerlendirildiğini ve bir paketin hangi durakta düştüğünü hangi okumanın gösterebildiğini kurar.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat