Mail sunucusu yönetiminin en kritik ama en az konuşulan konularından biri, gelen ve giden e-postalarin içeriğini filtrelemek. Postfix’in sunduğu header_checks ve body_checks mekanizmaları, bu işi kurallar bazlı, esnek ve performanslı bir şekilde yapmanı sağlıyor. Spam engellemekten veri sızıntısı önlemeye, şüpheli ekleri bloke etmekten kurumsal politika uygulamalarına kadar geniş bir kullanım alanı var. Bu yazıda bu iki mekanizmayı derinlemesine inceleyeceğiz.
Header Checks ve Body Checks Nedir?
Postfix, bir e-posta aldığında veya iletirken mesajı birkaç farklı katmanda inceleme imkanı sunar. header_checks, e-postanın başlık kısmını (From, To, Subject, X- başlıkları vb.) regex tabanlı kurallarla tarar. body_checks ise mesajın gövdesini, yani içeriğini aynı şekilde tarar.
Her iki mekanizma da temelde şu şekilde çalışır:
- Bir satır okunur
- Tanımlı regex kalıplarıyla eşleştirilir
- Eşleşme bulunursa belirlenen eylem uygulanır (REJECT, WARN, DISCARD, HOLD, PREPEND, REPLACE vb.)
Bu sistemin güzel yanı, harici bir yazılıma ihtiyaç duymadan Postfix’in kendi içinde çalışması. SpamAssassin veya Amavis gibi araçlarla entegre çalışırken bile header/body checks ek bir savunma katmanı olarak değerini korur.
Temel Yapılandırma
Önce main.cf dosyasına gerekli direktifleri ekleyelim:
# /etc/postfix/main.cf
header_checks = regexp:/etc/postfix/header_checks
body_checks = regexp:/etc/postfix/body_checks
# MIME başlıkları için ayrı kontrol (isteğe bağlı)
mime_header_checks = regexp:/etc/postfix/mime_header_checks
# İç ağdan gelen postalar için nested header kontrolü
nested_header_checks = regexp:/etc/postfix/header_checks
Burada regexp: öneki, dosyanın POSIX extended regular expression formatında olduğunu belirtir. Alternatif olarak pcre: önekini de kullanabilirsin, PCRE kütüphanesi kuruluysa:
# PCRE kullanmak istersen (daha güçlü regex desteği)
header_checks = pcre:/etc/postfix/header_checks
PCRE daha güçlü regex özellikleri sunsa da performans açısından regexp biraz daha hızlı çalışır. Büyük hacimli sunucularda bu fark hissedilebilir.
Eylem Tipleri
Kurallar yazarken kullanabileceğin eylemleri bilmek çok önemli. Yanlış eylem seçimi ya maillerin kaybolmasına ya da log’ların gereksiz dolmasına neden olur.
- REJECT: Maili reddeder ve gönderene bounce mesajı döner
- DISCARD: Maili sessizce siler, gönderene bildirim yapılmaz
- HOLD: Maili hold kuyruğuna alır, manuel inceleme için bekletir
- WARN: Sadece log yazar, maili iletir (test amaçlı harika)
- PREPEND: Başlığın başına yeni bir satır ekler
- REPLACE: Eşleşen satırı başka bir değerle değiştirir
- IGNORE: Eşleşen satırı sessizce siler
- FILTER: Maili belirtilen transport’a yönlendirir
- REDIRECT: Maili farklı bir adrese yönlendirir
Header Checks Dosyası Oluşturma
Şimdi gerçek dünya senaryolarına geçelim. /etc/postfix/header_checks dosyasını oluşturalım:
# /etc/postfix/header_checks
# Format: /regex/ eylem [açıklama]
# ---- SPAM VE PHISHING ENGELLEMESİ ----
# Boş From başlığını engelle
/^From:s*$/ REJECT Empty From header not accepted
# Sahte Microsoft/Apple/Google gönderenlerini engelle
/^From:.*@.*microsoft.com./ REJECT Forged Microsoft sender
/^From:.*@.*apple.com./ REJECT Forged Apple sender
/^From:.*@.*google.com./ REJECT Forged Google sender
# Çok yaygın phishing pattern'leri
/^Subject:.*Urgent.*Account.*Verification/i REJECT Phishing attempt detected
/^Subject:.*You have won/i REJECT Lottery spam not accepted
/^Subject:.*Nigerian/i DISCARD
# ---- ŞÜPHELİ X- BAŞLIKLARI ----
# Bilinen spam araçlarının imzaları
/^X-Mailer:.*The Bat!/i WARN Suspicious mailer detected
/^X-Mailer:.*Gammadyne/i REJECT Known spam tool
# ---- KURUMSAL POLİTİKA ----
# Dışarıdan gelen BCC kontrolü (isteğe bağlı, dikkatli kullan)
/^X-Original-To:.*@competitor.com/i HOLD Competitor domain - manual review
# Zararlı içerik işaretleme
/^X-Spam-Status: Yes/ DISCARD
Dosyayı oluşturduktan sonra Postfix’in okuyabileceği hash formatına dönüştürmek gerekiyor. Ama regexp/pcre dosyaları için postmap gerekmez, direkt okunur. Sadece Postfix’i yeniden yüklemek yeterli:
sudo postfix reload
# veya
sudo systemctl reload postfix
Body Checks Dosyası Oluşturma
Body checks, mailin metin içeriğini satır satır tarar. Bu yüzden regex’lerinizi çok genel tutarsanız false positive oranınız fırlar.
# /etc/postfix/body_checks
# ---- ZARALI LINK ENGELLEMESİ ----
# Bilinen zararlı domain'ler
/http[s]?://.*malware-site.com/i REJECT Malicious URL detected
/http[s]?://.*phishing-example.net/i REJECT Known phishing domain
# Kısaltılmış URL'leri işaretle (dikkatli ol, meşru kullanım da var)
# /http[s]?://(bit.ly|tinyurl.com|t.co)// WARN Shortened URL detected
# ---- VERİ SIZINTISI ÖNLEMESİ (DLP) ----
# Türkiye TC Kimlik No pattern'i (11 hane, belirli kurallara göre)
/b[1-9][0-9]{10}b/ HOLD Possible TC ID number - compliance review
# Kredi kartı numarası pattern'leri
/b4[0-9]{12}(?:[0-9]{3})?b/ HOLD Possible Visa card number
/b5[1-5][0-9]{14}b/ HOLD Possible Mastercard number
# ---- EXECUTABLE İÇERİK ----
# Base64 encoded executable başlıkları (PE format)
/TVqQAAMAAAAEAAAA/ REJECT Possible Windows executable in body
# ---- SPAM KELİMELERİ ----
# Dikkatli kullan, false positive riski yüksek
/bViagrab/i WARN Possible pharmaceutical spam
/bCialisb/i WARN Possible pharmaceutical spam
Önemli not: Body checks her satır için regex’i çalıştırır. Büyük mesajlarda bu performans sorununa yol açabilir. Bu yüzden body_checks’i mümkün olduğunca spesifik tutmak gerekir.
MIME Header Checks
HTML mailler, ekler ve çok parçalı mesajlar için MIME başlıklarını ayrıca kontrol edebilirsin:
# /etc/postfix/mime_header_checks
# Tehlikeli dosya uzantılarını engelle
/^Content-Disposition:.*.(exe|bat|cmd|com|pif|scr|vbs|js)(s|;|")/i REJECT Dangerous attachment type blocked
/^Content-Disposition:.*.(ps1|msi|reg|dll)(s|;|")/i HOLD PowerShell/system file - manual review
# Çift uzantılı dosyaları engelle (klasik sosyal mühendislik)
/^Content-Disposition:.*.(doc|pdf|xls|jpg|png).(exe|bat|scr)/i REJECT Double extension attack detected
# Content-Type kontrolü
/^Content-Type:.*application/x-msdownload/i REJECT Executable content type blocked
/^Content-Type:.*application/x-msdos-program/i REJECT DOS executable blocked
# Şifreli zip'leri işaretle (zararlı yazılım dağıtımında sık kullanılır)
/^Content-Disposition:.*.(zip|rar|7z)(s|;|")/i WARN Compressed attachment received
Gelişmiş Senaryolar
Senaryo 1: Outbound DLP (Giden Mail Denetimi)
Kurumsal bir ortamda çalışanların hassas bilgileri dışarı sızdırmasını önlemek için:
# /etc/postfix/header_checks - giden mail için ek kurallar
# Gizlilik etiketli mailleri logla
/^Subject:.*[CONFIDENTIAL]/i WARN Outbound confidential mail logged
# Yönetici onayı gereken büyük dağıtım listeleri
# Bu genellikle recipient_bcc_maps ile birlikte kullanılır
/^To:.*all-staff@/i PREPEND X-Bulk-Mail-Warning: Large distribution list detected
Senaryo 2: Amavis veya SpamAssassin Entegrasyonu ile Çalışma
SpamAssassin bir spam skoru ekliyorsa bu skoru header_checks ile değerlendirebilirsin:
# /etc/postfix/header_checks
# SpamAssassin skoru 10 ve üzerindeyse sil
/^X-Spam-Score: (10|[1-9][0-9]+)./ DISCARD High spam score - discarded
# Spam skoru 5-9 arasındaysa hold et
/^X-Spam-Score: [5-9]./ HOLD Medium spam score - held for review
# SpamAssassin kesin spam demiş
/^X-Spam-Flag: YES/ DISCARD Spam discarded per SA decision
Senaryo 3: Whitelist ile Birlikte Kullanım
Bazı durumlarda belirli gönderenleri veya domain’leri kuralların dışında tutmak gerekir. Postfix’te bunu check_sender_access ile kombinleyebilirsin:
# main.cf içinde smtpd_recipient_restrictions veya smtpd_data_restrictions kullan
# header_checks ile whitelist kombinasyonu için şöyle bir yaklaşım izlenebilir:
# header_checks içinde güvenilir gönderende de çalışır, o yüzden
# kritik kurallar için smtpd seviyesinde kontrol daha sağlıklı
Kuralları Test Etme
Yeni bir kural yazmadan önce mutlaka test et. Postfix’in postmap aracı regexp/pcre dosyalarını test edemez, onun yerine postfix komut satırı araçlarını kullanman gerekir. En pratik yöntem:
# Bir test maili oluştur ve postcat ile incele
echo "Subject: You have won a prize" | sendmail -bv test@localhost
# postfix loglarını canlı izle
tail -f /var/log/mail.log | grep -E "(header_checks|body_checks|REJECT|HOLD|WARN)"
# Belirli bir regex'in çalışıp çalışmadığını test et
echo "Subject: You have won a prize" | grep -iP "You have won"
Daha kapsamlı bir test için geçici olarak kuralı WARN moduna al, birkaç gün log izle, sonra REJECT’e geçir. Bu “kademeli devreye alma” yaklaşımı, üretim ortamında çok önemli:
# Önce test modunda çalıştır
/^Subject:.*You have won/i WARN TEST-RULE: Potential lottery spam
# Logda şöyle görünür:
# postfix/cleanup[1234]: warning: header Subject: You have won ...:
# TEST-RULE: Potential lottery spam
# Yeterince gözlemledikten sonra REJECT'e çevir
/^Subject:.*You have won/i REJECT Lottery spam not accepted
Performans Optimizasyonu
Header ve body checks yüksek trafikli sunucularda dikkatli yönetilmesi gereken özellikler. Birkaç önemli nokta:
- Body checks’i minimal tut: Her satır için tüm regex’ler çalışır. 50 kuralın olduğu bir body_checks dosyası büyük maillerde ciddi CPU yükü oluşturabilir.
- PCRE yerine regexp tercih et: Basit kurallar için regexp daha hızlı.
- Alternation kullan: Benzer kuralları tek bir regex’te birleştir.
# Verimsiz yaklaşım - üç ayrı kural
/^Content-Disposition:.*.exe/i REJECT
/^Content-Disposition:.*.bat/i REJECT
/^Content-Disposition:.*.cmd/i REJECT
# Verimli yaklaşım - tek kural
/^Content-Disposition:.*.(exe|bat|cmd|com|pif|scr|vbs|js|ps1)/i REJECT Dangerous file type
- Değişiklik sonrası reload yeterli:
restartyerinereloadkullan, kuyrukta bekleyen mailler etkilenmez.
# Doğru yaklaşım
sudo postfix reload
# Konfigürasyon sözdizimini önce kontrol et
sudo postfix check
Logları Anlama ve Sorun Giderme
Kuralların çalışıp çalışmadığını anlamak için log formatını bilmek şart:
# Gerçek log örnekleri
# REJECT durumu:
# postfix/cleanup[2341]: 8F3A22A1234: reject: header Subject: Win $1000000
# from mail.example.com[1.2.3.4]; from=<[email protected]> to=<[email protected]>
# proto=ESMTP helo=<mail.example.com>: 5.7.1 Lottery spam not accepted
# HOLD durumu:
# postfix/cleanup[2341]: A1B2C2A5678: hold: header X-Spam-Score: 7.2
# from ...: Mail held for review
# WARN durumu (mail iletilir, sadece log yazılır):
# postfix/cleanup[2341]: warning: header X-Mailer: The Bat! ...
# Suspicious mailer detected
# Hold kuyruğunu görüntüle
sudo postqueue -p | grep -i hold
# Hold'daki bir maili serbest bırak
sudo postsuper -H KUYRUK_ID
# Hold'daki bir maili sil
sudo postsuper -d KUYRUK_ID
# Tüm hold mesajlarını serbest bırak
sudo postsuper -H ALL
Yaygın Hatalar ve Dikkat Edilmesi Gerekenler
Çok geniş regex yazmak: /password/i REJECT gibi bir kural, şifre sıfırlama maillerini de reddeder. Daima bağlamı daralt.
DISCARD’ı körce kullanmak: Gönderene bildirim gitmediği için mesaj kaybolur. Özellikle iç iletişimde kullanmaktan kaçın. HOLD daha güvenli bir alternatif.
Regex’te özel karakterleri escape etmemek: .com yerine .com yaz, yoksa Xcom, 1com gibi değerler de eşleşir.
Body checks’i gelen ve giden mail için aynı tutmak: Giden maillerde body checks DLP amaçlı kullanılabilir ama gelen maillerde false positive riski çok yüksek. İkisini ayırt etmek için smtpd_data_restrictions veya transport bazlı farklı cleanup servisleri kullanabilirsin.
Test etmeden production’a almak: Yukarıda anlattığım WARN yaklaşımını atlamak, kritik iş maillerinin kaybına neden olabilir.
Sonuç
Postfix’in header_checks ve body_checks mekanizmaları, doğru kullanıldığında çok güçlü bir ilk savunma katmanı oluşturur. SpamAssassin ya da ticari anti-spam çözümleriyle birlikte çalışmak isteyen bir sysadmin için bu araçlar, kurumsal politikaları zorlamak, veri sızıntısını önlemek ve bilinen tehdit imzalarını engellemek açısından vazgeçilmez.
Ancak güç, dikkat ister. Regex kalıplarını geniş tutmak, false positive oranını artırır ve meşru maillerin kaybolmasına yol açar. Her yeni kural önce WARN modunda devreye alınmalı, loglar birkaç gün izlenmeli, ancak sonra aktif hale getirilmeli.
Bu yapılandırmaları düzenli olarak gözden geçirmek de önemli. Siber tehditler değişiyor, saldırı vektörleri evrim geçiriyor. Altı ayda bir kural setini gözden geçirip eskimiş veya artık ihtiyaç duyulmayan kuralları temizlemek, hem performans hem de yönetilebilirlik açısından faydalı olacaktır.