Postfix Multi-Instance: Gelen ve Giden Postayı Ayrı Kuyruklarda İzole Etmek
Tek Postfix instance'ında gelen ve giden postayı aynı kuyrukta çalıştırmak deliverability için zaman bombasıdır. postmulti ile aynı makinede ayrı spool, ayrı çıkış IP'si ve ayrı reputasyon havuzuna nasıl böleceğinizi adım adım gösteriyoruz.
EvilMail Team13 Temmuz 202612 dk okuma
Tek bir Postfix instance'ında hem 25 numaralı porttan anonim MX trafiğini hem de 587'den kimlik doğrulamalı giden postayı çalıştırıyorsanız, iki tamamen farklı posta sistemini tek bir main.cf, tek bir kuyruk ve tek bir çıkış IP'si üzerinde sıkıştırıyorsunuz demektir. Düşük hacimde sorun çıkmaz; ta ki bir gün giden bir bülten patlaması ya da ele geçirilmiş bir hesabın spam'ı active kuyruğu doldurana kadar. O an geldiğinde meşru inbound teslimatınız da aynı qmgr scheduler'ında sıraya girer ve dakikalarca bekler.
Çözüm "iki ayrı sunucu kurun" klişesi değil. Postfix'in yerleşik postmulti mekanizmasıyla tek makinede fiziksel olarak ayrı instance'lar, ayrı spool dizinleri ve ayrı çıkış IP'leri oluşturabilirsiniz. Bu yazıda tam olarak bunu kuruyoruz.
Neden tek instance çöküyor: paylaşılan kuyruğun üç arızası
Gelen ve giden posta akışları üç farklı boyutta çakışır ve her biri kendi başına bir teslimat sorunu üretir.
1. Paylaşılan kuyruk starvation.
Postfix'te
incoming
,
active
ve
deferred
kuyrukları instance geneldir.
active
kuyruğunun bir boyut limiti vardır (
qmgr_message_active_limit
, varsayılan 20000) ve
qmgr
mesajları buraya round-robin çeker. Giden bir kampanya 15.000 mesajı
deferred
'a düşürdüğünde,
postqueue -p
çıktısı binlerce giden mesajla dolar ve aynı scheduler'dan geçen inbound mesajlar bu gürültünün arasında sıra bekler:
text
-Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient-------
A1B2C3D4E5 4821 Sat Jul 4 09:12:03 [email protected]
(host gmail.com refused to talk: 421-4.7.0 throttled)
[email protected]
... (14.900 satır daha giden) ...
F9E8D7C6B5 2210 Sat Jul 4 09:14:41 [email protected][email protected] <-- meşru inbound, sırada bekliyor
2. `smtpd_recipient_restrictions` şizofreni. Tek bir smtpd aynı anda iki zıt politikayı uygulamak zorunda kalır: anonim istemciden gelen relay girişimini reddetmek (MX davranışı) ve kimlik doğrulaması yapmış kullanıcıya dünyanın her yerine göndertmek (submission davranışı). İkisini tek restriction bloğunda permit_sasl_authenticated ile karıştırdığınızda, kural sıralamasındaki tek bir hata sizi open relay yapar.
3. Tek çıkış IP'si = tek reputasyon havuzu. Inbound MX'inizin A kaydı ile outbound HELO/PTR aynı IP'yi işaret ettiğinde, giden trafiğinizin itibar hasarı doğrudan MX'inizi de vurur. Bir kullanıcı hesabı ele geçirilip spam gönderdiğinde o IP Spamhaus'a düşer ve artık gelen postanız da reddedilmeye başlar. İki yön birbirinin rehinesi olur.
Üç arızanın ortak kökü aynı: paylaşılan durum. Çözüm de tek: durumu fiziksel olarak ayırmak.
Mimari: postmulti ile üç instance topolojisi
Tasarım şu: ana (default) instance'ı yönetim ve loopback için olduğu gibi bırakıyoruz, altına iki alt instance ekliyoruz. postfix-in yalnızca MX görevini (port 25) üstlenir, postfix-out yalnızca submission/relay görevini (587 + 465) üstlenir. Her instance kendi queue_directory, kendi data_directory, kendi master.cf ve kendi chroot'una sahiptir.
Ayrı spool neden bu kadar önemli? Çünkü kuyruk sayacı, qmgr scheduler ve default_process_limitinstance başına bağımsız çalışır. Outbound kuyruğu 50.000 mesaja şişse bile inbound qmgr bunun farkında bile olmaz; farklı bir dizinde, farklı bir process ile çalışır. IP planı da net: inbound 203.0.113.10 (mevcut MX A kaydı) üzerinde kalır, outbound için ayrı bir IPv4 adresi ve o adrese ait ayrı bir PTR ayırırsınız.
Instance'ları oluşturmak: postmulti komut akışı
Önce multi-instance altyapısını ana instance üzerinde etkinleştirin, sonra iki alt instance'ı oluşturun:
bash
# Multi-instance yönetimini başlat (ana instance'ı manager yapar)
postmulti -e init
# İki alt instance oluştur
postmulti -I postfix-in -G mx -e create
postmulti -I postfix-out -G out -e create
# Oluşan instance'ları listele
postmulti -l
# - - y /etc/postfix
# postfix-in mx n /etc/postfix-in
# postfix-out out n /etc/postfix-out
Her instance kendi config dizinini (/etc/postfix-in, /etc/postfix-out) ve postmulti -e create sırasında ayrı spool/data dizinlerini alır. Instance'a özel parametreleri -x bayrağıyla, o instance'ın bağlamında yazarsınız:
Her şeyi tek komutla ayağa kaldırın ve durumu doğrulayın:
bash
postmulti -p start
postmulti -p status
# postfix-in mx running
# postfix-out out running
Tek bir instance'ı reload etmek için postmulti -i postfix-out -p reload kullanırsınız — diğeri hiç etkilenmez. Giden yapılandırmayı canlı değiştirirken inbound teslimatı riske atmamanın temel operasyonel kazancı budur.
Inbound instance: sadece MX, sıfır relay
postfix-in internetten mesaj almalı ama asla dışarı relay etmemeli. master.cf içinde yalnızca smtp inet servisi açıktır; submission ve smtps kapalıdır. main.cf çekirdeği:
reject_unauth_destination burada tek başına open-relay'i kapatır: kendi virtual_mailbox_domains'inize teslim eder, başka her hedefi reddeder. SASL yok, permit_sasl_authenticated yok — çünkü bu instance kimlik doğrulama servisi bile çalıştırmıyor. Yüzey alanı bilinçli olarak minimum. postscreen, mesaj smtpd'ye ulaşmadan önce Spamhaus ZEN'i 3, Barracuda'yı 2 puanla tartar; skor eşiğe (3) ulaşınca bağlantıyı daha cleanup'a girmeden düşürür, yani spam sizin kuyruğunuza hiç dokunmaz.
Multi-instance'ta bir tuzağa dikkat: lmtp:unix:private/dovecot-lmtp yolu görecelidir ve inbound instance'ın kendi queue_directory'sine göre çözülür. Yani Dovecot bu soketi /var/spool/postfix/private/ altında değil, /var/spool/postfix-in/private/ altında oluşturmalı. Dovecot service lmtp bloğunda soket yolunu inbound spool'a sabitleyin ya da soketi TCP'ye taşıyarak (lmtp:inet:127.0.0.1:24) bu bağımlılığı tamamen ortadan kaldırın.
Outbound instance: submission, auth ve reputasyon izolasyonu
postfix-out ise tam tersi: yalnızca kimlik doğrulamış kullanıcıdan mesaj alır ve ayrı çıkış IP'sinden gönderir. master.cf içinde submission ve smtps servisleri açık, smtp inet kapalıdır:
ini
# /etc/postfix-out/master.cf (ilgili satırlar)
submission inet n - y - - smtpd
-o syslog_name=postfix-out/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
smtps inet n - y - - smtpd
-o syslog_name=postfix-out/smtps
-o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
main.cf tarafında reputasyon izolasyonu ve throttle:
ini
# /etc/postfix-out/main.cf
smtp_bind_address = 212.22.69.211
smtp_helo_name = mail-out.evilmail.pro
# OpenDKIM yalnızca bu instance'ta
smtpd_milters = inet:127.0.0.1:8891
non_smtpd_milters = inet:127.0.0.1:8891
milter_default_action = accept
# Giden hız kontrolü — alıcı sunucuyu boğmadan
smtp_destination_rate_delay = 1s
default_destination_recipient_limit = 50
smtp_destination_rate_delay = 1s, aynı hedef domaine yapılan iki teslimat arasında en az 1 saniye bekletir — Gmail ve Outlook'un 421 throttled yanıtlarını tetiklememenin en basit yolu. Önemli bir ayrıntı: bu parametre sıfırdan farklı olduğunda Postfix hedef başına eşzamanlılığı otomatik olarak 1'e sabitler, yani smtp_destination_concurrency_limit bu instance'ta anlamsızlaşır ve teslimat aynı domaine seri akar; bu yüzden onu bilerek koymadık. DKIM milter'ın yalnızca burada tanımlı olması ise kritik: inbound instance gelen postayı asla imzalamamalı, yoksa forwarding senaryolarında orijinal imza kırılır.
DNS hizalaması: iki yön, iki kimlik
İki instance artık iki ayrı posta kimliğine sahip. DNS'i de buna göre kurmazsanız ayrı IP'nin hiçbir faydası olmaz — çünkü alıcı sunucular kimliği IP + PTR + HELO + SPF dörtlüsünden okur.
Somut kayıtlar:
dns
; Inbound — MX ve A
evilmail.pro. 3600 IN MX 10 mx.evilmail.pro.
mx.evilmail.pro. 3600 IN A 203.0.113.10
; 210 -> PTR: mx.evilmail.pro (mevcut)
; Outbound — ayrı hostname, ayrı IP, eşleşen PTR
mail-out.evilmail.pro. 3600 IN A 212.22.69.211
; 211 -> PTR: mail-out.evilmail.pro (FCrDNS)
; SPF: SADECE outbound IP'yi yetkilendir
evilmail.pro. 3600 IN TXT "v=spf1 ip4:212.22.69.211 -all"
; DKIM ve DMARC
out2026._domainkey.evilmail.pro. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBg..."
_dmarc.evilmail.pro. 3600 IN TXT "v=DMARC1; p=quarantine; rua=mailto:[email protected]; adkim=s; aspf=s"
Kritik nokta: SPF'te inbound IP (.210) yer almaz. SPF yalnızca kimin sizin adınıza gönderdiğini beyan eder; MX'iniz göndermediği için SPF'e girmesine gerek yoktur ve girmesi outbound reputasyon havuzunu gereksizce genişletir. smtp_helo_name (mail-out.evilmail.pro) ile .211'in PTR'ı bit-bit aynı olmalı — aksi halde HELO/PTR mismatch alırsınız ve büyük sağlayıcılar bunu spam sinyali sayar.
Doğrulama ve izleme: kuyrukların gerçekten ayrı olduğunu görmek
Outbound instance'ı 10.000 mesajla kasıtlı yükleyin, sonra bir dış makineden inbound teslim gecikmesini ölçün: postfix-in kuyruğu boş kalır, teslimat gecikmesi milisaniye seviyesinde sabit durur. Loglar syslog_name tag'ı sayesinde ayrılır:
bash
grep "postfix-out/" /var/log/mail.log # yalnızca giden akış
grep "postfix-in/" /var/log/mail.log # yalnızca gelen akış
554 5.7.1 Relay access denied cevabını görüyorsanız inbound instance open relay değil demektir. Son olarak IP itibar ayrımını gerçek dünyada takip edin: gönderilen mesajı mail-tester.com'a atıp 10/10 skorunu ve .211'in temiz durumunu doğrulayın, Gmail Postmaster Tools'ta mail-out.evilmail.pro IP reputation grafiğini izleyin. Artık inbound bir sorun outbound skorunuza, outbound bir sorun inbound teslimatınıza dokunamaz.
Operasyon kontrol listesi
Her instance ayrı queue_directoryve ayrı data_directory kullanıyor mu? (postmulti -l ile doğrula)
Outbound IP'nin PTR'ı smtp_helo_name ile bit-bit eşleşiyor mu? (FCrDNS)
SPF yalnızca outbound IP'yi içeriyor, inbound IP dışarıda mı?
postfix-inreject_unauth_destination ile kilitli, SASL servisi kapalı mı? (open-relay testi geçti mi)
Dovecot LMTP soketi postfix-in spool'u altında mı, yoksa inet mi? (aksi halde yerel teslim bozulur)
DKIM milter yalnızca postfix-out üzerinde tanımlı, inbound imzalamıyor mu?
postmulti -p status her iki instance için running gösteriyor mu?
logrotate /var/log/mail.log'u kesiyor, her iki spool da disk izlemesinde mi?
Sunucu yeniden başlatıldığında postmulti -p start her iki instance'ı da otomatik ayağa kaldırıyor mu? (systemd bağımlılığı)
Backup MX senaryosunda postfix-in outbound'dan bağımsız çalışabiliyor mu?
Tek makine, iki posta kimliği, üç ayrı kuyruk. Ele geçirilmiş bir hesabın spam'i artık yalnızca .211'i yakar; gelen postanız hiçbir şey olmamış gibi akmaya devam eder. Deliverability mühendisliğinde izolasyon, tek başına en yüksek getirili mimari karardır.