9 puan yazan GN⁺ 2026-01-23 | 1 yorum | WhatsApp'ta paylaş
  • Bir SSH oturumunda tek bir tuş vuruşunda yüzlerce paketin gönderildiği durum fark edildi ve nedeni iz sürülerek bulundu
  • tcpdump analizi, paketlerin çoğunun 36 baytlık tekrarlayan mesajlardan oluştuğunu ve yaklaşık 20 ms aralıklarla ortaya çıktığını gösterdi
  • Nedenin, 2023’te SSH’ye eklenen “tuş vuruşu zamanlaması bulanıklaştırma (keystroke timing obfuscation)” özelliği olduğu anlaşıldı; bu özellik kullanıcının giriş zamanlamasını gizlemek için çok sayıda “chaff” paketi (SSH2_MSG_PING) gönderiyor
  • Bu özellik devre dışı bırakıldığında veya sunucu [email protected] uzantısını duyurmayacak şekilde değiştirildiğinde CPU kullanımı ve bant genişliği yarıdan fazla azalıyor
  • Bu, SSH’nin güvenlik özelliğinin gerçek zamanlı performansın kritik olduğu uygulamalarda (ör. oyunlar) büyük bir yük oluşturabileceğini gösteren bir örnek

Sorunun fark edilmesi

  • SSH üzerinden çalışan yüksek performanslı bir oyunun TUI’si test edilirken, tek bir tuş vuruşunda bile 270 paket oluştuğu görüldü
    • tcpdump sonucunda bunun %66’sının 36 baytlık mesajlar, %33’ünün TCP ACK, kalanının ise az miktarda diğer veriler olduğu görüldü
    • Ortalama 90 paket/sn ile yaklaşık 11 ms aralıklarla veri iletimi vardı
  • Test sırasında sunucu yanlışlıkla yalnızca “your screen is too small” mesajı gönderecek şekilde ayarlanmıştı; bu durumda CPU ve bant genişliği kullanımı yarıya düştü
    • Oyun verisi gönderilmediğinden CPU kullanımının %0’a yakın olması gerekirken hâlâ yaklaşık %50 seviyesinde kaldı
    • Bu da SSH’nin kendisindeki iletişim ek yükü ihtimalini gündeme getirdi

İnceleme süreci

  • tcpdump kullanılarak normal çalışma ile hata durumundaki SSH trafiği karşılaştırıldı
    • Hata durumunda da 36 baytlık paketlerin 20 ms aralıklarla sürekli oluştuğu görüldü
    • macOS’in varsayılan SSH istemcisinde de aynı desen doğrulandı
  • Claude Code ile pcap dosyası analiz edildiğinde
    • Toplam 413.703 paketin %66’sının 36 bayt, %34’ünün ise 0 baytlık ACK olduğu görüldü
    • Paketleri esas olarak SSH istemcisinin ürettiği anlaşıldı

Kök neden

  • SSH hata ayıklama günlüğünde (ssh -vvv) şu mesajlar görüldü
    obfuscate_keystroke_timing: starting: interval ~20ms
    obfuscate_keystroke_timing: stopping: chaff time expired (101 chaff packets sent)
    
    • 20 ms aralık ve onlarca ila yüzü aşkın chaff paketi, gözlemlenen gerçek desenle birebir örtüşüyordu
  • Sorunun kaynağı, 2023’te SSH’ye eklenen tuş vuruşu zamanlaması bulanıklaştırma özelliğiydi
    • Kullanıcının yazma hızı deseninin ortaya çıkmasını engellemek için rastgele “chaff” paketleri gönderiliyor
    • Güvenlik açısından faydalı olsa da, gecikmenin (latency) önemli olduğu ortamlarda aşırı yük yaratabiliyor

Çözüm yöntemi

  • İstemci tarafında ObscureKeystrokeTiming=no seçeneğiyle özellik devre dışı bırakılabiliyor
    • Uygulandıktan sonra CPU kullanımı ve bant genişliği belirgin biçimde düştü, veri iletimi normal kaldı
  • Sunucu tarafındaki çözüm için Go’nun SSH kütüphanesinde [email protected] uzantısının duyurulması kaldırıldı
    • İlgili commit geri alındıktan sonra yapılan testte
      • CPU kullanımı %29,9 → %11,6,
        sistem çağrıları 3.10s → 0.66s,
        şifreleme işlemleri 1.6s → 0.11s,
        bant genişliği 6.5Mbit/s → 3Mbit/s
    • Performans %50’den fazla iyileşti

LLM ile hata ayıklama deneyimi

  • Claude Code kullanılarak tcpdump ve tshark analizi otomatikleştirildi ve sorunun nedeni hızla daraltıldı
    • Komutların çalıştırılma süreci gerçek zamanlı izlenerek zihinsel modelin korunması mümkün oldu
  • ChatGPT’nin SSH davranışını yanlışlıkla “normal” olarak değerlendirmesi gibi modeller arası farklar da gözlendi
  • LLM’ler sorun çözme sürecinin tamamının yerini almasa da, yardımcı analiz aracı olarak yüksek verimlilik sundu
  • İnsan muhakemesi ile LLM analizinin birleştirilmesi sayesinde karmaşık ağ performansı sorunlarının çözüldüğü bir örnek ortaya çıktı

1 yorum

 
GN⁺ 2026-01-23
Hacker News görüşleri
  • Go'nun crypto kütüphanesini fork etmek biraz ürkütücü geliyor
    Küçük yamamı güvenli biçimde nasıl koruyabileceğimi düşünüyorum
    Aslında böyle bir özelliğin ssh kütüphanesinin bir seçeneği olarak upstream edilmesi gerektiğini düşünüyorum
    Güvenilmeyen ortamlarda chaff (gürültü) paketleri göndermek varsayılan olarak iyi, ama bant genişliğinden tasarruf etmek isteyeceğiniz pek çok durum da var

    • Özelliği duyurmayan bir yolla kontrol etmek fazla istikrarsız bir yaklaşım
      Sunucunun istemciye “gerek yok” sinyali gönderebildiği bir seçenek eklemek ve istemcinin bunu kabul etmesi ya da uyarı vermesi doğru çözüm olur
    • Aslında benzer bir davranış zaten var
      Yalnızca TTY oturumlarında geçerli ve istemci bunu devre dışı bırakabiliyor
      Ancak bu vakada istisnai olan şey, sunucunun bunun önceden önemsiz bir bağlantı olduğunu bilmesiydi
      Çoğu durumda istemci ObscureKeystrokeTiming ayarının korunmasını bekler
    • Yine de bu değişikliğin reddedilme olasılığının yüksek olduğunu düşünüyorum
      crypto kütüphanesi çok güçlü görüşlere sahip bir kod tabanı; öyle ki TLS cipher suite sırasını bile değiştirmenize izin vermiyor
    • Güvenilen ortamlarda bile tehditler vardır
      Bu, SSH'in oldukça özel bir kullanım senaryosu gibi görünüyor
      Fazla geniş açılırsa “ayarla ve unut” durumuna dönüşüp güvenliği zayıflatabilir
    • Eskiden 1KB RAM'li bir ZX80 kullandığım günler vardı
      1200bps modemlerle haberleştiğimiz zamanlar da oldu, 56K modemler ise fiilen abartıydı
      1994 civarında Birleşik Krallık'ta bir askerî kolejde çalışırken WWW ile ilk kez karşılaştım ve o zaman “pek iyi değilmiş” diye düşünmüştüm
      Geriye dönüp bakınca zamanın değişimi gerçekten şaşırtıcı
  • Bu obfuscation özelliğini ilk kez duyuyorum, ilginçmiş
    ssh'in davranışını debug ederken “None” cipher'ını yamalayıp paket içeriğini doğrudan görmek de iyi bir yöntem
    Güvenliğin önemli olmadığı, performansın önemli olduğu bir terminal oyunu için doğrudan telnet kullanmak da düşünülebilir

  • SSH'in böyle bir şey yaptığını bilmiyordum
    Varsayılan olarak açık olmasını anlıyorum ama benim ortamımda kapatmak daha doğru gibi

    1. SSH üzerinden sırları doğrudan yazmam neredeyse hiç gerekmiyor
    2. Devlet düzeyinde bir saldırganın tuş vuruşlarımı sniff etmesi için bir neden yok
    3. Kıtalar arası bağlantı kullandığım için bant genişliği tasarrufu önemli
      Bu yüzden ObscureKeystrokeTiming=no ayarlamayı düşünüyorum. Bunu yapmamam için bir neden var mı?
    • Aşırı iyimser bir güvenlik yaklaşımı tehlikelidir
      (1) İnsanların ne zaman sır girdiğini her zaman ayırt etmek zordur ve tüm etkinlik örüntü analizi ile analiz edilebilir
      (2) Bu, üniversite laboratuvarı düzeyinde bile yapılabilen bir saldırıdır — USENIX makalesi ve araştırma örneği
      (3) İnternet trafiğine video hâkimken birkaç bayt tuş vuruşu verisi kazanmak için güvenlikten vazgeçmenin anlamı yok
    • TTY SSH bağlantısında sık girilen sır genellikle sudo parolasıdır
      Bir saldırgan tuş vuruşu zamanlamasını analiz ederek komutları ve şifrelenmiş parola desenini tahmin edebilir
      Elbette oturum anahtarı her seferinde değiştiği için şifre çözmek zor olur ama ihtimal var
      Ben de çoğu parolayı parola yöneticisinden kopyalayıp yapıştırıyorum
    • Sızan herhangi bir düz metnin saldırgan için işe yaramayacağından emin olamazsınız
      Çoğu insan SSH'in güvenlik özelliklerini kapatıp da sorun yaşamadığını düşünür, ama bu sadece şanslı oldukları anlamına gelir
      Gerçekten performans gerekiyorsa Telnet, gerçekten güvenlik gerekiyorsa ContainerSSH + OAuth2 kombinasyonu daha iyi olur
  • 2004'te SSH oturumlarında tuş vuruşları arasındaki gecikmeyi analiz ederek komut tahmini üzerine araştırma yapmıştım
    O dönemki analiz notları
    2023 yaması sonunda bu sorunu çözmüş oldu

    • HAL2001 hack konferansında Dug Song ve Solar Designer'ın SSH zamanlama analizi sunduğunu hatırlıyorum
      Sunum metni
      Zaman gerçekten çok hızlı geçiyor
  • Claude'un debug sürecinde gerçekten yardımcı olup olmadığından emin değilim
    Yazar zaten yönü biliyordu, Claude ise sadece onaylamış gibi geldi
    Claude'un “Holy Cow!” gibi şeyler söylemesi biraz sinir bozucu

    • Yine de Rubber Duck Debugging gibi düşünceleri toparlamaya yardım ettiyse bunun değeri vardır
      Ben de Claude ile sistem davranışlarını debug ederken, doğrudan bir cevap vermese bile anlayışı netleştirmeye ve motivasyonu korumaya yardımcı olduğunu görüyorum
      Rubber Duck Debugging wiki
    • Claude, pcap alanı çıkarma ya da awk işlemlerinde benden çok daha hızlı
    • Yapay zeka, metindeki kişiliği algılamada çok başarılı
      Yazarın “holy cow” tepkisini sevip bloga koyduğuna bakılırsa Claude ortamın havasını iyi okumuş
    • Geliştirme araçlarına kişilik vermek belki de iyi bir fikir değildi
  • TCP_CORK kullanırsanız gecikme eklemeden paket sayısını azaltabilirsiniz
    TCP_NODELAY'i kapatmak da bir yöntem ama bunun bedeli artan gecikme olur

    • TCP_CORK'u ilk kez duyuyorum, ilginçmiş
      Soketi cork edince çekirdek veriyi tamponlar, uncork edilince ya da MSS'e ulaşınca gönderir
      Yani paketleri gruplayarak gönderme yaklaşımıdır
      Referans
    • TCP_CORK'u bilmiyordum ama gerçekten kullanışlı görünüyor
      Ping'i yine alırım ama pong gönderme sayısını azaltabilirim gibi
      TCP_NODELAY'i daha önce kullandım ama gecikmeyi artırdığı için oyunum için uygun değildi
      Önceki HN gönderisi
    • Ancak chaff paketleri 20ms aralıklarla gönderildiği için TCP_CORK'un bunları gruplayıp gruplayamayacağı belirsiz
      Obfuscation amacı gereği coalescing yapmak mümkün görünmüyor
  • “The smoking gun!” ifadesi komikti
    Ana dili İngilizce olmayan biri olarak bunu Claude'un sık kullanması sayesinde ilk kez öğrendim
    Artık gerçekten yaygın bir kalıp hâline geliyor

  • LLM'e bu kadar bağımlı olunması üzücü
    Bu muhtemelen sadece Wireshark ile paket yakalamaya bakılarak daha hızlı çözülebilirdi
    SSH dissector'ı oldukça olgun

    • Ben de LLM hayranı değilim ama Wireshark'ta SSH paketlerine bakınca çoğunlukla sadece şifreli paketler görüyorsunuz, bu yüzden çok faydalı bilgi çıkmıyor
      tcpdump ile tek bir tuş vuruşunu yakalasanız bile yüzlerce şifreli paket çıkıyor
      Sonuçta LLM sayesinde yazar ilginç bir şey öğrenip paylaşmış, yani bunun bir değeri var
    • SSH dissector'ı kusursuz değil
      NEWKEYS mesajından sonra ayrıştırma yapamıyor ve none şifrelemesine yamalasanız bile akışı tamamen yorumlayamıyor
      Geliştirme payı var
    • “Sadece Wireshark'a bakmak yeterdi” tavrı biraz gatekeeping gibi geliyor
      Araçları kullanarak öğrenmenin de yeterince değeri var
    • SSH daha adından itibaren bir güvenlik protokolü
      Basit bir paket yakalama ile anlamlı bilgi elde etmek zor
    • Yazar SSH paket çözümleyicisini bilmiyordu ve bunun yerine genel amaçlı bir araç (LLM) kullandı
      Bunun neden kötü bir şey sayıldığını anlamıyorum
  • 2023'te SSH, tuş vuruşu zamanlamasını gizleme özelliği ekledi
    Karakterler yazma hızından tahmin edilebildiği için SSH araya chaff paketleri karıştırarak saldırganın ayırt etmesini zorlaştırıyor
    Ama bu yanlış bir yaklaşım gibi görünüyor
    Gerçekten istenirse tüm tuş vuruşları 50ms aralıklarla gönderilebilir

    • 50ms gecikme kullanım hissi açısından oldukça rahatsız edici olur gibi
    • 50ms aralıklarla göndermekten kasıt 20ms yerine 50ms'ye geçmek mi, yoksa sürekli sabit aralıklarla gönderim mi, tam net değil
      Mevcut uygulama 20ms birimlerle gruplayıp, bir süre giriş olmazsa chaff göndermeyi durduruyor
  • SSH'in özü güvenlik ama güvenlik gerekmiyorsa neden SSH kullandığınız sorgulanabilir
    Örneğin netcat (nc) çoğu platformda varsayılan olarak yüklü geliyor

    • “Güvenlik birinci öncelik” demek her şeyin bundan ibaret olduğu anlamına gelmez
      SSH'te performans, kullanım kolaylığı gibi başka değerlendirmeler de var
      Yazar sadece tuş vuruşu gizleme (privacy) özelliğini gereksiz bulduğunu söylüyor
      Şifreleme ya da bütünlük güvencesini yine de korumak isteyebilir
      Yani SSH'in çoğu güvenlik özelliğini bırakıp sadece bir kısmını kapatma tercihinden söz ediyoruz
    • Artık Windows'ta da SSH yerleşik geliyor; bu yüzden “her platformda nc vardır” demek tam olarak doğru değil