DKIM İmza Doğrulama Sorunu: Adım Adım Hata Tespiti

Mail sunucunuzdan gönderdiğiniz e-postalar spam klasörüne düşüyor mu? Alıcı taraf size “imza doğrulanamadı” hatası mı gönderiyor? O zaman büyük ihtimalle DKIM imza doğrulama sorununuzla boğuşuyorsunuzdur. Bu yazıda DKIM hatalarını nasıl tespit edeceğinizi, nerede aramak gerektiğini ve gerçek dünya senaryolarında nasıl çözeceğinizi adım adım anlatacağım.

DKIM Nedir ve Neden Bu Kadar Önemli

DKIM (DomainKeys Identified Mail), e-posta başlıklarına kriptografik imza ekleyen bir kimlik doğrulama mekanizmasıdır. Postfix, Sendmail veya Exchange fark etmez, modern mail altyapısında DKIM olmadan itibarınızı korumak neredeyse imkansız.

Kısaca çalışma mantığı şöyle: Gönderen sunucu, özel anahtar (private key) ile mesajı imzalar. Alıcı sunucu ise DNS’te yayınlanan genel anahtar (public key) ile bu imzayı doğrular. İkisi uyuşursa “pass”, uyuşmazsa “fail” döner.

Sorun şu ki DKIM konfigürasyonu bir kez yapıp unutulan türden değil. Key rotation, DNS propagasyonu, header değişiklikleri, mailing list geçişleri gibi onlarca faktör imzayı bozabilir.

Hata Tespit Sürecine Giriş

Önce şunu netleştirelim: DKIM hatası her zaman sizin sunucunuzdan kaynaklanmaz. Hata üç farklı noktada olabilir:

  • İmzalama aşaması: Sunucunuz mesajı imzalarken sorun çıkıyor
  • DNS yayını: Public key DNS’te yanlış veya eksik yayınlanmış
  • Doğrulama aşaması: Alıcı taraf imzayı doğrularken sorun yaşıyor

Bu yüzden hata tespitine önce mail başlıklarını inceleyerek başlamak gerekir.

Mail Başlıklarını Okumak

Gelen bir mailin başlıklarını incelediğinizde DKIM doğrulama sonucunu Authentication-Results başlığında görürsünüz. Gmail’e gönderdiğiniz bir mailin başlığı şöyle görünebilir:

# Gmail'den "Show original" ile aldığınız başlık örneği
Authentication-Results: mx.google.com;
       dkim=fail (bad signature) [email protected] header.s=mail header.b=ABC123XY;
       spf=pass (google.com: domain of [email protected] designates 1.2.3.4 as permitted sender)
       [email protected];
       dmarc=fail (p=REJECT sp=REJECT dis=REJECT) header.from=domain.com

Burada dikkat etmeniz gereken alanlar:

  • dkim=fail: İmza doğrulaması başarısız
  • header.i: İmzalayan domain
  • header.s: Kullanılan selector (anahtar seçici)
  • header.b: İmzanın ilk 8 karakteri (hangi imzanın sorunlu olduğunu bulmak için)

DNS’te DKIM Kaydını Kontrol Etmek

İlk yapmanız gereken şey DNS kaydınızın doğru olup olmadığını kontrol etmek. Selector’ınız mail ise:

# DKIM TXT kaydını sorgula
dig TXT mail._domainkey.domain.com +short

# Daha detaylı çıktı için
dig TXT mail._domainkey.domain.com

# nslookup ile alternatif sorgu
nslookup -type=TXT mail._domainkey.domain.com 8.8.8.8

Beklenen çıktı şöyle bir şey olmalı:

"v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC..."

Eğer hiç çıktı gelmiyorsa DNS kaydı yok demektir. Eğer p= kısmı boşsa (yani p=) key revoke edilmiş demektir, bu kasıtlı bir devre dışı bırakma olabilir.

OpenDKIM ile Lokal Test

Sunucunuzda OpenDKIM kuruluysa, imzalama ve doğrulamayı lokal ortamda test edebilirsiniz:

# OpenDKIM test aracıyla imzayı doğrula
opendkim-testkey -d domain.com -s mail -vvv

# Çıktı örneği (başarılı durum):
# opendkim-testkey: using default configfile /etc/opendkim.conf
# opendkim-testkey: checking key 'mail._domainkey.domain.com'
# opendkim-testkey: key OK

Eğer hata alıyorsanız çıktı şuna benzeyecek:

# Başarısız durum çıktısı
opendkim-testkey: using default configfile /etc/opendkim.conf
opendkim-testkey: checking key 'mail._domainkey.domain.com'
opendkim-testkey: key data is not secure
# veya
opendkim-testkey: key not found in DNS

key not found in DNS hatası genellikle ya DNS kaydını hiç eklememişsinizdir ya da propagasyon henüz tamamlanmamıştır.

Private Key ve İzin Sorunları

Gerçek dünyada en sık karşılaştığım sorunlardan biri dosya izinleri. OpenDKIM, private key dosyasını okuyamazsa sessizce başarısız olabilir ya da log’a minimal bilgi yazar.

# Private key konumunu ve izinlerini kontrol et
ls -la /etc/opendkim/keys/domain.com/
# Beklenen çıktı:
# -rw------- 1 opendkim opendkim 1679 Jan 15 10:23 mail.private
# -rw-r--r-- 1 opendkim opendkim  312 Jan 15 10:23 mail.txt

# Sahipliği düzelt
chown opendkim:opendkim /etc/opendkim/keys/domain.com/mail.private

# İzinleri düzelt
chmod 600 /etc/opendkim/keys/domain.com/mail.private

# OpenDKIM'in key dosyasını okuyabildiğini test et
sudo -u opendkim cat /etc/opendkim/keys/domain.com/mail.private | head -3

Eğer sudo -u opendkim cat komutu “Permission denied” dönüyorsa sorun burada.

Log Analizi: Postfix ve OpenDKIM

Log analizi olmadan DKIM hata tespiti kör adam fil tarifi gibi olur. Postfix ve OpenDKIM logları ayrı ayrı incelenmelidir:

# OpenDKIM loglarını gerçek zamanlı izle
tail -f /var/log/mail.log | grep -i dkim

# Daha kapsamlı arama (son 1000 satır)
grep -i "dkim" /var/log/mail.log | tail -100

# Hatalı imzaları filtrele
grep -E "dkim.*fail|dkim.*error|dkim.*unable" /var/log/mail.log

# Belirli bir domain için DKIM loglarını filtrele
grep "dkim" /var/log/mail.log | grep "domain.com" | tail -50

Tipik bir başarısız imzalama logu şöyle görünür:

Jan 15 14:23:45 mailserver opendkim[1234]: ABC123 unable to sign: key retrieval failed
Jan 15 14:23:45 mailserver opendkim[1234]: ABC123 no signature data

Bu tür bir log gördüğünüzde önce key dosyasını, sonra OpenDKIM konfigürasyonunu kontrol edin.

OpenDKIM Konfigürasyonunu Doğrulamak

Konfigürasyon dosyasındaki yaygın hatalar imzalamayı tamamen devre dışı bırakabilir:

# OpenDKIM konfigürasyonunu görüntüle
cat /etc/opendkim.conf

# Kritik parametreleri kontrol et
grep -E "^(Domain|KeyFile|Selector|Mode|Socket)" /etc/opendkim.conf

Doğru bir konfigürasyon şöyle görünmelidir:

# /etc/opendkim.conf temel parametreler
Mode                    sv
Domain                  domain.com
Selector                mail
KeyFile                 /etc/opendkim/keys/domain.com/mail.private
Socket                  local:/run/opendkim/opendkim.sock
UserID                  opendkim
UMask                   007

# Birden fazla domain için signing table kullanımı
KeyTable                /etc/opendkim/KeyTable
SigningTable            refile:/etc/opendkim/SigningTable
InternalHosts           /etc/opendkim/TrustedHosts

Mode parametresi özellikle kritik. s sadece imzalama, v sadece doğrulama, sv ikisi birden anlamına gelir. Eğer Mode değerini yanlış ayarladıysanız sunucunuz mesajları imzalamaz.

Gerçek Dünya Senaryosu 1: Mailing List Sonrası DKIM Fail

Bir müşteride şöyle bir senaryo yaşadım: Kendi sunucularından gönderdikleri mailler gayet iyi gidiyordu. Ancak Mailchimp veya benzeri bir bulk mail servisi üzerinden gönderdiklerinde alıcılar DKIM fail raporu alıyordu.

Sorun şuydu: Mailing list yazılımları genellikle mesajın body’sini veya başlıklarını değiştirir (footer eklemek, unsubscribe linki eklemek gibi). Bu değişiklik DKIM imzasını geçersiz kılar çünkü imza, mesajın hash’ini içerir.

# Mailing list geçişinden sonra mesajı analiz et
# Başlıktaki DKIM imzasını incele
grep -A5 "DKIM-Signature" /path/to/email.eml

# b= tag'i imzanın kendisi, bh= tag'i body hash'i
# Body değişmişse bh= değeri uyuşmaz

Çözüm: Ya l= tag’ini kullanarak imzalanan body uzunluğunu sınırlandırmak ya da mailing list’in kendi DKIM’ini kullanmasını sağlamak. Çoğu durumda ikinci seçenek daha temiz:

# OpenDKIM'de oversigning aktif ederek bazı başlıkların
# değiştirilmesini önleyebilirsiniz
# /etc/opendkim.conf içine ekleyin:
OversignHeaders From,To,Subject,Date

Gerçek Dünya Senaryosu 2: Key Rotation Sonrası Ortaya Çıkan Sorun

Key rotation yaptınız, yeni public key’i DNS’e eklediniz ama eski selector’ı kaldırdınız. Problem şu: Rotasyondan önce gönderilmiş ve henüz iletilmemiş mesajlar eski selector ile imzalı. Eski selector artık DNS’te yok, dolayısıyla doğrulama başarısız.

# Hangi selector'ların aktif kullanıldığını kontrol et
grep "Selector" /etc/opendkim.conf
# veya KeyTable kullanıyorsanız:
cat /etc/opendkim/KeyTable

# Eski selector'ın hala DNS'te olup olmadığını kontrol et
dig TXT eski-selector._domainkey.domain.com +short

# Yeni selector ekledikten sonra en az 48 saat bekle
# sonra eskiyi kaldır

Key rotation için güvenli yaklaşım: Yeni selector’ı ekle, en az 48-72 saat bekle (TTL propagasyonu için), sonra eski selector’ı kaldır. Acele etmeyin.

Header Canonicalization Sorunu

DKIM imzasında iki canonicalization (normalleştirme) modu var: simple ve relaxed. Bu iki mod header ve body için ayrı ayrı belirlenebilir.

# Mevcut DKIM imzasındaki canonicalization modunu kontrol et
grep "DKIM-Signature" /path/to/email.eml | grep -o "c=[^;]*"
# Örnek çıktı: c=relaxed/relaxed
  • relaxed/relaxed: Daha toleranslı, minor değişikliklere karşı dayanıklı
  • simple/simple: Katı mod, herhangi bir whitespace değişikliği imzayı bozar

Mail relay veya proxy üzerinden geçen mesajlarda simple mod kullanıyorsanız sorun yaşayabilirsiniz. OpenDKIM konfigürasyonunda bunu relaxed/relaxed olarak değiştirin:

# /etc/opendkim.conf içinde:
Canonicalization        relaxed/relaxed

Değişiklik sonrası servisi yeniden başlatın:

# OpenDKIM servisini yeniden başlat
systemctl restart opendkim

# Postfix'i de yeniden başlat
systemctl restart postfix

# Servis durumunu kontrol et
systemctl status opendkim

Online Araçlarla Test

Lokal testlerin yanı sıra online araçlar da çok işe yarıyor. Test maili gönderip anında rapor alabileceğiniz birkaç yöntem:

# mail-tester.com için test maili gönder
echo "DKIM test mesaji" | mail -s "DKIM Test" [email protected]

# Google'ın kendi test adresine gönder (Gmail hesabı gerekli)
# Gmail'de "Show original" ile Authentication-Results'u kontrol et

# Checker.email veya dkimvalidator.com kullanabilirsiniz
# Bu siteler size özel bir test adresi verir
# swaks aracıyla detaylı test
swaks --to [email protected] 
      --from [email protected] 
      --server localhost 
      --auth-user [email protected] 
      --auth-password "sifreniz" 
      --tls

# swaks kurulumu (yoksa)
apt install swaks  # Debian/Ubuntu
yum install swaks  # CentOS/RHEL

Postfix ile OpenDKIM Entegrasyon Sorunları

Bazen sorun OpenDKIM’in kendisinde değil, Postfix ile entegrasyonunda olur. Milter konfigürasyonunu kontrol edin:

# Postfix main.cf içindeki milter ayarlarını kontrol et
postconf | grep -E "milter|smtpd_milters|non_smtpd_milters"

# Beklenen çıktı:
# milter_default_action = accept
# smtpd_milters = local:/run/opendkim/opendkim.sock
# non_smtpd_milters = local:/run/opendkim/opendkim.sock

Socket dosyasının varlığını ve izinlerini kontrol edin:

# Socket dosyasının var olup olmadığını kontrol et
ls -la /run/opendkim/

# Eğer socket yoksa OpenDKIM çalışmıyor olabilir
systemctl status opendkim

# Socket yolu konfigürasyonla eşleşiyor mu?
grep Socket /etc/opendkim.conf
postconf smtpd_milters

DKIM İmzasını Elle Parse Etmek

Bir mailde DKIM imzasını elle parse ederek sorunun ne olduğunu anlayabilirsiniz:

# Mail dosyasından DKIM-Signature başlığını çıkar
grep -A20 "^DKIM-Signature:" email.eml

# Örnek DKIM-Signature tag'leri ve anlamları:
# v=1          -> DKIM versiyonu
# a=rsa-sha256 -> İmzalama algoritması
# c=relaxed/relaxed -> Canonicalization modu
# d=domain.com -> İmzalayan domain
# s=mail       -> Selector
# t=1705312345 -> İmzalama zamanı (Unix timestamp)
# x=1705398745 -> Geçerlilik süresi (Unix timestamp)
# bh=...       -> Body hash
# h=...        -> İmzalanan header listesi
# b=...        -> İmzanın kendisi

# Timestamp'i insanın okuyabileceği formata çevir
date -d @1705312345

x= tag’i önemli. Eğer imzanın geçerlilik süresi dolmuşsa alıcı sunucu “signature expired” hatası verir. Bu çok eski maillerin kuyrukta beklemesinden kaynaklanabilir.

Rspamd veya Amavis Kullanıyorsanız

Eğer mail altyapınızda Rspamd veya Amavis varsa, DKIM işlemlerini bunlar üstlenebilir. Bu durumda OpenDKIM’e bakmanıza gerek olmayabilir.

# Rspamd DKIM konfigürasyonunu kontrol et
cat /etc/rspamd/local.d/dkim_signing.conf

# Rspamd'ın DKIM modülü aktif mi?
rspamadm configdump dkim_signing

# Rspamd loglarında DKIM hatalarını ara
grep -i "dkim" /var/log/rspamd/rspamd.log | tail -50

# Rspamd ile test maili gönder ve sonucu kontrol et
rspamc symbols < /path/to/test.eml | grep -i dkim

Checklist: Sistematik Hata Ayıklama

Yukarıdaki her şeyi okudunuz ama hala kafanız karışık mı? Şu sırayla ilerleyin:

  • DNS kaydını kontrol et: dig TXT selector._domainkey.domain.com çalışıyor mu, doğru public key var mı?
  • OpenDKIM servisinin çalıştığını doğrula: systemctl status opendkim aktif mi?
  • Socket dosyasının var olduğunu kontrol et: /run/opendkim/opendkim.sock mevcut mu?
  • Key dosyası izinlerini kontrol et: opendkim kullanıcısı okuyabiliyor mu?
  • Postfix milter konfigürasyonunu doğrula: smtpd_milters doğru socket’e işaret ediyor mu?
  • opendkim-testkey ile DNS’teki public key’i doğrula: Hata veriyor mu?
  • Test maili gönder ve başlıkları incele: Authentication-Results ne diyor?
  • Canonicalization modunu kontrol et: relaxed/relaxed mı kullanıyorsunuz?
  • Log dosyalarını tara: Mail log’unda DKIM hatası var mı?
  • Key rotation geçmişini kontrol et: Eski selector kaldırıldı mı, DNS TTL beklendi mi?

Sonuç

DKIM imza doğrulama sorunları genellikle üç kategoriye giriyor: DNS yanlış konfigürasyonu, dosya izin sorunları ve mesaj içeriğinin transit sırasında değişmesi. Sistematik yaklaşım burada hayat kurtarıyor.

Önce DNS’i doğrulayın. DNS düzgünse servisleri kontrol edin. Servisler ayaktaysa log’lara bakın. Log’lar yetersizse debug modunu açın ve test maili gönderin. Bu sırayı takip etmezseniz saatlerce yanlış yerde arama yapabilirsiniz, bunu tecrübeyle öğrendim.

Son bir not: DKIM tek başına yeterli değil. SPF ve DMARC ile birlikte çalışmalı. DKIM pass olsa bile DMARC alignment sorunu yaşayabilirsiniz. Uzun vadeli mail deliverability için üçünü birlikte kurup monitoring’e alın. Zabbix veya Grafana’ya DKIM doğrulama başarı oranı metrikleri ekleyin, sorunları reaktif değil proaktif yakalayın.

Benzer Konular

Bir yanıt yazın

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