fail2ban ile SSH Brute Force Saldırılarına Karşı Koruma
Sunucunuza her gün binlerce SSH brute force denemesi geldiğini biliyor musunuz? Bunu ilk kez gördüğünüzde “bu kadar mı aktif saldırılar?” diye şaşırıyorsunuz. Auth log dosyasını açıp grep "Failed password" /var/log/auth.log | wc -l komutunu çalıştırdığınızda karşınıza çıkan rakam sizi ciddi şekilde düşündürüyor. İşte bu noktada fail2ban devreye giriyor ve bu kaotik trafiği otomatik olarak yönetiyor. Bu yazıda fail2ban’ı sıfırdan kurup yapılandıracağız, gerçek dünya senaryolarına göre özelleştireceğiz ve production ortamında güvenle kullanabileceğiniz bir kurulum ortaya çıkaracağız.
fail2ban Nedir ve Nasıl Çalışır
fail2ban, log dosyalarını izleyen ve belirli bir eşiği aşan başarısız giriş denemelerini tespit edince ilgili IP adresini otomatik olarak yasaklayan bir güvenlik aracıdır. Python ile yazılmış olan bu araç, sistem loglarını gerçek zamanlı olarak parse eder ve tanımladığınız kurallara göre firewall üzerinde geçici ya da kalıcı yasaklar oluşturur.
Çalışma mantığı şu şekilde:
- Filter: Log dosyasında hangi pattern’lerin aranacağını tanımlar (regex ile)
- Jail: Hangi servisi, hangi log dosyasını, kaç başarısız denemeden sonra ban uygulanacağını belirtir
- Action: Ban uygulandığında ne yapılacağını belirler (iptables kuralı ekle, mail gönder vb.)
fail2ban varsayılan olarak iptables veya nftables ile çalışır. Bir IP belirli sayıda başarısız deneme yaptığında, fail2ban otomatik olarak o IP’yi firewall düzeyinde engeller. Ban süresi dolunca kural kaldırılır ve IP tekrar bağlantı kurabilir hale gelir.
Kurulum
Debian/Ubuntu Üzerinde Kurulum
sudo apt update
sudo apt install fail2ban -y
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
RHEL/CentOS/AlmaLinux Üzerinde Kurulum
EPEL repository’nin aktif olması gerekiyor:
sudo dnf install epel-release -y
sudo dnf install fail2ban -y
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
Kurulumu Doğrulama
sudo systemctl status fail2ban
sudo fail2ban-client status
Bu komutların çıktısında Active: active (running) görüyorsanız servis ayakta demektir.
Yapılandırma Dosyaları ve Dizin Yapısı
fail2ban’ın yapılandırma dosyaları /etc/fail2ban/ altında bulunur. Burada bilmeniz gereken kritik bir kural var: /etc/fail2ban/jail.conf dosyasını doğrudan düzenlemeyin. Bu dosya paket güncellemelerinde üzerine yazılır ve tüm özelleştirmelerinizi kaybedersiniz.
Doğru yaklaşım şu:
/etc/fail2ban/jail.conf: Varsayılan ayarlar, dokunmuyoruz/etc/fail2ban/jail.local: Bizim özelleştirmelerimiz buraya gidiyor/etc/fail2ban/filter.d/: Filtre tanımları/etc/fail2ban/action.d/: Aksiyon tanımları
jail.local dosyası yoksa oluşturuyoruz:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Ya da sıfırdan oluşturmayı tercih edebilirsiniz, bu daha temiz bir yaklaşım:
sudo nano /etc/fail2ban/jail.local
Temel jail.local Yapılandırması
Şimdi SSH brute force koruması için temel bir yapılandırma oluşturalım. Aşağıdaki içeriği jail.local dosyasına yazıyoruz:
[DEFAULT]
# Varsayilan ban suresi: 1 saat
bantime = 3600
# Bu süre icinde...
findtime = 600
# ...bu kadar basarisiz deneme olursa ban uygula
maxretry = 5
# Beyaz liste - kendi IP'nizi buraya ekleyin!
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24
# Backend secimi - systemd kullanan sistemler icin
backend = systemd
# Ban aksiyonu
banaction = iptables-multiport
banaction_allports = iptables-allports
# E-posta bildirimleri (opsiyonel)
destemail = [email protected]
sendername = Fail2Ban
mta = sendmail
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
maxretry = 3
bantime = 7200
findtime = 300
Bu yapılandırmada dikkat etmeniz gereken birkaç nokta var:
- bantime: Saniye cinsinden ban süresi. 3600 = 1 saat. -1 değeri kalıcı ban anlamına gelir.
- findtime: Bu süre içindeki başarısız denemelere bakılır. 600 = 10 dakika.
- maxretry: Ban uygulanmadan önce kaç başarısız denemeye izin verilir.
- ignoreip: Bu IP’ler asla banlanmaz. Kendi IP adresinizi buraya mutlaka ekleyin, yoksa kendinizi kilitleyebilirsiniz.
Yapılandırmayı uygulamak için servisi yeniden başlatıyoruz:
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd
SSH Portu Değiştirilmişse Ne Yapmalı
Birçok sysadmin güvenlik amacıyla SSH portunu 22’den farklı bir porta taşır. fail2ban’a bu durumu bildirmemiz gerekiyor:
[sshd]
enabled = true
port = 2222
logpath = %(sshd_log)s
maxretry = 3
bantime = 86400
Eğer hem 22 hem de başka bir portu dinliyorsanız:
[sshd]
enabled = true
port = 22,2222
logpath = %(sshd_log)s
maxretry = 3
Agresif Ban Stratejisi: Tekrarlayan Saldırganlar İçin
Production ortamında bazen şunu görürsünüz: Aynı IP ban süresi dolunca tekrar saldırmaya başlıyor. Bu durumda tekrarlayan saldırganlar için artan ban süreleri (progressive banning) uygulamak mantıklı. fail2ban’ın recidive jail’i tam bu iş için var:
[recidive]
enabled = true
logpath = /var/log/fail2ban.log
banaction = %(banaction_allports)s
bantime = 604800 ; 1 hafta
findtime = 86400 ; 1 gun icinde
maxretry = 5 ; 5 kez banlanirsa
Bu yapılandırma şunu söylüyor: Bir IP 24 saat içinde 5 kez fail2ban tarafından banlanmışsa, bu sefer 1 hafta boyunca tüm portlardan engellenir. Çok etkili bir yöntem.
Özel Filtre Oluşturma
fail2ban’ın built-in SSH filtresi çoğu durumda yeterli olsa da bazen özelleştirme gerekiyor. Örneğin bazı saldırılar farklı log mesajları bırakıyor. Önce mevcut SSH filtresine bakalım:
cat /etc/fail2ban/filter.d/sshd.conf
Özel bir filtre oluşturmak için /etc/fail2ban/filter.d/ altına yeni bir dosya koyuyoruz. Örneğin port knocking dışı bağlantıları yakalamak için:
sudo nano /etc/fail2ban/filter.d/sshd-custom.conf
[Definition]
failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failure|error|failed) for .* from <HOST>( via S+)?s*$
^%(__prefix_line)s(?:error: )?Received disconnect from <HOST> port S+:s*S+: .*: Auth fail$
^%(__prefix_line)sFailed S+ for (?:invalid user )?(?P<user>S+) from <HOST>(?: port d+)?(?: sshd*)?s*$
^%(__prefix_line)sROOT LOGIN REFUSED.* FROM <HOST>s*$
^%(__prefix_line)s[iI](?:llegal|nvalid) user .* from <HOST>s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because not listed in AllowUserss*$
^%(__prefix_line)sconnection closed by <HOST>.*[preauth]s*$
ignoreregex =
Filtrenizi test etmek için fail2ban-regex aracını kullanın:
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd-custom.conf
Bu komutun çıktısında kaç satırın eşleştiğini göreceksiniz. Lines: X matched kısmı ne kadar iyi çalıştığını gösterir.
Gerçek Dünya Senaryosu: Çoklu Servis Koruması
SSH ile sınırlı kalmayalım. Gerçek bir production sunucusunda genellikle birden fazla servis çalışıyor. İşte kapsamlı bir jail.local örneği:
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5
ignoreip = 127.0.0.1/8 ::1 10.0.0.0/8 192.168.0.0/16
backend = auto
[sshd]
enabled = true
port = ssh
maxretry = 3
bantime = 86400
findtime = 300
[sshd-ddos]
enabled = true
port = ssh
filter = sshd-ddos
logpath = %(sshd_log)s
maxretry = 10
bantime = 3600
[nginx-http-auth]
enabled = true
filter = nginx-http-auth
port = http,https
logpath = /var/log/nginx/error.log
[nginx-badbots]
enabled = true
port = http,https
filter = nginx-badbots
logpath = /var/log/nginx/access.log
maxretry = 2
bantime = 86400
[postfix]
enabled = true
port = smtp,465,submission
filter = postfix
logpath = /var/log/mail.log
[dovecot]
enabled = true
port = pop3,pop3s,imap,imaps,submission,465,sieve
filter = dovecot
logpath = /var/log/mail.log
maxretry = 5
Bu yapılandırma SSH, Nginx ve mail servislerini aynı anda koruyor.
fail2ban Yönetimi: Günlük Kullanım Komutları
Kurulum yaptıktan sonra sistemi yönetmek için kullanacağınız temel komutları bilmek önemli.
Genel Durum Kontrolü
# Tüm aktif jail'leri göster
sudo fail2ban-client status
# Belirli bir jail'in detaylarini gör
sudo fail2ban-client status sshd
# Banlanan IP sayisi ve listesi
sudo fail2ban-client status sshd | grep "Banned IP"
IP Ban ve Unban İşlemleri
# Manuel olarak bir IP'yi banla
sudo fail2ban-client set sshd banip 1.2.3.4
# Banlanan bir IP'yi serbest birak
sudo fail2ban-client set sshd unbanip 1.2.3.4
# Tüm banları temizle (dikkatli kullan!)
sudo fail2ban-client set sshd unbanip $(sudo fail2ban-client status sshd | grep "Banned IP list" | sed 's/.*Banned IP list:s*//' | tr ' ' 'n')
Kendinizi kilitlediniz ve SSH bağlantısı kuramıyorsunuz? Sunucunun konsoluna veya out-of-band erişiminize gidin ve şu komutu çalıştırın:
sudo fail2ban-client set sshd unbanip KENDI_IP_ADRESINIZ
Log Takibi
# fail2ban loglarini canli izle
sudo tail -f /var/log/fail2ban.log
# Son banlanan IP'leri gör
sudo grep "Ban " /var/log/fail2ban.log | tail -20
# Belirli bir IP'nin gecmisini ara
sudo grep "1.2.3.4" /var/log/fail2ban.log
Kalıcı Ban Listesi: Database ile Çalışmak
fail2ban, ban bilgilerini SQLite veritabanında tutar. Servis yeniden başlatılsa bile banlar kaybolmaz (varsayılan olarak bu özellik aktif). Veritabanı konumunu kontrol edelim:
grep "dbfile" /etc/fail2ban/jail.conf
# Genellikle: /var/lib/fail2ban/fail2ban.sqlite3
Veritabanını sorgulamak için:
sudo sqlite3 /var/lib/fail2ban/fail2ban.sqlite3 "SELECT ip, timeofban, bantime, jail FROM bans ORDER BY timeofban DESC LIMIT 20;"
Bu komut size son 20 ban kaydını gösterir. Hangi IP’lerin ne zaman banlandığını ve hangi jail tarafından yakalandığını görmek için çok kullanışlı.
Performans Optimizasyonu
Yüksek trafikli sunucularda fail2ban’ın log parsing işlemi CPU kullanımına yol açabilir. Birkaç optimizasyon önerisi:
Backend seçimi önemli. Systemd journal kullanan modern sistemlerde backend = systemd seçeneği daha verimli çalışır çünkü log dosyasını polling yerine journal API üzerinden okur:
[DEFAULT]
backend = systemd
dbpurgeage ayarı: Eski ban kayıtlarını veritabanından temizler:
[DEFAULT]
dbpurgeage = 86400 ; 1 günden eski kayitlari temizle
Çok sayıda jail kullanıyorsanız her birinin ayrı log dosyasını izlediğinden emin olun. Aynı log dosyasını birden fazla jail izliyorsa, konsolidasyon düşünün.
nftables ile Kullanım
Debian 11+ ve RHEL 9+ gibi modern dağıtımlarda iptables’ın yerini nftables almaya başladı. fail2ban’ı nftables ile çalıştırmak için:
[DEFAULT]
banaction = nftables-multiport
banaction_allports = nftables-allports
nftables aksiyonlarının yüklü olduğundan emin olun:
ls /etc/fail2ban/action.d/ | grep nft
Eğer nftables aksiyon dosyaları yoksa, dağıtımınızın güncel fail2ban sürümünü kullandığınızdan emin olun.
Monitoring ve Alerting
Production ortamında fail2ban’ı izlemek için basit bir bash script yazalım. Bu script belirli eşikleri aşınca uyarı verecek:
#!/bin/bash
# /usr/local/bin/fail2ban-monitor.sh
THRESHOLD=100
JAIL="sshd"
ALERT_EMAIL="[email protected]"
LOG_FILE="/var/log/fail2ban-monitor.log"
BANNED_COUNT=$(fail2ban-client status $JAIL | grep "Currently banned" | awk '{print $NF}')
echo "$(date): $JAIL jail'inde $BANNED_COUNT IP banlandi" >> $LOG_FILE
if [ "$BANNED_COUNT" -gt "$THRESHOLD" ]; then
echo "UYARI: $JAIL jail'inde $BANNED_COUNT IP banlandi! Olasi DDoS saldirisi." |
mail -s "fail2ban UYARI: Yuksek Ban Sayisi" $ALERT_EMAIL
fi
Bu scripti cron’a ekleyelim:
sudo chmod +x /usr/local/bin/fail2ban-monitor.sh
echo "*/15 * * * * root /usr/local/bin/fail2ban-monitor.sh" | sudo tee -a /etc/cron.d/fail2ban-monitor
Her 15 dakikada bir çalışacak ve ban sayısı 100’ü aşarsa mail atacak.
Yaygın Sorunlar ve Çözümleri
Sorun: fail2ban başlamıyor
sudo journalctl -u fail2ban -n 50
Genellikle nedeni hatalı bir regex veya eksik log dosyasıdır. jail.local içindeki logpath değerlerini kontrol edin.
Sorun: IP’ler banlanmıyor
fail2ban-regex aracıyla filtrenizin log dosyasındaki satırları yakalayıp yakalamadığını test edin:
sudo fail2ban-regex /var/log/auth.log sshd
Sorun: Kendinizi kilitlediniz
Sunucu konsolundan veya VNC/IPMI üzerinden girin:
sudo iptables -L INPUT -n | grep BAN
sudo fail2ban-client set sshd unbanip IPADRESI
Sorun: Banlanan IP hâlâ bağlanabiliyor
iptables kurallarını kontrol edin:
sudo iptables -L f2b-sshd -n -v
Eğer f2b chain’inde kural yoksa, banaction’ın doğru çalışmadığı anlamına gelir. banaction değerini kontrol edin.
SELinux ile fail2ban
RHEL tabanlı sistemlerde SELinux aktifse fail2ban bazen log dosyalarına erişemeyebilir. Kontrol etmek için:
sudo ausearch -m avc -ts recent | grep fail2ban
Eğer SELinux denial’ları görüyorsanız:
sudo setsebool -P fail2ban_enable_logs 1
# veya
sudo semanage fcontext -a -t fail2ban_log_t "/var/log/fail2ban.log"
sudo restorecon -v /var/log/fail2ban.log
Sonuç
fail2ban, SSH brute force saldırılarına karşı en pratik ve etkili araçlardan biri. Kurulumu basit, yapılandırması esnek ve production ortamında güvenilir bir şekilde çalışıyor. Birkaç kritik noktayı tekrar vurgulayalım:
jail.confdosyasını asla doğrudan düzenlemeyin, her zamanjail.localkullanınignoreipsatırına kendi IP adresinizi ekleyin, aksi halde kendinizi kilitleyebilirsinizrecidivejail’ini aktifleştirin, tekrarlayan saldırganlar için çok etkili- Filtreleri
fail2ban-regexile test edin - fail2ban loglarını düzenli olarak takip edin
fail2ban tek başına yeterli bir güvenlik çözümü değil elbette. SSH key authentication’a geçmek, port numarasını değiştirmek ve AllowUsers direktifini kullanmak gibi temel sertleştirme adımlarıyla birlikte kullanıldığında gerçek bir koruma katmanı oluşturuyor. Güvenlik katmanlı olmalı, tek bir araca güvenmek doğru bir yaklaşım değil.
Sorularınızı yorumlara yazabilirsiniz, elimden geldiğince cevaplamaya çalışırım.
