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:

  • include yerine direkt ip4 blokları 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 TXT komutuyla kontrol edin
  • Gönderici IP’yi SPF kaydına ip4: olarak ekleyin ya da include: 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ı swaks ya 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.

Benzer Konular

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir