Postfix ile Spam Klasörüne Düşmeden Toplu E-posta Göndermenin Kuralları
Toplu e-postan spam'e düşüyorsa sorun genelde içerik değil, gönderim davranışıdır. Postfix'te alan-bazlı hız sınırlama, 30 günlük IP ısıtma çizelgesi, SPF/DKIM/DMARC hijyeni ve otomatik bounce temizliğiyle Gmail'in tolere ettiği tempoya nasıl inersin — kopyala-çalıştır konfiglerle.
EvilMail Team8 Temmuz 202612 dk okuma
Klasik senaryo: yeni bir VPS kiraladın, PTR kaydını düzelttin, temiz bir liste hazırladın, mail-tester.com'da 10/10 aldın — ve yine de ilk kampanyanın %90'ı Gmail'de Spam kutusunda. Buraya kadar her şeyi "doğru" yaptın ama alıcı MTA seni tanımıyor ve tanımadığı bir IP'den gelen ani hacme güvenmiyor.
Logda gördüğün satırlar zaten cevabı veriyor:
text
host gmail-smtp-in.l.google.com said: 421-4.7.28 [203.0.113.10] Our system has
detected an unusual rate of unsolicited mail originating from your IP address.
host gmail-smtp-in.l.google.com said: 550-5.7.1 [203.0.113.10] Our system has
detected that this message is likely unsolicited mail.
421-4.7.28 geçici bir kısıtlama — "yavaşla" demek. 550-5.7.1 ise itibarın çoktan dibe vurduğunun işareti. İkisinin de ortak nedeni içerik değil: alıcı MTA bir IP+alan çiftinin gönderim eğrisini puanlar. Ani sıçramalar, düzensiz tempo ve soğuk (ısıtılmamış) bir IP itibar çöküşü demektir. Binlerce alan üzerinde bu işi yürütürken en sık gördüğümüz hata, tek IP'den saatte binlerce mail atıp "neden spam'deyiz" diye sormak.
Elimizde dört kaldıraç var: hız sınırlama, IP ısıtma, kimlik/içerik hijyeni ve bounce yönetimi. Sırayla, Postfix seviyesinde çözelim.
Hız sınırlama: Postfix'i alıcı-alan bazında yavaşlat
İlk refleks main.cf'e global sınırlar koymaktır. İyi bir başlangıç ama tek başına yetmez, çünkü Gmail ve Outlook farklı toleranslar ister — Gmail düzenli ve yavaş akışı sever, Outlook eşzamanlı bağlantı sayısına daha hassastır.
Önce genel alanlar için makul bir global taban koyalım — eşzamanlı bağlantıyı ve alıcı sayısını sınırla:
default_destination_concurrency_limit = 2 aynı hedefe en fazla 2 paralel bağlantı açar. initial_destination_concurrency = 1 slow-start yapar: yeni bir alana tek bağlantıyla başlar, alan MTA reddetmedikçe eşzamanlılığı kademeli açar (varsayılan 5'tir, düşürmek soğuk başlangıçta güvenlidir). in_flow_delay = 1s ise ani kabul dalgalarını yumuşatır.
Asıl marifet alan-başına ayrı boru hattı kurmakta. Seçici sağlayıcılara master.cf'te özel transport'lar tanımla:
Önemli ayrıntı: bir transport'ta smtp_destination_rate_delay tanımladığın anda Postfix o hedefin eşzamanlılığını otomatik 1'e sabitler — bu yüzden rate_delay ile concurrency_limit'i birlikte yazmak gereksizdir, ikincisi yok sayılır. Yani rate_delay=3s demek "Gmail'e her seferinde tek bağlantı, iki teslimat arasında en az 3 saniye" demektir. Bu tek satır "burst" davranışını öldürür.
Sonra main.cf'te transport_maps = hash:/etc/postfix/transport ile yönlendir:
postmap /etc/postfix/transport && postfix reload sonrası Gmail'e giden trafik 3 saniyelik gecikmeyle, tek eşzamanlı bağlantıyla akar; geri kalan alanlar global tabanı (en fazla 2 paralel bağlantı) kullanır. Görsel karşılığı şu:
Kuyruğu postqueue -p (veya mailq) ile izle; birikme varsa postqueue -f ile flush et. Değeri canlıya almak için servisi durdurmadan postconf -e "default_destination_concurrency_limit=2" yazıp postfix reload demek yeterli.
IP ısıtma: 30 günlük çizelge ve neden kademeli
Yaygın yanılgı, yeni bir IP'nin "nötr" itibarla başladığıdır. Değil — pratikte itibarsızdır. Gmail geçmişi olmayan bir IP'den gelen hacme baştan şüpheyle yaklaşır. Isıtma, bu IP'ye bir gönderim geçmişi inşa etme işidir ve tek kuralı vardır: sabit, öngörülebilir, kademeli artış.
Alan başına ayrı sayarak ilerlettiğimiz çizelge şöyle:
Gün 1: 50 · Gün 2: 100 · Gün 3: 250
Gün 5: 500 · Gün 7: 1.000
Gün 10: 2.500 · Gün 14: 5.000
Gün 21: 10.000 · Gün 30: tam hacim
Kritik detay: ilk günlere en etkileşimli alıcıları koy — son 30 günde açan/tıklayanlar. Buna "engagement-first warmup" diyoruz. Gmail açılma ve pozitif etkileşimi doğrudan itibara yazar; ilk sinyalin güçlü olması sonraki günlerin tavanını yükseltir.
Isıtma sırasında myhostname, smtp_helo_name ve PTR/rDNS'in hepsi aynı FQDN'e eşleşmeli. rDNS eşleşmiyorsa ısıtmanın tamamı boşa gider — Gmail HELO adıyla ters DNS'i karşılaştırır:
203.0.113.10 için PTR kaydının mail.evilmail.pro döndüğünü dig -x 203.0.113.10 +short ile doğrula. Ölçümü Google Postmaster Tools üzerinden yap: IP/Domain Reputation "High"a çıkana kadar hacmi zorlamadan sabit tut. Bounce oranı %2'yi veya spam-şikâyet oranı %0.1'i aşarsa hacmi bir kademe geri çek. Ve en sık göz ardı edilen kural: ısıtma sırasında tek günlük büyük bir sıçrama, günlerce inşa ettiğin ilerlemeyi sıfırlar.
Kimlik ve içerik hijyeni: SPF, DKIM, DMARC + gövde
Hız doğruysa sıra kimliğe gelir. Üç kaydın da yayında ve hizalı olması, 2024'ten beri Gmail ve Yahoo'nun toplu göndericilerden talep ettiği asgari eşik.
SPF'i softfail (~all) değil hardfail (-all) ile bitir — softfail alıcı MTA'ya "belki sahte" der:
text
evilmail.pro. IN TXT "v=spf1 mx ip4:203.0.113.10 -all"
DKIM için 2048-bit anahtar üret ve selector kaydını yayınla:
text
default._domainkey.evilmail.pro. IN TXT
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A..."
DMARC'ı en az quarantine ile, sıkı hizalamayla başlat:
text
_dmarc.evilmail.pro. IN TXT
"v=DMARC1; p=quarantine; rua=mailto:[email protected]; adkim=s; aspf=s"
Geri kalanı klasik hijyen: From alanı DKIM d= ile aynı organizasyonel alanda olsun (hizalama), tutarlı bir gönderen kimliği kullan, link kısaltıcılardan kaçın (itibarını başkasının IP'sine bağlarlar), metin/HTML oranını dengede tut ve her HTML maile düz metin alternatifi koy.
Bounce ve şikâyet yönetimi: döngüyü kapat
Teslim edilebilirliğin görünmez katili, temizlenmeyen listedir. Var olmayan adreslere gönderdikçe hard bounce oranın yükselir ve Gmail bunu doğrudan "kötü liste hijyeni" olarak puanlar.
İlk ayrım hard/soft bounce. maillog'da yakala:
bash
grep 'status=bounced' /var/log/mail.log
DSN kodları kararını belirler: 5.1.1 (kullanıcı yok) ve 5.1.10 (alıcı adresi geçersiz) kalıcı hard bounce'tur — adresi anında suppression list'e al. 4.2.1 gibi 4.x kodlar geçicidir; Postfix zaten yeniden dener, sen dokunma. Kuralımız: hard bounce anında pasifleştir; art arda 3 soft bounce olan adresi de listeden çıkar.
Hangi alıcının bounce ettiğini kesin bilmek için VERP kullan — dönüş adresine alıcıyı gömer. Postfix'te VERP'i aç:
Uygulamadan gönderirken sendmail -XV bayrağını geçir ya da SMTP oturumunda MAIL FROM'dan sonra XVERP komutunu ver; böylece bounce mesajı [email protected] gibi kodlanmış zarf-göndericisine döner ve parse etmek trivial olur.
Şikâyet tarafında feedback loop kur: Microsoft için SNDS + JMRP kayıtlarını yap, Gmail şikâyetlerini Postmaster Tools'un Spam Rate grafiğinden izle (Gmail mesaj-başı FBL vermez, yalnızca toplu oran). Şikâyet oranını %0.1 altında tut — bu eşiği aşarsan Gmail hacmini otomatik kısar ve toparlanmak günler alır.
Deploy öncesi kontrol listesi
rDNS/PTR203.0.113.10 → mail.evilmail.pro eşleşiyor mu (dig -x)
SPF-all ile bitiyor mu (softfail değil)
DKIM imzası doğrulanıyor mu (opendkim-testkey ... key OK)
DMARC en az p=quarantine yayında mı
List-Unsubscribe + List-Unsubscribe-Post: One-Click başlıkları var mı
Per-destinationrate_delay ve alan-özel transport'lar ayarlı mı
Google Postmaster Tools + Microsoft SNDS'e alan/IP eklendi mi
Suppression list bounce webhook'una / maillog parse'ına bağlı mı
TLS giden için fırsatçı (smtp_tls_security_level = may) — encrypt kullanma, TLS'siz alıcı MTA'lara teslimatı kırar
Kuyrukpostqueue -p ile izleniyor, birikme alarmı var mı
Bu dört kaldıracı birlikte kurduğunda değişen şey basit: Postfix artık senin istediğin hızda değil, Gmail'in tolere ettiği tempoda gönderiyor. Isıtılmış bir IP, hizalı bir kimlik ve temiz tutulan bir liste — spam filtresinin aslında ölçtüğü tek şey bu üçlünün tutarlılığı. İçeriğini güzelleştirmeden önce gönderim davranışını düzelt; sıralama bu.