Sunucunuza her gece yüzlerce brute force denemesi geliyorsa ve siz bunlardan haberdar bile değilseniz, bir şeyleri eksik yapıyorsunuz demektir. fail2ban zaten bu saldırıları engelliyor olabilir, ama sessizce çalışan bir güvenlik aracı, yöneticiye hiçbir şey söylemez. İşte bu noktada e-posta bildirimleri devreye giriyor: birisi ban yediğinde, bir jail aktive olduğunda ya da ciddi bir saldırı gerçekleştiğinde anında haberdar olmak, reaktif değil proaktif bir güvenlik yaklaşımı benimsemenizi sağlar.
fail2ban’ın Bildirim Mimarisi
fail2ban, aksiyonlar (actions) sistemi üzerine kurulmuştur. Bir IP adresi belirli bir eşiği aştığında, fail2ban önce iptables veya firewalld üzerinden ban işlemini uygular, ardından tanımlı aksiyonları sırayla çalıştırır. E-posta bildirimi de bu aksiyon mekanizmasının bir parçasıdır.
fail2ban kurulumunda hazır gelen birkaç e-posta aksiyonu vardır:
- action_mw: Ban işlemi sırasında whois bilgisiyle birlikte e-posta gönderir
- action_mwl: Whois bilgisine ek olarak ilgili log satırlarını da ekler
- action: Sadece ban/unban işlemi yapar, e-posta göndermez
- sendmail-whois: Sendmail kullanarak whois bilgisiyle e-posta gönderir
- sendmail-whois-lines: Sendmail ile whois ve log satırları içeren detaylı e-posta
Bu aksiyonların dosyaları /etc/fail2ban/action.d/ dizininde bulunur. Hangi mail transfer agent (MTA) kullandığınıza göre doğru aksiyonu seçmeniz gerekir.
Ön Koşullar: MTA Kurulumu
fail2ban, e-posta göndermek için sistemde bir MTA’ya ihtiyaç duyar. En yaygın iki seçenek postfix ve sendmail’dir. Üretim sunucularında genellikle postfix tercih edilir çünkü daha modern ve yapılandırması daha kolaydır.
Postfix Kurulumu (Önerilen)
# Debian/Ubuntu
apt update && apt install -y postfix mailutils
# RHEL/CentOS/Rocky Linux
dnf install -y postfix mailx
# Postfix'i başlat
systemctl enable postfix
systemctl start postfix
Kurulum sırasında “Internet Site” seçeneğini seçin ve sistem hostname’inizi girin. Eğer sunucunuz harici bir SMTP relay kullanacaksa (Gmail, SendGrid, vb.), /etc/postfix/main.cf dosyasına relayhost tanımlaması eklenmelidir.
Basit bir relay konfigürasyonu için:
# /etc/postfix/main.cf dosyasına eklenecekler
cat >> /etc/postfix/main.cf << 'EOF'
relayhost = [smtp.gmail.com]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_tls_starttls_enforce = yes
smtp_tls_security_level = encrypt
EOF
SMTP kimlik bilgileri için:
# SMTP şifre dosyasını oluştur
echo "[smtp.gmail.com]:587 [email protected]:uygulama-sifresi" > /etc/postfix/sasl_passwd
# Güvenli izinler ayarla
chmod 600 /etc/postfix/sasl_passwd
postmap /etc/postfix/sasl_passwd
# Postfix'i yeniden yükle
systemctl reload postfix
Önemli Not: Gmail için normal şifre değil, Google hesabınızda 2FA aktifken oluşturduğunuz “Uygulama Şifresi” kullanmanız gerekir.
MTA’yı Test Etme
fail2ban konfigürasyonuna geçmeden önce e-posta gönderiminin çalıştığını doğrulayın:
# Test e-postası gönder
echo "fail2ban test mesaji - $(date)" | mail -s "Test: MTA Calisiyor" [email protected]
# Mail loglarını kontrol et
tail -f /var/log/mail.log
# veya
journalctl -u postfix -f
Eğer e-posta birkaç dakika içinde ulaşmıyorsa, mail kuyruğunu kontrol edin:
mailq
# Kuyrukta bekleyen mesajlar varsa zorla göndermeyi dene
postqueue -f
fail2ban E-posta Konfigürasyonu
jail.local Dosyasının Düzenlenmesi
fail2ban’ın ana konfigürasyonu /etc/fail2ban/jail.conf dosyasında bulunur, ancak bu dosyayı asla doğrudan düzenlemeyin. Güncellemeler bu dosyanın üzerine yazabilir. Bunun yerine /etc/fail2ban/jail.local oluşturun:
# jail.local dosyasını oluştur veya düzenle
nano /etc/fail2ban/jail.local
Dosya içeriği:
[DEFAULT]
# Kime bildirim gönderilecek
destemail = [email protected]
# Gönderen adres
sender = [email protected]
# Kullanılacak MTA (sendmail veya mail)
mta = sendmail
# Varsayılan aksiyon: ban + whois + log satırları ile e-posta
action = %(action_mwl)s
# Ban süresi (saniye cinsinden, -1 kalıcı ban anlamına gelir)
bantime = 3600
# Kaç dakikalık süre içinde
findtime = 600
# Kaç başarısız deneme sonrası ban
maxretry = 5
# Yerel ağları ban listesinden muaf tut
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 86400
[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 5
Aksiyon Seçimi: Neyi, Ne Zaman Kullanmalısınız?
Kalabalık bir sunucuda her ban için e-posta almak kısa sürede e-posta kutunuzu çöp kutusuna dönüştürebilir. Aksiyonları duruma göre seçmek önemlidir:
- %(action_)s: Sadece ban uygular, e-posta göndermez. Yüksek trafikli sunucularda tercih edilir
- %(action_mw)s: Ban + whois bilgisiyle e-posta. Günde düzinelerce ban beklenen ortamlar için dengeli seçim
- %(action_mwl)s: Ban + whois + log satırları. Forensic analiz yapmak isteyenler için ideal, ama e-postalar büyük olabilir
Farklı jail’ler için farklı aksiyonlar tanımlayabilirsiniz:
[sshd]
enabled = true
# SSH için detaylı log ile bildirim - kritik servis
action = %(action_mwl)s
[nginx-limit-req]
enabled = true
# Web botları için sadece ban, bildirim yok - çok sık tetiklenir
action = %(action_)s
[postfix-sasl]
enabled = true
# Mail brute force için whois yeterli
action = %(action_mw)s
Özel E-posta Şablonları Oluşturma
fail2ban’ın varsayılan e-posta şablonları /etc/fail2ban/action.d/ dizininde bulunur. Kendi özel şablonunuzu oluşturmak için mevcut bir şablonu kopyalayın:
# Mevcut aksiyonu kopyala
cp /etc/fail2ban/action.d/sendmail-whois-lines.conf
/etc/fail2ban/action.d/sendmail-custom.conf
# Düzenle
nano /etc/fail2ban/action.d/sendmail-custom.conf
Özelleştirilmiş aksiyon dosyası içeriği:
[Definition]
actionstart = printf %%b "From: <sender>nTo: <dest>nSubject: [fail2ban] <name>: Jail BASLATILDI - <fq-hostname>nDate: `LC_ALL=C date +'%%a, %%d %%b %%Y %%T %%z'`nnMerhaba,nn<fq-hostname> sunucusunda <name> jail'i baslatildi.nnSunucu: <fq-hostname>nTarih: `date`nIP Listesi: <br>nnGoreve hazir." | /usr/sbin/sendmail -f <sender> <dest>
actionstop = printf %%b "From: <sender>nTo: <dest>nSubject: [fail2ban] <name>: Jail DURDURULDU - <fq-hostname>nDate: `LC_ALL=C date +'%%a, %%d %%b %%Y %%T %%z'`nnMerhaba,nn<fq-hostname> sunucusunda <name> jail'i durduruldu.nnSunucu: <fq-hostname>nTarih: `date`" | /usr/sbin/sendmail -f <sender> <dest>
actionban = printf %%b "From: <sender>nTo: <dest>nSubject: [UYARI][fail2ban] <name>: <ip> ENGELLENDI - <fq-hostname>nDate: `LC_ALL=C date +'%%a, %%d %%b %%Y %%T %%z'`nn*** GUVENLiK UYARiSI ***nnSunucu: <fq-hostname>nEngellenen IP: <ip>nJail: <name>nTarih: `date`nn--- WHOiS BiLGiSi ---n`whois <ip> 2>/dev/null || echo 'whois bilgisi alinamadi'`nn--- iLGiLi LOG SATIRLARI ---n`grep '<ip>' <logpath> | tail -20 2>/dev/null || echo 'log okunamadi'`nnBu mesaj otomatik olarak olusturulmustur." | /usr/sbin/sendmail -f <sender> <dest>
actionunban = printf %%b "From: <sender>nTo: <dest>nSubject: [fail2ban] <name>: <ip> engeli kaldirildi - <fq-hostname>nDate: `LC_ALL=C date +'%%a, %%d %%b %%Y %%T %%z'`nnSunucu: <fq-hostname>nEngeli kaldirilan IP: <ip>nJail: <name>nTarih: `date`" | /usr/sbin/sendmail -f <sender> <dest>
[Init]
name = default
Bu özel aksiyonu jail’inizde kullanmak için:
[sshd]
enabled = true
action = sendmail-custom[name=%(__name__)s, dest=%(destemail)s, sender=%(sender)s, logpath=%(logpath)s]
Toplu Bildirim: Her Ban için E-posta Göndermeme
Yoğun saldırı altındaki bir sunucuda her ban için ayrı e-posta almak pratik değildir. Bunun yerine bir script ile günlük özet raporu oluşturabilirsiniz:
#!/bin/bash
# /usr/local/bin/fail2ban-daily-report.sh
# Her gün gece 23:59'da çalıştırılacak
REPORT_EMAIL="[email protected]"
HOSTNAME=$(hostname -f)
DATE=$(date '+%Y-%m-%d')
YESTERDAY=$(date -d "yesterday" '+%Y-%m-%d')
# fail2ban log dosyasından istatistik çek
LOG_FILE="/var/log/fail2ban.log"
BAN_COUNT=$(grep "Ban " $LOG_FILE | grep "$DATE" | wc -l)
UNBAN_COUNT=$(grep "Unban " $LOG_FILE | grep "$DATE" | wc -l)
TOP_IPS=$(grep "Ban " $LOG_FILE | grep "$DATE" | awk '{print $NF}' | sort | uniq -c | sort -rn | head -10)
JAIL_STATS=$(grep "Ban " $LOG_FILE | grep "$DATE" | grep -oP '[K[^]]+' | sort | uniq -c | sort -rn)
# Aktif ban listesi
ACTIVE_BANS=$(fail2ban-client status | grep "Jail list" | sed 's/.*Jail list:s*//' | tr ',' 'n' | while read jail; do
jail=$(echo $jail | tr -d ' ')
count=$(fail2ban-client status $jail 2>/dev/null | grep "Currently banned" | awk '{print $NF}')
echo " $jail: $count aktif ban"
done)
REPORT_BODY="fail2ban Gunluk Raporu - $HOSTNAME
Tarih: $DATE
========================================
OZET:
Toplam Ban: $BAN_COUNT
Toplam Unban: $UNBAN_COUNT
JAIL BAZLI AKTIF BANLAR:
$ACTIVE_BANS
EN COK BAN YIYEN IP'LER (BUGUN):
$TOP_IPS
JAIL ISTATISTIKLERI:
$JAIL_STATS
Bu rapor otomatik olarak olusturulmustur.
Sunucu: $HOSTNAME"
echo "$REPORT_BODY" | mail -s "[fail2ban] Gunluk Rapor - $HOSTNAME - $DATE" "$REPORT_EMAIL"
Script’i çalıştırılabilir yapın ve cron’a ekleyin:
chmod +x /usr/local/bin/fail2ban-daily-report.sh
# Crontab'a ekle
crontab -e
# Şu satırı ekle:
# 59 23 * * * /usr/local/bin/fail2ban-daily-report.sh
Konfigürasyonu Test Etme
Konfigürasyonu kaydettiğinizde fail2ban’ı yeniden başlatın ve hemen test edin:
# fail2ban'ı yeniden başlat
systemctl restart fail2ban
# Servis durumunu kontrol et
systemctl status fail2ban
# Tüm jail'lerin durumunu görüntüle
fail2ban-client status
# Belirli bir jail'in detayına bak
fail2ban-client status sshd
Bildirimin çalışıp çalışmadığını test etmek için manuel ban testi yapabilirsiniz:
# Test amaçlı bir IP'yi manuel ban et
fail2ban-client set sshd banip 1.2.3.4
# E-posta geldi mi kontrol et (birkaç dakika bekleyin)
# Ardından ban'ı kaldır
fail2ban-client set sshd unbanip 1.2.3.4
fail2ban loglarını gerçek zamanlı izlemek için:
tail -f /var/log/fail2ban.log
Başarılı bir ban bildiriminde şöyle satırlar görmelisiniz:
2024-01-15 14:23:11,456 fail2ban.actions [1234]: NOTICE [sshd] Ban 192.168.100.50
2024-01-15 14:23:11,789 fail2ban.actions [1234]: NOTICE sendmail-custom action: ban 192.168.100.50
Gerçek Dünya Senaryosu: WordPress Sitesi Koruması
Bir web hosting ortamında hem SSH hem de WordPress login brute force saldırılarına karşı bildirim yapılandırması:
[DEFAULT]
destemail = [email protected]
sender = [email protected]
mta = sendmail
bantime = 86400
findtime = 3600
maxretry = 5
[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 604800
# SSH brute force ciddi, detaylı log ile haber ver
action = %(action_mwl)s
[wordpress-auth]
enabled = true
port = http,https
filter = wordpress
logpath = /var/log/nginx/access.log
maxretry = 10
findtime = 1800
bantime = 86400
# WordPress için sadece whois yeterli
action = %(action_mw)s
[nginx-req-limit]
enabled = true
port = http,https
filter = nginx-limit-req
logpath = /var/log/nginx/error.log
maxretry = 20
# Bot trafiği için sadece ban, bildirim yok
action = %(action_)s
WordPress filter dosyası:
# /etc/fail2ban/filter.d/wordpress.conf oluştur
cat > /etc/fail2ban/filter.d/wordpress.conf << 'EOF'
[Definition]
failregex = ^<HOST> .* "POST /wp-login.php
^<HOST> .* "POST /xmlrpc.php
ignoreregex =
EOF
Sık Karşılaşılan Sorunlar ve Çözümleri
E-posta gelmiyor ama ban işlemi uygulanıyor:
Önce aksiyon dosyasının doğru çalışıp çalışmadığını kontrol edin:
# fail2ban log seviyesini artır
fail2ban-client set loglevel DEBUG
# Logları izle
tail -f /var/log/fail2ban.log
# Test sonrası log seviyesini normale döndür
fail2ban-client set loglevel INFO
sendmail komutu bulunamıyor hatası:
# sendmail binary'sinin konumunu bul
which sendmail
ls -la /usr/sbin/sendmail
# Postfix kullanıyorsanız sendmail symlink'i otomatik oluşturulur
# Eğer yoksa:
ln -s /usr/sbin/postfix /usr/sbin/sendmail
“mta = mail” kullanıyorsanız ve çalışmıyorsa:
# mailutils kurulu mu kontrol et
dpkg -l | grep mailutils
# veya
rpm -qa | grep mailx
# Manuel test
echo "test" | mail -s "test konu" [email protected]
Jail başlatma/durdurma bildirimleri gelmiyor ama ban bildirimi geliyor:
Bu genellikle actionstart komutundaki bir syntax hatasından kaynaklanır. Aksiyon dosyasını doğrulayın:
fail2ban-client -t
Bildirimleri Slack veya Telegram’a Yönlendirme
Modern ekipler için e-posta yerine Slack veya Telegram bildirimleri daha pratik olabilir. Bunun için özel aksiyon dosyası oluşturun:
# /etc/fail2ban/action.d/telegram-notify.conf
cat > /etc/fail2ban/action.d/telegram-notify.conf << 'EOF'
[Definition]
actionban = curl -s -X POST https://api.telegram.org/bot<telegram-bot-token>/sendMessage
-d chat_id=<telegram-chat-id>
-d text="🚨 [fail2ban] <fq-hostname>%0ASaldirgan IP: <ip>%0AJail: <name>%0ATarih: $(date)"
actionunban = curl -s -X POST https://api.telegram.org/bot<telegram-bot-token>/sendMessage
-d chat_id=<telegram-chat-id>
-d text="✅ [fail2ban] <fq-hostname>%0AEngel kaldirildi: <ip>%0AJail: <name>"
[Init]
telegram-bot-token = BOT_TOKEN_BURAYA
telegram-chat-id = CHAT_ID_BURAYA
EOF
Bu aksiyonu jail konfigürasyonunuzda kullanmak için:
[sshd]
enabled = true
action = iptables-multiport[name=sshd, port=ssh, protocol=tcp]
telegram-notify[name=%(__name__)s]
Hem iptables ban hem de Telegram bildirimi için iki aksiyon satırı arka arkaya yazılabilir.
Sonuç
fail2ban’ın e-posta bildirim altyapısı doğru yapılandırıldığında sizi gerçek anlamda uyanık tutan bir güvenlik katmanına dönüşür. Ancak her şey gibi bu konuda da denge önemlidir: çok fazla bildirim alarm yorgunluğuna yol açar ve gerçek tehditleri gürültü içinde kaybedebilirsiniz. Az bildirim ise sizi körleştirir.
En iyi yaklaşım kritik servisler (SSH, VPN, mail auth) için anlık bildirim tutmak, yüksek hacimli servisler (web, API) için ise günlük özet raporu yeterli görmektir. Telegram veya Slack entegrasyonu, e-postaya kıyasla çok daha hızlı tepki vermenizi sağlar ve mobil cihazlardan kolayca takip edilebilir.
Konfigürasyonunuzu oluşturduktan sonra düzenli olarak test edin: manuel ban testleri yapın, log dosyalarını inceleyin ve günlük raporların gerçekten gelip gelmediğini kontrol edin. Çalıştığını varsaydığınız ama aslında sessizce hata veren bir bildirim sistemi, hiç bildirim sistemi olmamaktan daha tehlikelidir.