Postfix ile Milter Protokolü ve Filtre Entegrasyonu

Mail sunucusu yönetiminde en çok baş ağrıtan konuların başında spam filtreleme ve içerik denetimi gelir. Postfix’i kurup çalıştırmak artık görece kolay, ancak gelen-giden mailleri filtrelemek, virüs taramak ve politika uygulamak bambaşka bir iş. İşte bu noktada Milter protokolü devreye giriyor. Bu yazıda Milter’ın ne olduğunu, nasıl çalıştığını ve Postfix ile nasıl entegre edileceğini gerçek dünya senaryolarıyla ele alacağız.

Milter Nedir ve Neden Kullanıyoruz?

Milter (Mail Filter), Sendmail projesi tarafından geliştirilen ancak bugün Postfix dahil pek çok MTA tarafından desteklenen bir filtreleme protokolüdür. Temel mantığı şu: mail sunucusu, bir mesajı kabul etmeden önce veya teslim etmeden önce harici bir programa danışıyor. Bu program mesajı inceliyor, gerekirse değiştiriyor ya da reddediyor.

Neden Milter? Çünkü alternatifler olan content_filter veya pipe yöntemleri mesajı tamamen kuyruktan alıp işler ve bu süreçte kayıp riski oluşabilir. Milter ise SMTP oturumu sırasında gerçek zamanlı çalışır. Yani bir spamci mail göndermeye çalıştığında, mesaj henüz kuyruğa girmeden reddedilir. Bu hem kaynak tasarrufu sağlar hem de bounce mesajı üretilmesini engeller.

Yaygın Milter uygulamaları şunlardır:

  • SpamAssassin (spamd/spamass-milter): İçerik tabanlı spam puanlama
  • ClamAV (clamav-milter): Virüs tarama
  • OpenDKIM: DKIM imzalama ve doğrulama
  • OpenDMARC: DMARC politika uygulaması
  • Rspamd: Modern, yüksek performanslı spam filtresi (milter arayüzü var)
  • Postgrey: Greylisting uygulaması

Milter Protokolünün Çalışma Mantığı

Bir SMTP bağlantısı kurulduğunda Postfix, Milter’a adım adım bilgi gönderir. Milter bu bilgilere dayanarak kararlar verir. Protokolde şu aşamalar vardır:

  • xxfi_connect: Bağlantı kurulduğunda tetiklenir, IP adresi ve hostname bilgisi gelir
  • xxfi_helo: EHLO/HELO komutu alındığında tetiklenir
  • xxfi_envfrom: MAIL FROM komutu, yani gönderici adresi geldiğinde tetiklenir
  • xxfi_envrcpt: RCPT TO komutu, yani alıcı adresi her eklendiğinde tetiklenir
  • xxfi_header: Her bir mail başlığı geldiğinde tetiklenir
  • xxfi_eoh: Tüm başlıklar bittikten sonra tetiklenir
  • xxfi_body: Mail gövdesi chunk’lar halinde gelir
  • xxfi_eom: Mesaj tamamen alındığında tetiklenir, burada en kapsamlı kararlar verilebilir

Milter bu aşamaların herhangi birinde ACCEPT, REJECT, TEMPFAIL, DISCARD veya CONTINUE kararları verebilir. Ayrıca başlık ekleyebilir, değiştirebilir veya silebilir.

Postfix Yapılandırması: Temel Milter Ayarları

Postfix’te Milter yapılandırması main.cf dosyasında yapılır. İki temel parametre vardır:

  • smtpd_milters: SMTP üzerinden gelen (inbound) mesajlar için geçerlidir
  • non_smtpd_milters: Postfix’in kendi ürettiği ya da pipe aracılığıyla gelen mesajlar için geçerlidir
# /etc/postfix/main.cf

# Inbound mail için milter'lar
smtpd_milters = inet:localhost:8891,inet:localhost:7357

# Lokal/internal mail için milter'lar
non_smtpd_milters = inet:localhost:8891

# Milter ile iletişim protokol versiyonu
milter_protocol = 6

# Bir milter erişilemez olduğunda ne yapılacak
# accept, reject, tempfail, quarantine
milter_default_action = accept

# Milter bağlantı zaman aşımı
milter_connect_timeout = 30s

# Milter komut zaman aşımı
milter_command_timeout = 30s

# Milter içerik okuma zaman aşımı
milter_content_timeout = 300s

milter_default_action parametresi kritik önem taşır. Üretim ortamında çoğunlukla accept tercih edilir, yani Milter erişilemez olursa mail geçirilir. Bu sayede bir filtre çöktüğünde mail akışı durmuyor. Ancak güvenlik odaklı ortamlarda tempfail da tercih edilebilir.

Milter adresleri için iki format kullanılabilir:

# TCP soket (uzak veya lokal sunucu)
inet:localhost:8891
inet:127.0.0.1:8891

# Unix domain soket (aynı sunucuda daha hızlı)
unix:/var/run/opendkim/opendkim.sock
local:/var/run/clamav/clamav-milter.ctl

Unix soketleri TCP’ye göre daha düşük latency sunar ancak local: ile unix: prefix’lerinin Postfix versiyonuna göre farklılık gösterdiğine dikkat edin. Postfix 2.6 ve sonrasında unix: kullanın.

OpenDKIM Entegrasyonu

DKIM (DomainKeys Identified Mail), giden maillere dijital imza ekler ve bu sayede alıcı sunucular mailin gerçekten sizin domain’inizden geldiğini doğrulayabilir. Kurulumdan entegrasyona kadar adım adım gidelim.

# Debian/Ubuntu
apt install opendkim opendkim-tools

# RHEL/CentOS/Rocky
dnf install opendkim

OpenDKIM yapılandırması:

# /etc/opendkim.conf

Mode                  sv
Syslog                yes
SyslogSuccess         yes
LogWhy                yes

UserID                opendkim:opendkim
Socket                inet:8891@localhost
PidFile               /var/run/opendkim/opendkim.pid

Canonicalization      relaxed/simple
Domain                example.com
Selector              mail2024

KeyFile               /etc/opendkim/keys/example.com/mail2024.private

# Birden fazla domain için tablo kullan
#KeyTable             /etc/opendkim/key.table
#SigningTable         refile:/etc/opendkim/signing.table
#ExternalIgnoreList   refile:/etc/opendkim/trusted.hosts
#InternalHosts        refile:/etc/opendkim/trusted.hosts

DKIM key çifti oluşturma:

# Key dizini oluştur
mkdir -p /etc/opendkim/keys/example.com

# 2048-bit RSA key oluştur
opendkim-genkey -t -s mail2024 -d example.com -b 2048 
    -D /etc/opendkim/keys/example.com/

# İzinleri ayarla
chown -R opendkim:opendkim /etc/opendkim/keys/
chmod 600 /etc/opendkim/keys/example.com/mail2024.private

# Public key'i görüntüle (DNS'e eklenecek)
cat /etc/opendkim/keys/example.com/mail2024.txt

Çıktı şuna benzer bir şey olacak:

mail2024._domainkey IN TXT ( "v=DKIM1; k=rsa; "
    "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..." )

Bu değeri DNS’e TXT kaydı olarak ekledikten sonra OpenDKIM’i başlatıp Postfix’e bağlayabilirsiniz:

systemctl enable --now opendkim

# Postfix main.cf'e ekle
postconf -e 'smtpd_milters = inet:localhost:8891'
postconf -e 'non_smtpd_milters = inet:localhost:8891'
postconf -e 'milter_default_action = accept'

systemctl reload postfix

DKIM imzasını test etmek için:

echo "Test mail" | mail -s "DKIM Test" [email protected]
# Gmail veya Yahoo üzerinden "Original Message"e bakın
# Authentication-Results başlığında dkim=pass görmelisiniz

# OpenDKIM'in çalıştığını doğrula
opendkim-testkey -d example.com -s mail2024 -vvv

ClamAV Milter ile Virüs Tarama

ClamAV-Milter, gelen mailleri virüs açısından tarar ve enfekte mesajları SMTP oturumu sırasında reddeder.

apt install clamav clamav-daemon clamav-milter

# İmzaları güncelle
freshclam

# ClamAV daemon'ı başlat
systemctl enable --now clamav-daemon

ClamAV Milter yapılandırması /etc/clamav/clamav-milter.conf:

# Soket tipi seçin - Unix soket daha hızlı
MilterSocket /var/run/clamav/clamav-milter.ctl
MilterSocketMode 666

# ClamAV daemon ile bağlantı
ClamdSocket unix:/var/run/clamav/clamd.ctl

# Enfekte mail bulunduğunda ne yapılacak
# Reject, Quarantine, BlackHole, Accept
OnInfected Reject

# Hata durumunda
OnFail Accept

# Büyük dosyaları atla (MB cinsinden)
MaxFileSize 25M

# Log ayarları
LogSyslog yes
LogVerbose no
systemctl enable --now clamav-milter

# Postfix yapılandırmasını güncelle
postconf -e 'smtpd_milters = inet:localhost:8891,local:/var/run/clamav/clamav-milter.ctl'

systemctl reload postfix

# Test: EICAR test virüsü gönderin
echo 'X5O!P%@AP[4PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*' | 
    mail -s "Virus Test" [email protected]

Log’larda şunu görmelisiniz:

clamav-milter[1234]: MilterLogId=xxx: Blocked INFECTED (Eicar-Signature)

Rspamd ile Gelişmiş Spam Filtreleme

Rspamd, SpamAssassin’e göre çok daha hızlı ve modern bir spam filtresidir. Bayesian öğrenme, IP itibar kontrolü, URL kara listesi ve dahili Milter desteği ile birlikte gelir.

# Rspamd resmi repo'su
curl https://rspamd.com/apt-stable/gpg.key | apt-key add -
echo "deb https://rspamd.com/apt-stable/ $(lsb_release -cs) main" 
    > /etc/apt/sources.list.d/rspamd.list
apt update && apt install rspamd

# Redis (Rspamd için gerekli)
apt install redis-server
systemctl enable --now redis-server

Rspamd Milter ayarları /etc/rspamd/local.d/worker-proxy.inc:

# /etc/rspamd/local.d/worker-proxy.inc
bind_socket = "127.0.0.1:11332";
milter = yes;
timeout = 120s;
upstream "local" {
    default = yes;
    self_scan = yes;
}

Rspamd’ın spam eşik değerlerini ayarlamak için /etc/rspamd/local.d/actions.conf:

# /etc/rspamd/local.d/actions.conf
reject = 15;      # 15 puan üstü reddet
add_header = 6;   # 6 puan üstü başlık ekle
greylist = 4;     # 4 puan üstü greylist
systemctl enable --now rspamd

# Postfix'e ekle
postconf -e 'smtpd_milters = inet:localhost:8891,inet:localhost:11332'
systemctl reload postfix

# Rspamd web arayüzü için şifre oluştur
rspamadm pw -p "güçlü_şifreniz"
# Çıkan hash'i /etc/rspamd/local.d/worker-controller.inc içine koyun

Rspamd’ın düzgün çalışıp çalışmadığını test etmek:

# Rspamd CLI ile test
rspamc < /tmp/test_mail.eml

# Bayesian öğrenme - spam klasöründen öğren
rspamc learn_spam < spam_ornek.eml
rspamc learn_ham < ham_ornek.eml

Birden Fazla Milter’ı Birlikte Kullanmak

Gerçek dünya senaryolarında birden fazla Milter’ı aynı anda kullanmak gerekir. Bu durumda dikkat edilmesi gereken birkaç nokta vardır.

Milter’lar zincir şeklinde çalışır, soldaki önce çalışır:

# /etc/postfix/main.cf
smtpd_milters = 
    inet:localhost:8891,
    local:/var/run/clamav/clamav-milter.ctl,
    inet:localhost:11332

non_smtpd_milters = 
    inet:localhost:8891

Tavsiye edilen sıralama genellikle şu şekildedir:

  • Birincisi OpenDKIM veya OpenDMARC: Bağlantı düzeyinde, hızlı kararlar
  • İkincisi ClamAV: Virüs tarama, daha ağır ama kritik
  • Sonuncusu Rspamd/SpamAssassin: İçerik analizi, en ağır işlem

Bir Milter zinciri koptuğunda ne olacağını her biri için ayrı ayrı ayarlayabilirsiniz. Ancak bu Postfix’in native özelliği değil, her Milter’ın kendi hata yönetimidir.

OpenDMARC Entegrasyonu

DMARC, DKIM ve SPF politikalarını bir araya getirerek domain sahteciliğine (spoofing) karşı güçlü bir savunma hattı oluşturur.

apt install opendmarc

# /etc/opendmarc.conf
Socket                  inet:8893@localhost
AuthservID              mail.example.com
TrustedAuthservIDs      mail.example.com
RejectFailures          false
IgnoreAuthenticatedClients true
RequiredHeaders         true
SPFIgnoreResults        false
SPFSelfValidate         true

# Tarihsel veri için (isteğe bağlı)
#HistoryFile            /var/run/opendmarc/opendmarc.dat
systemctl enable --now opendmarc

# Postfix'e ekle
postconf -e 'smtpd_milters = inet:localhost:8893,inet:localhost:8891,local:/var/run/clamav/clamav-milter.ctl,inet:localhost:11332'

systemctl reload postfix

DNS’e DMARC kaydı eklemek için:

# _dmarc.example.com TXT kaydı
"v=DMARC1; p=quarantine; rua=mailto:[email protected]; ruf=mailto:[email protected]; pct=100; adkim=r; aspf=r"

Sorun Giderme ve Monitoring

Milter sorunlarını tespit etmek için log analizi şarttır.

# Postfix mail loglarını takip et
tail -f /var/log/mail.log | grep -E "(milter|REJECT|reject)"

# Belirli bir Milter'ın kararlarını izle
grep "opendkim" /var/log/mail.log | tail -50
grep "clamav" /var/log/mail.log | tail -50

# Rspamd log'ları
journalctl -u rspamd -f

# Bir maili manuel olarak test et (telnet ile SMTP simülasyonu)
telnet localhost 25
EHLO test.local
MAIL FROM:<[email protected]>
RCPT TO:<[email protected]>
DATA
Subject: Milter Test
From: [email protected]
To: [email protected]

Test mesaji.
.
QUIT

Milter soket durumunu kontrol etmek:

# TCP soketleri listele
ss -tlnp | grep -E "(8891|8893|11332)"

# Unix soketlerini kontrol et
ls -la /var/run/clamav/
ls -la /var/run/opendkim/

# Postfix'in Milter'a bağlanıp bağlanamadığını test et
postfix check

# Milter konfigürasyonunu doğrula
postconf -n | grep milter

Yaygın hata senaryoları ve çözümleri:

  • “milter: can’t connect to Milter service”: Servis çalışmıyor veya soket izinleri yanlış. systemctl status opendkim ile kontrol edin
  • “milter-reject: END-OF-MESSAGE”: Milter mesajı reddetti, hangi Milter olduğunu log’dan bulun
  • Postfix soket izin hatası: postfix kullanıcısını ilgili gruba ekleyin, örneğin usermod -aG clamav postfix
  • Timeout hataları: milter_command_timeout değerini artırın, özellikle yoğun sistemlerde

Gerçek Dünya Senaryosu: Kurumsal Mail Ortamı

100 çalışanlı bir şirketin mail sunucusunu yönettiğinizi düşünelim. Günde 5.000 mail alıyorsunuz, bunun %40’ı spam. Aşağıdaki Milter yığını iyi bir başlangıç noktasıdır:

# /etc/postfix/main.cf - Üretim yapılandırması

# Milter zinciri
smtpd_milters = 
    inet:127.0.0.1:8893,
    inet:127.0.0.1:8891,
    unix:/var/run/clamav/clamav-milter.ctl,
    inet:127.0.0.1:11332

non_smtpd_milters = 
    inet:127.0.0.1:8891

# Protokol ve timeout ayarları
milter_protocol = 6
milter_default_action = accept
milter_connect_timeout = 30s
milter_command_timeout = 30s
milter_content_timeout = 300s

# Header kontrolü - başlık boyutu sınırı
header_size_limit = 32768

Bu yapıda DMARC önce çalışıp sahte gönderici tespiti yapıyor, DKIM imzayı doğruluyor, ClamAV virüs tarıyor ve Rspamd içerik analizini yapıyor. Bir spam maili genellikle DMARC veya Rspamd tarafından kesilebiliyor, dolayısıyla ClamAV yükü görece düşük kalıyor.

Performans optimizasyonu için Rspamd’a Redis bağlayarak greylist ve rate limiting özelliklerini aktif edin. Günde 5.000 mail için bu yığın tek bir orta boy sunucuda rahatlıkla koşar.

Sonuç

Postfix’te Milter entegrasyonu ilk bakışta karmaşık görünse de temel mantığı kavradıktan sonra oldukça esnek ve güçlü bir yapı ortaya çıkıyor. SMTP oturumu sırasında gerçek zamanlı filtreleme, hem kaynak tasarrufu hem de güvenlik açısından content_filter alternatifine göre önemli avantajlar sağlıyor.

Özetle iyi bir Milter yığını şu bileşenleri içermeli: DKIM imzalama için OpenDKIM, domain politikası uygulaması için OpenDMARC, virüs tarama için ClamAV-Milter ve spam filtreleme için Rspamd. Bu dördü birlikte çalıştığında kurumsal düzeyde bir mail güvenlik katmanı elde ediyorsunuz.

Her Milter’ı ayrı ayrı test ettikten sonra zincire dahil edin. milter_default_action = accept ile başlayıp sisteminizin davranışını izleyin. Zaman içinde eşik değerlerini ve politikaları kendi ortamınıza göre ayarlarsınız. Log’ları düzenli izlemek ve Rspamd’ı düzenli olarak Bayesian verilerle beslemek, filtreleme kalitesini ciddi ölçüde artırır.

Yorum yapın