Postfix ve Dovecot Loglarından Gerçek Zamanlı Alarm: Oran Tabanlı İzleme Boru Hattı
Mail sunucusunda önemli olan tekil log satırı değil, birim zamandaki oran ve türdür. SASL brute-force, kuyruk şişmesi, Dovecot Panic ve DMARC çöküşlerini çalışan Vector, mtail ve Alertmanager config'leriyle 60 saniyede doğru kişiye ulaştıran, gerisini susturan bir boru hattı kuruyoruz.
EvilMail Team30 Temmuz 202613 dk okuma
Bir gece mail sunucusunda kuyruk 40 bine tırmandı. Kimsenin haberi olmadı. Sabaha karşı ilk müşteri "mail gitmiyor" ticket'ı düştüğünde olay çoktan iki saatlik olmuştu. Oysa aynı sorun loglarda 20 dakika önce açık açık akıyordu:
Log her şeyi zamanında söylemişti. Eksik olan, o satırları bir orana çevirip doğru kişiye yönlendiren katmandı. Mail sunucusu izlemenin acı gerçeği şu: grep "error" | mail admin@ kuran ekipler ya kendini gereksiz alarma boğar ve iki hafta sonra kuralı kapatır, ya da gerçekten kritik olan tek Panic: satırını binlerce zararsız bounced arasında kaybeder. Çözüm daha çok alarm değil; sinyal taksonomisi + oran eşiği + doğru boru hattı.
Alarm demek olan log satırları: bir sinyal taksonomisi
Postfix ve Dovecot Loglarından Gerçek Zamanlı Alarm Kurma | evilmail.pro — EvilMail Blog
Postfix, Dovecot ve milter loglarında binlerce satırın belki yüzde biri gerçekten bir insana ulaşmalı. O yüzeyi dört kovaya ayırıyorum.
1. Kimlik ve güvenlik. Birileri kapıyı zorluyor demektir.
Tek bir başarısız login normaldir; parolasını yanlış giren kullanıcıdır. Aynı rip (remote IP) değerinden dakikada onlarca tanesi brute-force'tur ve hesap ele geçirilirse sunucun spam relay'ine döner.
2. Teslim edilebilirlik. Reputasyonun ve müşteri memnuniyetinin canlı sinyali.
Tek bounced gürültüdür. Ani dmarc=fail artışı ya spoof edilen bir alan adı ya da senin imzalama zincirinin kırıldığı anlamına gelir; ikisi de reputasyon konusudur.
3. Altyapı sağlığı. Kuyruğun neden dolduğunu buradan görürsün.
connect ... timed out, queue file write error, Permission denied — bunlar diske, DNS'e veya uzak MX'e dair yapısal sorunlardır.
4. Süreç ölümü. Tartışmasız page konusu.
dovecot: master: Panic: file ostream.c: line 197
dovecot: imap(user): Fatal: master: service(imap): child 5123 killed with signal 11
dovecot: Time just moved backwards by 34 seconds
Bir Dovecot Panic: veya Fatal: demek, o an bazı kullanıcıların IMAP oturumunun düştüğü demektir. Oran beklemezsin — tek olayda page.
Tek satır değil oran: pencere ve eşik seçmek
grep | mail neden çöker? Çünkü mail logunda bir olayın "kötü" olup olmadığını birim zamandaki yoğunluğu belirler. Uzak sunucu greylisting yapıyorsa deferred görmek tamamen normaldir; onu tek satır bazında alarma bağlarsan gece boyu telefonun titrer. Somut eşikler olmadan bu iş yürümez:
Sinyal
Eşik
Aksiyon
SASL fail (tek rip)
> 20/dk
page (brute-force)
Dovecot Panic/Fatal
1 olay
anında page
deferred kuyruk derinliği
> 200, for 10 dk
warn
deferred kuyruk derinliği
> 2000
page
bounce oranı (bounced/sent)
> %5, 15 dk
warn
TLS handshake fail
> 30/5 dk
warn
dmarc=fail
baz değerin 3 katı
reputation warn
İki mekanizma bu tablonun kalbi. increase(...[1m]) bir sayacın son bir dakikadaki artışını verir, yani satırı zaman penceresindeki adede çevirir; for: 2m ise "eşik geçici bir sıçrama değil, en az iki dakika sürdü" der. Bu ikisi birlikte tek seferlik gürültüyü otomatik eler.
Boru hattı mimarisi ve araç seçimi
Ham log satırından Slack bildirimine giden yol beş katmandan geçer: kaynak → shipper → kural/metrik motoru → Alertmanager → çıkış kanalları. 2026'da üç geçerli yaklaşım var ve hangisini seçeceğin ne kadar log sakladığına bağlı.
Vector — tek binary, VRL diliyle parse + throttle + doğrudan Slack sink. Küçük/orta kurulumda anlık güvenlik olayları için en pratiği. Loki'ye de yazabilir ama şart değil.
Promtail + Loki + ruler (LogQL) — logu aramak/saklamak istiyorsan. LogQL kuralları da oran hesaplayabilir.
mtail — logdan Prometheus metriği üretir. Oran tabanlı kurallar için en temiz yol; sayaçları Alertmanager'a bağlarsın.
Pratikte en dayanıklı kurulum hibrit: anlık olaylar (Panic, brute-force başlangıcı) için Vector'ün doğrudan sink'i, oran/eşik tabanlı alarmlar için mtail + Prometheus + Alertmanager. Böylece Prometheus çökse bile Vector'ün page yolu ayakta kalır.
Logu doğru üretmek: journald, rsyslog ve ayrıntı seviyesi
İzlemeye başlamadan önce logun kendisi tutarlı ve yeterli detayda akmalı. Modern kurulumda iki kaynak var: klasik /var/log/mail.log (rsyslog) ve systemd journal. Canlı bakmak için:
bash
journalctl -u postfix -u dovecot -f
# ya da dosyadan
tail -F /var/log/mail.log
Postfix'te TLS sorunlarını görebilmek için ayrıntıyı bir kademe aç — ama debug'ı açma, log'u boğar:
Dovecot tarafında auth denemelerini görünür kıl, ama parolayı asla loglama — bu bir gizlilik ihlali ve düz metin parola sızıntısıdır:
# /etc/dovecot/conf.d/10-logging.conf
auth_verbose = yes
auth_verbose_passwords = no
mail_debug = no
rsyslog kullanıyorsan mail facility'sini ayrı bir dosyaya yönlendir ve aynı anda shipper'a fan-out et; böylece Vector journald yerine dosyayı okuyabilir. Bir kritik uyarı: Dovecot Panic: çıktısı çok satırlı bir stack trace basar. Multiline parser kurmazsan tek çöküş 30 ayrı event'e bölünür ve 30 alarm patlar. Shipper'da "yeni event, tarih damgasıyla başlayan satırda başlar; girintili devam satırları ona eklenir" kuralı şart.
Vector ile desen eşleme, throttle ve Slack sink
Anlık güvenlik olayları için Vector'ün VRL transform'u fazlasıyla yeterli. Aşağıdaki config journald'den okur, severity etiketler, saldıran IP'yi rip= veya [...] biçiminden çıkarır, aynı IP'yi throttle'lar ve page olanları Slack'e atar:
throttle transform'u aynı rip'ten dakikada bir event'e indirir; key boş kalan olaylar (Panic gibi) hiç throttle edilmeden geçer. Böylece brute-force başlarken tek bildirim alırsın, ama iki ayrı çöküş asla birbirini yutmaz. Deploy öncesi mutlaka doğrula:
bash
vector validate /etc/vector/vector.toml
Oran tabanlı sinyaller: mtail programı + Alertmanager
Vector "oldu/olmadı" der, ama "dakikada 20'yi geçti mi" sorusunu en temiz mtail cevaplar. Kısa bir mtail programı SASL fail'lerini rip bazında sayar:
Prometheus bu metriği scrape eder, kural dosyası eşiği uygular. Dikkat: rate() saniye başına değer verir; "dakikada 20" istiyorsan increase(...[1m]) ile pencere içindeki adedi say:
Asıl mühendislik burada. Bir mail sunucusu günde milyonlarca satır basar; işin yüzde doksanı o satırları azaltmaktır, çoğaltmak değil. Alertmanager'ın üç aracı bunu yapar:
inhibit_rules — bir host down alarmı varken o hosttaki tüm warn'ları bastırır. Sunucu çöktüğünde 40 "TLS fail" alarmı almazsın, tek "host down" alırsın.
Bu bir huni. Aşağıdaki gerçek oranlarla düşün: günde 2.4 milyon ham satır, desen eşleşen 3.100 event, oran eşiğini aşan 48, dedup ve inhibition sonrası 9 alarm, gerçekten page eden 2. Her aşama bir öncekini bir büyüklük mertebesi kısar.
Kurulum kontrol listesi
[ ] mail facility ayrı dosyaya yazılıyor ve shipper'a gidiyor
[ ] Dovecot Panic/Fatal için tek-olay page kuralı var, multiline parser çok satırlı stack'i tek event yapıyor
[ ] Brute-force rip bazında throttle ediliyor + fail2ban ile ikili savunma kurulu
[ ] Bounce/deferred oranı hesaplanıyor, tek sayıya bakılmıyor
[ ] page ve warn için iki ayrı Slack kanalı + on-call e-posta ayrımı yapıldı
[ ] Bakım penceresi için amtool silence prosedürü yazılı bir runbook'ta
[ ] Alarmlar staging'de sahte log enjekte edilerek test edildi: logger -p mail.warning "postfix/smtpd: warning: unknown[203.0.113.7]: SASL LOGIN authentication failed"
Son bir hatırlatma: auth_verbose_passwords'ı asla açma, deferred'ı tek başına alarma bağlama (greylisting normaldir) ve her kuralı canlıya almadan önce sahte logla tetikle. Alarm sisteminin ilk defa gerçek bir olayda test edilmesi, en pahalı test senaryosudur.