DNS altyapınızın güvenliğini bir üst seviyeye taşımak istiyorsanız, DNSSEC tam da aradığınız şey. Özellikle production ortamlarda alan adı sahtecilik saldırılarına (DNS spoofing, cache poisoning) karşı korunmak artık bir lüks değil, zorunluluk haline geldi. PowerDNS, DNSSEC desteği açısından oldukça olgun bir çözüm sunuyor ve doğru yapılandırıldığında sizi ciddi baş ağrılarından kurtarıyor. Bu yazıda sıfırdan başlayıp gerçek bir ortamda DNSSEC’i nasıl devreye alacağınızı adım adım göstereceğim.
DNSSEC Nedir ve Neden Önemli?
DNSSEC (Domain Name System Security Extensions), DNS yanıtlarının bütünlüğünü ve özgünlüğünü kriptografik imzalar aracılığıyla doğrulayan bir güvenlik katmanıdır. Normal DNS trafiğinde bir saldırgan, DNS yanıtlarını değiştirerek kullanıcıları sahte IP adreslerine yönlendirebilir. DNSSEC bu senaryoyu engeller çünkü her DNS kaydı kriptografik olarak imzalanır ve bu imzalar doğrulanabilir.
Gerçek dünyada karşılaştığım tipik bir senaryo şu: Bir e-ticaret sitesinin DNS kayıtları zehirlenerek müşteriler sahte bir ödeme sayfasına yönlendiriliyor. DNSSEC bu tür saldırılara karşı doğrudan bir kalkan görevi görür. Türkiye’deki .tr alan adları için NIC.TR’nin DNSSEC desteğini aktif etmesi ve büyük registrar’ların bu özelliği sunmaya başlaması ile birlikte artık bu konuyu ertelemek için bir bahane kalmadı.
DNSSEC’in temel bileşenlerini anlamak, yapılandırmayı çok daha mantıklı hale getirecek:
- ZSK (Zone Signing Key): Zone kayıtlarını imzalamak için kullanılan anahtar
- KSK (Key Signing Key): ZSK’yı imzalamak için kullanılan ana anahtar
- DS (Delegation Signer): Üst domain’e (parent zone) iletilen hash değeri
- RRSIG: Her DNS kaydının kriptografik imzası
- NSEC/NSEC3: Var olmayan kayıtları kriptografik olarak kanıtlayan kayıtlar
- DNSKEY: Zone’un public anahtarını tutan kayıt
Ortam Hazırlığı ve PowerDNS Kurulumu
Bu yazıda Ubuntu 22.04 LTS üzerinde çalışıyoruz. PowerDNS’in Authoritative Server sürümünü kullanacağız çünkü DNSSEC signing işlemleri authoritative tarafında yapılıyor.
# Önce sistemi güncelleyelim
apt update && apt upgrade -y
# PowerDNS resmi repo'sunu ekleyelim
curl -sSL https://repo.powerdns.com/FD380FBB-pub.asc | apt-key add -
cat > /etc/apt/sources.list.d/pdns.list << 'EOF'
deb [arch=amd64] http://repo.powerdns.com/ubuntu jammy-auth-48 main
EOF
cat > /etc/apt/preferences.d/pdns << 'EOF'
Package: pdns-*
Pin: origin repo.powerdns.com
Pin-Priority: 600
EOF
apt update
apt install -y pdns-server pdns-backend-sqlite3
SQLite backend’i kullanmak küçük ve orta ölçekli ortamlar için gayet yeterli. Production’da yüksek yük varsa MySQL veya PostgreSQL backend tercih etmenizi öneririm. Şimdi veritabanını oluşturalım:
# SQLite veritabanı için schema oluştur
sqlite3 /var/lib/powerdns/pdns.sqlite3 < /usr/share/doc/pdns-backend-sqlite3/schema.sqlite3.sql
# Doğru izinleri set edelim
chown pdns:pdns /var/lib/powerdns/pdns.sqlite3
chmod 600 /var/lib/powerdns/pdns.sqlite3
Şimdi PowerDNS konfigürasyon dosyasını düzenleyelim:
cat > /etc/powerdns/pdns.conf << 'EOF'
# Temel ayarlar
setuid=pdns
setgid=pdns
# Network
local-address=0.0.0.0
local-port=53
# Backend
launch=gsqlite3
gsqlite3-database=/var/lib/powerdns/pdns.sqlite3
gsqlite3-dnssec=yes
# DNSSEC
default-ksk-algorithm=ecdsa256
default-zsk-algorithm=ecdsa256
# Güvenlik
allow-axfr-ips=127.0.0.1
master=yes
slave=no
# Logging
log-dns-queries=no
loglevel=4
EOF
Burada önemli bir nokta: gsqlite3-dnssec=yes satırı olmadan DNSSEC key’leri veritabanında saklanamaz. Bu satırı unutmak çok sık yapılan bir hata.
# Servisi başlatalım
systemctl enable pdns
systemctl start pdns
systemctl status pdns
İlk Zone’u Oluşturma
DNSSEC’i aktif etmeden önce zone’umuzu oluşturmamız gerekiyor. Örnek olarak ornek.com.tr domain’ini kullanalım:
# pdnsutil ile zone oluştur
pdnsutil create-zone ornek.com.tr
# SOA ve temel kayıtları ekle
pdnsutil add-record ornek.com.tr @ SOA "ns1.ornek.com.tr. hostmaster.ornek.com.tr. 2024010101 3600 900 604800 300"
pdnsutil add-record ornek.com.tr @ NS ns1.ornek.com.tr
pdnsutil add-record ornek.com.tr @ NS ns2.ornek.com.tr
pdnsutil add-record ornek.com.tr @ A 203.0.113.10
pdnsutil add-record ornek.com.tr ns1 A 203.0.113.11
pdnsutil add-record ornek.com.tr ns2 A 203.0.113.12
pdnsutil add-record ornek.com.tr www A 203.0.113.10
pdnsutil add-record ornek.com.tr mail MX "10 mail.ornek.com.tr"
pdnsutil add-record ornek.com.tr mail A 203.0.113.13
# Zone'u kontrol et
pdnsutil check-zone ornek.com.tr
Zone’da herhangi bir hata yoksa çıktı şöyle görünmeli: Zone ornek.com.tr. is ok.
DNSSEC’i Aktif Etme
Şimdi asıl konumuza geliyoruz. PowerDNS’te DNSSEC’i aktif etmek tek bir komutla yapılabiliyor ama arkasında ne döndüğünü anlamak kritik önem taşıyor:
# DNSSEC'i zone için aktif et
# Bu komut hem KSK hem ZSK oluşturur
pdnsutil secure-zone ornek.com.tr
# Oluşturulan key'leri görüntüle
pdnsutil show-zone ornek.com.tr
Çıktı şuna benzer bir şey olacak:
Zone is actively secured with algorithm 13, algo: ecdsa256, bits: 256
ID = 1 (KSK), flags = 257, tag = 12345, algo = 13, bits = 256
ID = 2 (ZSK), flags = 256, tag = 67890, algo = 13, bits = 256
Bu noktada iki anahtar oluştu. KSK (flags=257) zone imzalama hiyerarşisinin tepesinde oturuyor, ZSK (flags=256) ise gerçek kayıtları imzalamak için kullanılıyor.
Şimdi DS kaydını alalım. Bu kaydı registrar’ınıza bildirmeniz gerekecek:
# DS kaydını görüntüle
pdnsutil show-zone ornek.com.tr | grep DS
# Veya daha detaylı format için
pdnsutil export-zone-ds ornek.com.tr
Çıktı şuna benzer olacak:
ornek.com.tr. IN DS 12345 13 2 abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890
Bu DS kaydını registrar’ınızın yönetim paneline girmeniz gerekiyor. NIC.TR için Altyapı sekmesinden DNSSEC bölümüne gidip bu hash’i yapıştırabilirsiniz.
NSEC3 ile Zone Enumeration’ı Engelleme
Varsayılan NSEC konfigürasyonu zone’unuzdaki tüm kayıt isimlerini sıralı olarak ifşa eder. Bu bir güvenlik zaafiyeti olmasa da bazı ortamlarda istenmeyen bilgi sızıntısına yol açabilir. NSEC3 bu sorunu çözer:
# NSEC3 ile zone enumeration'ı engelle
# Parametreler: hash_algorithm iterations salt
pdnsutil set-nsec3 ornek.com.tr "1 0 10 $(openssl rand -hex 8)"
# Ayarı doğrula
pdnsutil show-zone ornek.com.tr | grep NSEC
Buradaki parametreleri açıklayayım:
- 1: SHA-1 hash algoritması
- 0: Opt-out flag (0 = güvenli)
- 10: Iteration sayısı (çok yüksek yapma, performansı etkiler)
$(openssl rand -hex 8): Rastgele bir salt değeri
Gerçek dünya deneyiminden bir not: Iteration sayısını 100’ün üzerine çıkarmayın. Bazı yöneticiler “daha güvenli olsun” diye bu değeri yüksek tutmak istiyor ama bu sadece CPU yükünü artırıyor, gerçek bir güvenlik faydası sağlamıyor. RFC 9276 artık 0 iteration öneriyor.
Key Rollover Yönetimi
DNSSEC yönetiminin en kritik ve en sık hata yapılan kısmı key rollover. Anahtarları periyodik olarak yenilemeniz gerekiyor. ZSK’yı genellikle 3-6 ayda bir, KSK’yı ise yılda bir yenilemeniz önerilir.
ZSK rollover süreci görece basit çünkü DS kaydını değiştirmeniz gerekmiyor:
# Yeni ZSK oluştur (eski ZSK hala aktif kalıyor)
pdnsutil add-zone-key ornek.com.tr zsk active ecdsa256
# Key ID'leri kontrol et
pdnsutil show-zone ornek.com.tr
# Eski ZSK'yı deaktif et (ID numarasını kendinize göre değiştirin)
pdnsutil deactivate-zone-key ornek.com.tr 2
# Bir süre bekledikten sonra eski ZSK'yı sil
# (TTL kadar beklemek iyi pratik)
pdnsutil remove-zone-key ornek.com.tr 2
KSK rollover daha dikkatli yapılmalı çünkü yeni DS kaydını registrar’a bildirmeniz gerekiyor:
# Yeni KSK oluştur
pdnsutil add-zone-key ornek.com.tr ksk active ecdsa256
# Yeni DS kaydını al
pdnsutil export-zone-ds ornek.com.tr
# ÖNEMLİ: Bu DS kaydını önce registrar'a ekle, propagasyon bekle
# Ardından eski KSK'yı deaktif et
# En son eski KSK'yı sil
KSK rollover’da çift imzalama (double signing) periyodu çok önemli. Yeni KSK’yı aktif ettikten sonra, eski KSK’yı hemen silmeyin. Registrar’a yeni DS kaydını ekleyip TTL kadar (genellikle 24-48 saat) bekleyin. Aksi takdirde bazı resolver’lar zone’u DNSSEC doğrulamasından geçiremez ve alan adınıza erişilmez hale gelir.
İzleme ve Doğrulama
DNSSEC kurulumunu doğrulamak için birkaç farklı araç kullanabilirsiniz:
# dig ile DNSSEC kayıtlarını sorgula
dig +dnssec ornek.com.tr @8.8.8.8
# DNSKEY kaydını sorgula
dig DNSKEY ornek.com.tr @8.8.8.8
# DS kaydının parent zone'da yayıldığını kontrol et
dig DS ornek.com.tr @a.dns.tr
# RRSIG kayıtlarının varlığını doğrula
dig +dnssec A ornek.com.tr @8.8.8.8 | grep RRSIG
# Detaylı doğrulama
dig +sigchase +trusted-key=/etc/trusted-key.key ornek.com.tr
Çıktıda ad (authenticated data) flag’ini görüyorsanız her şey yolunda demektir. dig +dnssec ile sorgulama yaptığınızda yanıtta flags: qr rd ra ad şeklinde bir satır görmelisiniz.
Online araçlar da işinizi kolaylaştırır. DNSViz (dnsviz.net) özellikle DNSSEC zincirini görsel olarak doğrulamak için harika bir araç. Üretim ortamına almadan önce kesinlikle bu aracı kullanmanızı öneririm.
Otomatik İmzalama ve Yenileme Scriptleri
Production ortamlarda DNSSEC imzalarının süresi dolabilir. PowerDNS bunu otomatik olarak yönetir ama bazı edge case’lerde manuel müdahale gerekebilir. İşte bir izleme scripti:
#!/bin/bash
# /usr/local/bin/dnssec-monitor.sh
DOMAIN="ornek.com.tr"
ALERT_DAYS=7
LOG_FILE="/var/log/dnssec-monitor.log"
ADMIN_MAIL="[email protected]"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
# RRSIG kayıtlarının geçerlilik süresini kontrol et
check_rrsig_expiry() {
local domain=$1
local expiry_date
expiry_date=$(dig +dnssec SOA "$domain" @127.0.0.1 |
grep RRSIG |
awk '{print $9}' |
head -1)
if [ -z "$expiry_date" ]; then
log "HATA: $domain icin RRSIG bulunamadi!"
echo "DNSSEC HATASI: $domain icin RRSIG kaydi yok" |
mail -s "DNSSEC Alert: $domain" "$ADMIN_MAIL"
return 1
fi
# Tarih formatını dönüştür (YYYYMMDDHHMMSS)
local year=${expiry_date:0:4}
local month=${expiry_date:4:2}
local day=${expiry_date:6:2}
local expiry_epoch=$(date -d "$year-$month-$day" +%s 2>/dev/null)
local current_epoch=$(date +%s)
local days_left=$(( (expiry_epoch - current_epoch) / 86400 ))
log "$domain RRSIG suresi dolmaya $days_left gun kaldi"
if [ "$days_left" -lt "$ALERT_DAYS" ]; then
log "UYARI: $domain RRSIG kaydi $days_left gun icinde dolacak!"
echo "UYARI: $domain DNSSEC imzasi $days_left gun icinde doluyor" |
mail -s "DNSSEC Uyarisi: $domain" "$ADMIN_MAIL"
fi
}
# Zone listesini al ve kontrol et
for zone in $(pdnsutil list-all-zones 2>/dev/null | grep -v "No zones"); do
if pdnsutil show-zone "$zone" 2>/dev/null | grep -q "actively secured"; then
check_rrsig_expiry "$zone"
fi
done
log "DNSSEC kontrol tamamlandi"
Bu scripti crontab’a ekleyelim:
chmod +x /usr/local/bin/dnssec-monitor.sh
# Her gün sabah 8'de çalıştır
echo "0 8 * * * root /usr/local/bin/dnssec-monitor.sh" > /etc/cron.d/dnssec-monitor
Yaygın Sorunlar ve Çözümleri
Gerçek ortamlarda en çok şu sorunlarla karşılaşıyorum:
DS kaydı propagasyonu gecikmesi: Registrar’a DS kaydı ekledikten sonra hemen doğrulama yapmaya çalışmayın. Özellikle .com.tr için propagasyon 24-48 saati bulabilir. Bu sürede sabırlı olun.
Yanlış algoritma seçimi: Eski sistemlerde RSA/SHA-1 (algoritma 5 ve 7) kullanılıyordu. Bunlar artık güvensiz kabul ediliyor. ECDSA P-256 (algoritma 13) veya Ed25519 (algoritma 15) kullanın. PowerDNS’te varsayılan olarak algoritma 13 geliyor, bu iyi.
Zone transfer ile DNSSEC: Slave sunucularınıza zone transfer yapıyorsanız, DNSSEC ayarlarının da aktarılması gerekiyor. pdns.conf dosyasında slave-renotify=yes ve master/slave konfigürasyonunu doğru yapılandırdığınızdan emin olun.
TTL uyumsuzlukları: DNSKEY kayıtlarınızın TTL’i ile diğer kayıtların TTL’i arasında ciddi farklar varsa, rollover sürecinde sorun yaşayabilirsiniz. DNSKEY TTL’ini SOA’daki minimum TTL değeriyle tutarlı tutun.
# Zone'daki olası sorunları otomatik tespit et
pdnsutil check-zone ornek.com.tr
# Tüm zone'ları tek seferde kontrol et
pdnsutil check-all-zones
# Rectify işlemi (NSEC/NSEC3 kayıtlarını yeniden hesapla)
pdnsutil rectify-zone ornek.com.tr
# İmzaları yenile
pdnsutil sign-zone ornek.com.tr
PowerDNS API ile DNSSEC Yönetimi
Modern ortamlarda PowerDNS API üzerinden DNSSEC yönetimi çok daha pratik. Özellikle çok sayıda zone yönetiyorsanız bu yaklaşım hayat kurtarıyor:
# Önce API'yi aktif et (pdns.conf'a ekle)
cat >> /etc/powerdns/pdns.conf << 'EOF'
api=yes
api-key=gizli-api-key-buraya
webserver=yes
webserver-address=127.0.0.1
webserver-port=8081
webserver-allow-from=127.0.0.1
EOF
systemctl restart pdns
# API üzerinden DNSSEC durumunu sorgula
curl -H "X-API-Key: gizli-api-key-buraya"
http://127.0.0.1:8081/api/v1/servers/localhost/zones/ornek.com.tr. |
python3 -m json.tool | grep -A5 dnssec
# API üzerinden DNSSEC'i aktif et
curl -X PUT
-H "X-API-Key: gizli-api-key-buraya"
-H "Content-Type: application/json"
-d '{"dnssec": true}'
http://127.0.0.1:8081/api/v1/servers/localhost/zones/ornek.com.tr.
# Cryptokeys listesi
curl -H "X-API-Key: gizli-api-key-buraya"
http://127.0.0.1:8081/api/v1/servers/localhost/zones/ornek.com.tr./cryptokeys
API kullanırken dikkat etmeniz gereken nokta: API key’i güvenli bir yerde saklayın ve asla versiyonlama sistemine commit etmeyin. Bunu .env dosyasında veya bir secret manager’da tutun.
Güvenlik Sertleştirme Önerileri
DNSSEC’i devreye aldıktan sonra genel DNS güvenliğinizi artırmak için şu adımları da uygulayın:
- CAA (Certification Authority Authorization) kaydı ekleyin: Hangi CA’ların alan adınız için sertifika verebileceğini sınırlandırır
- TLSA kaydı düşünün: DANE protokolü ile TLS sertifikalarınızı DNS’e bağlayabilirsiniz
- Zone transfer erişimini kısıtlayın:
allow-axfr-ipsparametresini sadece gerçek slave IP’leri ile sınırlandırın - Rate limiting uygulayın: PowerDNS’te
max-udp-queries-per-secondparametresi ile DDoS etkisini azaltın - Düzenli yedek alın: SQLite veritabanını günlük yedekleyin, DNSSEC key’lerinizi ayrı olarak şifreli ortamda saklayın
# CAA kaydı ekle (sadece Let's Encrypt kullanıyorsanız)
pdnsutil add-record ornek.com.tr @ CAA "0 issue "letsencrypt.org""
pdnsutil add-record ornek.com.tr @ CAA "0 issuewild ";""
pdnsutil add-record ornek.com.tr @ CAA "0 iodef "mailto:[email protected]""
# Zone'u doğrula ve imzaları yenile
pdnsutil check-zone ornek.com.tr
pdnsutil rectify-zone ornek.com.tr
Sonuç
PowerDNS ile DNSSEC uygulamak göründüğünden çok daha erişilebilir bir süreç. Temel adımlar şunlar: Zone oluştur, secure-zone komutu ile güvenliği aktif et, DS kaydını registrar’a bildir, propagasyonu bekle ve düzenli izleme kurarak anahtarları zamanında yenile.
En çok dikkat etmeniz gereken noktalar DS kaydı propagasyonu ve key rollover süreçleri. Bu iki konuda acele etmek, alan adınızın erişilemez hale gelmesine yol açabilir. Özellikle production ortamlarda rollover işlemini önce test ortamında deneyin.
DNSSEC tek başına yeterli bir güvenlik katmanı değil elbette. Onu CAA kayıtları, DANE, düzgün yapılandırılmış zone transfer güvenliği ve düzenli denetimlerle birlikte kullanmak bütünsel bir DNS güvenlik stratejisi oluşturur. Bir kez düzgün kurduğunuzda PowerDNS’in otomatik yenileme mekanizmaları sayesinde DNSSEC bakımı minimum efor gerektirir. Bu yatırımı yapmadan geçecek her gün, altyapınızı gereksiz risklere maruz bırakıyor demektir.