Birden Fazla Üçüncü Taraf Gönderici İçin Tek SPF ve DKIM Stratejisi
SendGrid, Mailgun ve Google Workspace'i aynı anda yönetirken her şeyi tek bir root SPF kaydına tıkıştırmak, kaydınızı sessizce PermError'a düşürüp tüm kimlik doğrulamayı bozar. Doğru mimari: gönderici başına alt alan segmentasyonu, hizalama çıpası olarak DKIM ve destekleyici role çekilmiş bir SPF.
EvilMail Team21 Temmuz 202612 dk okuma
Bir Salı sabahı SendGrid'i eklediniz. Kayıt zaten 9 DNS lookup'ta duruyordu ama kimse bakmıyordu, her şey çalışıyordu. Ertesi hafta pazarlama ekibi Mailgun'a geçmek isteyince root SPF kaydına bir include:mailgun.org daha eklediniz ve toplam 11'e çıktı. Birkaç saat sonra Gmail bütün alanı SPF PermError ile değerlendirmeye başladı — üstelik sadece Mailgun'ı değil, SendGrid'i ve kurumsal Google Workspace postalarınızı da. DMARC raporlarında ani bir spf=permerror dalgası. Fatura departmanının bordroları spam'e düştü. Sebep tek satırdı.
Bu, çok-göndericili kurulumların en yaygın sessiz arızasıdır. Asıl mesele "her göndericiye SPF nasıl eklerim" değil; SPF'nin RFC 7208'deki 10 DNS-lookup sınırının çok-göndericili gerçeklikle çarpışması. Yanlış içgüdü — her şeyi tek root kaydına tıkıştırmak — kaydınızı bir eşiği geçtiği anda geçersiz kılar. Bu yazının tezi net: SPF'yi baş köşeden indirin. Ölçeklenen katman DKIM'dir; hizalama çıpanız o olmalı, SPF destekleyici role çekilir.
SPF'nin 10-lookup duvarı: neden tek kayıt üç göndericiyi taşımaz
RFC 7208 §4.6.4 açık: bir SPF değerlendirmesi sırasında include
Çoklu Üçüncü Taraf Gönderici İçin SPF ve DKIM Stratejisi | evilmail — EvilMail Blog
,
a
,
mx
,
ptr
,
exists
ve
redirect
mekanizmalarının tetiklediği DNS sorgularının toplamı 10'u geçemez. Geçtiği anda sonuç
PermError
olur. Kritik nokta:
PermError
bir
softfail
ya da
fail
değildir — SPF'i tamamen
geçersiz
kılar. Alan sanki hiç SPF kaydı yokmuş gibi davranır. Meşru göndericileriniz dahil hepsi doğrulamayı kaybeder.
Maliyeti somutlaştıralım, çünkü "10 lookup" soyut kaldığı sürece kimse bütçesini takip etmez:
include:_spf.google.com tek başına 4 lookup yer — include'un kendisi bir sorgu, sonra içeride _netblocks, _netblocks2 ve _netblocks3'e açılan üç sorgu daha.
include:sendgrid.net ≈ 1 lookup.
include:mailgun.org ≈ 1-2 lookup.
include:amazonses.com ≈ 1 lookup.
Yani Google + SendGrid + Mailgun root'ta yan yana zaten 6-7 lookup demektir. Nested include'lar bütçeyi görünmez şekilde yer; bir gönderici bir gün kendi include'una bir alt-include eklerse sizin kaydınız haftalar sonra kendiliğinden patlar. Dördüncü bir gönderici sınırı aşmaya yeter.
İki tipik yanlış çözüm var, ikisi de çöp. Birincisi her şeyi tek root TXT'ye dizmek — yukarıdaki senaryo. İkincisi, panikleyip iki ayrı v=spf1 kaydı yazmak: bir alanda birden fazla SPF kaydı bulunması RFC gereği doğrudan PermError verir. SPF tek kayıttır, birleştirilemez.
Mimari karar: gönderici başına alt alan segmentasyonu
Doğru cevap kaydı sıkıştırmak değil, trafiği bölmektir. Kök alanı — kurumsal Google Workspace, gerçek MX kayıtları, insanların elle yazdığı e-postalar — temiz tutun. Her uygulama-göndericisine kendi alt alanını verin:
evilmail.pro (kök) → yalnızca Google Workspace ve gerçek MX
Bu mimarinin üç somut kazancı var. Birincisi: her alt alanın kendi 10-lookup bütçesi vardır. Kök alan yalnızca _spf.google.com taşır — 4 lookup, geri kalan pay bol bol yeter. SendGrid em. altında tek başına 10 lookup'ın tamamına sahiptir.
İkincisi: itibar izolasyonu. Pazarlama gönderiminin bounce ve şikâyet oranı kurumsal insan-postasının teslimatını çökertmez, çünkü alıcı sağlayıcılar itibarı gönderen alan/alt alan bazında tutar. mg.evilmail.pro yanarsa evilmail.pro'nun bordroları güvende kalır.
Üçüncüsü: politika esnekliği. DMARC'ın sp= (subdomain policy) etiketi sayesinde alt alanlarda daha gevşek bir politika uygularken kökte p=reject tutabilirsiniz. Yeni bir göndericiyi devreye alırken kök politikanızı riske atmadan alt alanda p=none ile başlarsınız.
SPF'yi doğru kurmak: kök vs alt alan ve flattening tuzağı
Kök alan minimal kalır:
dns
evilmail.pro. IN TXT "v=spf1 include:_spf.google.com ~all"
em.evilmail.pro. IN TXT "v=spf1 include:sendgrid.net -all"
mg.evilmail.pro. IN TXT "v=spf1 include:mailgun.org -all"
~all (softfail) mü, -all (hardfail) mı? Karar DMARC olgunluğunuza bağlı. DMARC p=reject yürürlükteyse ve alt alan tek bir göndericiye ayrılmışsa -all mantıklıdır — o alt alandan başka hiçbir şey çıkmaz. Geçiş dönemindeyseniz veya kökte hâlâ raporları izliyorsanız ~all daha güvenlidir; DMARC zaten asıl kararı verir, SPF'in hardfail'i gereksiz yere meşru postayı düşürmez.
Flattening tuzağı. SPF flattening, include'ları göndericinin gerçek ip4/ip6 bloklarıyla değiştirip lookup'ı sıfıra indirmektir. Cazip görünür ama statik flatten bir zaman bombasıdır: SendGrid veya Mailgun IP bloğunu değiştirdiği gün — ki değiştirirler — kaydınız sessizce yanlış IP'leri yetkilendirmeye devam eder, gerçek gönderen IP'ler fail alır. Flattening yalnızca cron ile otomatik yeniden üretiliyorsa kabul edilebilir; kendi kendini güncellemeyen elle-flatten yasaktır. Alternatif olarak Autospf veya EasyDMARC gibi dinamik SPF servisleri, macro tabanlı (exists:) tek bir include ile tüm göndericileri arka planda çözer ve lookup'ı 1'e indirir — çok sayıda göndericiyi tek alanda tutmak zorundaysanız meşru bir çözümdür.
Son teknik not: her TXT string en fazla 255 karakterdir. Uzun kayıtlar tırnaklı parçalara ("..." "...") bölünür, DNS bunları birleştirir. Segmentasyon yaptığınızda bu sınıra zaten çarpmazsınız; bu da mimarinin bir yan faydası.
DKIM: asıl ölçeklenen katman
DKIM'de "10 lookup" problemi yoktur, çünkü her gönderici kendi selector'ını kullanır ve selector çakışması fiziksel olarak imkânsızdır. Her selector <selector>._domainkey.<alan> adresinde ayrı bir kayıttır:
SendGrid:s1._domainkey ve s2._domainkey → SendGrid'in sendgrid.net altındaki hedeflerine CNAME
Mailgun:smtp._domainkey (ve hesaba göre krs._domainkey) → custom MAIL FROM ile mg. alt alanında
Google Workspace:google._domainkey → 2048-bit anahtar, TXT olarak Admin Console'dan elle
Mümkün olduğunca CNAME delegasyonunu tercih edin. CNAME ile anahtarın kendisi göndericinin DNS'inde durur, siz sadece bir işaretçi koyarsınız. Gönderici anahtarını rotasyona soktuğunda sizin hiçbir şey yapmanız gerekmez — TXT'yi elle güncelleme derdi biter. Google Workspace burada istisnadır: anahtarı TXT olarak siz yapıştırır, rotasyonu Admin Console'dan siz tetiklersiniz.
Alt alan mimarisiyle bağlantı burada kuruluyor: selector'ı alt alana asarsınız (s1._domainkey.em.evilmail.pro) ve imza d=em.evilmail.pro (ya da relaxed hizalama ile d=evilmail.pro) olur. Bu d= değeri bir sonraki bölümün kilididir.
DMARC hizalaması: neden DKIM SPF'ten güvenilir hizalanır
DMARC'ın "pass" vermesi için tek bir mekanizmanın hem geçmesi hem de hizalanması yeter: ya (SPF pass VE hizalı) ya da (DKIM pass VE hizalı). "Hizalı" demek, doğrulanan alanın sizin org-alanınızla eşleşmesi demektir.
İşte üçüncü taraf göndericilerin can alıcı noktası: bir SendGrid gönderiminde envelope-from (SMTP MAIL FROM) genellikle bounces.sendgrid.net gibi göndericinin alanıdır. SPF bu alanı kontrol eder ve pass verir — ama bu sendgrid.net'in SPF'idir, sizin alanınızla hizalanmaz. Sonuç: SPF geçer, DMARC-SPF başarısız olur. Buna karşılık DKIM imzası d=evilmail.pro taşıyorsa doğrudan sizin alanınızla hizalanır ve DMARC geçer. Üçüncü taraf gerçekliğinde DKIM asıl çıpadır, SPF koşulludur.
adkim ve aspf etiketleri hizalama modunu belirler: r (relaxed) org-domain eşleşmesi ister — yani em.evilmail.pro ile evilmail.pro hizalı sayılır, bu da alt alan mimarisiyle tam uyumludur. s (strict) tam eşleşme ister ve alt alanları kırar; segmentasyon yapıyorsanız relaxed kullanın.
Yine de SPF'i ikinci bir çıpa olarak hizalamak akıllıcadır — bir imza arızasında yedeğiniz olur. Bunu custom return-path ile yaparsınız: SendGrid'de "Sender Authentication" altındaki return-path CNAME'ini em.evilmail.pro üzerinden kurunca envelope-from sizin alt alanınız olur ve SPF de hizalanır. Mailgun'da aynısı custom MAIL FROM = mg.evilmail.pro ile sağlanır. Sonuç: hem SPF hem DKIM hizalı; tek imza bozulsa bile DMARC ayakta kalır.
Önce ve sonra durumu ölçün. dig ile kayıtları, checkdmarc veya MXToolbox ile lookup sayısını doğrulayın:
bash
dig +short TXT evilmail.pro
dig +short TXT em.evilmail.pro
dig +short TXT s1._domainkey.em.evilmail.pro
dig +short TXT _dmarc.evilmail.pro
pip install checkdmarc && checkdmarc evilmail.pro
# ya da MXToolbox SuperTool → "spf:evilmail.pro" → "Number of DNS Lookups" satırı 10 veya altı olmalı
rua raporlarını okurken her satırda üç ayrı bilgi vardır: SPF sonucu, DKIM sonucu ve bunlardan ayrı hizalama sütunları. En sık gördüğünüz üçüncü taraf senaryosu "spf=pass ama hizalama fail" olacaktır — bu normaldir, DKIM sütununa bakarsınız. Ani bir spf=permerror dalgası ise net bir sinyaldir: kök SPF'iniz lookup bütçesini taşırmış.
Devreye almayı kademelendirin: p=none ile başlayıp en az iki hafta rua toplayın, hizalamanın oturduğunu görün → p=quarantine pct=25 → sorun yoksa pct=100 → p=reject. Alt alanları sp= ile kökten bağımsız yönetin; yeni bir gönderici eklerken alt alanı none'da tutup kökü reject'te bırakabilirsiniz.
Devreye alma kontrol listesi
Kök SPF yalnız Google mı ve 10 lookup'ın altında mı?checkdmarc ya da MXToolbox ile sayın, tahmin etmeyin.
Her üçüncü taraf gönderici kendi alt alanında mı? SendGrid → em., Mailgun → mg., kök yalnızca insan-postası.
Her alt alanda hem SPF hem DKIM var mı? DKIM tercihen CNAME delegasyonuyla.
Her gönderici için `d=` sizin alanınız/alt alanınız mı? Tahmin değil, gerçek bir rua raporunda doğrulayın.
Custom return-path / MAIL FROM kuruldu mu? İkinci çıpa için — tek imza arızasında ayakta kalırsınız.
DMARC rua tek adrese akıyor ve en az iki hafta gözlemlendi mi? Politikayı sıkmadan önce veriye bakın.
Anahtar rotasyonu göndericiye mi bırakıldı? Elle TXT güncellemesi gerekiyorsa mimariniz kırılgandır.
Flattening kullanıyorsanız cron ile yeniden üretiliyor mu? Statik flatten IP değişiminde sessizce bozulur.