Sunucu yönetiminde en can sıkıcı şeylerden biri her bağlantıda şifre girmek zorunda kalmaktır. Özellikle onlarca sunucuyu yönetiyorsanız, bu durum hem verimliliğinizi düşürür hem de güvenlik açısından ciddi riskler taşır. SSH key authentication, yani açık anahtar kimlik doğrulaması, bu sorunu zarif bir şekilde çözer. Hem daha güvenli hem de çok daha pratiktir. Bu yazıda SSH key altyapısını sıfırdan kuracak, olası sorunlara çözüm bulacak ve gerçek dünya senaryolarıyla konuyu pekiştireceğiz.
SSH Key Nasıl Çalışır?
Konuya girmeden önce temel mantığı anlamak önemli. SSH key authentication asimetrik şifreleme kullanır. Elimizde iki anahtar bulunur: özel anahtar (private key) ve açık anahtar (public key).
- Private key: Sadece sizde bulunur, asla paylaşılmaz, genellikle
~/.ssh/id_rsaveya~/.ssh/id_ed25519dosyasında saklanır - Public key: Sunucuya yüklediğiniz anahtardır,
~/.ssh/id_rsa.pubgibi.pubuzantılıdır
Bağlantı kurulduğunda sunucu, açık anahtarınızla şifrelenmiş bir meydan okuma (challenge) gönderir. Siz bu meydan okumayı sadece özel anahtarınızla çözebilirsiniz. Çözümü sunucuya iletirsiniz, sunucu doğrular ve sizi içeri alır. Şifre hiçbir zaman ağ üzerinden geçmez.
Gerekli Araçlar ve Ön Koşullar
Bu işlemler için özel bir araç kurmanıza gerek yok. ssh-keygen, ssh-copy-id ve ssh komutları tüm modern Linux dağıtımlarında varsayılan olarak gelir. Windows kullanıcıları için PowerShell üzerinde de bu komutlar artık mevcut.
Senaryo olarak şunu düşünelim: Yerel makinenizden (laptop veya iş istasyonu) bir ya da birden fazla uzak sunucuya şifresiz bağlantı kurmak istiyorsunuz.
Adım 1: SSH Key Çifti Oluşturmak
İlk adım, yerel makinenizde bir key çifti oluşturmaktır. Eski standart RSA 2048-bit anahtardı, ancak günümüzde Ed25519 algoritması hem daha güvenli hem de daha küçük anahtarlar ürettiği için tercih edilmektedir.
ssh-keygen -t ed25519 -C "[email protected]"
Bu komutu çalıştırdığınızda birkaç soru sorar:
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/mustafa/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Dosya konumu: Varsayılanı genellikle iyidir, Enter’a basın. Ancak birden fazla key yönetiyorsanız anlamlı bir isim verin, örneğin /home/mustafa/.ssh/id_production.
Passphrase: Bu kısmı boş bırakabilirsiniz, ama production ortamlar için kesinlikle bir passphrase belirlemenizi öneririm. Passphrase, private key dosyanız çalınsa bile saldırganın onu kullanamamasını sağlar. SSH agent kullanarak bu passphrase’i bir kez girip oturum boyunca hatırlatabilirsiniz, bu konuya ileride değineceğiz.
Eski sistemlerle uyumluluk gerekiyorsa RSA 4096-bit kullanın:
ssh-keygen -t rsa -b 4096 -C "[email protected]"
Oluşturulan dosyaları kontrol edelim:
ls -la ~/.ssh/
-rw------- 1 mustafa mustafa 411 Oca 15 10:23 id_ed25519
-rw-r--r-- 1 mustafa mustafa 99 Oca 15 10:23 id_ed25519.pub
Private key dosyasının izinlerine dikkat edin: 600 yani sadece sahibi okuyabilir. Public key 644 olabilir, sorun değil.
Adım 2: Public Key’i Sunucuya Kopyalamak
Artık public key’i uzak sunucuya yüklememiz gerekiyor. Bunun için en kolay yol ssh-copy-id komutudur:
ssh-copy-id -i ~/.ssh/id_ed25519.pub [email protected]
Bu komut, uzak sunucudaki ~/.ssh/authorized_keys dosyasına public key’inizi ekler. Komut çalışırken sunucunun şifresini isteyecektir, bu son kez şifre gireceğiniz an.
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be added: '/home/mustafa/.ssh/id_ed25519.pub'
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s)
[email protected]'s password:
Number of key(s) added: 1
ssh-copy-id kullanamıyorsanız (örneğin Windows’tan bağlanıyorsanız ya da araç yoksa) manuel yöntem:
cat ~/.ssh/id_ed25519.pub | ssh [email protected] "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
Bu tek satır şunları yapar: remote makinede .ssh dizinini oluşturur, doğru izinleri verir, public key’i authorized_keys dosyasına ekler ve dosyanın izinlerini ayarlar.
Adım 3: Bağlantıyı Test Etmek
ssh [email protected]
Şifre sormadan bağlandıysanız her şey yolunda demektir. Eğer verbose modda ne olduğunu görmek istiyorsanız:
ssh -v [email protected]
Bu çıktıda hangi key dosyalarının denlendiğini, sunucunun nasıl yanıt verdiğini görebilirsiniz. Sorun giderirken çok işe yarar.
SSH Config Dosyası ile Yönetimi Kolaylaştırmak
On sunucunuz varsa her seferinde ssh [email protected] yazmak zahmetlidir. ~/.ssh/config dosyası bu sorunu çözer:
nano ~/.ssh/config
# Production Web Sunucu
Host web01
HostName 192.168.1.100
User deploy
IdentityFile ~/.ssh/id_production
Port 22
# Veritabani Sunucusu
Host db01
HostName 10.0.0.50
User dbadmin
IdentityFile ~/.ssh/id_database
Port 2222
# Gelistirme Ortami
Host dev
HostName dev.sirket.com
User mustafa
IdentityFile ~/.ssh/id_ed25519
# Tum sirket.com sunuculari icin genel ayar
Host *.sirket.com
User admin
IdentityFile ~/.ssh/id_company
ServerAliveInterval 60
ServerAliveCountMax 3
Artık sadece şunu yazmanız yeterli:
ssh web01
ssh db01
ssh dev
Config dosyasının izinleri doğru olmalı:
chmod 600 ~/.ssh/config
ServerAliveInterval: Sunucu idle connection’ları kesiyorsa bu parametre bağlantıyı canlı tutar. Her 60 saniyede bir keepalive paketi gönderir. ServerAliveCountMax: Kaç yanıtsız keepalive paketi sonrası bağlantının kesileceğini belirtir.
Sunucu Tarafında Güvenlik Ayarları
SSH key authentication’ı aktif etmek yetmez, sunucu tarafında da bazı ayarları yapmanız gerekir. /etc/ssh/sshd_config dosyasını düzenleyin:
sudo nano /etc/ssh/sshd_config
Kontrol etmeniz ve ayarlamanız gereken parametreler:
- PubkeyAuthentication yes: Public key kimlik doğrulamasını aktif eder, genellikle varsayılan olarak açıktır
- AuthorizedKeysFile .ssh/authorized_keys: Authorized keys dosyasının konumu
- PasswordAuthentication no: Key kurulumu tamamlandıktan sonra bunu kapatın, brute force saldırılarını engeller
- PermitRootLogin prohibit-password: Root’a şifreyle girişi engeller, key ile girise izin verir; ya da
noyaparak tamamen kapatabilirsiniz - ChallengeResponseAuthentication no: Şifre tabanlı doğrulamanın bir başka yolunu kapatır
- X11Forwarding no: Kullanmıyorsanız kapatın
Ayarları uygulamak için sshd servisini yeniden başlatın:
sudo systemctl restart sshd
Kritik uyarı: PasswordAuthentication no yapıp servisi yeniden başlatmadan önce key ile girişin çalıştığından emin olun. Aksi takdirde sunucunun dışında kalabilirsiniz.
SSH Agent ile Passphrase Yönetimi
Private key’inize passphrase koydunuz, harika! Ama her bağlantıda passphrase girmek de can sıkıcı olabilir. ssh-agent burada devreye girer. Passphrase’i bir kez girerek agent’a bırakırsınız, oturum boyunca otomatik kullanılır.
# Agent'i baslat
eval "$(ssh-agent -s)"
# Key'i agent'a ekle
ssh-add ~/.ssh/id_ed25519
Enter passphrase for /home/mustafa/.ssh/id_ed25519:
Identity added: /home/mustafa/.ssh/id_ed25519
Artık oturum boyunca passphrase sorulmaz. Agent’ta hangi keylerin yüklendiğini görmek için:
ssh-add -l
Agent’ı her terminal açışta otomatik başlatmak istiyorsanız ~/.bashrc veya ~/.bash_profile dosyanıza ekleyebilirsiniz:
# SSH Agent otomatik baslat
if [ -z "$SSH_AUTH_SOCK" ]; then
eval "$(ssh-agent -s)" > /dev/null
ssh-add ~/.ssh/id_ed25519 2>/dev/null
fi
Çoklu Kullanıcı ve Sunucu Senaryosu
Gerçek bir sysadmin ortamında genellikle birden fazla kişi birden fazla sunucuya erişmek zorundadır. Bunun için standart bir workflow önerim şu:
Her kullanıcı kendi key çiftini oluşturur ve public key’ini size (ya da sistem yöneticisine) iletir. Siz de bu public key’leri ilgili sunuculardaki authorized_keys dosyasına eklersiniz.
# Yeni bir kullanicinin public key'ini mevcut authorized_keys'e eklemek
echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... [email protected]" >> ~/.ssh/authorized_keys
Bir kullanıcının erişimini kaldırmak için authorized_keys dosyasından ilgili satırı silin:
# authorized_keys dosyasini duzenle, ilgili satiri sil
nano ~/.ssh/authorized_keys
# Ya da grep ile kaldirin
sed -i '/[email protected]/d' ~/.ssh/authorized_keys
Bu yaklaşımın güzelliği, bir kullanıcının erişimini kesmek için şifre değiştirmenize gerek olmamasıdır. Sadece onun public key satırını dosyadan siliyorsunuz.
Jump Host (Bastion) Konfigürasyonu
Birçok şirkette sunuculara doğrudan erişilmez, önce bir bastion (jump) host’a bağlanılır. SSH config bunu da zarif şekilde çözer:
nano ~/.ssh/config
# Bastion Host
Host bastion
HostName 203.0.113.10
User jumpuser
IdentityFile ~/.ssh/id_bastion
# Internal sunuculara bastion uzerinden ulas
Host internal-*
ProxyJump bastion
User admin
IdentityFile ~/.ssh/id_internal
Host internal-web
HostName 10.0.1.10
Host internal-db
HostName 10.0.1.20
Artık tek komutla bastion üzerinden internal sunucuya bağlanabilirsiniz:
ssh internal-web
SSH otomatik olarak bastion’a bağlanır, oradan internal sunucuya tünel kurar. Hem güvenli hem de kullanımı son derece kolay.
Sorun Giderme
SSH key kurulumunda en sık karşılaşılan sorunlar ve çözümleri:
Sorun: Hala şifre soruyor
İlk kontrol edin ki sunucudaki izinler doğru mu:
# Uzak sunucuda calistirin
ls -la ~/.ssh/
stat ~/.ssh/authorized_keys
~/.sshdizini:700(drwx——) olmalı~/.ssh/authorized_keys:600(-rw——-) olmalı- Home dizini çok geniş izinlere sahip olmamalı (max
755)
İzinleri düzeltmek için:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 755 ~
Sorun: Permission denied (publickey)
Verbose modda bağlanıp detayı görün:
ssh -vvv kullanici@sunucu 2>&1 | grep -E "Offering|Authentications|denied"
SSH hangi key’leri denediğini ve sunucunun ne dediğini göreceksiniz. Çoğunlukla ya yanlış key kullanılıyordur ya da authorized_keys dosyasına doğru key eklenmemiştir.
Sorun: SELinux veya AppArmor engelliyor
RHEL/CentOS sistemlerde SELinux authorized_keys dosyasının context’ini bozabilir:
restorecon -Rv ~/.ssh/
Sorun: Sunucu logundan kontrol
Sunucu tarafında ne olduğunu görmek için:
sudo journalctl -u sshd -f
# ya da
sudo tail -f /var/log/auth.log # Debian/Ubuntu
sudo tail -f /var/log/secure # RHEL/CentOS
Ansible ile Toplu Key Dağıtımı
Eğer onlarca sunucunuz varsa ve key dağıtımını otomatize etmek istiyorsanız Ansible’ın authorized_key modülü tam size göre:
# inventory.ini
[webservers]
web01 ansible_host=192.168.1.100
web02 ansible_host=192.168.1.101
web03 ansible_host=192.168.1.102
[dbservers]
db01 ansible_host=10.0.0.50
# deploy-keys.yml
---
- name: SSH Key Dagitimi
hosts: all
tasks:
- name: Ahmet'in public key'ini ekle
authorized_key:
user: deploy
state: present
key: "{{ lookup('file', 'keys/ahmet.pub') }}"
- name: Ayrilmis calisan key'ini kaldir
authorized_key:
user: deploy
state: absent
key: "{{ lookup('file', 'keys/eski_calisan.pub') }}"
ansible-playbook -i inventory.ini deploy-keys.yml
Bu yaklaşımla onlarca sunucudaki key yönetimini dakikalar içinde halledebilirsiniz. Biri şirketten ayrıldığında sadece state: absent ile tüm sunuculardan key’ini kaldırırsınız.
Güvenlik İpuçları ve Best Practice’ler
Birkaç önemli noktayı vurgulayalım:
- Her cihaz için ayrı key: Laptop’unuz için bir key, iş masaüstü için başka bir key kullanın. Bir cihaz kaybolursa sadece o cihazın key’ini kaldırırsınız
- Key rotation: Production sistemlerde keyleri periyodik olarak rotasyona tabi tutun, 1-2 yılda bir yeni key oluşturup eskisini kaldırın
- Passphrase kullanın: Özellikle root erişimi sağlayan keylerde passphrase şart
authorized_keysdosyasını izleyin: Dosyaya kimin ne zaman key eklediğini loglamak için auditd kullanabilirsiniz- Key’lerinizi yedekleyin: Private key’inizi encrypted bir yedekleme alanına koyun, kaybetmek istemezsiniz
- Gereksiz keyleri temizleyin: Kullanmadığınız, eski keyleri
authorized_keysdosyasından düzenli olarak kaldırın
authorized_keys dosyasına her satırın başına kısıtlamalar da ekleyebilirsiniz:
# Sadece belirli IP'den erisime izin ver
from="203.0.113.5" ssh-ed25519 AAAA... backup-script@server
# Sadece belirli bir komutu calistirabilsin
command="/usr/local/bin/backup.sh" ssh-ed25519 AAAA... restricted-user@host
# Port forwarding ve pty engelle
no-port-forwarding,no-pty,no-x11-forwarding ssh-ed25519 AAAA... monitoring@host
Bu kısıtlamalar özellikle otomasyon scriptleri veya monitoring araçları için kullanışlıdır. Bir key sadece belirli bir komutu çalıştırabilir, başka hiçbir şey yapamaz.
Sonuç
SSH key authentication, sysadmin toolbox’ınızda olması gereken temel becerilerden biridir. Doğru kurulduğunda hem güvenliği dramatik biçimde artırır hem de iş akışınızı hızlandırır. Şifre tabanlı girişlerin ortadan kalkması, brute force saldırılarını etkisiz hale getirir; passphrase ile korunan keyler ise cihaz kaybı senaryosunda bile sizi korur.
Özetle yapmanız gerekenler şu sırayla gider: Local’de key oluşturun, public key’i sunucuya kopyalayın, izinleri kontrol edin, sshd_config üzerinde güvenlik ayarlarını yapın ve son olarak şifre girişini devre dışı bırakın. ~/.ssh/config dosyasını da ihmal etmeyin, çok sayıda sunucu yönetirken hayat kurtarır.
Bir sonraki adım olarak bu altyapıyı Ansible veya benzeri bir araçla otomatize etmeyi ve key rotasyonu için bir süreç oluşturmayı düşünebilirsiniz. Küçük bir yatırım, uzun vadede büyük kazanımlar sağlar.