DNS sorgularınızın gerçekten güvenilir sunuculardan gelip gelmediğini nasıl anlarsınız? Bir kullanıcı bank.example.com adresine gittiğinde, aldığı IP adresi gerçekten o bankanın sunucusuna mı ait, yoksa araya giren biri bu cevabı mı değiştirdi? İşte DNSSEC tam olarak bu soruyu yanıtlamak için tasarlandı. Bu yazıda DNSSEC doğrulama sürecinin perde arkasında nasıl çalıştığını, zincir of trust kavramını ve pratik olarak nasıl test edeceğinizi adım adım inceleyeceğiz.
DNSSEC Nedir ve Neden Önemlidir
DNS sistemi tarihsel olarak güvenlik düşünülerek tasarlanmamıştı. 1983’te RFC 882 ile tanımlanan bu sistem, o dönemin daha küçük ve güvenilir internet ortamı için yeterliydi. Ancak bugün DNS cache poisoning, man-in-the-middle saldırıları ve spoofing gibi tehditler gerçek ve yaygın sorunlar haline geldi.
DNSSEC (Domain Name System Security Extensions), DNS yanıtlarına kriptografik imzalar ekleyerek bu açıkları kapatır. Önemli bir noktayı baştan vurgulamak gerekiyor: DNSSEC, DNS trafiğini şifrelemez. Yani sorgu içeriğini gizlemez. Bunun yerine DNS yanıtlarının bütünlüğünü ve özgünlüğünü doğrular. Şifreleme istiyorsanız DNS over HTTPS (DoH) veya DNS over TLS (DoT) konularına bakmanız gerekir.
DNSSEC’in temel amacı şudur: Aldığınız DNS yanıtının yetkili sunucudan geldiğini ve iletim sırasında değiştirilmediğini matematiksel olarak kanıtlamak.
Temel Kavramlar: Güven Zinciri
DNSSEC’i anlamak için önce birkaç temel kavramı kavramak gerekiyor.
Zone Signing Key (ZSK) ve Key Signing Key (KSK)
Her DNSSEC-etkin zone iki anahtar çifti kullanır:
ZSK (Zone Signing Key): Zone içindeki tüm DNS kayıtlarını imzalamak için kullanılır. Daha sık döndürülen, görece daha kısa ömürlü bir anahtardır.
KSK (Key Signing Key): ZSK’yı imzalamak için kullanılır. Daha uzun ömürlü ve daha büyük anahtar boyutuna sahiptir. Üst zone’a iletilen anahtardır.
DNSKEY, RRSIG ve DS Kayıtları
DNSSEC birkaç yeni kayıt tipi tanımlar:
- DNSKEY: Zone’un public anahtarlarını içerir
- RRSIG: Bir kayıt setinin kriptografik imzasıdır
- DS (Delegation Signer): Üst zone’da saklanan, alt zone’un KSK’sının hash değeridir
- NSEC/NSEC3: Var olmayan kayıtları kriptografik olarak kanıtlamak için kullanılır
Trust Anchor
Doğrulama süreci bir “güven çıpası” ile başlar. Bu genellikle root zone’un public anahtarıdır ve resolver’lara önceden yüklüdür. IANA tarafından yönetilen bu anahtar, tüm DNSSEC güven zincirinin temelini oluşturur.
Doğrulama Süreci Adım Adım
Şimdi bir kullanıcı www.example.com adresini sorguladığında arka planda neler olduğunu inceleyelim.
Adım 1: Recursive Resolver Sorguyu Alır
Kullanıcının cihazı recursive resolver’a sorar: “www.example.com nerede?” Resolver, DNSSEC doğrulama yapacaksa sorgu paketine DO (DNSSEC OK) bitini ekler. Bu bit, yetkili sunuculara “DNSSEC kayıtlarını da gönder” mesajı verir.
# DO bitini görmek için dig ile sorgu yapalım
dig +dnssec www.example.com A
# Daha detaylı çıktı için
dig +dnssec +multiline www.example.com A @8.8.8.8
Adım 2: DNSKEY Kayıtları Alınır
Resolver önce example.com zone’unun public anahtarlarını alır:
# example.com zone anahtarlarını sorgulayalım
dig DNSKEY example.com +dnssec
# Root zone anahtarlarını görmek için
dig DNSKEY . +dnssec @a.root-servers.net
Bu sorguya gelen cevap iki DNSKEY kaydı içerecektir: biri ZSK (flag değeri 256), biri KSK (flag değeri 257).
Adım 3: RRSIG ile İmza Doğrulanır
Resolver, www.example.com için aldığı A kaydının yanında bir RRSIG kaydı da alır. Bu RRSIG, o A kaydının ZSK ile imzalandığını gösterir.
# RRSIG kayıtlarını görüntüleme
dig +dnssec www.cloudflare.com A
# Sadece RRSIG kayıtlarını filtrele
dig +dnssec www.cloudflare.com A | grep RRSIG
Çıktıda şuna benzer bir şey görürsünüz:
# Örnek RRSIG çıktısı
www.cloudflare.com. 300 IN RRSIG A 13 3 300 (
20240215120000 20240201120000 34505 cloudflare.com.
base64encodedSignatureData== )
Bu kayıtta şunları okuyoruz:
- A: İmzalanan kayıt tipi
- 13: Kullanılan algoritma (ECDSAP256SHA256)
- 3: Label sayısı
- 300: Original TTL
- 20240215120000: İmzanın geçerlilik bitiş tarihi
- 20240201120000: İmzanın başlangıç tarihi
- 34505: Bu imzayı oluşturan DNSKEY’in Key Tag değeri
Adım 4: DS Kaydı ile ZSK-KSK Bağlantısı
ZSK’nın KSK tarafından imzalandığını doğruladık. Peki KSK’nın kendisi güvenilir mi? İşte burada DS kaydı devreye giriyor. Üst zone olan .com zone’u, example.com‘un KSK’sının hash değerini DS kaydı olarak tutar.
# .com zone'undaki DS kaydını sorgulayalım
dig DS example.com +dnssec
# Daha açıklayıcı çıktı için
dig DS cloudflare.com +dnssec +multiline
Resolver bu DS kaydını alır ve example.com‘un DNSKEY’inin hash değeriyle karşılaştırır. Eşleşiyorsa KSK güvenilirdir.
Adım 5: Zincir Root’a Kadar Uzanır
Bu süreç yukarıya doğru devam eder:
.comzone’unun DS kaydı root zone’da saklanır- Root zone kendi kendini imzalar (self-signed)
- Resolver’ın önceden yüklü trust anchor’ı root zone’un KSK’sıdır
# Root zone'un DS kayıtlarını .com için sorgulayalım
dig DS com. +dnssec @a.root-servers.net
# Trust anchor'ı kontrol etmek için (BIND sistemlerde)
cat /etc/bind/bind.keys
# Unbound sistemlerde
cat /etc/unbound/root.key
Pratik Senaryo: DNSSEC Doğrulamasını Test Etmek
Senaryo 1: Temel Doğrulama Testi
Bir domain’in DNSSEC’in düzgün yapılandırılıp yapılandırılmadığını test edelim:
#!/bin/bash
# dnssec_check.sh - Domain DNSSEC durumunu kontrol et
DOMAIN=$1
if [ -z "$DOMAIN" ]; then
echo "Kullanim: $0 <domain>"
exit 1
fi
echo "=== $DOMAIN icin DNSSEC Kontrolu ==="
# DNSKEY kaydi var mi?
echo -n "DNSKEY kaydi: "
DNSKEY=$(dig DNSKEY $DOMAIN +short)
if [ -n "$DNSKEY" ]; then
echo "BULUNDU"
else
echo "BULUNAMADI - DNSSEC yapilandirilmamis olabilir"
fi
# DS kaydi ust zone'da var mi?
echo -n "DS kaydi: "
DS=$(dig DS $DOMAIN +short)
if [ -n "$DS" ]; then
echo "BULUNDU"
else
echo "BULUNAMADI - Chain of trust kopuk olabilir"
fi
# RRSIG var mi?
echo -n "RRSIG kaydi: "
RRSIG=$(dig A $DOMAIN +dnssec +short | grep RRSIG)
if [ -n "$RRSIG" ]; then
echo "BULUNDU"
else
echo "BULUNAMADI"
fi
# AD biti set mi? (Authenticated Data)
echo -n "AD biti (dogrulama basarili): "
AD=$(dig A $DOMAIN +dnssec | grep "flags:" | grep " ad ")
if [ -n "$AD" ]; then
echo "EVET - DNSSEC dogrulama basarili"
else
echo "HAYIR - Dogrulama basarisiz veya DNSSEC yok"
fi
# Scripti calistirin
chmod +x dnssec_check.sh
./dnssec_check.sh cloudflare.com
./dnssec_check.sh google.com
Senaryo 2: AD Bitini Anlamak
DNSSEC doğrulaması başarılı olduğunda resolver, DNS yanıtındaki AD (Authenticated Data) bitini set eder. Bu bit, “bu veriyi doğruladım ve güvenilir” anlamına gelir.
# AD bitini gozlemleyelim
dig www.cloudflare.com A +dnssec
# Cikti icinde su satiri arayin:
# ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2
# 'ad' gozukuyorsa dogrulama basarili demektir
# Karsilastirma icin dogrulanamayan bir sorgu
dig www.example-without-dnssec.com A +dnssec
# Bu ciktitta 'ad' biti olmayacak
Senaryo 3: Kasıtlı Hata Durumu – SERVFAIL
DNSSEC doğrulaması başarısız olursa resolver SERVFAIL döner. Bu bir güvenlik özelliğidir; yanıltıcı veri vermek yerine hiç vermez.
# DNSSEC dogrulama hatasini simule eden test domain
# IANA bu amacla ozel bir test domain'i sunuyor
dig A dnssec-failed.org +dnssec
# Beklenen cevap: SERVFAIL
# ;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL
# CD (Checking Disabled) biti ile dogrulama atlanabilir
dig A dnssec-failed.org +dnssec +cd
# Bu sefer cevap gelir ama dogrulanmamis
BIND ile DNSSEC Yapılandırması
Kendi DNS sunucunuzda DNSSEC’i nasıl aktif edeceğinize bakalım:
# BIND icin zone anahtarlarini olustur
# Oncelikle key dizinine gec
cd /etc/bind/keys
# KSK olustur (Key Signing Key)
dnssec-keygen -a ECDSAP256SHA256 -b 256 -f KSK -n ZONE example.com
# ZSK olustur (Zone Signing Key)
dnssec-keygen -a ECDSAP256SHA256 -b 256 -n ZONE example.com
# Olusturulan dosyalari listele
ls -la
# Kexample.com.+013+XXXXX.key
# Kexample.com.+013+XXXXX.private
Zone dosyanızı imzalamak için:
# Zone dosyasini imzala
dnssec-signzone -A -3 $(head -c 1000 /dev/random | sha1sum | cut -b 1-16)
-N INCREMENT
-o example.com
-t /etc/bind/zones/db.example.com
# Veya daha basit sekilde
dnssec-signzone -o example.com
-k Kexample.com.+013+YYYYY
/etc/bind/zones/db.example.com
Kexample.com.+013+XXXXX
# Imzalanmis zone dosyasi olusturulur: db.example.com.signed
# named.conf icinde imzalanmis zone'u kullan
# /etc/bind/named.conf.local dosyasina ekle:
zone "example.com" {
type master;
file "/etc/bind/zones/db.example.com.signed";
allow-transfer { none; };
};
# BIND'i yeniden yukle
systemctl reload bind9
# Log'lari kontrol et
journalctl -u bind9 -f
Unbound ile Doğrulayıcı Resolver Kurulumu
Unbound, DNSSEC doğrulama yapan popüler bir recursive resolver’dır:
# Unbound kurulumu (Debian/Ubuntu)
apt-get install unbound
# Root anahtarini guncelle
unbound-anchor -a /etc/unbound/root.key
# /etc/unbound/unbound.conf temel yapilandirmasi
cat > /etc/unbound/unbound.conf << 'EOF'
server:
# Dinleme adresi
interface: 127.0.0.1
port: 53
# DNSSEC dogrulama
auto-trust-anchor-file: "/etc/unbound/root.key"
# Log seviyesi
verbosity: 1
log-queries: yes
# DNSSEC hata logla
val-log-level: 2
# Agresif NSEC kullanimi
aggressive-nsec: yes
# Access control
access-control: 127.0.0.0/8 allow
access-control: 0.0.0.0/0 refuse
EOF
# Unbound'u baslat ve test et
systemctl start unbound
systemctl enable unbound
# Test sorgusu
dig @127.0.0.1 www.cloudflare.com A +dnssec
# AD biti gozukmeli
DNSSEC Sorun Giderme
Sık Karşılaşılan Sorunlar
SERVFAIL alıyorsunuz ama neden? Bu durumda önce +cd bayrağı ile doğrulamayı devre dışı bırakarak sorunun kaynağını bulmaya çalışın:
# Sorun tespiti icin adimlar
# 1. CD biti ile dogrulama olmadan sorgula
dig www.example.com A +dnssec +cd
# Cevap geliyorsa DNSSEC imzasi hatali demektir
# 2. RRSIG gecerlilik tarihlerini kontrol et
dig www.example.com A +dnssec +multiline | grep RRSIG
# "20240215" gibi tarihleri guncel tarihle karsilastir
# 3. DS ve DNSKEY uyumunu kontrol et
# DS kaydi hash'i
dig DS example.com +short
# DNSKEY hash'i elle hesapla
dig DNSKEY example.com +short | dnssec-dsfromkey -f - example.com
# 4. Online validasyon araci kullan
# https://dnsviz.net veya
# https://dnssec-analyzer.verisignlabs.com
# BIND icin detayli DNSSEC log'lari aktif et
# named.conf icine ekle:
logging {
channel dnssec_log {
file "/var/log/bind/dnssec.log" versions 3 size 5m;
severity debug 3;
print-time yes;
print-severity yes;
};
category dnssec { dnssec_log; };
category trust-anchor-telemetry { dnssec_log; };
};
# Log dosyasini izle
tail -f /var/log/bind/dnssec.log | grep -E "DNSSEC|validation|RRSIG"
İmza Süresi Dolmuş Hatası
En yaygın DNSSEC sorunlarından biri imza sürelerinin dolmasıdır. Production ortamında bu kritik bir sorundur:
#!/bin/bash
# dnssec_expiry_check.sh - RRSIG gecerlilik surelerini kontrol et
DOMAIN=$1
WARNING_DAYS=7
# RRSIG son kullanma tarihini al
EXPIRY=$(dig $DOMAIN DNSKEY +dnssec +short | grep RRSIG | awk '{print $5}')
if [ -z "$EXPIRY" ]; then
echo "RRSIG bulunamadi!"
exit 2
fi
# Tarihi Unix timestamp'e cevir
EXPIRY_TS=$(date -d "${EXPIRY:0:8} ${EXPIRY:8:2}:${EXPIRY:10:2}:${EXPIRY:12:2}" +%s 2>/dev/null)
NOW_TS=$(date +%s)
DIFF_DAYS=$(( (EXPIRY_TS - NOW_TS) / 86400 ))
echo "RRSIG son kullanma: $EXPIRY"
echo "Kalan gun: $DIFF_DAYS"
if [ $DIFF_DAYS -lt 0 ]; then
echo "KRITIK: RRSIG suresi DOLMUS!"
exit 2
elif [ $DIFF_DAYS -lt $WARNING_DAYS ]; then
echo "UYARI: RRSIG $DIFF_DAYS gun icinde surecek!"
exit 1
else
echo "OK: RRSIG gecerliligi yeterli"
exit 0
fi
Gerçek Dünya Senaryosu: Registrar’da DS Kaydı Yayınlamak
DNSSEC’in çalışması için güven zincirinin tamamlanması gerekir. Bunu yapmak için DS kaydınızı domain registrar’ınıza iletmeniz gerekir.
# Oncelikle DS kaydini uret
# BIND kullananlar icin:
dnssec-dsfromkey Kexample.com.+013+XXXXX.key
# Cikti ornegi:
# example.com. IN DS 12345 13 2 ABCDEF1234567890...
# Veya mevcut zone'dan al:
dig DS example.com +short
# 12345 13 2 ABCDEF1234567890ABCDEF1234567890
# Bu bilgiyi registrar panelinize girin:
# Key Tag: 12345
# Algorithm: 13 (ECDSAP256SHA256)
# Digest Type: 2 (SHA-256)
# Digest: ABCDEF1234567890...
DS kaydı yayınlandıktan sonra yayılım birkaç saat sürebilir. Bu süreyi izlemek için:
# Farkli root server'lardan DS kaydi varligini kontrol et
for SERVER in a.root-servers.net b.root-servers.net c.root-servers.net; do
echo -n "$SERVER: "
dig DS example.com @$SERVER +short | head -1
done
# .com TLD name server'larindan kontrol
for SERVER in a.gtld-servers.net b.gtld-servers.net; do
echo -n "$SERVER: "
dig DS example.com @$SERVER +short | head -1
done
DNSSEC’in Sınırlılıkları
Yazıyı dengeli tutmak için DNSSEC’in her derde deva olmadığını da belirtmek gerekiyor.
DNSSEC zone bilgilerinin tamamını korumaz; sadece doğruluk ve bütünlük sağlar. Bir zone’da hangi kayıtların olduğu NSEC kayıtları aracılığıyla keşfedilebilir. Bu “zone walking” saldırısı olarak bilinir. NSEC3 bu sorunu kısmen hafifletir ama tamamen ortadan kaldırmaz.
Ayrıca DNSSEC, anahtar yönetimini karmaşık hale getirir. Anahtarların periyodik olarak döndürülmesi, imzaların yenilenmesi ve DS kayıtlarının güncellenmesi gibi operasyonel yükler getiriyor. Bunu otomatize etmezseniz imza süresi dolduğunda domain’iniz erişilemez hale gelebilir.
Son olarak DNSSEC, amplification saldırılarına zemin hazırlayabilir. DNSSEC kayıtları standart DNS cevaplarından çok daha büyüktür. Bu durum UDP tabanlı DDoS amplification saldırılarını potansiyel olarak güçlendirir.
Sonuç
DNSSEC doğrulama süreci, kriptografik bir güven zinciri oluşturarak DNS’in en temel güvenlik açıklarını kapatıyor. Root zone’dan başlayıp hedef domain’e uzanan bu zincir, ZSK, KSK, DS ve RRSIG kayıtlarının koordineli çalışmasıyla ayakta duruyor.
Pratikte sysadmin olarak dikkat etmeniz gereken birkaç kritik nokta var. İmza sürelerini mutlaka izleme sisteminize ekleyin; dolmuş bir RRSIG domain’inizi tamamen erişilemez kılabilir. Anahtar rollover süreçlerini önceden planlayın ve test edin. DS kaydı registrar’da güncellenmeden ZSK veya KSK değiştirmeyin. Ve en önemlisi, production’a almadan önce dnssec-failed.org gibi test domain’leriyle resolver’ınızın SERVFAIL döndürebildiğini doğrulayın.
DNSSEC mükemmel bir çözüm değil, ama DNS güvenliğinin vazgeçilmez bir katmanı. Özellikle kritik altyapı ve finansal hizmetler için DNSSEC olmayan bir ortam, günümüzde kabul edilebilir bir risk değil.