SPF, DKIM ve DMARC'ı Sıfırdan Kurmak: Doğru DNS Kayıtları ve Kanıtlanmış Doğrulama
Üç sihirli TXT kaydını kopyala-yapıştır etmek beş dakikalık iştir. Asıl mühendislik, her katmanı tek tek doğrulayıp DMARC'ı p=none'dan p=reject'e meşru postanı vurmadan taşımaktır. evilmail.pro'nun gerçek DNS'i, gerçek dig/opendkim çıktıları ve gerçek Authentication-Results başlıkları üzerinden.
EvilMail Team20 Temmuz 202611 dk okuma
Bir saldırgan From: [email protected] yazan bir mail atıp müşterine sahte ödeme linki gönderdiğinde, SPF kaydın bunu tek başına durduramaz. Durduramaz da, çünkü SPF senin From başlığına hiç bakmaz. Bu tek cümle, üç kaydın neden birlikte var olması gerektiğinin özetidir ve çoğu rehberin tam da atladığı yerdir.
SPF, DKIM ve DMARC'ı yayınlamak beş dakika sürer. İşin geri kalanı — hangi kaydın neyi doğruladığını anlamak, üçünün gerçekten çalıştığını alıcının başlığından okumak ve DMARC'ı meşru postanı reddetmeden p=reject'e taşımak — asıl mühendisliktir. Bu yazı bunu evilmail.pro'nun gerçek DNS'i üzerinden anlatır.
SPF tek başına neden çuvallar: tehdit modeli ve hizalanma
Bir e-postanın iki ayrı "kimden" alanı vardır ve bunları karıştırmak tüm kafa karışıklığının kaynağıdır:
Zarf gönderici (envelope sender / MAIL FROM / Return-Path): SMTP diyaloğunda MAIL FROM:<[email protected]>
SPF, DKIM, DMARC Kurulumu: DNS TXT Kayıtları ve Doğrulama Rehberi — EvilMail Blog
olarak geçen adres. Kullanıcı bunu görmez; bounce mesajları buraya döner.
Başlık From (header From): Mail istemcisinde görünen From: Destek <[email protected]>. Kullanıcının gördüğü tek adres budur.
SPF yalnızca zarfı doğrular.MAIL FROM alan adının SPF kaydına bakar ve gönderen IP'nin yetkili olup olmadığını söyler. Görünen From başlığına dokunmaz bile. Bir saldırgan kendi attacker.com alanından, zarfı [email protected] yapıp başlığı From: [email protected] diye yazarak mail atabilir — SPF saldırganın kendi alanında pass verir, çünkü zarf gerçekten attacker.com'dur.
DKIM yalnızca imzaladığı başlıkları doğrular. Mesaja kriptografik bir imza ekler; imza içindeki d= etiketi imzayı hangi alanın attığını söyler. Ama DKIM de tek başına, d= ile From başlığının aynı alan olmasını şart koşmaz.
İşte DMARC bu boşluğu kapatmak için icat edildi. DMARC tek bir şey sorar: SPF veya DKIM'den *en az biri*, görünen From başlığındaki alan adıyla hizalı (aligned) biçimde pass mı verdi? Hizalanma, doğrulanan alanın From alanıyla eşleşmesi demektir. Saldırganın örneğinde SPF attacker.com için pass verir ama Fromevilmail.pro'dur — hizalanma yok, DMARC fail, mesaj reddedilir.
Mevcut durumu ölç: yayınlamadan önce dig
Hiçbir kaydı değiştirmeden önce ne olduğunu gör. En sık rastlanan kirli başlangıç, alan adında iki ayrı `v=spf1` kaydı bulunmasıdır — bu otomatik PermError üretir ve DMARC bunu spf=fail sayar.
bash
# Mevcut kayıtlar (resolver önbelleği üzerinden)
dig +short TXT evilmail.pro
dig +short TXT _dmarc.evilmail.pro
dig +short TXT mail._domainkey.evilmail.pro
# Önbelleği atla, doğrudan authoritative sunucuya sor
dig @storm.example.net TXT evilmail.pro
Resolver önbelleği sinsi bir tuzaktır: kaydı değiştirirsin, dig +short eski TTL süresince hâlâ eski değeri döndürür ve saatlerce kaybolmuş kayıt kovalarsın. Geçiş yaparken daima authoritative sunucuya (@storm.example.net) sor. Bu yüzden geçiş boyunca TTL'i 300 saniyeye düşür, işler oturunca 3600'e çıkar.
SPF: doğru tek satır ve 10-lookup duvarı
evilmail.pro'nun SPF kaydı:
text
evilmail.pro. 300 IN TXT "v=spf1 mx a:mail.evilmail.pro ip4:203.0.113.10 -all"
Parça parça:
`v=spf1` — sürüm etiketi, zorunlu ilk token.
`mx` — alan adının MX kayıtlarındaki hostlar gönderebilir. Bir DNS lookup harcar.
`a:mail.evilmail.pro` — bu hostun A kaydındaki IP yetkili. Bir lookup daha.
`ip4:203.0.113.10` — sabit IP, lookup harcamaz. IP tabanlı mekanizmalar bedavadır; mümkün olduğunca bunları tercih et.
`-all` — hardfail: listede olmayan her IP reddedilsin.
10 DNS-lookup duvarı SPF'in en çok patlayan yeridir. RFC 7208, bir SPF değerlendirmesinde include, a, mx, ptr, exists mekanizmalarının toplam 10 DNS sorgusunu aşamayacağını söyler. Google + bir CRM + bir fatura sağlayıcısını include: ederek zincirlersen bunu kolayca aşarsın; sonuç PermError'dır ve DMARC bunu fail sayar. Her include:'ın kaç lookup getirdiğini bilmeden ekleme.
~all (softfail, "şüpheli ama kabul et") test aşaması içindir; üretimde -all (hardfail) kullan. ptr mekanizması ölüdür — yavaş, güvenilmez ve RFC tarafından "kullanmayın" damgalıdır. Bir alan adında yalnızca bir `v=spf1` kaydı olur. İkinci bir tane eklersen ikisi de geçersiz sayılır.
DKIM: 2048-bit anahtar üret, yayınla, imzala
Anahtar çiftini üret:
bash
cd /etc/opendkim/keys/evilmail.pro/
opendkim-genkey -b 2048 -s mail -d evilmail.pro
# Üretir: mail.private (özel anahtar) + mail.txt (yayınlanacak DNS kaydı)
chown opendkim:opendkim mail.private
chmod 600 mail.private
mail.private özel anahtardır ve sunucudan asla çıkmaz — 600 izinleri ve opendkim:opendkim sahipliği şart. mail.txt içindeki public key mail._domainkey.evilmail.pro altında yayınlanır:
Bir TXT string RFC 1035 gereği en fazla 255 karakter olabilir. 2048-bit public key bundan uzundur, bu yüzden opendkim-genkey çıktısı zaten tırnaklı parçalara böler. DNS sunucusu bu parçaları birleştirir; onları elle tek satıra yapıştırmaya çalışıp arada kaçak karakter bırakmak DKIM'i sessizce bozan klasik hatadır.
`mail` selector'dır. Anahtar rotasyonu için mail2026, mail2027 gibi tarihli selector'lar kullan; eskiyi bir süre yayında bırakıp yeniye geç, böylece transitteki mailler kırılmaz. 1024-bit artık kabul edilmez — 2048-bit standarttır. İstersen Ed25519 selector'ı da yayınla, ama tüm doğrulayıcılar desteklemediği için RSA'yı paralel tut.
`p=none` — gözlem modu. Hiçbir postayı reddetmez veya karantinaya almaz; sadece rapor ister. Enforcement'a geçmeden önce buradan başlanır.
`rua=` — agregat raporlar. Alıcı sunucular günde bir, adına hangi IP'lerin mail attığını ve SPF/DKIM/hizalanma sonuçlarını XML olarak buraya yollar. En kıymetli veri budur.
`ruf=` — forensic raporlar; fail eden tekil mesajların örnekleri. Çoğu büyük sağlayıcı gizlilik nedeniyle artık göndermez, ama tanımlamak zarar vermez.
`fo=1` — SPF veya DKIM'den herhangi biri hizalı pass üretemezse forensic üret.
`adkim=s` / `aspf=s` — strict hizalanma: doğrulanan alan From ile birebir eşleşmeli. `r` (relaxed) alt alan adlarına da izin verir (mail.evilmail.pro, evilmail.pro ile hizalı sayılır). Bir marketing sağlayıcısı alt alandan gönderiyorsa r gerekir; kontrolün sendeyse s daha sıkıdır.
Raporları başka bir alandaki adrese yolluyorsan (örn. [email protected]), o alan kendi DNS'inde evilmail.pro._report._dmarc.izleme-servisi.com altında bir v=DMARC1 yetki (authorization) kaydı yayınlamalı, yoksa raporlar hiç gelmez.
Üçünü birlikte doğrula: gerçek başlığı oku
Kayıt yayınlamak, çalışıyor demek değildir. Önce private/public eşleşmesini test et:
bash
opendkim-testkey -d evilmail.pro -s mail -vvv
# Beklenen: "key OK"
Sonra kendine gerçek bir test maili at ve alıcıdaki ham başlığı aç (Gmail'de "Orijinali göster"). Aradığın satır:
Üç pass yeterli değil — hizalanmayı gözle doğrula: smtp.mailfrom=evilmail.pro, header.d=evilmail.pro ve header.from=evilmail.pro aynı alanı göstermeli. En sinsi hata "pass ama align-fail"tir: DKIM pass verir ama header.d= bir sağlayıcının alanıdır ve From seninkidir — sonuç DMARC fail. Bir başka klasik: aradaki bir MTA (mailing list, forwarder) başlığı yeniden yazıp DKIM b= imzasını bozar; imza fail düşer, DMARC yalnızca SPF hizalanmasına kalır ve forwarding SPF'i de kırar.
Otomatik teyit için mail-tester.com'a mail at (10/10 hedefle); gönderim hacmin varsa alanını Google Postmaster Tools'a ekle.
p=none → p=reject: güvenli rampa
Enforcement'a geçiş, deliverability'nin en çok korkulan adımıdır çünkü yanlış yaparsan kendi meşru postanı reddedersin. Kural basit: raporlarda %100 hizalı pass görmeden `p=reject`'e geçme.
p=none ile 1-2 hafta boyunca rua raporlarını oku. Raporlar adına mail atan her kaynağı gösterir: uygulama sunucun, fatura maili, pazarlama sağlayıcın, hatta unuttuğun eski bir CRM. Her meşru kaynağı SPF'e (IP veya include) ve mümkünse DKIM'e ekle. fail=0 olana kadar burada kal.
Sonra p=quarantine; pct=25 — mesajların dörtte biri hizalanmazsa spam'e düşer, geri kalanı normal akar; yanlış-pozitifleri erken yakalarsın. pct=100'e çık, bir hafta izle, ardından p=reject. Forwarding hâlâ SPF'i kırar; bunu kurtaran zincir ARC'tir (Authenticated Received Chain) — forwarder'ın ARC imzasına güvenirsin. p=reject'e ulaştığında BIMI'nin (marka logosunu gelen kutusunda gösterme) kapısı açılır — ama BIMI'nin ön koşulu tam da reject enforcement'ıdır.
Kurulum ve doğrulama kontrol listesi
Tek SPF kaydı mı var? dig +short TXT evilmail.pro tek bir v=spf1 satırı dönmeli.
SPF içindeki toplam DNS lookup sayısı < 10 mu? include: zincirini say.
Üretimde `-all` mı? Test bittiyse ~all'ı değiştir.
opendkim-testkey ... -vvv"key OK" veriyor mu?
DKIM p= değeri 255-karakter parçalara doğru bölünmüş, k=rsa ve 2048-bit mi?
_dmarc kaydı yayında ve `rua` adresine gerçekten rapor düşüyor mu?
Test mailinin başlığında spf=pass, dkim=pass, dmarc=pass ve üçü de evilmail.pro ile hizalı mı?
Geçiş boyunca TTL 300s mı? Oturunca 3600'e çıkar.
`p=reject` öncesi tüm meşru göndericiler raporlarda haritalanıp SPF/DKIM'e eklendi mi?
Bu dokuz maddeyi geçen bir alan adı hem gelen kutusuna girer hem de adının başkası tarafından kullanılmasını kriptografik olarak imkânsız kılar. Kayıtları yazmak beş dakika; bu listeyi yeşile boyamak birkaç hafta — ve fark tam olarak burada saklıdır.