DNS altyapınızda neler olduğunu bilmiyorsanız, sorun çıktığında kör uçuş yapıyorsunuz demektir. PowerDNS, doğru yapılandırıldığında size son derece detaylı loglama ve izleme imkanı sunar. Bu yazıda PowerDNS’in loglama mekanizmalarını, metrik toplama yöntemlerini ve gerçek dünya senaryolarında nasıl kullanacağınızı ele alacağım.
PowerDNS Loglama Temelleri
PowerDNS varsayılan olarak syslog üzerinden log üretir. Authoritative Server (pdns) ve Recursor (pdns-recursor) için loglama yapılandırması birbirinden farklıdır, bu yüzden ikisini ayrı ayrı inceleyeceğiz.
Authoritative Server Loglama Yapılandırması
/etc/powerdns/pdns.conf dosyanızda temel loglama ayarları şu şekildedir:
# Log seviyesi: 0=Emergency, 1=Alert, 2=Critical, 3=Error, 4=Warning, 5=Notice, 6=Info, 7=Debug
loglevel=6
# Syslog yerine dosyaya yazmak isterseniz
logging-facility=0
# Her DNS sorgusunu logla (dikkat: yüksek trafik ortamlarında disk I/O artırır)
log-dns-queries=yes
# DNS detaylarını logla
log-dns-details=yes
# Yavaş sorguları logla (ms cinsinden)
# 500ms üzeri süren sorgular loglanır
query-logging=yes
Değişiklikleri uyguladıktan sonra servisi yeniden başlatın:
systemctl restart pdns
systemctl status pdns
Recursor Loglama Yapılandırması
Recursor için /etc/powerdns/recursor.conf dosyasında aşağıdaki ayarları kullanabilirsiniz:
# Log seviyesi
loglevel=6
# Sorgu loglaması
log-common-errors=yes
# NXDOMAIN cevapları logla
log-rpz-changes=yes
# Yavaş sorgu eşiği (microsecond cinsinden, 1000000 = 1 saniye)
spoof-nearmiss-max=20
# Thread başına log
pdns-distributes-queries=no
Syslog ile Entegrasyon
Varsayılan durumda PowerDNS logları syslog’a daemon facility ile gider. Bunları ayrı bir dosyaya yönlendirmek için rsyslog yapılandırması şu şekilde yapılır:
# /etc/rsyslog.d/powerdns.conf dosyası oluşturun
cat > /etc/rsyslog.d/powerdns.conf << 'EOF'
# PowerDNS Authoritative Server logları
if $programname == 'pdns_server' then /var/log/powerdns/pdns.log
if $programname == 'pdns_server' then stop
# PowerDNS Recursor logları
if $programname == 'pdns_recursor' then /var/log/powerdns/recursor.log
if $programname == 'pdns_recursor' then stop
EOF
# Log dizinini oluşturun
mkdir -p /var/log/powerdns
chown syslog:adm /var/log/powerdns
# rsyslog'u yeniden başlatın
systemctl restart rsyslog
Log rotasyonu için logrotate yapılandırması ekleyelim:
cat > /etc/logrotate.d/powerdns << 'EOF'
/var/log/powerdns/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
sharedscripts
postrotate
/usr/bin/systemctl kill -s HUP rsyslog.service
endscript
}
EOF
PowerDNS API ve Metrik Toplama
PowerDNS’in en güçlü özelliklerinden biri dahili HTTP API’sidir. Bu API üzerinden anlık metrikler, zone bilgileri ve sunucu durumu alabilirsiniz.
API Etkinleştirme
# pdns.conf'a ekleyin
webserver=yes
webserver-address=127.0.0.1
webserver-port=8081
webserver-allow-from=127.0.0.1,10.0.0.0/8
api=yes
api-key=guclu-bir-api-anahtari-belirleyin
API’yi test etmek için:
# Sunucu istatistiklerini al
curl -s -H 'X-API-Key: guclu-bir-api-anahtari-belirleyin'
http://127.0.0.1:8081/api/v1/servers/localhost/statistics | python3 -m json.tool
# Zone listesini al
curl -s -H 'X-API-Key: guclu-bir-api-anahtari-belirleyin'
http://127.0.0.1:8081/api/v1/servers/localhost/zones | python3 -m json.tool
Önemli Metrikler
API’den dönen istatistikler arasında dikkat etmeniz gereken değerler:
- udp-queries: Gelen UDP sorgu sayısı
- tcp-queries: Gelen TCP sorgu sayısı
- servfail-packets: SERVFAIL cevap sayısı (arttıysa sorun var)
- nxdomain-packets: NXDOMAIN cevap sayısı
- recursing-answers: Recursive cevap sayısı
- cache-hits: Cache’den karşılanan sorgu sayısı
- cache-misses: Cache’den karşılanamayan sorgu sayısı
- latency: Ortalama gecikme süresi (microsecond)
- corrupt-packets: Bozuk paket sayısı (ağ sorununa işaret edebilir)
- timedout-packets: Zaman aşımına uğrayan paketler
Prometheus ile Metrik Toplama
Modern bir izleme altyapısı için PowerDNS Exporter kullanarak metrikleri Prometheus’a aktarabilirsiniz.
# PowerDNS Exporter kurulumu
# GitHub: https://github.com/janeczku/powerdns-exporter
# Binary indirme
wget https://github.com/janeczku/powerdns-exporter/releases/download/v0.4.0/powerdns_exporter-v0.4.0.linux-amd64.tar.gz
tar xzf powerdns_exporter-v0.4.0.linux-amd64.tar.gz
mv powerdns_exporter /usr/local/bin/
# Systemd service dosyası
cat > /etc/systemd/system/powerdns-exporter.service << 'EOF'
[Unit]
Description=PowerDNS Exporter for Prometheus
After=network.target
[Service]
Type=simple
User=nobody
ExecStart=/usr/local/bin/powerdns_exporter
-api-url=http://127.0.0.1:8081/api/v1
-api-key=guclu-bir-api-anahtari-belirleyin
-listen-address=:9120
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now powerdns-exporter
Prometheus yapılandırmasına ekleyin:
# /etc/prometheus/prometheus.yml içine scrape job ekleyin
cat >> /etc/prometheus/prometheus.yml << 'EOF'
- job_name: 'powerdns'
static_configs:
- targets: ['localhost:9120']
scrape_interval: 30s
EOF
systemctl reload prometheus
Gerçek Dünya Senaryosu: Anormal Sorgu Tespiti
Bir sabah iş başına geçtiğinizde DNS sunucunuzun olağandışı yük altında olduğunu görüyorsunuz. Bu durumu nasıl analiz edersiniz?
Adım 1: Anlık Durum Kontrolü
# PowerDNS istatistiklerini anlık olarak izle
watch -n 2 'curl -s -H "X-API-Key: guclu-bir-api-anahtari-belirleyin"
http://127.0.0.1:8081/api/v1/servers/localhost/statistics |
python3 -c "import sys,json; data=json.load(sys.stdin);
[print(f"{item['"'"'name'"'"']:40} {item['"'"'value'"'"']}")
for item in data if item['"'"'name'"'"'] in
['"'"'udp-queries'"'"','"'"'servfail-packets'"'"','"'"'latency'"'"','"'"'corrupt-packets'"'"']]"'
Adım 2: Log Analizi
# Son 1000 satırda en çok sorgulanan domainleri bul
tail -n 10000 /var/log/powerdns/pdns.log |
grep "query" |
awk '{print $NF}' |
sort | uniq -c | sort -rn | head -20
# SERVFAIL üretilen domainleri bul
grep -i "servfail" /var/log/powerdns/pdns.log |
awk '{print $(NF-1)}' |
sort | uniq -c | sort -rn | head -10
# Belirli bir IP'den gelen sorguları filtrele
grep "192.168.1.100" /var/log/powerdns/pdns.log | tail -50
Adım 3: Kaynak IP Analizi
# pdns-recursor için sorgu istatistiklerini kaynak IP bazlı izle
rec_control get-all 2>/dev/null | grep -E "^(queries|servfails|nxdomain)"
# tcpdump ile DNS trafiğini anlık yakala
tcpdump -i eth0 -n port 53 -c 1000 2>/dev/null |
awk '/A?/ {print $NF}' |
sort | uniq -c | sort -rn | head -20
Grafana Dashboard Yapılandırması
Prometheus’tan gelen verileri görselleştirmek için Grafana kullanabilirsiniz. Kritik alertler için şu PromQL sorgularını kullanın:
# Grafana'ya import edebileceğiniz temel alert kuralları
# /etc/prometheus/rules/powerdns.yml
cat > /etc/prometheus/rules/powerdns.yml << 'EOF'
groups:
- name: powerdns_alerts
rules:
- alert: PowerDNSHighServfailRate
expr: rate(powerdns_authoritative_servfail_packets_total[5m]) > 10
for: 2m
labels:
severity: warning
annotations:
summary: "PowerDNS SERVFAIL orani yuksek"
description: "Son 5 dakikada saniyede {{ $value }} SERVFAIL uretiliyor"
- alert: PowerDNSHighLatency
expr: powerdns_authoritative_latency_average > 100000
for: 5m
labels:
severity: critical
annotations:
summary: "PowerDNS gecikme suresi yuksek"
description: "Ortalama gecikme {{ $value }}us seviyesinde"
- alert: PowerDNSDown
expr: up{job="powerdns"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "PowerDNS servisi cevaplanmiyor"
EOF
systemctl reload prometheus
dnstap ile Detaylı Sorgu Loglama
Eğer her DNS sorgusunu detaylı olarak kaydetmeniz gerekiyorsa, dnstap en doğru çözümdür. Performans etkisi minimal, veri kalitesi ise son derece yüksektir.
# pdns.conf'a dnstap ekleyin
cat >> /etc/powerdns/pdns.conf << 'EOF'
# dnstap yapılandırması
# Dikkat: Bu özellik PowerDNS 4.x ve üzerinde mevcut
lua-dns-script=/etc/powerdns/dnstap-logger.lua
EOF
# Basit bir Lua sorgu loglama scripti
cat > /etc/powerdns/dnstap-logger.lua << 'EOF'
-- Tüm gelen sorguları logla
function preresolve(dq)
if dq.qtype == pdns.A or dq.qtype == pdns.AAAA then
pdnslog(string.format("QUERY client=%s qname=%s qtype=%s",
dq.remoteaddr:toString(),
dq.qname:toString(),
dq:getTypeName()
))
end
return false, {}
end
-- Cevapları logla (opsiyonel, disk kullanımını artırır)
function postresolve(dq)
if dq.rcode == pdns.SERVFAIL then
pdnslog(string.format("SERVFAIL client=%s qname=%s",
dq.remoteaddr:toString(),
dq.qname:toString()
), pdns.loglevels.Warning)
end
return false, {}
end
EOF
systemctl restart pdns
Zabbix ile Entegrasyon
Eğer ekibiniz Zabbix kullanıyorsa, PowerDNS’i Zabbix ile de izleyebilirsiniz:
# Zabbix external check scripti
cat > /usr/lib/zabbix/externalscripts/check_powerdns.sh << 'EOF'
#!/bin/bash
# Kullanim: check_powerdns.sh <metric_adi> <api_key>
METRIC=$1
API_KEY=$2
API_URL="http://127.0.0.1:8081/api/v1/servers/localhost/statistics"
VALUE=$(curl -s -H "X-API-Key: ${API_KEY}" "${API_URL}" |
python3 -c "
import sys, json
data = json.load(sys.stdin)
metric = '${METRIC}'
for item in data:
if item['name'] == metric:
print(item['value'])
sys.exit(0)
print(-1)
")
echo "${VALUE}"
EOF
chmod +x /usr/lib/zabbix/externalscripts/check_powerdns.sh
# Test
/usr/lib/zabbix/externalscripts/check_powerdns.sh latency guclu-bir-api-anahtari-belirleyin
Log Analizi İçin Pratik Script’ler
Günlük rutin kontroller için kullanabileceğiniz hazır script koleksiyonu:
#!/bin/bash
# /usr/local/bin/pdns-daily-report.sh
# Her gün cron ile çalıştırın: 0 8 * * * /usr/local/bin/pdns-daily-report.sh
API_KEY="guclu-bir-api-anahtari-belirleyin"
API_URL="http://127.0.0.1:8081/api/v1/servers/localhost"
LOG_FILE="/var/log/powerdns/pdns.log"
REPORT_DATE=$(date '+%Y-%m-%d')
echo "=== PowerDNS Gunluk Rapor - ${REPORT_DATE} ==="
echo ""
# Toplam sorgu sayısı
TOTAL_QUERIES=$(curl -s -H "X-API-Key: ${API_KEY}"
"${API_URL}/statistics" |
python3 -c "import sys,json; data=json.load(sys.stdin);
[print(item['value']) for item in data if item['name']=='udp-queries']")
echo "Toplam UDP Sorgu: ${TOTAL_QUERIES}"
# SERVFAIL oranı
SERVFAIL=$(curl -s -H "X-API-Key: ${API_KEY}"
"${API_URL}/statistics" |
python3 -c "import sys,json; data=json.load(sys.stdin);
[print(item['value']) for item in data if item['name']=='servfail-packets']")
echo "Toplam SERVFAIL: ${SERVFAIL}"
# Ortalama gecikme
LATENCY=$(curl -s -H "X-API-Key: ${API_KEY}"
"${API_URL}/statistics" |
python3 -c "import sys,json; data=json.load(sys.stdin);
[print(item['value']) for item in data if item['name']=='latency']")
echo "Ortalama Gecikme: ${LATENCY} microsecond"
echo ""
# En çok NXDOMAIN alan domainler
echo "=== Son 24 Saatte En Cok NXDOMAIN Alan Domainler ==="
grep "$(date '+%b %d')" "${LOG_FILE}" |
grep -i "nxdomain|not found" |
awk '{for(i=1;i<=NF;i++) if($i~/./) print $i}' |
grep '.' | sort | uniq -c | sort -rn | head -10
echo ""
echo "=== Rapor Sonu ==="
Güvenlik Odaklı Log İzleme
DNS logları sadece performans izleme için değil, güvenlik açısından da kritiktir. DNS tünelleme, DGA (Domain Generation Algorithm) saldırıları ve data exfiltration girişimlerini log analizi ile tespit edebilirsiniz.
Şüpheli DNS Aktivitesi Tespiti
#!/bin/bash
# Uzun domain adlarını tespit et (DNS tünelleme belirtisi olabilir)
# 50 karakterden uzun subdomain içeren sorgular
grep "query" /var/log/powerdns/pdns.log |
awk '{print $NF}' |
awk -F. 'length($1) > 50 {print}' |
sort | uniq -c | sort -rn | head -20
# Çok sayıda unique subdomain sorgulayan IP'leri bul
# (DGA veya tünelleme göstergesi)
grep "query" /var/log/powerdns/pdns.log |
awk '{print $5, $NF}' |
awk '{split($2,a,"."); if(length(a)>=3) print $1}' |
sort | uniq -c | sort -rn |
awk '$1 > 100 {print "Supheceli IP:", $2, "- Sorgu sayisi:", $1}'
Güvenlik izleme sürecinde dikkat edilmesi gereken durumlar:
- Anormal domain uzunluğu: 60 karakteri aşan subdomainler DNS tünellemeye işaret edebilir
- Yüksek NXDOMAIN oranı: Genellikle botnet veya DGA aktivitesi gösterir
- Belirli bir TXT veya NULL record talebi: Veri sızdırma aracı olarak kullanılıyor olabilir
- Saniyede onlarca farklı domain sorgusu yapan tek IP: Tarama veya saldırı botu
- Gece yarısı anormal trafik artışı: Scheduler ile tetiklenen kötü amaçlı yazılım
Recursor Özel İzleme: Cache Hit Oranı
Recursor kullanıyorsanız cache hit oranı son derece önemli bir metriktir. Düşük cache hit oranı, hem upstream DNS sunucularınıza gereksiz yük bindirdiğiniz hem de kullanıcılarınıza yavaş cevap verdiğiniz anlamına gelir.
# rec_control ile anlık cache istatistikleri
rec_control get cache-hits
rec_control get cache-misses
rec_control get cache-entries
# Cache hit oranını hesapla
HITS=$(rec_control get cache-hits 2>/dev/null | awk '{print $2}')
MISSES=$(rec_control get cache-misses 2>/dev/null | awk '{print $2}')
TOTAL=$((HITS + MISSES))
if [ $TOTAL -gt 0 ]; then
RATIO=$(echo "scale=2; ($HITS / $TOTAL) * 100" | bc)
echo "Cache Hit Orani: %${RATIO}"
echo "Cache Hits: ${HITS}"
echo "Cache Misses: ${MISSES}"
fi
# Cache'i flush et (gerekirse)
# rec_control wipe-cache example.com
Cache hit oranını artırmak için recursor.conf’da şu ayarları gözden geçirin:
- max-cache-entries: Varsayılan genellikle düşük gelir, bellek durumunuza göre artırın
- max-cache-ttl: Kayıtları cache’de tutma süresini uzatabilirsiniz
- min-ttl-override: Çok düşük TTL’li domainler için minimum değer belirleyin
- serve-stale-extensions: Upstream cevap vermediğinde eski cache’i sunma özelliği
Sonuç
PowerDNS’in loglama ve izleme yetenekleri, doğru yapılandırıldığında altyapınızın DNS katmanında tam görünürlük sağlar. Temel syslog entegrasyonundan başlayıp Prometheus ve Grafana ile profesyonel bir izleme altyapısına kadar adım adım ilerlemenizi öneririm.
Özellikle üretim ortamlarında şu üç şeyi mutlaka yapın: API’yi aktif edin ve metrik toplamayı başlatın, günlük SERVFAIL ve yüksek gecikme alertleri kurun, güvenlik amaçlı log analizini rutin hale getirin. DNS’in “kendiliğinden çalışan bir şey” olduğu algısı, sorun çıkana kadar devam eder. Ancak o zaman loglara bakmaya başlarsınız ki bu genellikle çok geç olur.
Bir de şunu söyleyeyim: log-dns-queries=yes ayarını dikkatli kullanın. Yüksek trafikli ortamlarda bu ayar diskinizi hızla doldurabilir ve I/O performansını düşürebilir. Yeterince test etmeden bunu production’a açmayın ya da açacaksanız log rotasyonunuzun ve disk kapasiteniizin hazır olduğundan emin olun.