fail2ban Loglarını İzleme ve Engellenen IP Takibi

Sunucunu koruma altına aldın, fail2ban kurulu ve çalışıyor. Peki şimdi ne oluyor? Hangi IP’ler engellendi, hangi servisler saldırı altında, ne zamandan beri bekçin görev yapıyor? Çoğu sysadmin fail2ban’ı kurar, çalıştığını görür ve bir daha bakmaz. Oysa asıl değer, logları düzenli okumak ve engelleme örüntülerini anlamaktan geçiyor. Bu yazıda fail2ban loglarını nasıl izleyeceğini, engellenen IP’leri nasıl takip edeceğini ve bu verilerden anlamlı sonuçlar çıkaracağını ele alacağız.

fail2ban Log Dosyası Nerede ve Ne Anlatır

fail2ban varsayılan olarak loglarını /var/log/fail2ban.log dosyasına yazar. Bazı dağıtımlarda bu journald’ye yönlendirilmiş olabilir, ama klasik kurulumda bu dosya senin ana kaynağın.

tail -f /var/log/fail2ban.log

Bu komutu çalıştırdığında akan satırları okumayı öğrenmek önemli. Tipik bir log satırı şöyle görünür:

2024-01-15 14:23:45,891 fail2ban.filter [12847]: INFO    [sshd] Found 192.168.1.100 - 2024-01-15 14:23:45
2024-01-15 14:23:52,104 fail2ban.filter [12847]: INFO    [sshd] Found 192.168.1.100 - 2024-01-15 14:23:52
2024-01-15 14:24:01,338 fail2ban.actions [12847]: NOTICE  [sshd] Ban 192.168.1.100

Her satırda şunlar var:

  • Tarih ve saat: Olayın tam zamanı
  • Modül adı: filter mi, actions mı, server mı
  • PID: fail2ban process ID’si
  • Seviye: INFO, NOTICE, WARNING, ERROR
  • Jail adı: Hangi kural setinin devreye girdiği (sshd, nginx-http-auth vs.)
  • Eylem: Found (tespit), Ban (engelleme), Unban (engel kaldırma)
  • IP adresi: İşlem yapılan IP

Found satırı her başarısız denemeyi gösterir. Ban satırı artık o IP’nin engelle karşılaştığını söyler. Unban ise banTime süresi dolduğunda otomatik olarak yazdırılır.

fail2ban-client ile Anlık Durum Takibi

Log dosyasına bakmak geçmişe bakmak demek. Anlık durumu görmek için fail2ban-client kullanıyorsun.

# Genel durum - hangi jail'ler aktif
fail2ban-client status

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

fail2ban-client status sshd komutu sana şu bilgileri verir:

  • Filter: Toplam bulgu sayısı, geçerli bulgu sayısı
  • Actions: Toplam ban sayısı, şu an aktif ban sayısı
  • Banned IP list: Şu an engellenmiş IP listesi

Eğer nginx, apache gibi birden fazla jail kullanıyorsan her birini ayrı ayrı kontrol etmek yerine şöyle bir döngü kurabilirsin:

fail2ban-client status | grep "Jail list" | sed 's/.*://;s/,//g' | xargs -n1 fail2ban-client status

Bu komut önce aktif jail listesini alır, virgülleri temizler ve her jail için status komutunu çalıştırır. Sabah kahveni içerken sunucunun genel sağlık durumunu görmek için idealdir.

Engellenen IP’leri Listeleme

Şu an sistemde engellenmiş tüm IP’leri görmek için birkaç yol var. En temizi yine fail2ban-client üzerinden:

# Tüm jail'lerdeki ban'ları toplu görmek için script
for jail in $(fail2ban-client status | grep "Jail list" | sed 's/.*://;s/,//g'); do
    echo "=== $jail ==="
    fail2ban-client status $jail | grep "Banned IP"
done

Ama bazen iptables veya firewalld üzerinden doğrudan bakmak daha hızlı:

# iptables kullanan sistemlerde
iptables -L f2b-sshd -n --line-numbers

# Tüm fail2ban chain'lerini listele
iptables -L -n | grep -A 10 "Chain f2b"
# firewalld kullanan sistemlerde (CentOS/RHEL)
firewall-cmd --direct --get-all-rules | grep fail2ban

ipset kullanan kurulumda ise:

ipset list | grep -i ban

Log Analizi: Kimler Saldırıyor, Neyi Hedef Alıyor

Anlık durumun ötesine geçip tarihsel analiz yapmak istiyorsun. Bunun için log dosyasını işlememiz gerekiyor.

En çok ban yiyen IP’leri bulmak:

grep "Ban " /var/log/fail2ban.log | awk '{print $NF}' | sort | uniq -c | sort -rn | head -20

Bu komut log içindeki tüm Ban satırlarını bulur, son alanı (IP adresi) çıkarır, sayar ve en fazla ban yiyen 20 IP’yi listeler. Bir IP birden fazla kez ban yediyse bu önemli bir sinyal; o IP aralığını kalıcı olarak blocklist’e almanın zamanı gelmiş olabilir.

Hangi servis en çok saldırı alıyor:

grep "Ban " /var/log/fail2ban.log | awk '{print $6}' | sort | uniq -c | sort -rn

Çıktı şöyle görünür:

     847 [sshd]
     312 [nginx-http-auth]
      89 [wordpress]
      23 [postfix]

Bu sana “nereye odaklanacağını” söyler. SSH 847 ban ile açık arayla önde geliyorsa ve sen gerçekten SSH’ı dışarıya açık bırakıyorsan, port değiştirmeyi veya sadece belirli IP’lerden erişime izin vermeyi düşünme vaktidir.

Zaman bazlı analiz – hangi saatlerde saldırı yoğun:

grep "Ban " /var/log/fail2ban.log | awk '{print $2}' | cut -d: -f1 | sort | uniq -c | sort -rn

Gece 03:00-05:00 arasında yoğunlaşma görüyorsan bu otomatik botların favori saatlerini gösterir. Sabah 09:00-11:00 arasında yoğunlaşma varsa insan kontrolündeki saldırı olabilir ya da farklı timezone’dan bir aktör söz konusudur.

Gerçek Dünya Senaryosu: WordPress Sitesinde Şüpheli Aktivite

Diyelim ki bir müşterinin WordPress sitesini yönetiyorsun ve fail2ban ile wp-login.php’yi koruyorsun. Sabah kontrol ettiğinde şüpheli bir durum fark ediyorsun. İşte tam o an ne yapacağını adım adım görelim.

# Önce bugünkü ban sayısını kontrol et
grep "$(date +%Y-%m-%d)" /var/log/fail2ban.log | grep "Ban" | wc -l

Diyelim 234 çıktı. Bu dün 12’ydi. Bir şeyler oluyor demek ki.

# Hangi IP'ler ban yemiş bugün
grep "$(date +%Y-%m-%d)" /var/log/fail2ban.log | grep "Ban" | awk '{print $NF}' | sort | uniq -c | sort -rn | head -10

Çıktıda 5-6 farklı IP görüyorsun ama hepsi aynı /24 subnet’ten. Bu distributed brute force ataması işareti.

# O subnet'ten gelen tüm aktiviteyi görmek için
grep "185.220.101" /var/log/fail2ban.log | tail -50

Şimdi eğer bu IP aralığı gerçekten saldırgan ve müşterinin hiçbir kullanıcısı o lokasyondan değilse, o subnet’i kalıcı olarak engellemeyi düşünebilirsin.

# Manuel olarak bir IP veya range'i hemen ban'la
fail2ban-client set wordpress banip 185.220.101.0/24

Otomatik Raporlama: Günlük Ban Özeti Script’i

Her sabah fail2ban durumunu kontrol etmek yerine, özeti mail olarak almanı sağlayan bir script yazalım.

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

LOG="/var/log/fail2ban.log"
DATE=$(date +%Y-%m-%d)
YESTERDAY=$(date -d "yesterday" +%Y-%m-%d)
REPORT_FILE="/tmp/fail2ban-report-$DATE.txt"

echo "=== fail2ban Gunluk Raporu: $DATE ===" > $REPORT_FILE
echo "" >> $REPORT_FILE

# Dünkü toplam ban sayısı
TOTAL_BANS=$(grep "$YESTERDAY" $LOG | grep -c "Ban ")
echo "Dun toplam ban sayisi: $TOTAL_BANS" >> $REPORT_FILE
echo "" >> $REPORT_FILE

# Jail bazinda ban dagilimy
echo "--- Jail Bazinda Dagılım ---" >> $REPORT_FILE
grep "$YESTERDAY" $LOG | grep "Ban " | awk '{print $6}' | sort | uniq -c | sort -rn >> $REPORT_FILE
echo "" >> $REPORT_FILE

# En çok ban yiyen IP'ler
echo "--- En Çok Ban Yiyen IP'ler (Top 10) ---" >> $REPORT_FILE
grep "$YESTERDAY" $LOG | grep "Ban " | awk '{print $NF}' | sort | uniq -c | sort -rn | head -10 >> $REPORT_FILE
echo "" >> $REPORT_FILE

# Şu an aktif ban'lar
echo "--- Şu An Aktif Banlar ---" >> $REPORT_FILE
for jail in $(fail2ban-client status | grep "Jail list" | sed 's/.*://;s/,//g'); do
    BANNED=$(fail2ban-client status $jail | grep "Banned IP" | sed 's/.*://')
    if [ -n "$BANNED" ]; then
        echo "$jail: $BANNED" >> $REPORT_FILE
    fi
done

# Raporu mail ile gönder
cat $REPORT_FILE | mail -s "fail2ban Gunluk Raporu - $DATE" [email protected]

echo "Rapor gönderildi: $REPORT_FILE"

Bu script’i cron’a ekle:

# Her sabah 07:00'de çalışsın
echo "0 7 * * * root /usr/local/bin/fail2ban-daily-report.sh" >> /etc/cron.d/fail2ban-report

fail2ban Log Rotasyonu ve Arşivleme

Log dosyası zamanla büyüdükçe analiz zorlaşır. logrotate bu iş için var ve fail2ban genellikle kurulumla birlikte bir logrotate config’i getiriyor. Kontrol edelim:

cat /etc/logrotate.d/fail2ban

Eğer dosya yoksa veya konfigürasyonu beğenmediysen kendin yaz:

/var/log/fail2ban.log {
    daily
    rotate 30
    compress
    delaycompress
    missingok
    notifempty
    postrotate
        fail2ban-client flushlogs 1>/dev/null
    endscript
}

Bu ayar ile:

  • daily: Her gün döndür
  • rotate 30: 30 günlük arşiv tut
  • compress: Eski logları gzip ile sıkıştır
  • postrotate: Rotasyondan sonra fail2ban’a yeni dosyaya yazmaya başlamasını söyle

30 günlük log tutmak analiz için yeterli. Daha uzun süre tutmak istiyorsan rotate sayısını artır, ama disk kullanımını takip et.

Engellenen IP Hakkında Bilgi Toplama

Bir IP’yi engelliyorsun güzel. Ama kim bu IP, hangi ülkeden geliyor, gerçekten kötü niyetli mi? Bunu anlamak özellikle false positive’leri önlemek için önemli.

# Temel whois sorgusu
whois 185.220.101.47

# IP'nin ülkesini hızlıca öğren
curl -s "https://ipapi.co/185.220.101.47/json/" | python3 -m json.tool

# geoiplookup kuruluysa
geoiplookup 185.220.101.47

# Reverse DNS
dig -x 185.220.101.47

Karşında Tor exit node mu var, bilinen bir hosting provider mı, yoksa normal bir ISP müşterisi mi? Bu soruların cevapları aksiyonunu belirler. Bir Tor exit node’u kalıcı olarak blocklamak mantıklı olabilir. Bir ISP müşterisi ise belki enfekte bir makine kullanıyor ve bunu ISP’ye bildirmek daha doğru.

Yanlış Engelleme (False Positive) Tespiti ve Çözümü

Bir müşteri arıyor: “Siteye giremiyorum, bir şeyler var.” Sen hemen kontrol ediyorsun ve IP’nin fail2ban tarafından banlandığını görüyorsun. Nasıl çözüyorsun?

# Önce hangi jail'de ban yemiş bul
for jail in $(fail2ban-client status | grep "Jail list" | sed 's/.*://;s/,//g'); do
    fail2ban-client status $jail | grep "Banned IP" | grep -q "MUSTERI_IP" && echo "Ban yeri: $jail"
done

# Ban'ı kaldır
fail2ban-client set sshd unbanip MUSTERI_IP

# Ban'ın kaldırıldığını doğrula
fail2ban-client status sshd | grep "Banned IP"

Sadece ban kaldırmak yetmez, neden ban yediğini de anlamalısın. O IP’nin log geçmişine bak:

grep "MUSTERI_IP" /var/log/fail2ban.log | tail -20
grep "MUSTERI_IP" /var/log/auth.log | tail -20

Eğer müşteri VPN kullanıyorsa veya şifresiyle ciddi mücadele ediyorsa, o IP’yi kalıcı olarak whitelist’e al:

# /etc/fail2ban/jail.local dosyasına ekle
# ignoreip satırını bul ve müşteri IP'sini ekle
ignoreip = 127.0.0.1/8 ::1 MUSTERI_IP
# Değişikliği uygula
systemctl reload fail2ban

fail2ban ile Entegre İzleme: Zabbix veya Grafana

Prod ortamda log dosyası okumak yetmez, görsel bir dashboard isteyebilirsin. Basit bir çözüm olarak fail2ban metriklerini bir monitoring sistemine besleyebilirsin.

Zabbix için basit bir external check script’i:

#!/bin/bash
# /etc/zabbix/scripts/fail2ban-stats.sh
# Kullanim: fail2ban-stats.sh [total_bans|active_bans|jail_count]

JAIL=${2:-sshd}

case "$1" in
    total_bans)
        grep "Ban " /var/log/fail2ban.log | wc -l
        ;;
    active_bans)
        total=0
        for jail in $(fail2ban-client status | grep "Jail list" | sed 's/.*://;s/,//g'); do
            count=$(fail2ban-client status $jail | grep "Currently banned" | awk '{print $NF}')
            total=$((total + count))
        done
        echo $total
        ;;
    jail_count)
        fail2ban-client status | grep "Number of jail" | awk '{print $NF}'
        ;;
    jail_bans)
        fail2ban-client status $JAIL | grep "Currently banned" | awk '{print $NF}'
        ;;
esac

Promtheus ve Grafana kullanıyorsan fail2ban-exporter adında hazır bir tool var, onu kurarak fail2ban metriklerini Prometheus formatında expose edebilirsin.

Log Takibinde İşe Yarayan Alias’lar

Her seferinde uzun komutlar yazmak yorucu. .bashrc veya .bash_aliases dosyasına şunları ekle:

# fail2ban hızlı kontrol alias'ları
alias f2b-status='fail2ban-client status'
alias f2b-banned='for j in $(fail2ban-client status | grep "Jail list" | sed "s/.*://;s/,//g"); do echo "=== $j ==="; fail2ban-client status $j | grep "Banned IP"; done'
alias f2b-log='tail -f /var/log/fail2ban.log'
alias f2b-today='grep "$(date +%Y-%m-%d)" /var/log/fail2ban.log | grep "Ban " | awk "{print $NF}" | sort | uniq -c | sort -rn'
alias f2b-top='grep "Ban " /var/log/fail2ban.log | awk "{print $NF}" | sort | uniq -c | sort -rn | head -20'

Artık f2b-today yazınca bugün ban yiyen IP’lerin listesini anında görüyorsun. f2b-top ile de tüm zamanların en çok ban yiyen IP’lerine bakıyorsun.

Kritik Durumlar İçin Anlık Uyarı

Bazı durumlar mail raporu bekleyemez. Örneğin bir anda 50+ farklı IP aynı anda saldırıyorsa (distributed attack), bunu anlık bilmek isteyebilirsin.

#!/bin/bash
# /usr/local/bin/fail2ban-alert.sh
# Bu script her 5 dakikada bir cron ile çalışır

THRESHOLD=10
PERIOD=5  # dakika
ALERT_MAIL="[email protected]"

# Son 5 dakikadaki ban sayısını hesapla
RECENT_BANS=$(grep "$(date +%Y-%m-%d) $(date -d "-$PERIOD minutes" +%H:%M)" /var/log/fail2ban.log 2>/dev/null | grep -c "Ban " || 
    awk -v start="$(date -d "-$PERIOD minutes" +"%Y-%m-%d %H:%M")" '$0 >= start' /var/log/fail2ban.log | grep -c "Ban ")

if [ "$RECENT_BANS" -ge "$THRESHOLD" ]; then
    echo "SON $PERIOD DAKIKADA $RECENT_BANS BAN TESPIT EDILDI!" | 
    mail -s "ACIL: fail2ban Yuksek Ban Sayisi - $(hostname)" $ALERT_MAIL
fi
# Her 5 dakikada çalıştır
echo "*/5 * * * * root /usr/local/bin/fail2ban-alert.sh" >> /etc/cron.d/fail2ban-alert

Sonuç

fail2ban kurmak yolun sadece yarısı. Asıl değer, o sistemin ne söylediğini düzenli olarak dinlemekten geliyor. Günlük rapor script’i, anlık uyarı mekanizması ve periyodik log analizi birlikte çalışıldığında hem saldırı örüntülerini erken fark eder hem de false positive’lere hızlı müdahale edersin.

Pratik olarak şunları rutin haline getirmeni öneririm: Her sabah fail2ban-client status ile genel duruma bak, haftada bir f2b-top ile en saldırgan IP aralıklarını incele ve o aralıkları kalıcı blocklist’e almayı değerlendir, ayda bir de log rotasyonunun ve arşivlemenin sağlıklı çalıştığını kontrol et.

Saldırılar durmuyor, botlar uyumuyor. Ama iyi takip edilmiş bir fail2ban kurulumu, senin adına sessiz sedasız güvenlik nöbeti tutar. Asıl işin onu çalışır halde tutmak ve zaman zaman ne anlatmaya çalıştığını anlamak için dinlemek.

Yorum yapın