fail2ban Engelleme Süresi ve Eşik Değer Ayarları

Sunucunuza her gün yüzlerce, hatta binlerce başarısız giriş denemesi geliyor olabilir. fail2ban bu saldırıları tespit ederek IP adreslerini geçici olarak engelliyor, ama asıl soru şu: ne kadar süreyle engelleyeceksiniz ve kaç denemeden sonra bu engeli devreye sokacaksınız? Bu iki parametre, sisteminizin güvenlik dengesi açısından kritik öneme sahip. Çok kısa engelleme süresi saldırganı durdurmaz, çok uzun süre meşru kullanıcıları bloke eder. Eşik değeri çok düşük ayarlarsanız sizi kilit dışı bırakırsınız, çok yüksek bırakırsanız brute force saldırılarına kapı aralarsınız.

fail2ban’ın Temel Mantığı

fail2ban log dosyalarını izler, belirli bir zaman diliminde belirlediğiniz sayıda başarısız deneme görürse ilgili IP’yi firewall kuralıyla engeller. Bu döngünün içinde üç temel kavram var:

  • findtime: Kaç saniyelik zaman penceresinde başarısız denemeleri sayacağız
  • maxretry: Bu zaman penceresi içinde kaç başarısız denemeye kadar tolerans göstereceğiz
  • bantime: IP engellendiğinde ne kadar süre yasaklı kalacak

Bu üç parametre birlikte çalışır ve birini değiştirdiğinizde diğerlerini de gözden geçirmeniz gerekir. Örneğin findtime değerini çok kısa tutarsanız, saldırgan denemeleri aralıklı yaparak maxretry sınırını hiç aşmadan sisteminizi zorlayabilir.

Yapılandırma Dosyası Hiyerarşisi

fail2ban iki katmanlı bir yapılandırma sistemi kullanır. .conf uzantılı dosyalar varsayılan ayarları içerir ve paket güncellemelerinde üzerine yazılabilir. .local uzantılı dosyalar ise özelleştirmelerinizi barındırır ve güncellemelerden etkilenmez. Bu yüzden her zaman .local dosyaları üzerinde çalışın.

# Ana yapılandırma dosyasını düzenlemek için
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local

Kendi jail tanımlarınız için ayrı dosyalar da oluşturabilirsiniz:

# Özel jail dosyası oluşturma
sudo nano /etc/fail2ban/jail.d/custom-rules.local

Bu yaklaşım daha temiz bir yapı sağlar. Servis başına ayrı dosya tutmak, ileride sorun gidermede işinizi kolaylaştırır.

Global Engelleme Ayarları

jail.local dosyasındaki [DEFAULT] bloğu tüm jail’ler için geçerli olan varsayılan değerleri belirler. Burada yaptığınız ayarlar, jail özelinde ezilmediği sürece geçerli olur.

[DEFAULT]
# Beyaz liste - bu IP'ler hiçbir zaman engellenmez
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24 10.0.0.5

# 10 dakikalık zaman penceresi
findtime = 600

# Bu pencerede 5 başarısız deneme eşik değeri
maxretry = 5

# 1 saatlik engelleme süresi
bantime = 3600

# Backend seçimi - systemd kullanan sistemlerde
backend = systemd

ignoreip parametresine kendi ofis IP adresinizi, VPN ağınızı ve yönetim sistemlerinin IP’lerini mutlaka ekleyin. Kendinizi kilitlemek çok can sıkıcı bir deneyim, bunu bir kez yaşayanlar bir daha unutmuyor.

Servis Bazında Eşik Değerleri

Her servis farklı risk profiline sahiptir. SSH için çok katı kurallar koyarken web uygulaması girişleri için daha esnek davranmak isteyebilirsiniz. Hatta bazı servislerde tek seferlik hatalı denemeyi bile engellemek mantıklı olabilir.

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
# SSH için çok daha sıkı kurallar
findtime = 300
maxretry = 3
bantime = 86400

[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
findtime = 600
maxretry = 10
bantime = 3600

SSH için 24 saatlik ban ve sadece 3 deneme hakkı oldukça makul bir yaklaşım. Gerçek kullanıcılar şifrelerini genellikle ilk ya da ikinci denemede hatırlar. Üç denemeden sonra hâlâ başaramıyorsa büyük ihtimalle ya şifreyi gerçekten unutmuş ya da izniniz olmadan giriş yapmaya çalışıyor demektir.

Artan Ceza Süresi ile Recidivism Kontrolü

fail2ban’ın çok güçlü ama az bilinen bir özelliği: aynı IP tekrar tekrar yakalandığında ceza süresini kademeli olarak artırabilirsiniz. Bu özellik için bantime.increment ve bantime.multiplier parametrelerini kullanıyoruz.

[DEFAULT]
# Artan ceza süresini aktif et
bantime.increment = true

# Her yakalanmada ceza ne kadar artsın (çarpan)
bantime.multiplier = 2

# Maksimum ceza süresi (saniye cinsinden, -1 kalıcı ban)
bantime.maxtime = 604800

# İlk ban süresi (10 dakika)
bantime = 600

# Ban geçmişi ne kadar süre hatırlansın
bantime.overalljails = true

Bu yapılandırmayla bir IP ilk yakalandığında 10 dakika yasaklanır, ikinci seferinde 20 dakika, üçüncüde 40 dakika… 1 haftaya kadar bu artış devam eder. bantime.overalljails = true parametresi ise herhangi bir jail’den yakalanan IP’nin bu geçmişini tüm jail’lerde paylaşmasını sağlar. Yani SSH’dan yakalanan bir IP, web uygulamasına saldırmaya çalıştığında da bu geçmişten etkilenir.

Gerçek Dünya Senaryosu: WordPress Sitesi

Bir müşterinin WordPress sitesini yönetirken /wp-login.php adresine dakikada onlarca deneme geldiğine şahit oldum. Varsayılan ayarlar bu saldırıyı yeterince hızlı kesemiyordu. İşte bu durum için oluşturduğum yapılandırma:

[wordpress-auth]
enabled = true
port = http,https
filter = wordpress-auth
logpath = /var/log/nginx/access.log
findtime = 120
maxretry = 5
bantime = 43200

[wordpress-xml-rpc]
enabled = true
port = http,https
filter = wordpress-xml-rpc
logpath = /var/log/nginx/access.log
# XML-RPC amplification saldırıları için çok sıkı
findtime = 60
maxretry = 2
bantime = 604800

XML-RPC endpointi için sadece 2 deneme ve 1 haftalık ban oldukça agresif görünebilir, ama bu endpoint üzerinden gelen trafiğin meşru kullanıcıdan gelmesi artık çok nadir. Yeni WordPress sitelerde XML-RPC’yi tamamen devre dışı bırakmak daha iyi bir tercih, ama eski entegrasyonları olan sitelerde bu yaklaşım işe yarıyor.

Özel filter dosyasını da oluşturmanız gerekiyor:

sudo nano /etc/fail2ban/filter.d/wordpress-auth.conf
[Definition]
failregex = ^<HOST> .* "POST /wp-login.php
ignoreregex =

Mevcut Ban Durumunu İzleme

Ayarları yaptıktan sonra fail2ban’ın düzgün çalışıp çalışmadığını düzenli olarak kontrol etmek gerekiyor. Sysadmin olarak günlük rutinime aldığım birkaç komut var:

# Tüm jail'lerin genel durumu
sudo fail2ban-client status

# Belirli bir jail'in detaylı durumu
sudo fail2ban-client status sshd

# Kaç IP'nin banlandığını görme
sudo fail2ban-client status sshd | grep "Banned IP"

# Son 100 ban olayını logdan görme
sudo grep "Ban " /var/log/fail2ban.log | tail -100

# Belirli bir IP'nin ban durumunu sorgulama
sudo fail2ban-client get sshd banip 203.0.113.45

fail2ban-client status sshd komutu size şu bilgileri verir: kaç dosya izleniyor, kaç IP şu an yasaklı, toplamda kaç kez ban işlemi yapıldı. Bu rakamları haftalık olarak not edip trend analizi yapıyorum. Anormal artışlar bazen daha büyük bir saldırı kampanyasının habercisi olabiliyor.

Ban Süresini Manuel Yönetme

Bazen bir IP’yi elle yasaklamak ya da yanlışlıkla yasaklanan meşru bir IP’yi kaldırmak gerekiyor. Bu durumlar için:

# Bir IP'yi manuel olarak yasaklama
sudo fail2ban-client set sshd banip 203.0.113.100

# Yasaklı bir IP'yi kaldırma
sudo fail2ban-client set sshd unbanip 203.0.113.100

# Tüm jail'lerdeki tüm banları kaldırma (DİKKATLİ KULLANIN)
sudo fail2ban-client unban --all

# Belirli bir IP'yi tüm jail'lerden kaldırma
for jail in $(fail2ban-client status | grep "Jail list" | sed 's/.*://;s/,//g'); do
    sudo fail2ban-client set $jail unbanip 203.0.113.100 2>/dev/null
done

Bir keresinde müşteri “benim kendi IP’mi yasaklamışsın” diye aradı. VPN bağlantısı üzerinden sisteme girmeye çalışırken yanlış şifre girmiş, ban yemişti. Yukarıdaki for döngüsü bu tür durumlarda çok işe yarıyor, tek komutla tüm jail’lerden temizliyor.

Kalıcı Ban Listesi

Bazı IP’ler için geçici ban yeterli değil. Sürekli gelen, farklı portları deneyen, botnet kaynaklı IP’leri kalıcı olarak engellemek istiyorsanız bantime = -1 kullanabilirsiniz:

[persistent-blocklist]
enabled = true
filter = persistent-blocklist
logpath = /var/log/fail2ban.log
# Zaten fail2ban'dan ban yemiş IP'leri kalıcı engelle
maxretry = 3
bantime = -1
findtime = 86400

Bu jail, fail2ban’ın kendi log dosyasını izler. Yani bir IP başka bir jail tarafından 3 kez banlandıysa artık kalıcı olarak engellenir. Biraz “double jeopardy” gibi ama production ortamında bu yaklaşım gerçekten saldırı trafiğini ciddi ölçüde azaltıyor.

Performans ve Zaman Damgası Sorunları

Yüksek trafikli sunucularda fail2ban bazen log dosyalarını yeterince hızlı işleyemez. Bu durumda findtime ve maxretry kombinasyonunuzu gözden geçirmeniz gerekebilir. Ayrıca sisteminizin saat dilimi ayarlarının doğru olduğundan emin olun, aksi takdirde zaman penceresi hesaplamaları yanlış çalışabilir:

# Sistem saatini kontrol et
timedatectl status

# fail2ban'ın log zaman damgalarını incele
sudo tail -f /var/log/fail2ban.log

# fail2ban servisini log düzeyini debug olarak başlat
sudo fail2ban-client set loglevel DEBUG

# Normal log düzeyine geri dön
sudo fail2ban-client set loglevel INFO

fail2ban’ın işlem süresini test etmek için şunu yapabilirsiniz: bir test ortamında yüksek frekanslı başarısız giriş denemeleri oluşturun ve ban’ın ne kadar sürede devreye girdiğini ölçün. İdeal olarak findtime süresinin çok altında bir tepki süresi beklenir.

Yapılandırma Değişikliklerini Test Etme

Yeni bir eşik değeri veya ban süresi ayarlamadan önce mutlaka test edin. fail2ban’ın regex’lerini ve yapılandırmasını test etmek için:

# Filter regex'ini gerçek log satırı üzerinde test et
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

# Belirli bir log satırını test et
sudo fail2ban-regex "Nov 15 10:23:45 server sshd[1234]: Failed password for root from 203.0.113.50 port 22 ssh2" /etc/fail2ban/filter.d/sshd.conf

# Yapılandırma dosyasını kontrol et (syntax hatası var mı?)
sudo fail2ban-client -t

# Yapılandırmayı yeniden yükle (servisi durdurmadan)
sudo fail2ban-client reload

# Sadece belirli bir jail'i yeniden yükle
sudo fail2ban-client reload sshd

fail2ban-client -t komutu bence en değerli araç. Yapılandırmada syntax hatası varsa servisi yeniden başlatmadan önce söylüyor. Production sunucuda fail2ban’ı yanlış yapılandırmayla yeniden başlatmak ve log’a “Failed to start fail2ban” görmek hiç keyifli bir deneyim değil.

Önerilen Değerler: Servis Tiplerine Göre

Her ortam farklı olsa da yıllar içinde geliştirdiğim başlangıç noktası değerleri:

SSH Servisi:

  • findtime: 300 saniye (5 dakika)
  • maxretry: 3
  • bantime: 86400 saniye (24 saat)
  • Neden: SSH brute force saldırıları genellikle hızlı ve yoğun gelir. 3 deneme meşru kullanıcı için yeterli, düşük tolerans şart.

FTP Servisi:

  • findtime: 600 saniye
  • maxretry: 5
  • bantime: 3600 saniye
  • Neden: FTP kullanan sistemlerde genellikle legacy uygulamalar var, biraz daha toleranslı olmak gerekebilir.

Web Uygulama Girişi:

  • findtime: 600 saniye
  • maxretry: 10
  • bantime: 7200 saniye
  • Neden: Kullanıcılar şifrelerini daha sık unutur, mobil uygulamalar bazen arka planda retry yapar.

Mail Servisi (SMTP/IMAP):

  • findtime: 300 saniye
  • maxretry: 5
  • bantime: 3600 saniye
  • Neden: Mail brute force hem hesap güvenliği hem de spam relay açısından tehlikeli.

API Endpoint:

  • findtime: 60 saniye
  • maxretry: 20
  • bantime: 300 saniye
  • Neden: Meşru API istemcileri hata durumunda retry yapar, kısa ama etkili ban yeterli.

Logrotate ile Entegrasyon

fail2ban’ın log dosyaları izleme mekanizması, logrotate ile çakışabilir. Log döndürüldüğünde fail2ban eski dosya handle’ını tutmaya devam edebilir:

# /etc/logrotate.d/fail2ban dosyasını kontrol et
cat /etc/logrotate.d/fail2ban

# Log döndürme sonrası fail2ban'a bildir
sudo fail2ban-client flushlogs

Logrotate yapılandırmanızda postrotate bloğuna fail2ban-client flushlogs eklemeniz bu sorunu önler. Aksi takdirde findtime hesaplamaları bozulabilir ve hem false positive hem de false negative sonuçlar alabilirsiniz.

Monitoring ve Alerting

fail2ban ban etkinliklerini takip etmek için basit bir script:

#!/bin/bash
# /usr/local/bin/fail2ban-report.sh

THRESHOLD=50
BAN_COUNT=$(grep -c "Ban " /var/log/fail2ban.log)

if [ "$BAN_COUNT" -gt "$THRESHOLD" ]; then
    echo "UYARI: Son dönemde $BAN_COUNT ban işlemi gerçekleşti" | 
    mail -s "fail2ban Yüksek Ban Aktivitesi - $(hostname)" [email protected]
fi

# En çok ban yiyen IP'leri raporla
echo "=== Son 24 Saatin En Aktif Saldırganları ==="
grep "Ban " /var/log/fail2ban.log | 
    grep "$(date +%Y-%m-%d)" | 
    awk '{print $NF}' | 
    sort | uniq -c | sort -rn | head -20

Bu script’i cron’a ekleyerek günlük rapor alabilirsiniz:

# Crontab'a ekle
sudo crontab -e
# Her sabah 08:00'de rapor
0 8 * * * /usr/local/bin/fail2ban-report.sh

Sık Yapılan Hatalar

Yıllar içinde hem kendi hatalarımdan hem de başkalarının sorunlarını çözerken öğrendiğim kritik noktalar:

  • ignoreip’e kendi IP’nizi eklemeyi unutmak: Bu hatayı yapan sysadmin sayısı çok fazla. Özellikle dynamic IP’niz varsa VPN veya jump host IP’nizi beyaz listeye almayı unutmayın.
  • bantime.increment kullanırken bantime.maxtime ayarlamamak: Sonsuz artış teorik olarak mümkün, ama pratikte makul bir maksimum değer koyun.
  • Çok düşük maxretry: Bazı uygulamalar bağlantı kurulurken birden fazla auth denemesi yapabilir. Özellikle LDAP entegrasyonlu sistemlerde maxretry=1 kendinizi kolayca kilitleyebilir.
  • Backend seçimi: systemd kullanan modern sistemlerde backend = systemd tercih edin. auto her zaman en iyi seçimi yapmayabilir.
  • Yapılandırma değişikliklerini reload yerine restart ile uygulamak: reload mevcut ban listesini korur, restart sıfırlar. Genellikle reload istediğiniz şey budur.

Sonuç

fail2ban’ın engelleme süresi ve eşik değerleri, ayarlanıp unutulacak parametreler değil. Sunucunuzun trafik profili değiştikçe, yeni servisler eklendikçe ve saldırı yöntemleri evrimlestikçe bu değerleri gözden geçirmeniz gerekiyor. Ben kendi yönettiğim sistemlerde aylık olarak fail2ban istatistiklerini inceliyor, anormal pattern’ler gördüğümde eşik değerlerini ayarlıyorum.

Başlangıç noktası olarak SSH için sıkı (3 deneme, 24 saat ban), web servisleri için orta (5-10 deneme, 1-2 saat ban) değerleriyle başlayın. bantime.increment özelliğini mutlaka aktif edin, bu tek başına saldırganların büyük çoğunluğunu caydırıyor. Ve en önemlisi: kendi IP adreslerinizi ignoreip‘e eklemeyi asla atlama. Sabah 03:00’de erişim problemi yaşamak ve bunun kendi fail2ban yapılandırmanızdan kaynaklandığını anlamak hiç keyifli değil, bana güvenin.

Yorum yapın