Return-Path, Envelope-From ve From: Bounce'ları Kaybettiren Üç Adres
Bir kampanya gönderdin, bounce raporu bomboş sanıyorsun ama aslında dönen mesajlar görmediğin bir kutuya düşüyor. Sorun neredeyse her zaman aynı: görünen From, Envelope-From ve Return-Path'in üç ayrı şey olduğunu bilmemek. SMTP zarfını, SPF'in neye baktığını, DMARC hizalamasını ve VERP ile bounce yakalamayı somut SMTP diyaloğu, Postfix config'i ve DNS örnekleriyle sökeriz.
EvilMail Team16 Temmuz 202612 dk okuma
Bir kampanya gönderdin. Açılma oranı normal, tıklamalar geliyor, her şey yolunda görünüyor. Ama bounce raporun bomboş. "Demek ki hiç bounce yok" diye düşünüyorsun. Hayır. Bounce'lar var; sadece senin görmediğin bir kutuya, yanlış bir dönüş adresine düşüyorlar. Üç hafta sonra elinde ölmüş adreslerle dolu bir liste, düşen bir gönderici itibarı ve nedenini çözemediğin bir spam-klasörü problemi kalıyor.
Kaynak neredeyse her zaman aynı: bir e-postanın üç ayrı "gönderen" adresi olduğunu ve bunların farklı işler yaptığını bilmemek. Teslimat, spam skoru ve bounce'ların nereye düştüğü, alıcının ekranında gördüğü From: ile değil, SMTP zarfının içindeki adresle belirlenir. Bu ayrımı oturttuğunda deliverability'nin yarısı çözülür.
Üç ayrı "gönderen": zarf, başlık ve dönüş yolu
Bir e-posta, zarfın içindeki bir mektup gibi çalışır. Birbirinden bağımsız iki katman var:
SMTP zarfı (RFC 5321):MAIL FROM ve RCPT TO komutları. Postacının okuduğu adres budur; mesaj bu adreslere göre yönlendirilir. MAIL FROM
değerine
Envelope-From
ya da
return-path
denir — aynı şeyin üç adı.
Mesaj başlığı (RFC 5322):From:, To:, Subject:. Bu, zarfın içindeki mektubun üstünde yazan addır. Alıcının mail istemcisi ekranda bunu gösterir.
Kritik nokta: zarftaki adres ile başlıktaki `From:` farklı olabilir ve bu tamamen meşrudur. Mailing list'ler, ESP'ler (Mailchimp, SendGrid), yönlendirmeler — hepsi bunu yapar.
Return-Path: başlığı ise özeldir; onu sen yazmazsın. Mesajı son teslim eden MTA, MAIL FROM değerini alıp teslim edilen mesajın en üstüne Return-Path: olarak yazar. RFC 5321 §4.4, gönderilen mesaja elle Return-Path eklemenin yanlış olduğunu söyler — MTA'nın işine karışmış olursun. Yani teslim edilmiş bir mesajın Return-Path: başlığını okumak, o mesajın gerçek MAIL FROM'unu okumaktır.
Bir alıcı MTA mesajı teslim edemezse (kutu yok, kota dolu, domain geçersiz), bounce mesajını başlıktaki `From:`'a değil, zarftaki `MAIL FROM`'a geri yollar. Kampanyanın bounce'larının kaybolduğu yer tam olarak burası: MAIL FROM'un işaret ettiği kutuyu kimse okumuyor.
Canlı SMTP diyaloğu: adresler nerede geçiyor
Teoriyi ham SMTP oturumunda görelim. openssl ile 587 portuna bağlanıp elle bir mesaj gönderiyorum:
text
$ openssl s_client -connect mail.evilmail.pro:587 -starttls smtp -quiet
EHLO client.local
MAIL FROM:<[email protected]>
250 2.1.0 Ok
RCPT TO:<[email protected]>
250 2.1.5 Ok
DATA
354 End data with <CR><LF>.<CR><LF>
From: EvilMail <[email protected]>
To: [email protected]
Subject: Test
Govde.
.
250 2.0.0 Ok: queued as 8B2F1A0C
QUIT
MAIL FROM[email protected], ama From: başlığı [email protected]. İkisi farklı ve bu geçerli. Gmail bu mesajı teslim ettiğinde başlıkların en üstüne şunu yazar:
smtp.mailfrom alanına dikkat: Google'ın SPF için baktığı adres From: değil, zarftaki adres. header.from ise ayrı — DMARC onu kullanıyor. Bu iki satır, yazının tamamının özeti.
SPF Envelope-From'a bakar, görünen From'a değil
SPF (RFC 7208) tek bir soruyu cevaplar: "Bu IP, bu domain adına posta göndermeye yetkili mi?" Buradaki "bu domain" `MAIL FROM`'un domainidir — görünen From: değil. (HELO/EHLO üzerinden ikinci bir SPF kontrolü daha vardır, ama teslimat kararında belirleyici olan MAIL FROM kontrolüdür.)
Sonuç şu: From: ile MAIL FROM farklı domainlerdeyse, SPF görünen From:'u hiç doğrulamaz. Herkesin gördüğü adres tamamen sahte olabilir, SPF yine pass verir. TXT kayıtları böyle görünür:
dns
evilmail.pro. IN TXT "v=spf1 include:_spf.evilmail.pro -all"
mail.evilmail.pro. IN TXT "v=spf1 ip4:203.0.113.10 -all"
Bir saldırgan From: [email protected] yazıp MAIL FROM:<[email protected]> kullansa, SPF saldirgan.com'u kontrol eder, kendi kaydına göre pass alır — ve evilmail.pro adına sahte posta teslim edilir. SPF tek başına spoofing'i durduramaz. Boşluğu kapatan katman DMARC.
DMARC hizalaması: zarf ile başlığı birbirine bağlayan katman
DMARC (RFC 7489), SPF ve DKIM'in üstüne bir hizalama (alignment) şartı ekler: en az bir mekanizma hem geçmeli (pass) hem de görünen From: domaini ile hizalı olmalı.
SPF hizalaması, RFC5321.MailFrom domaini ile RFC5322.From domainini karşılaştırır. İki mod var:
`aspf=r` (relaxed): Organizational domain eşleşmesi yeter. mail.evilmail.pro (MAIL FROM) ile evilmail.pro (From) relaxed modda hizalıdır — ikisi de evilmail.pro organizational domaini altında.
`aspf=s` (strict): Tam eşleşme gerekir. mail.evilmail.pro ≠ evilmail.pro, strict modda hizalanmaz.
adkim aynı mantığı DKIM'in d= etiketi için uygular. Tipik kayıt:
dns
_dmarc.evilmail.pro. IN TXT "v=DMARC1; p=reject; rua=mailto:[email protected]; adkim=s; aspf=r; pct=100"
Burada ESP kullananlar için en yaygın felaket devreye girer. ESP'nin varsayılan kurulumunda From: senin domainin (sirket.com), ama MAIL FROM ESP'nin domaini (bounces.sendgrid.net). SPF bounces.sendgrid.net'e göre pass verir — ama sirket.com ile hizalanmaz. DKIM de imzalanmamışsa ya da o da hizasızsa, DMARC p=reject politikasında mesajı reddeder. Kendi kampanyan, kendi p=reject politikana takılır.
Çözüm custom return-path (özel Envelope-From). ESP'ye kendi alt-domainini bounce domaini olarak tanıtır ve DNS'te delegasyon yaparsın:
dns
bounce.sirket.com. IN CNAME esp.bounces.net.
Böylece MAIL FROMbounce.sirket.com olur, relaxed modda sirket.com ile hizalanır ve SPF hizalaması kurtarılır. Return-path'i doğru domaine taşımak, ESP entegrasyonlarında DMARC uyumunun anahtarıdır.
Bounce'ları yakalamak: VERP ve özel return-path
Bounce mesajlarının kendisi (DSN — Delivery Status Notification, RFC 3464) boş zarf göndericisiyle yollanır: MAIL FROM:<>. Sebep mail loop'unu kırmaktır — bir bounce mesajı bounce ederse, boş return-path sayesinde sonsuza kadar oradan oraya dönmez. Ama boş return-path'i normal postanda asla kullanma; kullanırsan kendi bounce'larını hiçbir yere yollamamış olursun, telemetri sıfırlanır.
Bounce'ları hangi adresin ürettiğini bilmek için VERP (Variable Envelope Return Path) kullanılır. Fikir basit: her alıcıya benzersiz bir MAIL FROM yazarsın, alıcı adresini return-path'in içine gömersin:
Bounce geri döndüğünde adresin kendisi sana hangi alıcının patladığını söyler — DSN gövdesini parse etmene bile gerek kalmaz. Postfix'te default_verp_delimiters = += ayarı ve sendmail -V bayrağı bu formatı üretir.
Dönen mesajları sınıflandırırken SMTP kodunun ilk hanesi belirleyici: hard bounce'lar `5.x.x` (kalıcı — 550 5.1.1 no such user, adresi listeden çıkar), soft bounce'lar `4.x.x` (geçici — 451 4.3.0, kota/gecikme, tekrar dene). DSN status alanları RFC 3463'te tanımlı; 5.1.1 kutu yok, 4.2.2 kota dolu demektir.
Postfix'te doğru kurulum
Return-path'i override etmenin doğru yolu header_checks değil — sender_canonical_maps. main.cf:
sender_canonical_classes = envelope_sender kritik: sadece zarf göndericisini yeniden yazar, mesaj başlığındaki From:'a dokunmaz. /etc/postfix/sender_canonical:
DKIM milter'ının başlık From:'a göre imzaladığından emin ol (OpenDKIM evilmail.pro selector'ıyla imzalar) — çünkü DMARC'ın DKIM hizalaması From: domainine bakar, return-path'e değil. Zarfı bir alt-domaine, imzayı ana domaine bırakırsın; ikisi relaxed modda hizalanır.
Alt-domain return-path'in DNS'i de tamam olmalı — SPF'in yanında, MTA'nın bounce'ı geri getirebilmesi için MX/A da gerekir:
dns
mail.evilmail.pro. IN A 203.0.113.10
mail.evilmail.pro. IN MX 10 mail.evilmail.pro.
mail.evilmail.pro. IN TXT "v=spf1 ip4:203.0.113.10 -all"
evilmail.pro tarafında geçici (disposable) adreslerde return-path'i bilinçli olarak ayrı bir bounce domainine yönlendiriyoruz. Sebep mimari: kullanıcının inbox'ı geçici ve birazdan yok olacak, ama gönderdiğimiz sistem postalarının bounce telemetrisini biz tutmak istiyoruz. Return-path'i mail.evilmail.pro altında ayrık tutunca, kullanıcı kutusu silinse bile hangi domainlere teslimat bozuluyor görebiliyoruz ve gönderici itibarımızı koruyoruz.
Hızlı doğrulama checklist'i
Return-Path'i gerçek teslimatta oku. Kendine bir test at, ham başlıkta Return-Path: satırının beklediğin bounce adresi olduğunu doğrula. From: ile karıştırma.
SPF'i MAIL FROM domainine göre kontrol et:dig +short TXT mail.evilmail.pro — görünen From'un domainini değil, zarfın domainini sorgula.
DMARC hizalamasını iki yönlü test et:dig +short TXT _dmarc.evilmail.pro, sonra teslim edilen mesajda Authentication-Results: satırında hem spf=pass hem dmarc=pass header.from=... gör.
Bounce kutusuna gerçekten mesaj düşüyor mu? Kasıtlı olarak var olmayan bir adrese gönder, 550 5.1.1 DSN'inin return-path kutuna ulaştığını doğrula.
VERP açıksa çözümleme çalışıyor mu?bounce+user=example.com@... formatındaki bir bounce'ı sistemin doğru alıcıya eşliyor mu, kontrol et.
Boş return-path'i (`<>`) yanlışlıkla normal postada kullanma — sadece DSN'lerin kendisi için.
Uçtan uca canlı test:swaks --to [email protected] --from [email protected] --header 'From: [email protected]' --server mail.evilmail.pro ile zarf/başlık ayrışmasını gerçek bir kutuya karşı dene, ardından mail-tester.com veya dmarcian ile skoru oku.
Return-Path, Envelope-From ve From: üçünü ayrı ayrı kontrol edebiliyorsan — hangisine SPF'in, hangisine DMARC'ın, hangisine bounce'ın baktığını gösterebiliyorsan — deliverability sorunlarının çoğu artık gizemli değil, izlenebilir bir zincirdir.