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 opendkimaktif mi? - Socket dosyasının var olduğunu kontrol et:
/run/opendkim/opendkim.sockmevcut mu? - Key dosyası izinlerini kontrol et:
opendkimkullanıcısı okuyabiliyor mu? - Postfix milter konfigürasyonunu doğrula:
smtpd_miltersdoğru socket’e işaret ediyor mu? opendkim-testkeyile DNS’teki public key’i doğrula: Hata veriyor mu?- Test maili gönder ve başlıkları incele:
Authentication-Resultsne diyor? - Canonicalization modunu kontrol et:
relaxed/relaxedmı 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.
