Unbound DNS Log Analizi ve Sorun Giderme Rehberi
DNS sunucunuzda bir şeyler ters gittiğinde, ilk içgüdünüz muhtemelen servisi yeniden başlatmak olur. Ben de öyle yapıyordum, ta ki bir gece yarısı üretim ortamında Unbound’un log dosyasını düzgünce okumayı öğrenene kadar. O geceden sonra şunu anladım: Unbound’un logları, sorunu çözmek için gereken her şeyi zaten söylüyor, yeter ki dinlemeyi bilin.
Unbound Loglama Altyapısını Anlamak
Unbound, varsayılan kurulumda oldukça sessiz çalışır. verbosity seviyesi 0 ya da 1 olarak gelir ve bu seviyede sadece kritik hatalar görünür. Sorun giderme sürecine girmeden önce, loglama altyapısını doğru yapılandırmak gerekiyor.
Unbound’un log seviyeleri şu şekilde çalışır:
- verbosity: 0 – Hiçbir şey loglanmaz, sadece başlangıç ve kapanış mesajları
- verbosity: 1 – Operasyonel mesajlar, kritik hatalar
- verbosity: 2 – Detaylı operasyonel bilgi, bağlantı bilgileri
- verbosity: 3 – Sorgu düzeyinde bilgi, her DNS sorgusu loglanır
- verbosity: 4 – Algoritmik detaylar, önbellek işlemleri
- verbosity: 5 – Her şey, gerçekten her şey (üretimde kullanmayın)
Log yapılandırması için /etc/unbound/unbound.conf dosyasını açın:
server:
verbosity: 2
log-queries: yes
log-replies: yes
log-tag-queryreply: yes
logfile: "/var/log/unbound/unbound.log"
log-time-ascii: yes
use-syslog: no
use-syslog: no ayarı, logları doğrudan dosyaya yönlendirir. Eğer merkezi log yönetimi kullanıyorsanız yes yapıp syslog’a bırakabilirsiniz. Ben her iki ortamda da farklı yaklaşımlar denedim; küçük ve orta ölçekli altyapılarda dosyaya yazmak, analiz açısından çok daha pratik.
Log dizinini oluşturun ve izinleri ayarlayın:
mkdir -p /var/log/unbound
chown unbound:unbound /var/log/unbound
chmod 750 /var/log/unbound
Log Rotasyonu Yapılandırması
Unbound logları üretim ortamında hızla büyür. Verbosity 3 ile çalışan bir sunucuda günde birkaç GB log üretmek mümkün. Logrotate yapılandırması olmadan disk dolması kaçınılmaz:
cat > /etc/logrotate.d/unbound << 'EOF'
/var/log/unbound/unbound.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 640 unbound unbound
postrotate
kill -HUP $(cat /var/run/unbound.pid 2>/dev/null) 2>/dev/null || true
endscript
}
EOF
kill -HUP ile Unbound’a log dosyasını yeniden açması sinyali gönderilir. Bu olmadan rotasyon sonrası eski dosyaya yazmaya devam eder.
Log Formatını Okumak
Unbound log satırları ilk bakışta biraz kafa karıştırıcı görünebilir. Tipik bir sorgu logu şöyle görünür:
[1704067200] unbound[1234:0] info: 192.168.1.100 google.com. A IN NOERROR 0.001234 0 34
Bu satırı parçalayalım:
- [1704067200] – Unix timestamp (log-time-ascii: yes ile okunabilir formata döner)
- unbound[1234:0] – Process ID ve thread ID
- info – Log seviyesi
- 192.168.1.100 – Sorguyu yapan istemci IP’si
- google.com. – Sorgulanan domain (nokta ile biter, bu FQDN göstergesi)
- A – Sorgu tipi
- IN – Sorgu sınıfı (Internet)
- NOERROR – Yanıt kodu
- 0.001234 – Yanıt süresi (saniye)
- 0 – Önbellekten mi geldi (0=hayır, 1=evet)
- 34 – Yanıt boyutu (byte)
SERVFAIL, NXDOMAIN gibi yanıt kodlarını görmek için şu komutu kullanabilirsiniz:
grep -E "SERVFAIL|NXDOMAIN|REFUSED" /var/log/unbound/unbound.log |
awk '{print $NF, $(NF-1), $(NF-2)}' |
sort | uniq -c | sort -rn | head -20
Gerçek Dünya Senaryo 1: SERVFAIL Fırtınası
Bir sabah geldiniz, monitoring ekranınız kırmızı, DNS sorguları yanıt vermiyor. İlk iş logu açmak:
tail -f /var/log/unbound/unbound.log | grep SERVFAIL
Eğer belirli bir domain için SERVFAIL yağıyorsa, o domain’in upstream DNS’te sorun yaşıyor olabilir. Şu scriptle hangi domain’lerin en çok SERVFAIL ürettiğini bulun:
#!/bin/bash
LOG_FILE="/var/log/unbound/unbound.log"
echo "Son 1 saatteki SERVFAIL analizi:"
awk -v start=$(date -d '1 hour ago' +%s) '
/SERVFAIL/ {
# Timestamp kontrolu
gsub(/[[]]/, "", $1)
if ($1 > start) {
# Domain adini al
print $6
}
}' "$LOG_FILE" | sort | uniq -c | sort -rn | head -10
SERVFAIL’in nedeni çoğunlukla şunlardan biri olur:
- DNSSEC doğrulama hatası – Domain’in DNSSEC yapılandırması bozuk
- Upstream resolver erişim sorunu – Forward sunucusuna ulaşılamıyor
- Zaman aşımı – Yetkili sunucular yanıt vermiyor
- Yanlış yapılandırılmış delegation – Parent zone ile uyumsuzluk
DNSSEC kaynaklı SERVFAIL için log’da şu tür mesajlar görünür:
[timestamp] unbound[pid] info: validation failure google.com. A IN
[timestamp] unbound[pid] info: DNSSEC signature verification failed
Geçici olarak DNSSEC doğrulamasını devre dışı bırakıp sorunun kaybolup kaybolmadığını test edebilirsiniz (sadece sorun giderme amaçlı):
# Sadece test ortaminda, gerekiyorsa:
unbound-checkconf
echo "val-permissive-mode: yes" >> /etc/unbound/unbound.conf.d/temp-test.conf
systemctl restart unbound
Gerçek Dünya Senaryo 2: Yavaş DNS Yanıtları
Kullanıcılar sayfa açılışlarının yavaşladığından şikayet ediyor ama sunucular sağlıklı görünüyor. DNS gecikmeleri genellikle bu tür şikayetlerin arkasında gizlidir.
Yanıt sürelerini analiz etmek için:
#!/bin/bash
LOG_FILE="/var/log/unbound/unbound.log"
# Yanit surelerini topla ve istatistik hesapla
awk '/info:.*IN [A-Z]+ [0-9]/ {
# Yanit suresi 6. alandan itibaren sayilir
for(i=1; i<=NF; i++) {
if ($i ~ /^[0-9]+.[0-9]+$/ && $i < 10) {
latency = $i * 1000 # ms cevir
if (latency > 500) slow++
if (latency > 100) medium++
total++
}
}
}
END {
print "Toplam sorgu:", total
print "100ms+ yanit:", medium, "(" int(medium*100/total) "%)"
print "500ms+ yanit:", slow, "(" int(slow*100/total) "%)"
}' "$LOG_FILE"
500ms üzerinde yanıt süreleri görüyorsanız, önce unbound-control stats çıktısına bakın:
unbound-control stats | grep -E "total.|cache.|num."
Kritik metrikler şunlar:
- total.num.cachehits – Önbellekten karşılanan sorgular (yüksek olmalı)
- total.num.cachemiss – Upstream’e giden sorgular
- total.num.prefetch – Önceden yüklenen kayıtlar
- total.recursion.time.avg – Ortalama özyineleme süresi
Cache hit oranı düşükse (yüzde 70’in altı tipik bir alarm sinyali), önbellek boyutunu artırın:
server:
msg-cache-size: 128m
rrset-cache-size: 256m
key-cache-size: 32m
neg-cache-size: 8m
cache-max-ttl: 86400
cache-min-ttl: 300
Log Analizi için Pratik Script Koleksiyonu
Yıllar içinde biriktirdiğim, günlük işimde kullandığım bazı script’ler:
En çok sorgu yapan istemciler:
#!/bin/bash
# Top 10 DNS istemcisi
LOG_FILE="${1:-/var/log/unbound/unbound.log}"
echo "=== En Cok Sorgu Yapan Istemciler ==="
grep "info:" "$LOG_FILE" |
awk '{print $5}' |
grep -E '^[0-9]{1,3}.[0-9]{1,3}.' |
sort | uniq -c | sort -rn | head -10
echo ""
echo "=== En Cok Sorgulanan Domainler ==="
grep "info:" "$LOG_FILE" |
awk '{print $6}' |
grep '.' |
sed 's/.$//' |
sort | uniq -c | sort -rn | head -10
Hata oranı zaman serisi:
#!/bin/bash
# Saatlik hata orani
LOG_FILE="/var/log/unbound/unbound.log"
echo "Saatlik SERVFAIL orani:"
grep "SERVFAIL" "$LOG_FILE" |
awk '{
gsub(/[[]]/, "", $1)
cmd = "date -d @" $1 " +%Y-%m-%d-%H"
cmd | getline hour
close(cmd)
hours[hour]++
}
END {
for (h in hours) print h, hours[h]
}' | sort | tail -24
Unbound-Control ile Canlı İzleme
Log analizi reaktif bir yaklaşım. Proaktif izleme için unbound-control vazgeçilmez:
# Servisi sagligi kontrolu
unbound-control status
# Anlik istatistikler (ve sayaclari sifirla)
unbound-control stats_noreset
# Onbellekteki belirli bir kaydi sorgula
unbound-control lookup google.com
# Onbellegi temizle (dikkatli kullanin)
unbound-control flush_zone .
# Belirli bir domaini onbellekten kaldir
unbound-control flush example.com
# Yerel zone ekle (dinamik)
unbound-control local_data "test.local. 300 IN A 192.168.1.100"
Monitoring entegrasyonu için basit bir health check script’i:
#!/bin/bash
# /usr/local/bin/unbound-health-check.sh
WARN_LATENCY=200 # ms
CRIT_LATENCY=500 # ms
WARN_CACHE_HIT=70 # yuzde
STATS=$(unbound-control stats_noreset 2>/dev/null)
if [ $? -ne 0 ]; then
echo "CRITICAL: Unbound'a ulasilamiyor"
exit 2
fi
CACHE_HITS=$(echo "$STATS" | grep "total.num.cachehits" | cut -d= -f2)
CACHE_MISS=$(echo "$STATS" | grep "total.num.cachemiss" | cut -d= -f2)
TOTAL=$((CACHE_HITS + CACHE_MISS))
if [ "$TOTAL" -gt 0 ]; then
HIT_RATE=$((CACHE_HITS * 100 / TOTAL))
if [ "$HIT_RATE" -lt "$WARN_CACHE_HIT" ]; then
echo "WARNING: Cache hit orani dusuk: %$HIT_RATE"
exit 1
fi
fi
AVG_RECURSION=$(echo "$STATS" | grep "total.recursion.time.avg" | cut -d= -f2 | awk '{print int($1*1000)}')
if [ "$AVG_RECURSION" -gt "$CRIT_LATENCY" ]; then
echo "CRITICAL: Ortalama yanit suresi ${AVG_RECURSION}ms"
exit 2
elif [ "$AVG_RECURSION" -gt "$WARN_LATENCY" ]; then
echo "WARNING: Ortalama yanit suresi ${AVG_RECURSION}ms"
exit 1
fi
echo "OK: Unbound saglikli - Cache: %$HIT_RATE, Latency: ${AVG_RECURSION}ms"
exit 0
Yaygın Sorunlar ve Çözümleri
“Cannot retrieve nameservers” Hatası
Bu hata, root sunucularına ulaşamadığınızda görünür. Log’da şu şekilde görünür:
error: can not retrieve root NS
error: failed to prime trust anchor
Kontrol listesi:
/etc/unbound/root.hintsdosyasının güncel olup olmadığını kontrol edin- Firewall’un 53/UDP çıkış trafiğine izin verdiğini doğrulayın
- Forwarder kullanıyorsanız, forwarder’ın erişilebilir olduğunu test edin
# Root hints guncelle
curl -o /etc/unbound/root.hints https://www.internic.net/domain/named.root
# Baglanabilirlik testi
dig @a.root-servers.net . NS +norec +time=5
# Unbound'u yeniden yukle
unbound-control reload
Yüksek CPU Kullanımı
Verbosity 3+ ayarında Unbound yüksek I/O ve CPU kullanabilir. Bunu yaşadığınızda şu adımları takip edin:
# Hangi thread en cok CPU kullaniyor
ps -eLf | grep unbound | sort -k5 -rn | head -10
# Thread sayisini kontrol et
grep num-threads /etc/unbound/unbound.conf
# Istatistiklerden sorgu hacmini anla
unbound-control stats_noreset | grep "total.num.queries"
Thread sayısını CPU çekirdek sayısıyla eşleştirmek genellikle iyi bir başlangıç noktasıdır:
server:
num-threads: 4
msg-cache-slabs: 8
rrset-cache-slabs: 8
infra-cache-slabs: 8
key-cache-slabs: 8
Slab sayısı thread sayısının iki katı olmalı, ve her ikisi de 2’nin kuvveti olmalı.
Belirli Domainlere Erişim Sorunları
Bir domain için sürekli NXDOMAIN ya da SERVFAIL alıyorsanız, sorun gidermeyi adım adım yapın:
# Onbellekteki bilgiyi temizle
unbound-control flush problematic-domain.com
unbound-control flush_type problematic-domain.com A
# Unbound'un ne gordugunu anla
unbound-host -v problematic-domain.com
# DNSSEC zincirini kontrol et
unbound-host -D problematic-domain.com
# Direkt yetkili sunucuya sor
dig @8.8.8.8 problematic-domain.com A +dnssec
Syslog Entegrasyonu ve Merkezi Log Yönetimi
Birden fazla Unbound sunucusu varsa, logları merkezi bir sistemde toplamak hayat kurtarır. Syslog yapılandırması:
server:
use-syslog: yes
log-identity: "unbound-prod-01"
Rsyslog ile belirli bir log sunucusuna yönlendirme:
cat > /etc/rsyslog.d/unbound.conf << 'EOF'
if $programname == 'unbound-prod-01' then {
action(type="omfwd"
target="log-server.internal"
port="514"
protocol="tcp")
action(type="omfile" file="/var/log/unbound/unbound.log")
stop
}
EOF
systemctl restart rsyslog
Elasticsearch’e log gönderiyorsanız, Filebeat ile yapılandırma oldukça düzgün çalışıyor. Ama bu konu başlı başına ayrı bir yazının konusu.
Sonuç
Unbound log analizi, bir kez düzgünce kurulduktan sonra son derece güçlü bir sorun giderme aracına dönüşüyor. Özetlemek gerekirse kritik noktalara bir bakalım:
- Verbosity seviyesini ortama göre ayarlayın. Üretimde 1-2, sorun giderirken 3, asla 5
- Log rotasyonu olmadan disk dolacak, bunu baştan ayarlayın
- unbound-control stats komutunu düzenli izleme alışkanlığı edinin
- Cache hit oranı en önemli performans göstergenizdir
- SERVFAIL’leri tek tek incelemeyin, pattern arayın
En iyi sysadmin’ler sorun çıktıktan sonra değil, çıkmadan önce ne arayacaklarını bilir. Unbound’un loglarını okumayı öğrenmek, DNS kaynaklı sorunları dakikalar içinde çözmenizi sağlar. O gece yarısı bunu öğrenmeye mecbur kalmak zorunda kalmadınız, bu yazıyı okudunuz, şanslısınız.
