---
title: 'Güvenli Kabuk'
source: 'https://academia.sh/tr/kurslar/linux-ag-yonetimi/guvenli-kabuk'
course: 'Linux Ağ Yönetimi ve Sorun Giderme'
language: tr
updated: '2026-08-17T18:09:59+00:00'
license: 'CC BY-SA 4.0'
---

# Güvenli Kabuk

Anahtar tabanlı kimlik doğrulama ve sunucu sertleştirmesi kurulur; oturumun açılmamasının dokuz aday nedeni yedi sınamayla elenir ve kırk altı satırlık ayrıntılı istemci çıktısının beş, üç satırlık sunucu günlüğünün yedi aday elediği sayılır.

Önceki konu bir arızanın izini aradı ve izin çoğu zaman geç bakana kalmadığını gösterdi:
aralıklı arıza kayıt başlamadan önce başlar, düşürülen paket varsayılan olarak hiçbir satır
yazmaz. Bu konu aynı soruyu erişimin kendisine sorar. Bir sunucuya bağlanmanın yolu kapandığında
ortada tek bir satır vardır ve o satır genellikle "izin reddedildi" der.

Sorulacak soru şudur: o satır kaç aday nedeni eliyor. Kursun kuralı değişmez — bir sınamanın
sayısı verdiği yanıt değil, **elediği aday nedendir**. Bu derste sınamalar bir araya geldiğinde
bile eleyemedikleri bir çift kalacak ve o çifti ayıran şey bir araç değil, arızadan önce yapılmış
bir ayar olacak.

## Anahtar Çiftinin İki Ucu

Güvenli kabuk (secure shell) bağlantısında iki ayrı doğrulama üst üste durur ve karıştırılmaları
tanıyı bozar. Birincisinde **istemci sunucuyu** doğrular: sunucunun **konak anahtarı** (host key)
ilk bağlantıda kaydedilir, sonraki bağlantılarda kayıtla karşılaştırılır. İkincisinde **sunucu
kullanıcıyı** doğrular: kullanıcının **özel anahtarı** (private key) istemcide durur, karşılığı
olan **açık anahtar** (public key) sunucudaki yetkili anahtarlar dosyasında bulunur.

Anahtar çifti istemcide üretilir ve özel anahtar oradan hiç çıkmaz; sunucuya yalnız açık anahtar
kopyalanır. Bu asimetri sertleştirmenin temelidir: sunucu ele geçse bile orada oturan şey
kullanıcının kimliğini üretmeye yetmez. **Bu derste gerçek bir anahtar, parmak izi ya da parola
yazılmaz;** anahtar dizgilerinin bulunduğu yerlerde köşeli ayraç içinde yer tutucu kullanılır.

Sunucu tarafındaki sertleştirme birkaç ayardan oluşur. Aşağıdaki döküm çalıştırılmamıştır;
ayarların adlarını ve aldıkları değerleri göstermek için yazılmış bir örnektir:

```text
# ornek dokum , calistirilmamistir
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
LogLevel VERBOSE
```

Bu satırların her biri aday neden kümesini değiştirir ve ölçümün asıl konusu budur. Parola
doğrulamasını kapatmak, parolayla ilgili bütün aday nedenleri listeden çıkarır ve yerine bir
tane koyar: anahtarı olmayan kullanıcının geri düşeceği bir yöntem kalmaz. Yetkili anahtarlar
dosyasının yerini sabitlemek, dosyanın yanlış yerde aranması adayını çıkarır. Günlük ayrıntı
düzeyini yükseltmek hiçbir adayı çıkarmaz, **ama ayırt edilebilirliği artırır** ve bu dersin
son ölçüsü tam olarak onu sayar.

Bir ayar daha vardır ve sık gözden kaçar: yetkili anahtarlar dosyasının ve onu içeren dizinin
izinleri fazla genişse sunucu dosyayı **okumaz**. Dosya yerindedir, içeriği doğrudur, anahtar
eşleşecektir; sunucu yine de reddeder. Bu davranış listeye ayrı bir aday neden ekler ve ölçümde
en can sıkıcı sonucu üreten aday odur.

## Açık Anahtarın Karşı Tarafa Geçmesi

Anahtar çifti üretildikten sonra geriye tek bir iş kalır: açık anahtarın sunucudaki doğru
kullanıcının yetkili anahtarlar dosyasına **eklenmesi**. Bu iş göründüğünden fazla aday neden
üretir, çünkü dört ayrı yerde yanlış yapılabilir. Anahtar yanlış kullanıcının dosyasına
eklenebilir; dosya doğru olup içindeki satır satır sonu eksikliğiyle bir öncekiyle birleşebilir;
dizin sunucuda hiç yoksa ekleme sessizce başka bir yola düşebilir; kopyalama sırasında satır
başına bir boşluk girip anahtarı geçersiz kılabilir. Dördünün ortak yanı, işlem çıktısının
**başarılı** dönmesidir.

Bu yüzden anahtarın yerleştirildiği tek başına doğrulanmaz. Doğrulama, işlemin çıktısıyla değil,
**yeni bir oturum denemesiyle** yapılır ve deneme mevcut oturum kapatılmadan yapılır. Bu ayrıntı
sonraki derslerde kural yazımında aynen tekrarlanacak: değişikliği doğrulayan şey değişikliği
yapan komutun döndürdüğü değer değil, ayrı bir kanaldan yapılan bir denemedir.

Anahtarın ömrü, düzenli olarak değiştirilmesi, merkezi bir kasada saklanması ve sertifikayla
imzalanması bu kursun konusu değildir; bunlar **Siber Güvenlik** müfredatının anahtar yönetimi
derslerinde ölçülmüştür. Burada ölçülen tek şey, tek bir makinenin yerel yapılandırmasının bir
arıza karşısında ne kadarını ayırt edilebilir kıldığıdır.

## Dokuz Aday Neden

Kurgu şudur: kullanıcı bağlanmayı deniyor ve oturum açılmıyor. Sağlam durumun tek bir alanını
bozan dokuz aday neden var. Ortak tanımın sekiz ağ arızası bu listede tek bir adaya, ağın
erişilemez oluşuna toplanmıştır; bu konu ağın üstündeki katmanı ölçer.

- **EF1** — Aday neden listesi **dokuz** maddedir ve tüketicidir; kurgu bu dokuz durumun
  dışına çıkmaz.
- **EF2** — Kâhin `acik-anahtar-yetkisiz` seçilmiştir: kullanıcının anahtarı vardır, sunucudaki
  yetkili anahtarlar dosyasında karşılığı yoktur.
- **EF3** — Yedi sınama tanımlıdır. Dördü **dışarıdan**, oturum açmadan yapılabilir; ikisi
  **sunucuda** çalışmayı gerektirir, biri ise sunucu günlüğünün temel düzeyidir.
- **EF4** — Her sınamaya bir **satır sayısı** verilmiştir. Bu sayı kurgunun parçasıdır, ölçülmüş
  bir değer değildir; amacı çıktı hacmi ile eleme gücünü yan yana koymaktır.
- **EF5** — Ayrıntılı istemci çıktısı **46**, ayrıntılı sunucu günlüğü **3**, temel sunucu
  günlüğü **1**, dinleyen listesi **12**, yerel anahtar denetimi **4**, yöntem listesi **9**,
  varsayılan istemci iletisi **1** satır sayılır.
- **EF6** — Ayrıntılı günlük düzeyi arızadan **önce** açılmış varsayılır; sonradan açmak geçmiş
  denemeyi geri getirmez.
- **EF7** — Anahtar izinlerinin genişliği ile açık anahtarın yetkisiz oluşu sunucuda **aynı
  başarısızlık dalına** düşer; bu, kurgunun değil gerçek davranışın yansımasıdır.
- **EF8** — Aday kümesi süpürmesi üç listeyle yapılır: sekiz, dokuz ve on aday.
- **EF9** — On adaylı listeye eklenen `yontem-kapatildi`, sunucunun anahtar yöntemini reddetmesi
  durumudur ve `acik-anahtar-yetkisiz` ile **aynı yanıt desenini** verir.
- **EF10** — Bütün sayılar tam sayımdır; rastgelelik ve tohum yoktur.

```python
"""Guvenli kabuk oturumu acilmiyor: dokuz aday neden , yedi sinama.

Kahin = gercek neden (kurguyu biz sectik). Olculen sey , her sinamanin
kac aday nedeni eledigi ve geriye kac aday biraktigidir.
"""
ADAY = ("ag-erisilemez", "servis-dinlemiyor", "konak-anahtari-degisti",
        "ozel-anahtar-yok", "acik-anahtar-yetkisiz", "anahtar-izni-genis",
        "kullanici-yok", "hesap-kilitli", "parola-yontemi-kapali")
SAGLAM = {"tasima_kuruldu": True, "servis_dinliyor": True,
          "konak_anahtari_uyusuyor": True, "istemci_anahtar_sunar": True,
          "sunucu_kabul": True, "hesap_gecerli": True, "parola_acik": True}
BOZUK = {
    "ag-erisilemez": {"tasima_kuruldu": False},
    "servis-dinlemiyor": {"tasima_kuruldu": False, "servis_dinliyor": False},
    "konak-anahtari-degisti": {"konak_anahtari_uyusuyor": False},
    "ozel-anahtar-yok": {"istemci_anahtar_sunar": False, "sunucu_kabul": False},
    "acik-anahtar-yetkisiz": {"sunucu_kabul": False},
    "anahtar-izni-genis": {"sunucu_kabul": False},
    "kullanici-yok": {"sunucu_kabul": False, "hesap_gecerli": False},
    "hesap-kilitli": {"sunucu_kabul": False, "hesap_gecerli": False},
    "parola-yontemi-kapali": {"parola_acik": False},
}
SATIR = {"istemci-iletisi": 1, "ayrintili-istemci": 46, "yerel-anahtar": 4,
         "yontem-listesi": 9, "dinleyen": 12, "gunluk-temel": 1,
         "gunluk-ayrintili": 3}


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


def t_istemci(d):
    if not d["tasima_kuruldu"]:
        return "baglanti-yok"
    if not d["konak_anahtari_uyusuyor"]:
        return "konak-anahtari-uyarisi"
    return "oturum-acildi" if d["sunucu_kabul"] else "izin-reddedildi"


def t_ayrintili(d):
    if not d["tasima_kuruldu"]:
        return "tasima-kurulamadi"
    if not d["konak_anahtari_uyusuyor"]:
        return "konak-anahtari-uyusmuyor"
    if not d["istemci_anahtar_sunar"]:
        return "anahtar-sunulmadi"
    return "oturum-acildi" if d["sunucu_kabul"] else "anahtar-reddedildi"


def t_gunluk_temel(d):
    if not d["tasima_kuruldu"]:
        return "satir-yok"
    return "kabul-edildi" if d["sunucu_kabul"] else "basarisiz"


def t_gunluk_ayrintili(d):
    if not d["tasima_kuruldu"]:
        return "satir-yok"
    if not d["hesap_gecerli"]:
        return "gecersiz-hesap"
    if not d["istemci_anahtar_sunar"]:
        return "yontem-sunulmadi"
    return "kabul-edildi" if d["sunucu_kabul"] else "anahtar-eslesmedi"


SINAMA = {
    "istemci-iletisi": t_istemci, "ayrintili-istemci": t_ayrintili,
    "yerel-anahtar": lambda d: ("anahtar-var" if d["istemci_anahtar_sunar"]
                                else "anahtar-yok"),
    "yontem-listesi": lambda d: ("parola-acik" if d["parola_acik"]
                                 else "parola-kapali"),
    "dinleyen": lambda d: "dinliyor" if d["servis_dinliyor"] else "dinlemiyor",
    "gunluk-temel": t_gunluk_temel, "gunluk-ayrintili": t_gunluk_ayrintili,
}
DISARIDAN = ["istemci-iletisi", "ayrintili-istemci", "yerel-anahtar",
             "yontem-listesi"]
SUNUCUDA = ["dinleyen", "gunluk-ayrintili"]
KAHIN = "acik-anahtar-yetkisiz"


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]


print("aday neden:", len(ADAY), "| sinama:", len(SINAMA), "| kahin:", KAHIN)
print()
print("sinama              satir  ayri yanit  elenen  kalan  satir basina")
for s in SINAMA:
    kalan = len(ele(ADAY, s, SINAMA[s](durum(KAHIN))))
    el = len(ADAY) - kalan
    print(f"  {s:18s} {SATIR[s]:5d} {len({SINAMA[s](durum(a)) for a in ADAY}):11d}"
          f" {el:7d} {kalan:6d} {el / SATIR[s]:13.4f}")
print()
print("arac kumesi                   satir  ayrilamayan obek  en buyuk obek")
for ad, k in (("yalniz istemci iletisi", ["istemci-iletisi"]),
              ("yalniz ayrintili istemci", ["ayrintili-istemci"]),
              ("disaridan erisilebilen 4", DISARIDAN),
              ("disaridan 4 + temel gunluk", DISARIDAN + ["gunluk-temel"]),
              ("sunucuda calisan 2", SUNUCUDA),
              ("yedi sinama", list(SINAMA))):
    o = obek(k)
    print(f"  {ad:28s} {sum(SATIR[s] for s in k):5d} {len(o):17d}"
          f" {max((len(x) for x in o), default=0):14d}")
print()
print("aday kumesi supurmesi (kahin ayni)")
BOZUK["yontem-kapatildi"] = {"sunucu_kabul": False}
for ad, k in (("8 aday: hesap-kilitli cikarildi",
               tuple(a for a in ADAY if a != "hesap-kilitli")),
              ("9 aday: temel liste", ADAY),
              ("10 aday: yontem-kapatildi eklendi",
               ADAY + ("yontem-kapatildi",))):
    kalan = len(ele(k, "gunluk-ayrintili",
                    SINAMA["gunluk-ayrintili"](durum(KAHIN))))
    o = obek(list(SINAMA), k)
    print(f"  {ad:35s} ayrintili gunluk elenen {len(k) - kalan:2d}"
          f" kalan {kalan:2d} | ayrilamayan obek {len(o)}"
          f" en buyuk {max((len(x) for x in o), default=0)}")
print()
print("ayrilamayan obekler (yedi sinama):", obek(list(SINAMA)))
```

```
aday neden: 9 | sinama: 7 | kahin: acik-anahtar-yetkisiz

sinama              satir  ayri yanit  elenen  kalan  satir basina
  istemci-iletisi        1           4       4      5        4.0000
  ayrintili-istemci     46           5       5      4        0.1087
  yerel-anahtar          4           2       1      8        0.2500
  yontem-listesi         9           2       1      8        0.1111
  dinleyen              12           2       1      8        0.0833
  gunluk-temel           1           3       4      5        4.0000
  gunluk-ayrintili       3           5       7      2        2.3333

arac kumesi                   satir  ayrilamayan obek  en buyuk obek
  yalniz istemci iletisi           1                 2              5
  yalniz ayrintili istemci        46                 2              4
  disaridan erisilebilen 4        60                 2              4
  disaridan 4 + temel gunluk      61                 2              4
  sunucuda calisan 2              15                 3              2
  yedi sinama                     76                 2              2

aday kumesi supurmesi (kahin ayni)
  8 aday: hesap-kilitli cikarildi     ayrintili gunluk elenen  6 kalan  2 | ayrilamayan obek 1 en buyuk 2
  9 aday: temel liste                 ayrintili gunluk elenen  7 kalan  2 | ayrilamayan obek 2 en buyuk 2
  10 aday: yontem-kapatildi eklendi   ayrintili gunluk elenen  7 kalan  3 | ayrilamayan obek 2 en buyuk 3

ayrilamayan obekler (yedi sinama): [['acik-anahtar-yetkisiz', 'anahtar-izni-genis'], ['hesap-kilitli', 'kullanici-yok']]
```

## Üç Sayı

**Kâhin:** gerçek neden `acik-anahtar-yetkisiz` — anahtar sunuluyor, sunucu tanımıyor.
**Sınama:** varsayılan istemci iletisi tek satırda "izin reddedildi" diyor; ayrıntılı istemci
çıktısı kırk altı satır basıyor ve "anahtar reddedildi" diyor; ayrıntılı sunucu günlüğü üç
satırda "anahtar eşleşmedi" diyor. **Elenen aday:** varsayılan ileti **4**, ayrıntılı istemci
**5**, ayrıntılı sunucu günlüğü **7**.

Ortadaki karşılaştırma kursun ikinci iddiasının bu dersteki biçimidir. Ayrıntılı istemci çıktısı
sunucu günlüğünün **on beş katı** satır üretiyor ve **iki aday az** eliyor. Satır başına eleme
oranı 0,1087'ye karşı 2,3333; aradaki fark yirmi bir kat. Nedeni yapısaldır: ayrıntılı istemci
çıktısı **el sıkışmanın istemci tarafını** ayrıntılandırır, oysa ayrılmayan adayların hepsi
sunucu tarafındadır. Ayrıntı düzeyini yükseltmek görülen tarafı büyütür, görülmeyen tarafı
açmaz.

Aynı tablonun en zayıf satırı `dinleyen`. On iki satır basıyor ve yalnız **bir** aday eliyor.
Ortak tanımda dinleyen listesinin eleme gücü de birdi; erişim katmanında da bir. Servisin
dinlediğini görmek, bağlanabildiğinizi göstermez ve bu iki cümle arasındaki mesafe bu kursun
tamamıdır.

## Ayrılamayan İkili

Alt tablo daha sert bir şey söylüyor. Yedi sınamanın hepsi birlikte kullanıldığında bile
ayrılamayan **iki öbek** kalıyor ve ikisi de iki üyeli: `acik-anahtar-yetkisiz` ile
`anahtar-izni-genis`, `hesap-kilitli` ile `kullanici-yok`. Yetmiş altı satır çıktı üretiliyor
ve bu dört durum dörde ikiye bölünemiyor.

Birinci çift dersin sertleştirme bölümüne bağlanır. Yetkili anahtarlar dosyasının izinleri
genişse sunucu dosyayı okumaz ve reddeder; açık anahtar dosyada yoksa da reddeder. İkisi de
sunucunun bakış açısından "sunulan anahtar kabul edilebilir değil" dalıdır. Aradaki farkı
gösterecek olan şey bir sınama değil, **sunucunun o dalda ne yazdığıdır** — ve ne yazacağı
günlük ayrıntı düzeyine bağlıdır.

Bu, kursun üçüncü iddiasının erişim katmanındaki biçimidir. Temel düzeyde tutulan günlük üç
ayrı yanıt veriyor ve dört aday eliyor; ayrıntılı düzeyde beş yanıt veriyor ve yedi eliyor.
Fark üç satırlık bir çıktıda saklı. Ancak düzey **arızadan önce** yükseltilmiş olmalıdır:
sonradan açılan ayrıntı, geçmişte olan denemeyi geri getirmez. **Kanıt beklemez.**

Tablodaki bir satır daha bunu pekiştiriyor. Dışarıdan erişilebilen dört sınama altmış satır
üretiyor ve en büyük ayrılamayan öbeği **dört üyeli** bırakıyor. Sunucuda çalışan iki sınama
on beş satır üretiyor ve en büyük öbeği **iki üyeli**. Eleme gücünün tamamı sunucudadır; sorun
ise sunucuya girmenin kapalı olmasıdır. Bunun cevabı, güvenli kabuğun yanında ikinci bir yol
bırakmaktır: kaydedilebilen bir konsol ya da ayrı bir yönetim kanalı. O yol yoksa tanı dışarıdan
erişilebilen dört sınamayla sınırlı kalır ve dört üyeli öbek olduğu gibi durur.

## Aday Kümesi Süpürmesi

Bu kursta ikinci tohum yoktur, çünkü rastgelelik yoktur. Yerine aday listesi değiştirilir. Alt
tablo üç listeyi yan yana koyuyor ve okunması gereken şey elenen sütunu değil, **kalan** sütunu.

Listeden `hesap-kilitli` çıkarıldığında ayrıntılı günlüğün elediği aday sayısı yediden altıya
iniyor; kalan iki, ayrılamayan öbek sayısı ikiden bire düşüyor. Listeye `yontem-kapatildi`
eklendiğinde elenen sayısı **değişmiyor** — yine yedi — ama kalan ikiden **üçe** çıkıyor ve
ayrılamayan öbeğin en büyüğü iki üyeden üçe genişliyor. Aynı sınama, aynı yanıt, aynı eleme
sayısı; tanı ise kötüleşti.

Buradan çıkan kural şudur: **eleme sayısı tek başına bir ölçü değildir.** Aday listesi
büyüdükçe aynı sınama aynı sayıda adayı eler ve geriye daha fazlasını bırakır. Ölçülmesi gereken
şey eleme değil, **kalan belirsizliktir**. Bu, kursun kuralının ikinci yarısıdır ve sonraki
derslerde sıçrama sunucusu, zincirler ve adres dönüştürme aday listesini büyüttükçe tekrar
tekrar karşımıza çıkacaktır.

## Özet

- Güvenli kabuk bağlantısında iki doğrulama üst üste durur: istemci konak anahtarıyla sunucuyu,
  sunucu açık anahtarla kullanıcıyı doğrular. Özel anahtar istemciden çıkmaz.
- Sertleştirme ayarları aday neden listesini değiştirir: parola doğrulamasını kapatmak parolayla
  ilgili adayları çıkarır, yetkili anahtarlar dosyasının izinleri yeni bir aday ekler.
- Dokuz aday neden ve yedi sınamada elenen sayıları eşit değil: ayrıntılı sunucu günlüğü üç
  satırda **7**, ayrıntılı istemci çıktısı kırk altı satırda **5**, dinleyen listesi on iki
  satırda **1** aday eliyor.
- Yedi sınama birlikte kullanıldığında **iki öbek** ayrılamıyor; ayrımı yapan şey bir araç değil,
  arızadan önce yükseltilmiş günlük ayrıntı düzeyidir. Temel düzey **4**, ayrıntılı düzey **7**
  aday eliyor.
- Aday listesine bir madde eklendiğinde elenen sayısı sabit kalıp kalan **2'den 3'e** çıkıyor;
  ölçülmesi gereken eleme değil, kalan belirsizliktir.

## Sonraki Adım

Bu dersin en keskin sonucu, eleme gücünün sunucuda olması ve sunucuya girmenin kapalı olmasıydı.
Dışarıdan erişilebilen dört sınama dört üyeli bir öbeği olduğu gibi bırakıyor. Sonraki ders bu
tıkanmanın olağan çözümünü ele alır: doğrudan erişilemeyen bir makineye, erişilebilen bir başka
makinenin üzerinden gitmek. Sıçrama sunucusu ve tünel, yolu ikiye böler ve tanıyı da ikiye
böler — arıza artık iki makineden birinde olabilir. Ölçülecek soru, uçtan uca tek bir denemenin
bu genişlemiş aday kümesinden kaçını elediğidir.
