SPF Hatası: Mail Reddi ve Çözüm Yöntemi
Bir sabah uyandığınızda mail kuyruğunuzun dolup taştığını, müşterilerinizin “maillerim gitmiyor” diye telefon ettiğini ve log dosyalarının kırmızı bayraklarla dolu olduğunu hayal edin. SPF hatalarıyla tanışmanın en kötü yolu budur. Ama merak etmeyin, bu yazıda SPF’nin ne olduğunu, neden hata verdiğini ve nasıl çözeceğinizi adım adım ele alacağız.
SPF Nedir ve Neden Önemlidir?
SPF (Sender Policy Framework), bir domain adına mail göndermeye yetkili IP adreslerini tanımlayan bir DNS kaydıdır. Alıcı mail sunucusu, gelen maili gönderen sunucunun IP’siyle SPF kaydını karşılaştırır. Eğer IP yetkili değilse, mail reddedilir veya spam olarak işaretlenir.
Temel mantık şudur: ornek.com adresinden mail gönderiyorsanız, ornek.com‘un DNS kaydında hangi IP’lerin bu işe yetkili olduğu yazıyor olmalıdır. Alıcı sunucu bunu DNS’den sorgular ve kontrolü yapar. Yetkisiz bir IP’den geliyorsa, “SPF fail” yani SPF hatası alırsınız.
SPF kaydı olmayan ya da yanlış yapılandırılmış bir domain, modern mail sistemlerinde ciddi sorunlar yaşar. Gmail, Outlook, Yahoo gibi büyük sağlayıcılar SPF kontrolünü ciddiye alır ve hatalı kayıtlarda maillerinizi direkt çöpe atar ya da reddeder.
Gerçek Dünya Senaryosu: Ne Oldu?
Diyelim ki şirketiniz sirket.com domainini kullanıyor. Ana mail sunucunuz mail.sirket.com üzerinde çalışıyor ve her şey yıllardır düzgün işliyordu. Bir gün yeni bir CRM sistemi kurdunuz ya da pazarlama ekibi üçüncü parti bir mail servisi (Mailchimp, SendGrid, Brevo gibi) kullanmaya başladı. İşte tam bu noktada SPF sorunları baş gösterir. Çünkü yeni servisin IP’leri SPF kaydınızda tanımlı değildir.
Ya da tam tersi: Sunucu taşıması yaptınız, IP adresiniz değişti ama SPF kaydını güncellemeyi unuttunuz. Eski IP hâlâ kayıtta yazıyor, yeni IP’den gönderdiğiniz mailler reddediliyor.
SPF Hatalarını Tespit Etmek
Mail Log Dosyalarını İnceleme
İlk adım her zaman log dosyalarına bakmaktır. Postfix kullanan bir sistemde:
# Postfix log dosyasını SPF hatası için tara
grep -i "spf" /var/log/mail.log | tail -50
# Daha spesifik olarak fail durumlarına bak
grep -i "spf.*fail|spf.*reject|550.*spf" /var/log/mail.log | tail -20
# Belirli bir domain için filtrele
grep "sirket.com" /var/log/mail.log | grep -i "spf" | tail -30
Tipik bir SPF fail logu şöyle görünür:
Oct 15 09:23:11 mailserver postfix/smtpd[12345]: NOQUEUE: reject: RCPT from unknown[203.0.113.45]: 550 5.7.23 <[email protected]>: Recipient address rejected: Message rejected due to: SPF fail - not authorized
Bu çıktıda dikkat etmeniz gereken noktalar şunlardır:
- 203.0.113.45: Gönderici IP adresi
- 550 5.7.23: SMTP hata kodu, SPF başarısızlığını gösterir
- not authorized: Bu IP, domain’in SPF kaydında tanımlı değil
Mevcut SPF Kaydını Kontrol Etme
DNS’deki SPF kaydınızı sorgulamak için birkaç yöntem vardır:
# dig ile SPF kaydını sorgula
dig TXT sirket.com | grep spf
# nslookup alternatifi
nslookup -type=TXT sirket.com | grep spf
# host komutuyla
host -t TXT sirket.com | grep spf
# Daha detaylı çıktı için
dig +short TXT sirket.com
Örnek bir çıktı şöyle görünebilir:
"v=spf1 ip4:192.168.1.100 include:_spf.google.com ~all"
Eğer hiç SPF kaydı yoksa, dig komutu SPF ile ilgili hiçbir şey döndürmez. Bu da kendi başına bir sorundu.
Gönderici IP’nin Yetkili Olup Olmadığını Test Etme
# SPF sorgusu yapmak için Python'daki spf modülünü kullan
pip install pyspf
python3 -c "
import spf
result, code, message = spf.check2(i='203.0.113.45', s='[email protected]', h='mail.ornek.com')
print(f'Sonuc: {result}')
print(f'Kod: {code}')
print(f'Mesaj: {message}')
"
Ya da spfquery aracını kullanabilirsiniz:
# spfquery kurulumu (Debian/Ubuntu)
apt-get install libmail-spf-perl
# SPF sorgusu yap
spfquery --ip=203.0.113.45 [email protected] --helo=mail.ornek.com
SPF Kaydı Sözdizimi ve Mekanizmaları
SPF kaydını düzgün yazabilmek için sözdizimini anlamak gerekir. Bir SPF kaydı her zaman v=spf1 ile başlar.
Temel Mekanizmalar
- ip4:x.x.x.x: Tekil bir IPv4 adresi için yetkilendirme yapar
- ip4:x.x.x.x/24: Bir IPv4 CIDR bloğu için yetkilendirme yapar
- ip6:xxxx::xxxx: IPv6 adresi için yetkilendirme yapar
- a: Domain’in A kaydındaki IP’yi yetkilendirir
- a:subdomain.sirket.com: Belirtilen alt domainin A kaydını yetkilendirir
- mx: Domain’in MX kayıtlarındaki IP’leri yetkilendirir
- include:baskadomain.com: Başka bir domain’in SPF kaydını dahil eder
- ptr: PTR kaydını kontrol eder (kullanımı önerilmez, yavaştır)
- exists: Belirtilen domain var mı diye kontrol eder
Niteleyiciler (Qualifiers)
- +: Pass (varsayılan, açıkça yazılmasa da geçerlidir)
- –: Fail (sert ret, mail kesinlikle reddedilir)
- ~: SoftFail (yumuşak ret, genellikle spam olarak işaretlenir)
- ?: Neutral (tarafsız, ne izin ne de yasak)
all Mekanizması
SPF kaydının sonundaki all ifadesi kritik önem taşır:
- -all: Yukarıdaki hiçbir kurala uymayan IP’leri kesin olarak reddeder (önerilen üretim ayarı)
- ~all: Uymayan IP’leri yumuşak reddeder (test aşaması için iyi)
- ?all: Tarafsız kalır (çok zayıf koruma)
- +all: Herkese izin verir (kesinlikle kullanmayın!)
Yaygın SPF Hata Senaryoları ve Çözümleri
Senaryo 1: Yeni IP Eklenmesi Gereken Durum
Şirketiniz yeni bir mail sunucusu kurdu ya da IP değişti. Eski SPF kaydı:
v=spf1 ip4:192.0.2.10 -all
Yeni sunucu IP’si 198.51.100.25 ise kaydı şöyle güncellersiniz:
# Önce mevcut kaydı kontrol et
dig TXT sirket.com +short
# DNS yönetim panelinizde veya BIND zone dosyasında güncelle
# BIND zone dosyası örneği (/etc/bind/db.sirket.com):
# sirket.com. IN TXT "v=spf1 ip4:192.0.2.10 ip4:198.51.100.25 -all"
# Değişiklikten sonra TTL süresi kadar bekle, ardından doğrula
dig TXT sirket.com +short
# Veya belirli bir DNS sunucusundan sorgula
dig @8.8.8.8 TXT sirket.com +short
Senaryo 2: Üçüncü Parti Servis Entegrasyonu
Pazarlama ekibi SendGrid kullanmaya başladı. SendGrid’in IP’lerini tek tek eklemek yerine include mekanizması kullanılır:
v=spf1 ip4:192.0.2.10 include:sendgrid.net include:_spf.google.com -all
Mailchimp için:
v=spf1 ip4:192.0.2.10 include:servers.mcsv.net -all
Birden fazla servis kullanıyorsanız:
v=spf1 ip4:192.0.2.10 ip4:198.51.100.25 include:sendgrid.net include:_spf.google.com include:servers.mcsv.net -all
Senaryo 3: DNS Lookup Limiti Aşımı
SPF’nin en sinsi sorunu budur. SPF standardı, bir kaydın değerlendirilmesi sırasında en fazla 10 DNS lookup’a izin verir. Her include, a, mx ifadesi bir lookup tüketir. Bu limiti aşarsanız, SPF otomatik olarak permerror döndürür ve mailler reddedilir.
# SPF kayıtlarındaki lookup sayısını kontrol etmek için
# spf-tools veya online araçlar kullanılabilir
# Manuel kontrol: kaç tane include, a, mx var?
dig TXT sirket.com +short | tr ' ' 'n' | grep -c "include|^a|^mx|^ptr|^exists"
Lookup sayısını azaltmak için birkaç yöntem vardır:
includeyerine direktip4blokları kullanın- SPF flattening yapın (tüm IP’leri birleştirip tek bir kayıt oluşturun)
- Gereksiz servisleri SPF’den çıkarın
SPF flattening örneği:
# SendGrid'in tüm IP'lerini çek
dig TXT sendgrid.net +short | grep "v=spf1"
# Sonra alt SPF kayıtlarını da çek
dig TXT _spf.google.com +short
# Tüm IP'leri birleştirip tek kayıt oluştur
# Örnek düzleştirilmiş kayıt:
# v=spf1 ip4:192.0.2.0/24 ip4:198.51.100.0/24 ip4:203.0.113.10 -all
Senaryo 4: Postfix’te SPF Doğrulamasını Etkinleştirme
Kendi mail sunucunuzda SPF kontrolü yapmak istiyorsanız, Postfix’e postfix-policyd-spf-python kurmanız gerekir:
# Ubuntu/Debian için kurulum
apt-get install postfix-policyd-spf-python
# /etc/postfix/master.cf dosyasına ekle
echo "policyd-spf unix - n n - 0 spawn
user=policyd-spf argv=/usr/bin/policyd-spf" >> /etc/postfix/master.cf
# /etc/postfix/main.cf dosyasını düzenle
# smtpd_recipient_restrictions bölümüne ekle:
cat >> /etc/postfix/main.cf << 'EOF'
policyd-spf_time_limit = 3600
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination,
check_policy_service unix:private/policyd-spf
EOF
# Postfix'i yeniden başlat
systemctl restart postfix
# Durum kontrolü
systemctl status postfix
Senaryo 5: Birden Fazla SPF Kaydı Hatası
Bu çok sık karşılaşılan bir hatadır. DNS’de bir domain için sadece bir SPF kaydı olmalıdır. Birden fazla SPF TXT kaydı varsa, RFC 7208’e göre bu bir hata sayılır ve davranış tanımsız hale gelir.
# Birden fazla SPF kaydı var mı kontrol et
dig TXT sirket.com +short | grep "v=spf1"
# Eğer iki satır çıktı alıyorsanız, sorun burada
# "v=spf1 ip4:192.0.2.10 -all"
# "v=spf1 include:_spf.google.com ~all"
Çözüm basittir: İki kaydı birleştirip tek kayıt haline getirin:
v=spf1 ip4:192.0.2.10 include:_spf.google.com -all
SPF Kaydını Test Etme
Değişiklik yaptıktan sonra mutlaka test edin. Birkaç pratik yöntem:
# swaks ile test maili gönder ve başlıkları incele
# swaks kurulumu
apt-get install swaks
# Test maili gönder
swaks --to [email protected]
--from [email protected]
--server mail.sirket.com
--port 587
--auth LOGIN
--auth-user [email protected]
--auth-password "sifre"
--tls
# Gelen mailin başlıklarında şunu arayın:
# Received-SPF: pass (google.com: domain of [email protected] designates 198.51.100.25 as permitted sender)
# Python ile hızlı SPF testi
python3 << 'EOF'
import subprocess
import sys
domain = "sirket.com"
ip = "198.51.100.25"
result = subprocess.run(
["spfquery", f"--ip={ip}", f"--sender=test@{domain}", f"--helo=mail.{domain}"],
capture_output=True,
text=True
)
print(f"Çıkış kodu: {result.returncode}")
print(f"Stdout: {result.stdout}")
print(f"Stderr: {result.stderr}")
if result.returncode == 0:
print("SPF: PASS - IP yetkili")
elif result.returncode == 1:
print("SPF: FAIL - IP yetkisiz!")
else:
print(f"SPF: Diğer sonuç (kod: {result.returncode})")
EOF
DMARC ile SPF’yi Birlikte Kullanmak
SPF tek başına yeterli değildir. DMARC (Domain-based Message Authentication, Reporting and Conformance), SPF ve DKIM sonuçlarını birleştirerek daha güçlü bir koruma sağlar. En azından monitoring modunda bir DMARC kaydı ekleyin:
# DMARC kaydını kontrol et
dig TXT _dmarc.sirket.com +short
# Temel bir DMARC kaydı (önce p=none ile başlayın, raporları izleyin)
# _dmarc.sirket.com. IN TXT "v=DMARC1; p=none; rua=mailto:[email protected]; ruf=mailto:[email protected]; sp=none; adkim=r; aspf=r"
# Zamanla p=quarantine ya da p=reject'e geçin
# "v=DMARC1; p=quarantine; pct=100; rua=mailto:[email protected]"
DMARC’ı monitor modunda bırakıp birkaç hafta rapor alın. Raporlar size hangi IP’lerden domain’iniz adına mail gönderildiğini gösterecektir. Bu, SPF kaydınızı eksiksiz yazmak için harika bir veri kaynağıdır.
Hızlı Tanı Aracı: Bir Script
Aşağıdaki script, bir domain için SPF ile ilgili temel kontrolleri otomatik yapar:
#!/bin/bash
# spf_check.sh - Hızlı SPF tanı scripti
DOMAIN=${1:-"sirket.com"}
IP=${2:-""}
echo "=== SPF Tanı Raporu: $DOMAIN ==="
echo ""
echo "[1] TXT Kayitlari:"
dig TXT "$DOMAIN" +short
echo ""
echo "[2] SPF Kaydi:"
SPF_RECORD=$(dig TXT "$DOMAIN" +short | grep "v=spf1")
if [ -z "$SPF_RECORD" ]; then
echo "UYARI: SPF kaydi bulunamadi!"
else
echo "$SPF_RECORD"
# Lookup sayisini tahmin et
INCLUDES=$(echo "$SPF_RECORD" | grep -o "include:" | wc -l)
MX_COUNT=$(echo "$SPF_RECORD" | grep -o 'bmxb' | wc -l)
A_COUNT=$(echo "$SPF_RECORD" | grep -o 'bab' | wc -l)
TOTAL=$((INCLUDES + MX_COUNT + A_COUNT))
echo ""
echo "[3] Tahmini DNS Lookup Sayisi: $TOTAL"
if [ "$TOTAL" -gt 8 ]; then
echo "UYARI: Lookup sayisi $TOTAL, 10 limitine yaklasiyorsunuz!"
elif [ "$TOTAL" -gt 10 ]; then
echo "HATA: Lookup sayisi $TOTAL, 10 limitini asiyor! SPF permerror verecek!"
else
echo "OK: Lookup sayisi guvenli seviyede."
fi
fi
echo ""
echo "[4] Birden Fazla SPF Kaydi Kontrolu:"
SPF_COUNT=$(dig TXT "$DOMAIN" +short | grep -c "v=spf1")
if [ "$SPF_COUNT" -gt 1 ]; then
echo "HATA: $SPF_COUNT adet SPF kaydi bulundu! Sadece 1 olmali."
else
echo "OK: Tek SPF kaydi mevcut."
fi
echo ""
echo "[5] DMARC Kaydi:"
DMARC=$(dig TXT "_dmarc.$DOMAIN" +short)
if [ -z "$DMARC" ]; then
echo "UYARI: DMARC kaydi bulunamadi!"
else
echo "$DMARC"
fi
echo ""
echo "=== Tanı Tamamlandi ==="
# Scripti çalıştırılabilir yap ve kullan
chmod +x spf_check.sh
./spf_check.sh sirket.com
./spf_check.sh sirket.com 198.51.100.25
SPF Propagasyon Süresi
DNS değişiklikleri anlık yansımaz. TTL (Time to Live) değerinize bağlı olarak birkaç dakikadan 48 saate kadar sürebilir. Değişiklik sonrası farklı DNS sunucularından sorgulayarak yayılımı takip edebilirsiniz:
# Farklı DNS sunucularından sorgula
for dns in 8.8.8.8 1.1.1.1 9.9.9.9 208.67.222.222; do
echo -n "DNS $dns: "
dig @$dns TXT sirket.com +short | grep "v=spf1"
done
Tüm sunucular aynı kaydı gösterene kadar sorun çözülmüş saymayın.
Sonuç
SPF hataları ilk başta karmaşık görünebilir ama temel mantığı kavradıktan sonra tanı ve çözüm süreci oldukça sistematik hale gelir. Özetleyecek olursak:
- Log dosyalarından SPF fail’i tespit edin, hangi IP’nin reddedildiğini bulun
- Mevcut SPF kaydınızı
dig TXTkomutuyla kontrol edin - Gönderici IP’yi SPF kaydına
ip4:olarak ekleyin ya dainclude:ile üçüncü parti servisi dahil edin - Birden fazla SPF kaydı varsa tek kayıtta birleştirin
- DNS lookup sayısının 10’u geçmediğinden emin olun
- Değişiklik sonrası
swaksya da online araçlarla test edin - DMARC kaydı ekleyerek mail güvenliğinizi bir üst seviyeye taşıyın
Mail sunucu yönetiminde SPF, DKIM ve DMARC üçlüsünü doğru kurmak, hem alan adınızın itibarını korur hem de phishing/spoofing saldırılarına karşı ciddi bir engel oluşturur. Bu üçlüye yatırım yapmanın maliyeti yoka yakın, getirisi ise çok yüksektir.
