SSH Bağlantı Sorunları: Hata Mesajlarını Okuma ve Çözme
SSH ile bağlantı kurmaya çalışırken karşına çıkan “Connection refused”, “Permission denied” veya “Host key verification failed” gibi hata mesajları, deneyimli sysadmin’lerin bile canını sıkabiliyor. Ama şunu söyleyeyim: SSH hata mesajları aslında oldukça bilgilendirici. Sadece ne söylediklerini doğru okumayı öğrenmek gerekiyor. Bu yazıda, gerçek dünya senaryoları üzerinden SSH bağlantı sorunlarını nasıl teşhis edip çözeceğini adım adım anlatacağım.
SSH Verbose Modu: En İyi Arkadaşın
SSH sorunlarını çözmenin ilk adımı her zaman verbose modu kullanmak. Normal ssh komutu çok az bilgi verir ama -v, -vv veya -vvv parametreleriyle bağlantı sürecinin her adımını görebilirsin.
# Temel verbose mod
ssh -v [email protected]
# Daha fazla detay
ssh -vv [email protected]
# Maksimum debug çıktısı
ssh -vvv [email protected]
-vvv ile bağlandığında ekranda akan onlarca satır seni korkutmasın. Önemli olan debug1, debug2, debug3 ile başlayan satırları takip etmek. Özellikle bağlantının nerede takıldığını bulmak için bu çıktıyı dikkatli oku.
Tipik bir verbose çıktısında şunları görürsün:
- OpenSSH_8.x, OpenSSL…: İstemci versiyonu
- Connecting to…: TCP bağlantı denemesi
- Connection established: TCP katmanı başarılı
- Server host key: Sunucunun public key’i
- Authentications that can continue: Sunucunun kabul ettiği auth yöntemleri
Bu akışın nerede kesildiği sana sorunun kaynağını söyler.
“Connection refused” Hatası
Bu hata, hedef makinede SSH port’unda hiçbir şeyin dinlemediği anlamına gelir. TCP bağlantısı kurulamamış demektir.
ssh: connect to host sunucu.com port 22: Connection refused
Olası Nedenler ve Çözümler
1. SSH servisi çalışmıyor olabilir.
Sunucuya başka bir yoldan (console, VNC, IPMI) erişip kontrol et:
# Systemd tabanlı sistemlerde
systemctl status sshd
# Servis çalışmıyorsa başlat
systemctl start sshd
systemctl enable sshd
# SysV init sistemlerde
service ssh status
service ssh start
2. SSH farklı bir port’ta dinliyor olabilir.
Bazı sysadmin’ler güvenlik için SSH’ı 22 dışında bir port’a taşır. Eğer bu senin sunucunsa /etc/ssh/sshd_config dosyasını kontrol et. Eğer değilse, sistem sahibine sor:
# Hangi portu dinlediğini kontrol et
ss -tlnp | grep sshd
# Veya netstat ile
netstat -tlnp | grep :22
# Farklı port ile bağlanmak için
ssh -p 2222 [email protected]
3. Firewall engelliyor olabilir.
Bu en sık karşılaşılan durum. Sunucu tarafında:
# UFW kullanıyorsan
ufw status
ufw allow 22/tcp
# firewalld kullanıyorsan
firewall-cmd --list-all
firewall-cmd --permanent --add-service=ssh
firewall-cmd --reload
# iptables ile kontrol
iptables -L INPUT -n -v | grep 22
Gerçek dünya senaryosu: Bir keresinde yeni kurulan bir Ubuntu 22.04 sunucusunda SSH bağlantısı çalışırken birden kesildi. Sorun şuydu: Otomatik güvenlik güncellemesi ufw paketini yüklemiş ve varsayılan olarak etkinleştirmişti. UFW’nun varsayılan politikası gelen bağlantıları engellemek. Sunucuya IPMI üzerinden girip ufw allow ssh komutunu çalıştırınca sorun çözüldü.
“Permission denied (publickey)” Hatası
Bu hata, kimlik doğrulamanın başarısız olduğunu söyler. Genellikle key tabanlı auth kullanıyorsun ama bir şeyler ters gidiyor.
[email protected]: Permission denied (publickey).
Verbose modda bunu görürsün:
ssh -vvv [email protected]
Çıktıda şunu ara:
debug1: Offering public key: /home/kullanici/.ssh/id_rsa RSA
debug1: Authentications that can continue: publickey
debug1: No more authentication methods to try.
Yaygın Nedenler
1. Public key sunucuya eklenmemiş:
# Public key'ini sunucuya kopyalamanın en temiz yolu
ssh-copy-id [email protected]
# Manuel olarak yapmak istersen
cat ~/.ssh/id_rsa.pub | ssh [email protected] "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
2. Dosya izinleri yanlış:
SSH, güvenlik açısından çok titizdir. İzinler yanlışsa key kullanmayı reddeder:
# Sunucuda bu izinler olmalı
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/id_rsa # Private key
chmod 644 ~/.ssh/id_rsa.pub # Public key
# İstemcide de private key izni kritik
chmod 600 ~/.ssh/id_rsa
3. Yanlış kullanıcı adı:
# Verbose çıktısında hangi kullanıcıyla bağlandığını kontrol et
debug1: Authenticating to sunucu.com:22 as 'yanlis_kullanici'
# Doğru kullanıcıyla bağlan
ssh [email protected]
# Veya config dosyasında tanımla
# ~/.ssh/config
Host sunucu
HostName sunucu.com
User dogru_kullanici
IdentityFile ~/.ssh/id_rsa
4. SELinux veya özel güvenlik politikaları:
RHEL/CentOS tabanlı sistemlerde SELinux bazen authorized_keys dosyasını engeller:
# SELinux context'ini kontrol et
ls -laZ ~/.ssh/
# Context'i düzelt
restorecon -Rv ~/.ssh/
“Host key verification failed” Hatası
Bu hata, sunucunun fingerprint’i daha önce kaydettiğinle eşleşmediğinde çıkar. Tehlikeli olabilir ama çoğu zaman masum bir nedeni vardır.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Ne Zaman Tehlikeli, Ne Zaman Değil?
Masum nedenler:
- Sunucu yeniden kuruldu
- IP adresi değişti, yeni bir sunucu o IP’yi aldı
- SSH key’leri yeniden üretildi
Tehlikeli nedenler:
- Man-in-the-middle saldırısı
Eğer sunucuyu gerçekten yeniden kurduğunu biliyorsan veya IP değişikliği yaptıysan:
# Eski kaydı sil
ssh-keygen -R sunucu.com
# Veya IP ile
ssh-keygen -R 192.168.1.100
# Sonra tekrar bağlan, yeni key'i kabul et
ssh [email protected]
Kritik uyarı: Eğer sunucuda değişiklik yapmadıysan ve bu hatayı görüyorsan, bağlanma. Güvenlik ekibini bilgilendir ve durumu araştır. Bu, gerçek bir MITM saldırısının belirtisi olabilir.
“No route to host” ve “Network unreachable” Hataları
Bu hatalar ağ katmanında sorun olduğunu gösterir.
ssh: connect to host sunucu.com port 22: No route to host
# Önce temel ağ bağlantısını test et
ping sunucu.com
# DNS çözümlemesini kontrol et
nslookup sunucu.com
dig sunucu.com
# Route'u kontrol et
traceroute sunucu.com
# veya
tracepath sunucu.com
# Portun erişilebilir olup olmadığını test et
telnet sunucu.com 22
# veya daha modern bir yöntem
nc -zv sunucu.com 22
Gerçek dünya senaryosu: Bir üretim ortamında, gece yarısı bir sunucuya erişemez hale geldim. Ping gidiyordu ama SSH vermiyordu. nc -zv ile test ettiğimde port 22’nin kapalı olduğunu gördüm. Sorun şuydu: Cloud güvenlik grubu (security group) kuralları başka bir ekip tarafından yanlışlıkla değiştirilmişti. Security group’ta 22. porta izin ekleyince sorun düzeldi. Bu yüzden her zaman hem network level hem de OS level firewall’ı kontrol etmek gerekiyor.
SSH Config Dosyası ile Sorun Tespiti
~/.ssh/config dosyası hem bağlantıyı kolaylaştırır hem de sorun gidermede yardımcı olur.
# ~/.ssh/config örneği
Host prod-sunucu
HostName 10.0.1.50
User admin
Port 2222
IdentityFile ~/.ssh/prod_key
ServerAliveInterval 60
ServerAliveCountMax 3
ConnectTimeout 10
LogLevel DEBUG3
Host jump-host
HostName bastion.sirket.com
User operator
IdentityFile ~/.ssh/jump_key
ForwardAgent yes
Host internal-sunucu
HostName 192.168.10.20
User devuser
ProxyJump jump-host
IdentityFile ~/.ssh/internal_key
ServerAliveInterval: SSH bağlantısının kesilmemesi için belirli aralıklarla keepalive paketi gönderir. ConnectTimeout: Bağlantı denemesi için maksimum bekleme süresi. LogLevel DEBUG3: Bu host’a bağlanırken otomatik olarak maksimum debug çıktısı üretir.
Sunucu Tarafında Log Analizi
İstemci tarafında ne olduğunu gördün, şimdi sunucu tarafına bakalım. Sunucu logları çoğu zaman istemci tarafının göremediği detayları içerir.
# Debian/Ubuntu'da
tail -f /var/log/auth.log | grep ssh
# RHEL/CentOS'ta
tail -f /var/log/secure | grep ssh
# Systemd tabanlı sistemlerde (her dağıtım)
journalctl -u sshd -f
# Son 100 satırı göster
journalctl -u sshd -n 100
# Belirli bir zaman aralığında
journalctl -u sshd --since "2024-01-15 10:00" --until "2024-01-15 11:00"
Başarısız giriş denemelerini analiz etmek:
# Kaç başarısız deneme var?
grep "Failed password" /var/log/auth.log | wc -l
# Hangi IP'lerden geliyor?
grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head 20
# Geçersiz kullanıcı denemeleri
grep "Invalid user" /var/log/auth.log | awk '{print $8}' | sort | uniq -c | sort -rn
Sunucu loglarında görebileceğin kritik mesajlar:
- Authentication refused: bad ownership or modes: Dosya izin sorunu
- User root not allowed because not listed in AllowUsers: Config’de kısıtlama var
- Received disconnect from … Too many authentication failures: İstemci çok fazla key denedi
- error: maximum authentication attempts exceeded: Aynı sorun, farklı mesaj
“Too many authentication failures” Hatası
Bu ilginç bir hata. Genellikle SSH agent’ında çok fazla key varsa oluşur. SSH, sunucunun kabul ettiğinden fazla key denediğinde sunucu bağlantıyı keser.
Received disconnect from 10.0.1.50 port 22:2: Too many authentication failures
# SSH agent'ındaki key'leri listele
ssh-add -l
# Tüm key'leri agent'dan temizle
ssh-add -D
# Sadece belirli bir key ile bağlanmayı dene
ssh -i ~/.ssh/dogru_key -o IdentitiesOnly=yes [email protected]
IdentitiesOnly=yes: Bu parametre kritik. SSH’a “sadece belirttiğim key’i kullan, agent’daki key’leri deneme” der.
Config dosyasına da ekleyebilirsin:
Host sorunlu-sunucu
HostName sorunlu-sunucu.com
User kullanici
IdentityFile ~/.ssh/dogru_key
IdentitiesOnly yes
Jump Host (Bastion) Bağlantı Sorunları
Kurumsal ortamlarda çoğu zaman internal sunuculara doğrudan bağlanamaz, bastion host üzerinden geçmen gerekir. Bu setup’larda hata ayıklamak biraz daha karmaşık olabilir.
# Manuel ProxyJump ile bağlanma
ssh -J [email protected] [email protected]
# Eski yöntem (ProxyCommand)
ssh -o ProxyCommand="ssh -W %h:%p [email protected]" [email protected]
# Verbose ile debug etmek için her iki hop'ta da verbose aktif et
ssh -v -J [email protected] [email protected]
Jump host senaryolarında sık karşılaşılan sorunlar:
- Bastion’da ForwardAgent açık değil: Internal sunucu bastion’un key’ini görmüyor
- Bastion’da AllowTcpForwarding kapalı: ProxyCommand çalışmıyor
- Internal sunucu sadece bastion’un IP’sine izin veriyor: Ama bastion’da kaynak IP korunmuyor
# Bastion'da ForwardAgent'ı test et
ssh -A [email protected]
# Bağlandıktan sonra
ssh-add -l # Agent'daki key'leri görüyor musun?
SSH Servisini Debug Modunda Çalıştırma
Bazen standart loglar yetmez. Bu durumda sshd’yi debug modunda çalıştırabilirsin. Ama dikkat: Bunu production’da yaparken mevcut servisi kapatma, farklı bir port’ta çalıştır.
# Farklı bir portta debug modunda sshd başlat
/usr/sbin/sshd -d -p 2222
# Maksimum debug ile
/usr/sbin/sshd -ddd -p 2222
# Sonra istemciden bu porta bağlan
ssh -v -p 2222 [email protected]
Bu yöntemle istemci ve sunucu tarafından aynı anda detaylı log görebilirsin. Karmaşık key sorunlarını çözmek için mükemmel bir yöntem.
sshd_config Yaygın Yanlış Konfigürasyonlar
Sunucu tarafında yanlış yapılandırma da bağlantı sorunlarına yol açar. Kontrol etmen gereken kritik parametreler:
# /etc/ssh/sshd_config dosyasını incele
grep -v "^#" /etc/ssh/sshd_config | grep -v "^$"
Dikkat edilmesi gereken satırlar:
PermitRootLogin: Root ile direkt bağlantıya izin verip vermediği. prohibit-password veya no olması önerilen değer. PasswordAuthentication: Parola ile girişe izin. no ise sadece key ile girebilirsin. PubkeyAuthentication: Key tabanlı auth aktif mi? yes olmalı. AllowUsers: Sadece belirtilen kullanıcılara izin. Listede yoksan giremezsin. AllowGroups: Sadece belirtilen gruplar. Listede değilsen giremezsin. MaxAuthTries: Maksimum auth deneme sayısı. Düşük bir değer “too many failures” hatasına yol açabilir. ListenAddress: Sadece belirli bir IP’de dinliyor olabilir.
Config değiştirdikten sonra:
# Config'i test et, hata varsa söyler
sshd -t
# Servis yeniden başlatmadan config'i yeniden yükle
systemctl reload sshd
# Veya
kill -HUP $(cat /var/run/sshd.pid)
Kritik uyarı: Config değiştirmeden önce mevcut SSH bağlantını kapatma. Yeni bir terminal sekmesinde bağlanmayı dene. Eğer yanlışlıkla kendinizi kilitlediyseniz, console erişimine ihtiyacınız olur.
Bağlantı Zaman Aşımı Sorunları
Bağlantı kuruluyor ama bir süre sonra “Broken pipe” veya “Connection timed out” ile kopuyorsa, bu genellikle NAT veya firewall’un idle bağlantıları kesmesinden kaynaklanır.
# İstemci tarafında keepalive ayarla (~/.ssh/config)
Host *
ServerAliveInterval 30
ServerAliveCountMax 6
# Veya komut satırından
ssh -o ServerAliveInterval=30 -o ServerAliveCountMax=6 [email protected]
Sunucu tarafında da ayarlayabilirsin (/etc/ssh/sshd_config):
ClientAliveInterval 60
ClientAliveCountMax 3
ClientAliveInterval: Sunucunun istemciye keepalive göndereceği saniye aralığı. ClientAliveCountMax: Yanıt alınamazsa kaç deneme yapılacağı. 3 x 60 = 180 saniye yanıt vermezse bağlantı kesilir.
Sonuç
SSH hata mesajları seni korkutmasın. Her mesaj aslında sana neye bakman gerektiğini söylüyor. Genel stratejim şu şekilde:
İlk adım olarak her zaman -vvv ile verbose modu kullan ve hatanın hangi aşamada olduğunu belirle. TCP katmanında mı (connection refused/timeout), kimlik doğrulama katmanında mı (permission denied), yoksa key exchange’de mi?
İkinci adım sunucu loglarını kontrol et. İstemci sana bir şey söylerken sunucu başka bir şey söylüyor olabilir. journalctl -u sshd -f açık tutarak bağlantı denemesi yap.
Üçüncü adım sırayla şunları kontrol et: servisin çalışıp çalışmadığını, firewall kurallarını, dosya izinlerini, sshd_config parametrelerini.
Dördüncü adım olarak sorun hala çözülmediyse sshd -ddd -p 2222 ile debug modunda sshd başlatıp detaylı analiz yap.
Yıllar içinde öğrendim ki SSH sorunlarının yüzde doksanı şu üç şeyden kaynaklanır: firewall/güvenlik grubu kuralları, yanlış dosya izinleri, ve yanlış kullanıcı adı veya key. Sistematik bir şekilde bu üçünü ele aldığında çoğu sorunu on dakika içinde çözebilirsin. Geri kalan yüzde onu için ise verbose mod ve sunucu logları neredeyse her zaman cevabı verir.
