Sunucuya Brute Force Saldırısı Geliyor: Ne Yapmalısınız?
Gece yarısı telefon çalıyor. Monitoring sisteminiz alarm veriyor: SSH portuna saniyede onlarca bağlantı denemesi geliyor. Ekrana bakıyorsunuz, auth.log dolup taşıyor. İşte o an, paniklemeden ne yapacağınızı bilmeniz gerekiyor. Bu yazıda brute force saldırısıyla karşılaştığınızda adım adım ne yapmanız gerektiğini, hangi araçları kullanacağınızı ve uzun vadeli nasıl korunacağınızı anlatacağım.
Önce Durumu Anlayın
Bir şey yapmadan önce ne ile karşı karşıya olduğunuzu net görmeniz şart. Çoğu sysadmin panikleyip hemen bir şeyler yapmaya çalışır, bu da bazen işleri daha da karmaşık hale getirir.
Saldırının boyutunu anlamak için ilk yapacağınız şey auth loglarına bakmak:
# Son 100 başarısız giriş denemesini listele
grep "Failed password" /var/log/auth.log | tail -100
# Hangi IP'den kaç deneme geldiğini öğren
grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -20
# Hangi kullanıcı adlarını deniyorlar?
grep "Failed password" /var/log/auth.log | awk '{print $(NF-5)}' | sort | uniq -c | sort -rn | head -20
CentOS/RHEL tabanlı sistemlerde log dosyası farklı bir yerde olabilir:
grep "Failed password" /var/log/secure | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -20
Bu komutların çıktısına bakın. Eğer tek bir IP’den binlerce deneme geliyorsa klasik brute force, birden fazla farklı IP’den geliyorsa distributed brute force (botnet) ile uğraşıyorsunuz demektir. İkincisi biraz daha can sıkıcı.
Anlık Müdahale: Saldıran IP’yi Engelleyin
Durumu anladıktan sonra ilk aksiyon saldıran IP’yi kesmek. Bunu iptables veya firewalld ile yapabilirsiniz.
# iptables ile tek IP engelleme
iptables -A INPUT -s 185.220.101.45 -j DROP
# Birden fazla IP varsa döngüyle ekleyebilirsiniz
for ip in 185.220.101.45 45.142.212.100 193.32.162.50; do
iptables -A INPUT -s $ip -j DROP
done
# Kuralı kalıcı hale getirin (Ubuntu/Debian)
iptables-save > /etc/iptables/rules.v4
# firewalld kullananlar için
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="185.220.101.45" drop'
firewall-cmd --reload
Burada önemli bir nokta: DROP mu, REJECT mu kullanmalısınız? Ben production ortamlarda her zaman DROP kullanırım. REJECT ile saldırgana “bu port kapalı” mesajı gönderirsiniz, en azından sunucunuzun var olduğunu doğrulamış olursunuz. DROP ile paket sessizce yok olur, saldırgan bağlantı timeout’u bekler ve bu onun için hem zaman kaybı hem de kaynak tüketimi demektir.
Fail2ban: Otomatik Kalkan
Manuel IP engelleme anlık çözüm için işe yarar ama sürdürülebilir değil. Özellikle distributed saldırılarda yüzlerce farklı IP’yi tek tek eklemek mümkün olmaz. İşte burada fail2ban devreye giriyor.
Fail2ban logları izler, belirli bir süre içinde belirlediğiniz başarısız deneme sayısına ulaşan IP’leri otomatik olarak engeller.
# Kurulum
apt install fail2ban -y # Debian/Ubuntu
yum install fail2ban -y # CentOS/RHEL
# Konfigürasyon dosyasını oluşturun (orijinalini değiştirmeyin)
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
jail.local dosyasını düzenleyin. Ben genelde şu değerleri kullanırım:
[DEFAULT]
# 10 dakika içinde 5 başarısız deneme = 24 saat ban
bantime = 86400
findtime = 600
maxretry = 5
# Kendi IP'nizi asla engellemeyin
ignoreip = 127.0.0.1/8 ::1 10.0.0.0/8 192.168.0.0/16
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
maxretry = 3
bantime = 86400
Fail2ban’ı başlatın ve durumunu kontrol edin:
systemctl enable fail2ban
systemctl start fail2ban
# Hangi IP'ler banlandı?
fail2ban-client status sshd
# Belirli bir IP'yi manuel ban kaldır (kendi IP'nizi yanlışlıkla banladıysanız)
fail2ban-client set sshd unbanip 203.0.113.1
# Fail2ban loglarını izleyin
tail -f /var/log/fail2ban.log
Fail2ban’ın bir numaralı avantajı sadece SSH için değil, web sunucusu, FTP, mail servisi gibi pek çok servis için de çalışıyor olması. Nginx, Apache, Postfix için ayrı jail konfigürasyonları yazabilirsiniz.
SSH Yapılandırmasını Güçlendirin
Anlık tehdidi atlattıktan sonra asıl işe bakmanın zamanı. SSH konfigürasyonunuzu gözden geçirin. /etc/ssh/sshd_config dosyasında yapmanız gereken değişiklikler var.
# Önce yedeğini alın
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
# Şu satırları değiştirin veya ekleyin:
# Port 22 --> Port 2222 (veya başka bir port)
# PermitRootLogin yes --> PermitRootLogin no
# MaxAuthTries 6 --> MaxAuthTries 3
# PasswordAuthentication yes --> PasswordAuthentication no
# X11Forwarding yes --> X11Forwarding no
Yapılandırmayı şöyle düzenleyin:
cat >> /etc/ssh/sshd_config << 'EOF'
# Brute force koruma ayarları
MaxAuthTries 3
MaxSessions 5
LoginGraceTime 30
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
X11Forwarding no
AllowAgentForwarding no
EOF
# Konfigürasyonu test edin
sshd -t
# Hata yoksa servisi yeniden başlatın
systemctl restart sshd
Önemli uyarı: PasswordAuthentication no yapmadan önce mutlaka SSH key kurulumunuzu tamamlayın ve test edin. Aksi halde sunucunuzun dışında kalırsınız. Konsol erişiminiz yoksa bu adımı çok dikkatli atın.
Port değiştirmek “security through obscurity” olarak eleştirilir ve haklı da eleştirilir, ancak pratik etkisi inkar edilemez. 22 portunuzu 2222’ye taşıdığınızda otomatik botların %95’ini durduruyor olursunuz çünkü bu botların büyük çoğunluğu sadece 22. portu tarıyor.
SSH Key Tabanlı Kimlik Doğrulama
Parola tabanlı girişi kapatıp key tabanlı kimlik doğrulamaya geçmek, brute force saldırılarına karşı alınabilecek en etkili önlemdir. Saldırgan doğru anahtarı tahmin edemez çünkü milyonlarca yıl uğraşsa bile RSA 4096 bit anahtarı kıramaz.
Eğer henüz key tabanlı auth kullanmıyorsanız hemen kurun:
# Client tarafında (kendi bilgisayarınızda)
ssh-keygen -t ed25519 -C "sunucu-adi-$(date +%Y%m%d)" -f ~/.ssh/sunucu_adi_ed25519
# Public key'i sunucuya kopyalayın
ssh-copy-id -i ~/.ssh/sunucu_adi_ed25519.pub kullanici@sunucu-ip
# Manuel kopyalama (ssh-copy-id yoksa)
cat ~/.ssh/sunucu_adi_ed25519.pub | ssh kullanici@sunucu-ip "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys && chmod 700 ~/.ssh"
Ed25519 algoritmasını kullanmanızı öneririm. RSA’dan daha modern, daha küçük key boyutu ile daha yüksek güvenlik sağlıyor ve performans açısından da daha iyi.
Gerçek Dünya Senaryosu: 2 Saatte 40.000 Deneme
Geçen yıl bir müşterinin sunucusuna baktım, küçük bir e-ticaret sitesi barındırıyorlardı. Monitoring alarmı verdi, baktık: sabahın 3’ünden beri iki saatte 40.000’den fazla başarısız SSH girişi. 847 farklı IP’den geliyordu, klasik botnet saldırısı.
İlk baktığımızda sunucu load average 0.8, normal seyrediyor. Saldırı sistemi çökertmemişti ama auth.log dosyası 2 GB’ı geçmişti ve disk doluyor, bu da asıl tehlikeydi.
Yaptıklarımız sırasıyla şunlardı:
- Fail2ban kurulu değildi, hemen kurduk ve konfigüre ettik
- 847 IP’yi tek tek eklemek yerine coğrafi engelleme uyguladık (Türkiye ve birkaç Avrupa ülkesi dışındaki tüm trafiği kestik)
- Log rotation’ı düzeltik
- SSH portunu değiştirdik
- Root login’i kapattık
- Parola kimlik doğrulamasını kapattık
Coğrafi engelleme kısmında ipset kullandık çünkü iptables’a yüzlerce IP tek tek eklemek hem yönetilmesi zor hem de performans sorunu yaratır:
# ipset kurulumu
apt install ipset -y
# Yeni bir IP seti oluştur
ipset create blacklist hash:ip hashsize 4096
# IP ekle
ipset add blacklist 185.220.101.45
# iptables ile kullan
iptables -A INPUT -m set --match-set blacklist src -j DROP
# Listeyi kaydet
ipset save > /etc/ipset.conf
UFW Kullananlar İçin Hızlı Çözüm
Eğer sunucunuzda UFW varsa hayat biraz daha kolay:
# Hızlı rate limiting (UFW'nin built-in özelliği)
ufw limit ssh
# Bu komut aslında şunu yapar:
# 30 saniye içinde 6'dan fazla bağlantı denemesi yapan IP'yi engeller
# Belirli IP'yi engelle
ufw deny from 185.220.101.45 to any
# Durumu kontrol et
ufw status verbose
UFW’nin limit komutu basit brute force için yeterli olabilir ama gelişmiş saldırılara karşı fail2ban daha iyi seçenek.
Logları İzleme: Saldırı Sürerken Ne Yapmalısınız?
Aktif saldırı sırasında logları canlı takip etmeniz gerekebilir. Bu komutları bilmek işinizi kolaylaştırır:
# Canlı auth log takibi
tail -f /var/log/auth.log | grep "Failed password"
# Şu anki aktif bağlantıları gör
ss -tn | grep :22
# SYN paketlerini say (SYN flood tespiti)
netstat -ant | grep SYN_RECV | wc -l
# Son 5 dakikada kaç başarısız deneme geldi?
awk -v date="$(date --date='5 minutes ago' '+%b %e %H:%M')" '$0 > date' /var/log/auth.log | grep "Failed password" | wc -l
# Başarılı girişler var mı? (Kritik!)
grep "Accepted password|Accepted publickey" /var/log/auth.log | tail -20
Son komut kritik. Saldırı sırasında başarılı giriş olup olmadığını kontrol edin. Eğer başarılı giriş gördüyseniz durum farklı bir seviyeye taşınmış demektir ve incident response prosedürlerinizi başlatmanız gerekir.
Uzun Vadeli Önlemler
Saldırıyı atlattıktan sonra yapmanız gereken daha kapsamlı değişiklikler var. Bunları bir sonraki gün yapayım diye ertelemeyin.
Two-Factor Authentication (2FA): Google Authenticator veya benzeri bir TOTP çözümünü SSH ile entegre edebilirsiniz. PAM modülü ile kurulumu birkaç dakika sürer ve güvenliği dramatik biçimde artırır.
Bastion/Jump Host: Eğer birden fazla sunucunuzu yönetiyorsanız, tüm SSH trafiğini tek bir jump host üzerinden geçirin. Bu jump host’u sıkı şekilde koruyun, diğer sunucuların SSH portlarına internetten doğrudan erişimi tamamen kapatın.
Monitoring ve Alerting: Zaten monitoring varsa iyidir ama özellikle auth log’larını izleyen alertler kurun. Dakikada 10’dan fazla başarısız giriş denemesi anında size SMS veya Telegram mesajı göndersin.
OS Level Hardening: CIS Benchmark’larına göre sunucunuzu sertleştirin. Bu kapsamlı bir konu ama SSH güvenliği açısından en kritik maddeler şunlar:
- Root girişini kapat (PermitRootLogin no)
- Boş parola girişini kapat (PermitEmptyPasswords no)
- Sadece belirli kullanıcılara SSH izni ver (AllowUsers kullanici1 kullanici2)
- SSH protokol versiyonunu kontrol et, sadece SSHv2 kullan
# sshd_config'e eklenecek satırlar
echo "AllowUsers deployuser adminuser" >> /etc/ssh/sshd_config
echo "Protocol 2" >> /etc/ssh/sshd_config
echo "PermitEmptyPasswords no" >> /etc/ssh/sshd_config
# Test et ve uygula
sshd -t && systemctl reload sshd
CloudFlare, AWS Security Group veya Benzeri Hizmetler
Eğer sunucunuz bir cloud ortamında veya CDN arkasındaysa, ağ katmanında bu işleri çok daha kolay yönetebilirsiniz.
AWS kullanıyorsanız Security Group’unuzu sadece bilinen IP adreslerine SSH erişimi verecek şekilde kısıtlayın. Dinamik IP kullanıyorsanız bunun için VPN çözümü düşünebilirsiniz. VPN’e bağlandığınızda sabit bir IP alır ve sadece o IP’ye SSH açarsınız.
Azure NSG veya GCP Firewall Rules ile benzer yaklaşım uygulanabilir. Bu yöntem işletim sistemi seviyesindeki tüm ayarlardan daha önce devreye giriyor ve saldırı paketleri sunucunuza hiç ulaşmıyor, ki bu en temiz çözüm.
Ne Zaman Paniklemeli, Ne Zaman Sakin Olmalısınız?
Şunu net söyleyeyim: eğer sadece başarısız giriş denemeleri görüyorsanız ve başarılı giriş yoksa teknik olarak saldırı henüz başarılı olmamış demektir. Sunucunuz tehdit altında ama ele geçirilmemiş. Sakin olun, sistematik hareket edin.
Ancak şu durumlar gördüğünüzde panik yapmak değil ama acil hareket etmek gerekir:
- Auth loglarında başarılı giriş görüyorsunuz
- Sunucunuzda tanımadığınız yeni kullanıcılar var
- Alışılmadık çalışan process’ler var
- Ağ trafiği normalde bu saatte bu kadar yüksek değil
- /tmp veya /var/tmp altında garip dosyalar var
Bu belirtiler varsa sunucunuz ele geçirilmiş olabilir ve bu tamamen farklı bir senaryo, incident response zamanı.
Sonuç
Brute force saldırısı sysadmin hayatının kaçınılmaz bir parçası. İnternete açık herhangi bir SSH servisi eninde sonunda bu saldırılarla yüz yüze gelir. Önemli olan bu gerçekliği kabul edip hazırlıklı olmak.
Öncelik sıralaması şöyle olmalı: önce fail2ban kur ve konfigüre et, SSH key tabanlı kimlik doğrulamaya geç ve parola girişini kapat, root girişini engelle, SSH portunu değiştirmeyi değerlendir, monitoring kur ki bir dahaki sefere telefon çalmadan önce haberin olsun.
Bu adımları uygulamış bir sunucuya başarılı brute force saldırısı gerçekleştirmek neredeyse imkansız hale gelir. Saldırganlar da bunu bilir ve direnci yüksek sistemleri atlayıp daha kolay hedeflere geçer. Amacınız “hacklenemez” olmak değil, “bu kadar uğraşmaya değmez” olmak.
Ve evet, bir dahaki gece alarmı çaldığında bu kez ne yapacağınızı bileceksiniz.
