Exim Rate Limiting ile Spam Koruması: Adım Adım Yapılandırma

Mail sunucunuzu yönetiyorsanız, bir sabah uyandığınızda sunucunuzun spam göndermek için kullanıldığını ya da dışarıdan gelen spam dalgasının sistemlerinizi felç ettiğini görmek kabusu yaşamış olabilirsiniz. Exim, doğru yapılandırıldığında bu tür saldırılara karşı oldukça etkili bir kalkan oluşturabilir. Rate limiting, yani hız sınırlama, bu kalkanın en kritik katmanlarından biridir.

Rate Limiting Nedir ve Neden Gereklidir?

Rate limiting, belirli bir zaman diliminde belirli bir kaynaktan gelebilecek bağlantı veya mesaj sayısını sınırlama tekniğidir. Exim’de bu mekanizma son derece esnek ve güçlü bir şekilde uygulanmaktadır. Temel olarak şu senaryolara karşı koruma sağlar:

  • Brute force saldırıları: Binlerce farklı parola denemesi yapan saldırganları yavaşlatmak
  • Spam patlamaları: Ele geçirilmiş bir hesabın kısa sürede binlerce mail göndermesini engellemek
  • Dictionary saldırıları: Geçersiz alıcılara yönelik toplu mail denemelerini kesmek
  • Connection flooding: Sunucuya aynı IP’den aşırı bağlantı açılmasını önlemek

Bir hosting şirketinde çalıştığınızı düşünün. Müşterilerinizden birinin WordPress sitesi hacklenmiş ve saldırgan, PHP mail() fonksiyonu üzerinden saatte 50.000 mail gönderiyor. Rate limiting olmadan bu durum hem sunucunuzu kara listeye sokar hem de diğer müşterilerinizi etkiler.

Exim’de Rate Limiting Temelleri

Exim’in rate limiting özelliği ratelimit ACL (Access Control List) koşulu ile çalışır. Bu koşul, her değerlendirildiğinde dahili bir sayaç günceller ve tanımlanan limiti aşıp aşmadığını kontrol eder.

Temel sözdizimi şu şekildedir:

ratelimit = <sayı> / <süre> / <seçenekler> / <anahtar>
  • sayı: İzin verilen maksimum olay sayısı
  • süre: Zaman penceresi (1s, 1m, 1h, 1d gibi)
  • seçenekler: strict, leaky, average, per_conn, per_rcpt gibi modlar
  • anahtar: Sayacın kimlere özel tutulacağını belirler (IP, kullanıcı adı vb.)

Exim bu sayaçları /var/spool/exim/db/ dizininde tutar. Dolayısıyla disk I/O açısından çok ağır bir yük oluşturmaz ancak yüksek trafikli sistemlerde bu dizinin performansını göz önünde bulundurmalısınız.

ACL Yapılandırması

Exim yapılandırma dosyası genellikle /etc/exim4/exim4.conf veya cPanel/WHM sistemlerinde /etc/exim.conf yolundadır. Rate limiting kuralları ACL bölümlerine eklenir.

RCPT ACL’de Temel Rate Limiting

En yaygın yaklaşım, acl_smtp_rcpt bölümüne kural eklemektir:

acl_smtp_rcpt:
  # Aynı IP'den gelen bağlantıları sınırla
  warn  ratelimit = 100 / 5m / strict / $sender_host_address
        log_message = Rate limit: $sender_host_address $rate mesaj/dakika

  deny  message   = Cok fazla mesaj gonderdiniz, lutfen bekleyin.
        log_message = Rate limit asimldi: $sender_host_address
        ratelimit = 100 / 5m / strict / $sender_host_address

Burada warn ile önce sayacı güncelleyip logluyoruz, deny ile de limiti aşanları reddediyoruz. Bu iki adımlı yaklaşım, aynı ratelimit çağrısının iki kez çalışmasını önlemek için aslında biraz verimsizdir. Daha temiz bir yaklaşım için defer veya tek deny bloğu kullanılabilir.

Kimlik Doğrulaması Yapılmış Kullanıcılar İçin Rate Limiting

SMTP AUTH kullanan kullanıcıları, IP yerine kullanıcı adına göre sınırlamak genellikle daha mantıklıdır:

acl_smtp_rcpt:
  # Kimlik dogrulamas yapilmis kullanicilari sinirla
  deny  message    = Hesabiniz cok fazla mail gonderiyor, 1 saat bekleyin.
        authenticated = *
        ratelimit = 500 / 1h / strict / $authenticated_id
        log_message = AUTH rate limit: $authenticated_id ($rate msg/h)

Bu kural, bir kullanıcının saatte 500’den fazla mail göndermesini engeller. Özellikle paylaşımlı hosting ortamlarında bu tür bir kural, ele geçirilmiş hesapların zararını minimize eder.

IP Başına Bağlantı Sınırlama

CONNECT ACL’de bağlantı sayısını sınırlamak, DDoS tipi saldırılara karşı ilk savunma hattıdır:

acl_smtp_connect:
  # Ayni IP'den cok fazla baglanti geliyorsa reddet
  deny  ratelimit = 30 / 1m / per_conn / $sender_host_address
        message   = Baglanti limitini astiniz.
        log_message = Connection rate limit: $sender_host_address

  # Whitelist kontrolu (guvenilir IP'ler muaf)
  accept hosts = /etc/exim4/whitelist_ips

per_conn seçeneği, eşzamanlı bağlantıları değil zaman içindeki bağlantı hızını ölçer. Eğer eşzamanlı bağlantıları sınırlamak isterseniz Exim’in smtp_accept_max_per_host global parametresini kullanmanız gerekir.

Gerçek Dünya Senaryoları

Senaryo 1: Toplu Mail Gönderen Script Tespiti

Bir müşterinizin PHP scripti dakikada 200 mail göndermeye çalışıyor. Önce bunu tespit etmek için loglara bakalım:

# Son 1 saatte en cok mail gonderenleri bul
grep "$(date -d '1 hour ago' '+%Y-%m-%d %H')" /var/log/exim4/mainlog | 
  grep "=>" | 
  awk '{print $NF}' | 
  sort | uniq -c | sort -rn | head -20

Tespit ettikten sonra sınırlamayı devreye alıyoruz:

acl_smtp_data:
  # DATA sonrasi sender domain bazli sinirla
  deny  message    = Bu adresten cok fazla mail alindi.
        ratelimit = 50 / 10m / strict / $sender_address_domain
        log_message = Domain rate limit: $sender_address_domain exceeded ($rate)

Senaryo 2: Geçersiz Alıcı Saldırıları

Dictionary saldırıları, saldırganın sisteminizdeki geçerli adresleri bulmak için binlerce deneme yapması anlamına gelir. Bu hem kaynak tüketir hem de kullanıcıları açığa çıkarır:

acl_smtp_rcpt:
  # Gecersiz alici denemeleri icin farkli bir sayac tut
  accept  domains = +local_domains
          verify  = recipient

  # Recipient verify basarisiz olursa say
  deny    message   = Bilinmeyen alici.
          !verify   = recipient
          ratelimit = 10 / 1h / strict / $sender_host_address
          log_message = Invalid recipient flood: $sender_host_address tried $local_part@$domain

Bu yapılandırmayla bir IP adresi saatte 10’dan fazla geçersiz alıcı denerse reddedilir.

Senaryo 3: Gece Yarısı Spam Patlaması

Bir müşteri hesabının gece 2’de aniden binlerce mail göndermeye başladığını düşünün. Hem rate limiting hem de anlık bildirim için şu yapıyı kullanabilirsiniz:

acl_smtp_rcpt:
  warn  authenticated = *
        ratelimit     = 200 / 1h / strict / $authenticated_id
        condition     = ${if >{$rate}{150}{yes}{no}}
        log_message   = UYARI: $authenticated_id yuksek mail hizi: $rate/saat

  deny  authenticated = *
        ratelimit     = 200 / 1h / strict / $authenticated_id
        message       = Saatlik mail limitinizi (200) astiniz.

Loglardaki uyarıları izlemek için basit bir script:

#!/bin/bash
# /usr/local/bin/exim-rate-monitor.sh

LOGFILE="/var/log/exim4/mainlog"
THRESHOLD=150
ADMIN_EMAIL="[email protected]"

# Son 5 dakikada rate limit uyarisi alan hesaplari bul
WARNINGS=$(grep "UYARI:" "$LOGFILE" | 
  awk -v d="$(date -d '5 minutes ago' '+%Y-%m-%d %H:%M')" '$0 >= d' | 
  grep -oP 'UYARI: K[^s]+' | sort -u)

if [ -n "$WARNINGS" ]; then
  echo "Rate limit uyarilari tespit edildi:" | 
  mail -s "Exim Rate Limit Uyarisi" "$ADMIN_EMAIL" <<< "$WARNINGS"
fi

Bu scripti cron’a ekleyin:

*/5 * * * * /usr/local/bin/exim-rate-monitor.sh

Gelişmiş Rate Limiting Teknikleri

Leaky Bucket Algoritması

strict mod, zaman penceresi dolduğunda sayacı sıfırlar. Bu bazen kaba kesimler yaratır. leaky mod ise daha akıcı bir sınırlama sağlar ve ani patlamalara daha iyi tepki verir:

acl_smtp_rcpt:
  deny  ratelimit = 30 / 1m / leaky / $sender_host_address
        message   = Lutfen gonderi hiziinizi azaltin.

leaky modda Exim, sliding window (kayan pencere) benzeri bir yaklaşım kullanır. Bu, “tam olarak 1 dakikada 30 mail” yerine “ortalama olarak dakikada 30 mail” anlamına gelir.

Per-Connection Rate Limiting

Bazı durumlarda bir bağlantı içindeki alıcı sayısını sınırlamak istersiniz:

acl_smtp_rcpt:
  # Tek baglantida 50'den fazla aliciya izin verme
  deny  ratelimit  = 50 / 1s / per_conn / $sender_host_address
        message    = Tek baglantiyla cok fazla aliciya gonderi yapamazsiniz.

per_conn burada o aktif bağlantıyla ilgili sayacı tutar, yani bağlantı kapandığında sıfırlanır.

Whitelist ile Rate Limiting Birleştirme

Güvenilir sunucuları rate limiting’den muaf tutmak önemlidir, aksi takdirde meşru toplu mail göndericilerini de engellersiniz:

acl_smtp_rcpt:
  # Whitelist'teki IP'ler icin rate limiting uygulama
  accept  hosts        = /etc/exim4/trusted_senders
          log_message  = Trusted sender: $sender_host_address

  # Whitelist'te olmayanlara rate limiting uygula
  deny    ratelimit    = 100 / 5m / strict / $sender_host_address
          message      = Rate limit asildi.

/etc/exim4/trusted_senders dosyası:

# Her satira bir IP veya CIDR blogu
1.2.3.4
10.0.0.0/8
192.168.1.0/24
# Google Mail sunuculari
209.85.128.0/17

Rate Limit Sayaçlarını Yönetmek

Exim rate limit veritabanını exim_dumpdb ve exim_tidydb araçlarıyla yönetebilirsiniz:

# Rate limit veritabanini goruntule
exim_dumpdb /var/spool/exim/db ratelimit

# Belirli bir IP icin sayaci sifirla (elle mudahale gerektiren durumlarda)
exim_fixdb /var/spool/exim/db ratelimit

# Eski kayitlari temizle (haftalik cron olarak eklenebilir)
exim_tidydb -t 7d /var/spool/exim/db ratelimit

Aşağıdaki script ile mevcut rate limit durumunu izleyebilirsiniz:

#!/bin/bash
# /usr/local/bin/check-ratelimits.sh
# Rate limit veritabanindaki aktif kayitlari listeler

echo "=== Aktif Rate Limit Kayitlari ==="
echo "Tarih: $(date)"
echo ""

exim_dumpdb /var/spool/exim/db ratelimit 2>/dev/null | 
  awk '/^[0-9]/{
    split($0, a, " ");
    if (a[2] > 10) print "IP/User: " a[1] " | Oran: " a[2] " | Son guncelleme: " a[3]
  }' | sort -t: -k3 -rn | head -30

Exim Yapılandırmasını Test Etmek

Rate limiting kurallarını canlıya almadan önce test etmek kritik önem taşır:

# Yapılandirma sozdizimini kontrol et
exim -C /etc/exim4/exim4.conf -bV

# Belirli bir adres icin ACL testini simule et
exim -C /etc/exim4/exim4.conf -bh 1.2.3.4

# Exim'i debug modunda calistir (sadece test ortaminda)
exim -d -bd -oX 2525

# Belirli bir mesaj icin routing testı
exim -bt [email protected]

ACL değişikliklerini test ortamında doğruladıktan sonra canlıya alırken Exim’i yeniden başlatmak yerine reload kullanın:

# Exim'i yeniden yukle (aktif baglantilari kesmez)
systemctl reload exim4

# Veya dogrudan sinyal gonder
kill -HUP $(cat /var/run/exim4/exim.pid)

Logları Analiz Etmek

Rate limiting’in ne kadar etkili çalıştığını görmek için log analizi şarttır:

# Rate limit nedeniyle reddedilen mailleri say
grep "rate limit" /var/log/exim4/mainlog | 
  grep "rejected" | 
  awk '{print $4}' | 
  sort | uniq -c | sort -rn | head -20

# Son 24 saatte en cok rate limit yiyen IP'ler
grep "$(date -d 'yesterday' '+%Y-%m-%d')|$(date '+%Y-%m-%d')" 
  /var/log/exim4/mainlog | 
  grep -i "rate" | 
  grep -oP 'd+.d+.d+.d+' | 
  sort | uniq -c | sort -rn | head -10

# Saatlik rate limit ihlali trendi
grep "rate limit" /var/log/exim4/mainlog | 
  awk '{print substr($3, 1, 5)}' | 
  sort | uniq -c

Yaygın Hatalar ve Çözümleri

Problem: Rate limiting tüm kullanıcıları etkiliyor, meşru göndericiler de engelleniyor.

Çözüm: Whitelist mekanizmasını mutlaka ekleyin ve limitler koyarken gerçek iş gereksinimlerinizi göz önünde bulundurun. Bir e-ticaret sitesi promosyon döneminde saatte 10.000 mail gönderebilir, bu normaldir.

Problem: Rate limit veritabanı çok büyüdü ve disk doldu.

Çözüm: exim_tidydb komutunu düzenli çalıştırın ve eski kayıtları temizleyin. Ayrıca /var/spool/exim/ dizinini ayrı bir partition’a alın.

Problem: ratelimit koşulu ACL’de iki kez değerlendirilince sayaç iki kez artıyor.

Çözüm: readonly seçeneğini kullanın. Bu seçenek sayacı güncellemeden sadece okur:

acl_smtp_rcpt:
  warn  ratelimit = 100 / 1h / readonly / $sender_host_address
        log_message = Mevcut oran: $rate

  deny  ratelimit = 100 / 1h / strict / $sender_host_address
        message   = Saatlik limit asildi.

Problem: Exim yeniden başlatıldığında tüm sayaçlar sıfırlanıyor gibi görünüyor.

Çözüm: Bu normal değil. Veritabanı dosyalarının izinlerini kontrol edin:

ls -la /var/spool/exim/db/
# ratelimit dosyalari exim kullanicisina ait olmali
chown exim:exim /var/spool/exim/db/ratelimit*
chmod 640 /var/spool/exim/db/ratelimit*

cPanel/WHM Ortamlarında Rate Limiting

cPanel sistemlerinde /etc/exim.conf direkt düzenlenmez, bunun yerine WHM arayüzündeki “Exim Configuration Manager” veya /etc/exim.conf.local dosyası kullanılır:

# /etc/exim.conf.local dosyasina eklenecek ACL kurallari
# WHM bu dosyayi ana konfigurasyonla birlestirır

begin acl

acl_smtp_rcpt:
  # Onceki kurallar devam eder...

  deny  authenticated = *
        ratelimit     = 300 / 1h / strict / $authenticated_id
        message       = Saatlik mail limitinizi astiniz. Destek ile iletisime gecin.

Değişiklikleri uygulamak için:

# cPanel Exim rebuild
/scripts/buildeximconf
/scripts/restartsrv_exim

Sonuç

Exim’de rate limiting, spam korumasının olmazsa olmaz bir parçasıdır. Doğru yapılandırılmış bir rate limiting sistemi, hem dışarıdan gelen saldırıları hem de içeriden kaynaklanan (ele geçirilmiş hesaplar, güvensiz scriptler) tehditleri büyük ölçüde azaltır.

Yapılandırırken dikkat etmeniz gereken en önemli nokta denge kurmaktır. Çok agresif limitler meşru kullanıcıları etkiler, çok gevşek limitler ise koruma sağlamaz. Bu yüzden önce mevcut trafik paternlerinizi analiz edin, limitlerı ona göre belirleyin ve ilk hafta boyunca log takibini sıkı tutun.

Rate limiting tek başına yeterli değildir. SPF, DKIM, DMARC yapılandırmaları, greylisting ve RBL kontrolleri ile birlikte katmanlı bir savunma stratejisi oluşturduğunuzda mail sunucunuz hem kendinizi hem de kullanıcılarınızı etkin biçimde korur. Exim’in bu konudaki esnekliği, onu enterprise ortamlarda bile tercih edilen bir çözüm haline getirmektedir.

Yorum yapın