"Authentication passed" bir yalan olabilir: SPF/DKIM/DMARC hizalama uyumsuzluğunu teşhis etmek
Mesaj SPF ve DKIM kontrollerini geçip yine de DMARC'ta çakılabilir — çünkü asıl mesele geçmek değil, doğrulanan alan adının From: başlığıyla hizalanması. Sessiz teslimat kaybını rua raporlarından ve Authentication-Results başlığından adım adım nasıl teşhis edip düzelteceğinizi anlatan komut ağırlıklı bir sorun giderme rehberi.
EvilMail Team16 Temmuz 202612 dk okuma
Mailleriniz spam klasörüne düşmüyor. Sadece bir kısmı Gmail'de Promotions sekmesine gidiyor, bir kısmı hiç ulaşmıyor, transactional maillerin açılma oranı sebepsiz yere eriyor. Google Postmaster Tools'a bakıyorsunuz: DMARC uyum oranınız %72. Ama Postfix/Dovecot logunuzda tek bir reject yok, bounce yok, defer yok. Sunucu tarafında her şey yeşil.
Bu tablonun sebebi neredeyse hiçbir zaman kimlik doğrulamanın başarısız olması değildir. Sebep, kimlik doğrulamanın hizalanmamasıdır (identifier alignment). Kulağa çelişkili gelse de tamamen mümkün: bir mesaj SPF'i geçer, DKIM'i geçer, yine de DMARC'ta çakılır. Çünkü DMARC "geçtin mi?" diye sormaz; "geçtiğin alan adı, kullanıcının gördüğü From: alanıyla aynı mı?" diye sorar.
SPF ve DKIM'de "geçmek" ile "hizalanmak" farkı
Bir e-postada iki farklı gönderen alanı vardır ve bunları karıştırmak bütün teşhisi baştan bozar:
envelope-from (Return-Path, SMTP diyalogundaki MAIL FROM
SPF/DKIM/DMARC Hizalama Uyumsuzluğu: Sessiz Teslimat Kaybını Teşhis Etme — EvilMail Blog
): Zarfın üzerindeki adres. Kullanıcı bunu görmez.
SPF bu alana bakar.
header-from (From: başlığı): Gmail'de gördüğünüz gönderen. DMARC bu alana bakar. Kullanıcının güvendiği kimlik budur.
SPF, envelope-from alanının yetkili IP'lerden gelip gelmediğini doğrular. DKIM ise imzadaki d= etiketinde belirtilen alan adına ait bir anahtarla mesajın imzalanıp imzalanmadığını doğrular. İkisi de kendi başına "pass" verebilir. DMARC bunun üzerine tek bir şart koyar:
Bu iki doğrulamadan en az biri, sonucun pass olması ve doğrulanan alanın header-from ile hizalı olması durumunda DMARC pass verir. (OR mantığı.)
Yani SPF de DKIM de teknik olarak "pass" dönebilir ama doğruladıkları alan From: alanınızdan farklıysa — DMARC fail. Makalenin çekirdeği bu ayrım. Diyagram bunu tek bakışta anlatıyor:
Relaxed vs strict: `aspf` ve `adkim` etiketleri
Hizalamanın "aynı alan" tanımı sizin DMARC kaydınızda kontrol edilir. İki mod var:
relaxed (r, varsayılan): Organizasyonel alan eşleşmesi yeter. Public Suffix List'e göre mail.evilmail.pro ile evilmail.pro aynı organizasyonel alandır, dolayısıyla hizalı sayılır.
strict (s): Birebir aynı FQDN olmalı. mail.evilmail.pro ile evilmail.pro hizalı sayılmaz.
Üretimde gördüğüm kırılmaların büyük kısmı birinin "daha güvenli olsun" diye adkim=s yazıp, ESP'sinin mesajı d=sendgrid.net (ya da d=amazonses.com) ile imzaladığını fark etmemesinden çıkıyor. Strict modda alt alan bile kurtarmıyor, üçüncü taraf alan hiç kurtarmıyor.
Pratik tavsiye net: relaxed ile başlayın.adkim=r; aspf=r. Kendi altyapınız tamamen organizasyonel alanınız içinde imzalayıp hizalanana kadar strict'e geçmeyin. Strict, hizalamayı iyileştirmez — sadece toleransı düşürür.
Teşhis: bir mesajın Authentication-Results başlığını okumak
Teoriyi bırakıp gerçek bir başlığa bakalım. Gmail'de mesajı açıp "Orijinali göster" (Show original) deyin, ya da .eml dosyasını indirin. İşte hizalama fail'i gösteren tipik bir blok:
Satır satır çözelim, çünkü teşhisin tamamı burada:
spf=pass ama smtp.mailfrom=sendgrid.net — SPF geçti, fakat doğrulanan alan sendgrid.net. header.from=evilmail.pro ile eşleşmiyor → SPF hizalanmadı.
dkim=pass [email protected] — imza geçerli, ama d=/header.i= yine sendgrid.net. From ile eşleşmiyor → DKIM hizalanmadı.
İki hizalamadan biri bile tutmadığı için: dmarc=fail.
dis=NONE kısmı kritik: politikanız p=none olduğu için Gmail mesajı reddetmiyor, sadece rapora fail yazıyor. Sunucu logunuzun neden temiz göründüğünü açıklayan şey bu. Kimse kapıda reddedilmedi; ama Gmail'in itibar motoru bunu not aldı ve yavaş yavaş sizi Promotions'a itiyor.
Komut satırından bir .eml üzerinde aynı satırları tek seferde çekmek için:
Aradığınız üçlü karşılaştırma şu: From: alanındaki alan adı, Return-Path alanındaki alan adı ve DKIM-Signature'daki d= değeri. Bu üçünden en az biri From ile aynı organizasyonel alanda değilse, DMARC fail alırsınız.
DMARC agregat (rua) raporları: sessiz kırılmanın tek görünür kaydı
p=none'da hiçbir mesaj reddedilmez, dolayısıyla sunucu logunuz temiz görünür. Sessiz kırılmanın tek makine-okur kaydı DMARC agregat raporlarıdır. Alıcı sağlayıcılar (Google, Microsoft, Yahoo…) günde bir kez, sizin adınıza kimin gönderdiğini ve her kaynağın hizalama sonucunu XML olarak rua= adresine yollar.
Önce kaydınızda toplama adresinin tanımlı olduğundan emin olun:
Gelen XML'in okumanız gereken iki bloğu var. <record> içinde kaynak IP ve mesaj sayısı, <policy_evaluated> içinde DMARC'ın hizalamayı değerlendirdikten sonra verdiği karar, <auth_results> içinde ise ham SPF/DKIM sonuçları bulunur:
Buradaki hikaye çok net: auth_results içinde SPF ve DKIM pass, ama policy_evaluated içinde ikisi de fail. Aradaki fark tam olarak hizalamadır — policy_evaluated, ham sonucu değil hizalanmış sonucu yazar. sendgrid.net alanından 431 mesaj evilmail.pro adına gönderilmiş, ikisi de geçmiş ama hiçbiri hizalanmamış. Kaynak IP 167.89.118.50 size hangi ESP'nin sorunlu olduğunu söylüyor.
Ham XML'i günde onlarca dosya olarak okumak sürdürülebilir değil. Küçük ölçekte kendiniz parse edin; büyük ölçekte raporları bir toplama aracına (self-hosted parsedmarc + Elasticsearch iyi bir başlangıç) yönlendirip kaynak/alan/hizalama-oranı tablosuna dönüştürün. Okumanız gereken tek metrik: hizalanmış geçen mesaj yüzdesi.
Tipik kırılma senaryoları ve düzeltmeleri
1) ESP üzerinden gönderim (SendGrid / Mailgun / Amazon SES). En yaygın sebep. ESP varsayılan olarak envelope-from'u kendi bounce alanına (sendgrid.net) ayarlar ve mesajı kendi d= anahtarıyla imzalar. İkisi de hizalanmaz. Çözüm iki parçalı:
ESP panelinde custom return-path / branded link açın. Bu genelde bir CNAME'dir: em.evilmail.pro → sendgrid.net. Böylece envelope-from em.evilmail.pro olur ve relaxed modda evilmail.pro ile hizalanır → SPF hizalanır.
Aynı panelde kendi DKIM selector'ünüzü yayınlayın. ESP size s1._domainkey.evilmail.pro gibi bir CNAME/TXT verir; bunu yayınladığınızda imza d=evilmail.pro olur → DKIM hizalanır.
İkisinden biri yeterlidir (OR mantığı), ama ikisini de kurmak dayanıklılık sağlar.
2) Alt alandan gönderim ve `sp=` politikası.marketing.evilmail.pro üzerinden gönderiyorsanız, DMARC değerlendirmesi organizasyonel alanın kaydına bakar ama alt alanlar için ayrı bir politika etiketi vardır: sp=. sp= tanımlamazsanız alt alanlar p= değerini miras alır. Alt alandan test/pazarlama gönderirken üst alanı p=reject yapıp sp='yi unutursanız, o trafiği de reddetmiş olursunuz.
3) Mail listeleri ve auto-forward. Mailman gibi liste yazılımları Subject: başına [liste] ekler, gövdeye altbilgi ekler. Bu, DKIM'in body hash'ini bozar → DKIM imzası artık geçmez. Liste From:'u koruduğu için (RFC 5322) DMARC de fail olur. Çözüm alıcı tarafında ARC (Authenticated Received Chain) ya da liste tarafında From-rewrite (From: Ali via Liste <liste@...>). Kendi domaininizden liste işletiyorsanız From-rewrite'ı açın; işletmiyorsanız bu trafiği rua'da tanıyıp meşru kabul edin, ona bakarak politikayı sıkılaştırmayın.
4) Birden çok SPF kaydı veya 10 DNS lookup limiti aşımı. SPF'nin sert bir kuralı var: değerlendirme sırasında en fazla 10 DNS sorgusu (include, a, mx, ptr, exists, redirect). Zinciriniz bunu aşarsa sonuç permerror olur ve SPF tarafı tamamen çöker. Her include: bir veya daha fazla lookup demektir; üç dört ESP eklediyseniz sınırı çoktan aşmışsınızdır. include sayınızı sayın, gereksizleri temizleyin, gerekirse SPF flattening kullanın. Ayrıca bir alan için yalnızca tek bir SPF TXT kaydı olmalı — iki tane varsa yine permerror.
Doğru kayıtları yazmak: kopyalanabilir DNS + doğrulama
Üç kaydın çalışan hali:
; SPF — tek kayıt, ~all softfail ile başla
evilmail.pro. IN TXT "v=spf1 include:_spf.evilmail.pro ip4:203.0.113.10 ~all"
; DKIM — 2048-bit, selector'lı; uzun p= değeri 255-char chunk'lara bölünür
s1._domainkey.evilmail.pro. IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCS...AQAB"
; DMARC — gözlem aşaması
_dmarc.evilmail.pro. IN TXT "v=DMARC1; p=none; rua=mailto:[email protected]; ruf=mailto:[email protected]; adkim=r; aspf=r; fo=1; pct=100"
Notlar: ~all (softfail) yerine -all (hardfail) itibar açısından daha güçlü ama tüm meşru kaynaklarınızı SPF'e eklediğinizden emin olmadan -all yazmayın — yoksa unuttuğunuz bir sunucu sessizce reddedilir. DKIM'de 1024-bit yerine 2048-bit tercih edin; p= değeri 255 karakteri aşınca DNS TXT kaydı otomatik olarak tırnaklı parçalara bölünür, panelinizin bunu doğru birleştirdiğini doğrulayın. fo=1 etiketi, SPF veya DKIM'den herhangi biri hizalı-pass vermediğinde forensic (ruf) raporu üretilmesini ister — teşhis sırasında değerlidir.
7. SPF include zincirini say — 10 lookup'ı aşıyorsa permerror, SPF tarafı çöker.
8. Alt alanlardan gönderiyorsan sp= politikasını ayrıca ayarla.
9. Liste / forward trafiğin varsa ARC veya From-rewrite durumunu kontrol et; bu fail'lere bakıp panik yapma.
10. Her değişiklikten sonra kendine test maili at, Authentication-Results satırını elle oku.
rua raporunda 30 gün üst üste %98+ hizalama görmeden p=reject'e geçmeyin. Yeşil tikin bir yalan olabileceğini bir kez öğrendikten sonra, itibarınızı bir varsayıma dayandırmayın.