Apache mod_evasive ile Brute Force ve DoS Koruması

Web sunucunuza gelen trafiği izlediğinizde, belirli IP adreslerinin kısa sürede yüzlerce istek gönderdiğini fark etmişsinizdir. Bu tür saldırılar hem sunucu kaynaklarını tüketir hem de meşru kullanıcıların hizmet almasını engeller. Apache’nin mod_evasive modülü, tam da bu noktada devreye girerek brute force ve DoS saldırılarına karşı etkili bir ilk savunma katmanı oluşturur. Bu yazıda modülü sıfırdan kurup yapılandıracağız, gerçek senaryolarda nasıl davrandığını inceleyeceğiz.

mod_evasive Nedir ve Nasıl Çalışır?

mod_evasive, Apache HTTP Sunucusu için geliştirilmiş bir anti-DoS ve anti-brute force modülüdür. Temel çalışma mantığı şudur: gelen istekleri bir hash tablosunda izler, belirli bir zaman diliminde aynı IP adresinden veya aynı kaynaktan gelen istek sayısı eşik değerini aşarsa o IP’yi geçici olarak engeller.

Modül üç farklı eşik kontrolü yapar:

  • DOSPageCount: Aynı URI’ye tek bir IP’den gelen istek sayısı eşiği
  • DOSSiteCount: Aynı IP’den herhangi bir sayfaya gelen toplam istek sayısı eşiği
  • DOSBlockingPeriod: IP’nin kaç saniye boyunca engelleneceği

Engelleme gerçekleştiğinde Apache, istemciye 403 Forbidden yanıtı döndürür. İsteğe bağlı olarak bir komut çalıştırabilir (örneğin iptables kuralı eklemek) veya bir e-posta bildirimi gönderebilir.

Kurulum

Ubuntu/Debian Sistemlerde Kurulum

Ubuntu ve Debian tabanlı sistemlerde mod_evasive doğrudan paket deposunda bulunur.

sudo apt update
sudo apt install libapache2-mod-evasive -y

# Modülün etkin olup olmadığını kontrol et
sudo apache2ctl -M | grep evasive

# Eğer aktif değilse etkinleştir
sudo a2enmod evasive

# Apache'yi yeniden başlat
sudo systemctl restart apache2

Kurulumun ardından /etc/apache2/mods-available/evasive.conf dosyası otomatik oluşur. Ancak içeriği genellikle yorum satırlarıyla dolu gelir, bizim bunu düzenlememiz gerekecek.

CentOS/RHEL/AlmaLinux Sistemlerde Kurulum

Red Hat tabanlı sistemlerde modül mod_evasive adıyla EPEL deposunda yer alır.

# EPEL deposunu ekle (henüz eklenmemişse)
sudo dnf install epel-release -y

# mod_evasive kur
sudo dnf install mod_evasive -y

# Modül yapılandırma dosyası şu konumda oluşur:
ls /etc/httpd/conf.d/mod_evasive.conf

# Apache'yi yeniden başlat
sudo systemctl restart httpd

Log Dizinini Hazırlama

mod_evasive log dosyalarını varsayılan olarak /var/log/mod_evasive/ dizinine yazar. Bu dizin otomatik oluşmayabilir.

# Log dizini oluştur
sudo mkdir -p /var/log/mod_evasive

# Apache kullanıcısına sahipliği ver
sudo chown www-data:www-data /var/log/mod_evasive   # Debian/Ubuntu için
# sudo chown apache:apache /var/log/mod_evasive     # RHEL tabanlı için

# İzinleri ayarla
sudo chmod 755 /var/log/mod_evasive

Temel Yapılandırma

Debian/Ubuntu İçin Yapılandırma

sudo nano /etc/apache2/mods-available/evasive.conf

Dosyanın içeriğini aşağıdaki gibi düzenleyin:

<IfModule mod_evasive20.c>
    # Aynı URI'ye yapılan maksimum istek sayısı (DOSPageInterval içinde)
    DOSHashTableSize    3097
    DOSPageCount        5
    DOSSiteCount        50
    DOSPageInterval     1
    DOSSiteInterval     1
    DOSBlockingPeriod   60

    # Log ve bildirim ayarları
    DOSEmailNotify      [email protected]
    DOSLogDir           /var/log/mod_evasive
    DOSSystemCommand    "sudo /usr/local/bin/block_ip.sh %s"
</IfModule>

CentOS/RHEL İçin Yapılandırma

sudo nano /etc/httpd/conf.d/mod_evasive.conf
LoadModule evasive20_module modules/mod_evasive20.so

<IfModule mod_evasive20.c>
    DOSHashTableSize    3097
    DOSPageCount        5
    DOSSiteCount        50
    DOSPageInterval     1
    DOSSiteInterval     1
    DOSBlockingPeriod   300

    DOSEmailNotify      [email protected]
    DOSLogDir           /var/log/mod_evasive
    DOSSystemCommand    "sudo /usr/local/bin/block_ip.sh %s"
</IfModule>

Parametrelerin Açıklaması

  • DOSHashTableSize: IP adreslerini takip etmek için kullanılan hash tablosunun boyutu. Yüksek trafikli sitelerde bu değeri artırın
  • DOSPageCount: Aynı IP’nin aynı sayfaya DOSPageInterval saniye içinde yapabileceği maksimum istek sayısı
  • DOSSiteCount: Aynı IP’nin tüm siteye DOSSiteInterval saniye içinde yapabileceği toplam maksimum istek sayısı
  • DOSPageInterval: Sayfa istek sayacının sıfırlandığı süre (saniye cinsinden)
  • DOSSiteInterval: Site istek sayacının sıfırlandığı süre (saniye cinsinden)
  • DOSBlockingPeriod: Engellenen IP’nin kaç saniye boyunca bloke kalacağı
  • DOSEmailNotify: Engelleme gerçekleştiğinde bildirim gönderilecek e-posta adresi
  • DOSLogDir: mod_evasive log dosyalarının yazılacağı dizin
  • DOSSystemCommand: Engelleme tetiklendiğinde çalışacak sistem komutu (%s engellenen IP adresiyle değiştirilir)

iptables Entegrasyonu

mod_evasive tek başına Apache katmanında engelleme yapar, ancak istekler yine de sunucuya ulaşır ve işlenmek zorunda kalır. Daha etkili bir koruma için DOSSystemCommand ile iptables kuralı ekleyebilirsiniz.

sudo nano /usr/local/bin/block_ip.sh
#!/bin/bash
# mod_evasive tarafından tetiklenen IP engelleme scripti

IP=$1
LOG_FILE="/var/log/mod_evasive/blocked_ips.log"
BLOCK_DURATION=3600  # 1 saat

if [ -z "$IP" ]; then
    echo "Kullanim: $0 <ip_adresi>"
    exit 1
fi

# IP formatini dogrula (basit kontrol)
if ! echo "$IP" | grep -qE '^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$'; then
    echo "Gecersiz IP formati: $IP" >> "$LOG_FILE"
    exit 1
fi

# Zaten engelli mi kontrol et
if iptables -C INPUT -s "$IP" -j DROP 2>/dev/null; then
    echo "$(date): $IP zaten engelli" >> "$LOG_FILE"
    exit 0
fi

# iptables kuralini ekle
iptables -I INPUT -s "$IP" -j DROP
echo "$(date): $IP engellendi" >> "$LOG_FILE"

# Belirtilen sure sonra kurali kaldir (arkaplanda)
(sleep "$BLOCK_DURATION" && iptables -D INPUT -s "$IP" -j DROP && 
    echo "$(date): $IP engeli kaldirildi" >> "$LOG_FILE") &

exit 0
# Script'e çalıştırma izni ver
sudo chmod +x /usr/local/bin/block_ip.sh

# Apache'nin bu scripti sudo ile çalıştırabilmesi için sudoers'a ekle
sudo visudo

visudo ile açılan dosyaya şu satırı ekleyin:

www-data ALL=(ALL) NOPASSWD: /usr/local/bin/block_ip.sh
# RHEL tabanlı sistemler için:
# apache ALL=(ALL) NOPASSWD: /usr/local/bin/block_ip.sh

Whitelist Yapılandırması

Kendi ofis IP adresinizi, monitöring sistemlerinizi veya güvenilir hizmetleri yanlışlıkla engellemek istemezsiniz. mod_evasive whitelist desteği sunmaz, ancak bunu Apache’nin SetEnvIf direktifiyle çözebilirsiniz.

sudo nano /etc/apache2/sites-available/000-default.conf
<VirtualHost *:80>
    ServerName www.sirketiniz.com
    DocumentRoot /var/www/html

    # Güvenilir IP adreslerini whitelist'e ekle
    SetEnvIf Remote_Addr "192.168.1.0/24" TRUSTED_IP
    SetEnvIf Remote_Addr "10.0.0.100" TRUSTED_IP
    SetEnvIf Remote_Addr "203.0.113.50" TRUSTED_IP

    # mod_evasive'i whitelist IP'leri için devre disi birak
    <IfModule mod_evasive20.c>
        DOSWhitelist 192.168.1.*
        DOSWhitelist 10.0.0.*
    </IfModule>

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

DOSWhitelist direktifi wildcard destekler. Birden fazla DOSWhitelist satırı ekleyebilirsiniz.

Gerçek Dünya Senaryoları

Senaryo 1: WordPress Giriş Sayfası Brute Force Koruması

Bir müşterinin WordPress sitesinde wp-login.php sayfasına yoğun brute force saldırısı geldiğini düşünelim. Günlük 50.000 başarısız giriş denemesi normal Apache loglarını gömebilir ve sunucuyu yavaşlatabilir.

sudo nano /etc/apache2/sites-available/wordpress.conf
<VirtualHost *:443>
    ServerName blog.sirketiniz.com
    DocumentRoot /var/www/wordpress

    # wp-login.php icin cok daha siki mod_evasive kurallari
    <Location /wp-login.php>
        <IfModule mod_evasive20.c>
            DOSPageCount        3
            DOSPageInterval     60
            DOSBlockingPeriod   3600
        </IfModule>
    </Location>

    # wp-admin dizini icin orta seviye koruma
    <Location /wp-admin/>
        <IfModule mod_evasive20.c>
            DOSPageCount        10
            DOSSiteCount        20
            DOSBlockingPeriod   1800
        </IfModule>
    </Location>

    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/blog.crt
    SSLCertificateKeyFile /etc/ssl/private/blog.key
</VirtualHost>

Senaryo 2: API Endpoint Koruması

REST API sunuyorsanız, belirli endpointlerin kötüye kullanımını önlemek için rate limiting benzeri bir yapı kurabilirsiniz.

<VirtualHost *:443>
    ServerName api.sirketiniz.com
    DocumentRoot /var/www/api

    # Genel API korumasi
    <IfModule mod_evasive20.c>
        DOSPageCount        20
        DOSSiteCount        100
        DOSPageInterval     1
        DOSSiteInterval     10
        DOSBlockingPeriod   120
        DOSLogDir           /var/log/mod_evasive
    </IfModule>

    # Auth endpoint'i cok daha katı
    <Location /api/v1/auth>
        <IfModule mod_evasive20.c>
            DOSPageCount        5
            DOSPageInterval     30
            DOSBlockingPeriod   900
        </IfModule>
    </Location>
</VirtualHost>

Test Etme

Yapılandırmanızın doğru çalışıp çalışmadığını test etmek için ab (Apache Benchmark) aracını kullanabilirsiniz. Testi kendi sunucunuza yapın.

# ab aracini kur
sudo apt install apache2-utils -y  # Debian/Ubuntu

# Test: 1 saniyede 100 istek gonder
ab -n 100 -c 10 http://localhost/

# Sonuclari kontrol et
# 403 yaniti aliyorsaniz mod_evasive calisiyor demektir

# Log dosyalarini kontrol et
ls -la /var/log/mod_evasive/
cat /var/log/mod_evasive/dos-*

# Apache error log'unu izle
sudo tail -f /var/log/apache2/error.log | grep evasive

Test sonrasında kendi IP adresinizin engellenmiş olma ihtimali var. Engeli kaldırmak için:

# Engellenen IP'leri goster
sudo iptables -L INPUT -n | grep DROP

# Kendi IP'nizi engelden kaldir
sudo iptables -D INPUT -s 127.0.0.1 -j DROP

# Veya tum mod_evasive engellerini temizle (dikkatli kullanin)
sudo iptables -F INPUT

Log Analizi ve İzleme

mod_evasive log dosyaları oldukça basit yapıdadır. Her engellenen IP için dos-IPADRESI formatında bir dosya oluşturur.

# En cok engellenen IP adreslerini bul
sudo find /var/log/mod_evasive/ -name "dos-*" | 
    awk -F'dos-' '{print $2}' | 
    sort | uniq -c | sort -rn | head 20

# Bugun engellenen IP sayisi
sudo find /var/log/mod_evasive/ -name "dos-*" -newer /var/log/mod_evasive/ | wc -l

# Apache log'undan 403 dondurulen istekleri say
sudo awk '$9 == 403' /var/log/apache2/access.log | 
    awk '{print $1}' | sort | uniq -c | sort -rn | head 20

# Gercek zamanli izleme
sudo watch -n 5 'find /var/log/mod_evasive/ -name "dos-*" | wc -l'

Yaygın Sorunlar ve Çözümleri

Modül Yüklenmiyor

Apache başlatıldığında modülün yüklenmediğini görüyorsanız:

# Modülün mevcut olup olmadığını kontrol et
find /usr/lib/apache2/modules/ -name "*evasive*"

# Syntax hatasini kontrol et
sudo apache2ctl configtest

# Modülü manuel olarak etkinleştir
sudo a2enmod evasive
sudo systemctl restart apache2

# Hata loglarını kontrol et
sudo journalctl -u apache2 -n 50

E-posta Bildirimleri Gelmiyor

DOSEmailNotify direktifinin çalışması için sunucuda bir MTA (Mail Transfer Agent) kurulu olması gerekir.

# Postfix kurulu mu kontrol et
which sendmail || which postfix

# Basit test
echo "Test mesaji" | mail -s "mod_evasive test" [email protected]

# Postfix kurulumu (kurulu degilse)
sudo apt install postfix mailutils -y

Meşru Kullanıcılar Engelleniyor

Eğer meşru kullanıcılardan şikayet geliyorsa, eşik değerleriniz çok düşük olabilir. Önce gerçek trafiği analiz edin:

# Son 1 saatte en aktif IP'lerin istek sayisini goster
sudo awk -v date="$(date -d '1 hour ago' +'%d/%b/%Y:%H')" 
    '$4 > "["date' /var/log/apache2/access.log | 
    awk '{print $1}' | sort | uniq -c | sort -rn | head 30

Bu çıktıya bakarak DOSSiteCount değerinizi normal kullanıcı davranışının biraz üzerinde ayarlayabilirsiniz.

mod_evasive ile Birlikte Kullanılabilecek Araçlar

mod_evasive tek başına yeterli olmayabilir. Aşağıdaki araçlarla birlikte kullanıldığında çok daha sağlam bir koruma elde edersiniz:

  • fail2ban: Apache loglarını izleyerek tekrarlayan saldırıları iptables ile engeller
  • mod_security: Web Application Firewall özelliği sunar, SQL injection ve XSS gibi saldırılara karşı korur
  • CSF (ConfigServer Security Firewall): Gelişmiş firewall yönetimi ve otomatik engelleme sağlar
  • Cloudflare veya başka CDN/WAF hizmetleri: Trafik sunucunuza ulaşmadan filtrelenir

fail2ban ile mod_evasive’i birlikte kullanmak özellikle güçlüdür. mod_evasive anlık tepki verirken, fail2ban uzun vadeli engelleme için devreye girer.

Performans Değerlendirmesi

mod_evasive hafif bir modüldür, ancak yüksek trafikli ortamlarda dikkat edilmesi gereken noktalar var:

  • DOSHashTableSize değerini trafiğinize göre ayarlayın. Çok düşük bir değer hash çakışmalarına yol açar, çok yüksek bir değer gereksiz bellek tüketir. 3097 veya 6151 gibi asal sayılar kullanın.
  • DOSBlockingPeriod değerini makul tutun. 3600 saniye (1 saat) çoğu senaryo için yeterlidir. Süresiz engelleme için fail2ban daha uygun bir araçtır.
  • Log dizininin bulunduğu diskin dolu olmadığından emin olun. Yoğun saldırı altında log dosyaları hızla birikebilir.
# Log dizininin boyutunu duzenli kontrol et
du -sh /var/log/mod_evasive/

# Eski log dosyalarini temizlemek icin cron job ekle
sudo crontab -e
# Su satiri ekle: Her gece saat 02:00'de 7 gunden eski loglari sil
# 0 2 * * * find /var/log/mod_evasive/ -name "dos-*" -mtime +7 -delete

Sonuç

mod_evasive, Apache tabanlı web sunucularınız için kurulumu ve yapılandırması kolay, etkili bir ilk savunma katmanıdır. Brute force saldırılarına ve basit DoS girişimlerine karşı hızlı tepki verir. Ancak şunu unutmamak gerekir: mod_evasive tek başına DDoS saldırılarını durduramaz, çünkü bant genişliği tüketimi gibi sorunları çözmez.

Gerçek dünyada en iyi sonucu şu yaklaşımla alırsınız: mod_evasive anlık Apache katmanında engelleme yapsın, iptables entegrasyonuyla sistem seviyesinde trafik kesilsin, fail2ban tekrarlayan saldırganları uzun vadeli bloke etsin ve Cloudflare gibi bir CDN/WAF hizmeti tüm bunlardan önce bir filtre katmanı oluştursun.

Yapılandırmanızı yaparken kendi uygulamanızın normal kullanım kalıplarını iyi analiz edin. Bir e-ticaret sitesinde flash sale sırasında oluşan yoğunluk, bir brute force saldırısından ayırt edilemez görünebilir. Bu nedenle whitelist yönetiminizi titizlikle yapın ve eşik değerlerinizi kör takip etmek yerine kendi log verilerinize dayandırın.

Yorum yapın