BIND Log Analizi ve Hata Ayıklama

DNS sunucunuz garip davranışlar sergilemeye başladığında, ilk başvurmanız gereken yer BIND’ın log dosyaları olacak. Yıllarca DNS yönetimi yapan biri olarak söyleyebilirim ki, iyi yapılandırılmış bir loglama sistemi olmadan BIND sorunlarını çözmek adeta karanlıkta el yordamıyla yürümek gibidir. Bu yazıda BIND’ın loglama mimarisini, yaygın hata mesajlarını ve gerçek dünya senaryolarında nasıl hata ayıklayacağınızı detaylıca ele alacağız.

BIND Loglama Mimarisi

BIND, named.conf içinde tanımlanan logging bloğu aracılığıyla son derece esnek bir loglama sistemi sunar. İki temel kavramı anlamak gerekiyor: channel (kanal) ve category (kategori).

Channel, logların nereye yazılacağını tanımlar. Dosyaya, syslog’a veya stderr’e yazabilirsiniz.

Category, hangi tür olayların loglanacağını belirler. queries, security, resolver, xfer-in gibi onlarca kategori mevcuttur.

Temel Loglama Yapılandırması

Önce minimal ama işlevsel bir yapılandırmayla başlayalım:

# /etc/named.conf içine eklenecek logging bloğu

logging {
    channel default_log {
        file "/var/log/named/default.log" versions 3 size 20m;
        print-time yes;
        print-severity yes;
        print-category yes;
        severity dynamic;
    };

    channel query_log {
        file "/var/log/named/queries.log" versions 5 size 50m;
        print-time yes;
        print-severity yes;
        print-category yes;
        severity info;
    };

    channel security_log {
        file "/var/log/named/security.log" versions 3 size 10m;
        print-time yes;
        print-severity yes;
        print-category yes;
        severity info;
    };

    category default { default_log; };
    category queries { query_log; };
    category security { security_log; };
    category resolver { default_log; };
    category xfer-in { default_log; };
    category xfer-out { default_log; };
};

Log dizinini oluşturup izinleri ayarlamayı unutmayın:

mkdir -p /var/log/named
chown named:named /var/log/named
chmod 755 /var/log/named

# SELinux kullananlar için
restorecon -R /var/log/named

Severity Seviyeleri

BIND’da şu severity seviyeleri kullanılır, en ayrıntılıdan en azına doğru:

  • critical: Sistem çökmesine yol açabilecek hatalar
  • error: İşlem başarısız oldu ama sistem çalışmaya devam ediyor
  • warning: Dikkat edilmesi gereken durumlar
  • notice: Normal ama önemli olaylar
  • info: Genel bilgi mesajları
  • debug: Hata ayıklama bilgileri (çok fazla çıktı üretir)
  • dynamic: rndc ile dinamik olarak ayarlanabilir seviye

Gerçek Zamanlı Log İzleme

Aktif bir DNS sunucusunda sorun yaşandığında hızla müdahale etmek için şu komutları kullanıyorum:

# Tüm BIND loglarını gerçek zamanlı izle
tail -f /var/log/named/*.log

# Sadece sorgu loglarını izle ve filtreleme yap
tail -f /var/log/named/queries.log | grep "NXDOMAIN"

# Birden fazla log dosyasını aynı anda izle
multitail /var/log/named/default.log /var/log/named/security.log

# Syslog üzerinden BIND loglarını izle
journalctl -u named -f

# Son 100 satırı göster ve takip et
journalctl -u named -n 100 -f

rndc aracıyla çalışan BIND’a bağlanarak dinamik olarak debug seviyesini değiştirebilirsiniz. Bunu production ortamında çok kullandım, servisi yeniden başlatmadan detaylı log almak büyük kolaylık sağlıyor:

# Debug seviyesini 1 olarak ayarla
rndc trace 1

# Daha ayrıntılı debug için seviye 3
rndc trace 3

# Debug'ı kapat, normal seviyeye dön
rndc notrace

# BIND'ın mevcut durumunu göster
rndc status

# İstatistikleri dök
rndc stats
cat /var/named/data/named_stats.txt

Yaygın Hata Mesajları ve Çözümleri

Zone Transfer Hataları

En sık karşılaştığım sorunların başında zone transfer hataları gelir. Slave sunucunuzda şuna benzer bir mesaj görürsünüz:

transfer of 'example.com/IN' from 192.168.1.1#53: Transfer status: REFUSED
transfer of 'example.com/IN' from 192.168.1.1#53: Transfer completed: 0 messages, 0 records

Bu mesaj genellikle master sunucuda allow-transfer direktifinin yanlış yapılandırılmış olduğunu gösterir. Master sunucuda kontrol edin:

# named.conf veya zone dosyasında kontrol
grep -A5 "allow-transfer" /etc/named.conf

# Test için elle transfer deneyin
dig @192.168.1.1 example.com AXFR

# named-checkconf ile konfigürasyonu doğrulayın
named-checkconf /etc/named.conf

Master sunucuda düzeltme:

# /etc/named.conf zone bloğuna ekleyin
zone "example.com" IN {
    type master;
    file "/var/named/example.com.zone";
    allow-transfer { 192.168.1.2; 192.168.1.3; };
    also-notify { 192.168.1.2; 192.168.1.3; };
};

DNSSEC Doğrulama Hataları

DNSSEC etkin bir sunucuda şu mesajları görebilirsiniz:

validating example.com/DNSKEY: no valid signature found
validating example.com/A: no valid RRSIG
RRSIG has expired

Bu durumda önce ne zaman sona erdiğini kontrol edin:

# Zone imzalama durumunu kontrol et
dig +dnssec example.com DNSKEY @localhost

# RRSIG kayıtlarının süresini kontrol et
dig +dnssec example.com A | grep RRSIG

# OpenSSL ile sertifika benzeri bilgi alın
dig +short +dnssec example.com RRSIG | awk '{print $5, $6}'

Eğer zone dosyasını elle yönetiyorsanız ve imzalar süresi dolmuşsa:

# Zone'u yeniden imzala
cd /var/named
dnssec-signzone -A -3 $(head -c 1000 /dev/random | sha1sum | cut -b 1-16) 
    -N INCREMENT -o example.com -t example.com.zone

# named'ı yeniden yükle
rndc reload example.com

LAME Server Uyarıları

Log dosyalarında sıkça şunu görürsünüz:

lame-servers: info: unexpected SERVFAIL resolving 'www.example.com/A/IN': 8.8.8.8#53
lame-servers: info: DNS format error from 192.0.2.1#53 resolving example.com/A for client

Bu mesajlar genellikle karşı taraftaki DNS sunucusunun sorunlu olduğunu gösterir ve çoğunlukla normaldir. Ama eğer çok fazla görüyorsanız:

# Lame server loglarını istatistiksel olarak analiz et
grep "lame-server" /var/log/named/default.log | 
    awk '{print $NF}' | 
    sort | uniq -c | sort -rn | head -20

# Belirli bir domaine karşı debug sorgusunu çalıştır
dig +trace problematic-domain.com A

# named.conf'ta lame-servers kategorisini susturabilirsiniz
# (eğer çok fazla gürültü yapıyorsa)
category lame-servers { null; };

Recursive Query Reddedilme Hataları

client 203.0.113.45#41223 (www.google.com): query (cache) 'www.google.com/A/IN' denied

Bu mesaj, recursive sorgu yapmaya yetkisi olmayan bir istemcinin sorgu gönderdiğini gösterir:

# İzin verilen istemcileri kontrol et
grep "allow-recursion|allow-query" /etc/named.conf

# Hangi IP'lerden en çok reddedilme geliyor?
grep "query.*denied" /var/log/named/security.log | 
    awk '{print $4}' | cut -d# -f1 | 
    sort | uniq -c | sort -rn | head -10

Log Analiz Araçları ve Script’ler

Manuel log okumak yerine bazı araçları ve scriptleri kullanmak çok daha verimli. İşte gerçekten kullandığım bir analiz scripti:

#!/bin/bash
# dns-log-analyzer.sh
# BIND query log analizi

LOG_FILE="/var/log/named/queries.log"
REPORT_DATE=$(date +%Y-%m-%d)

echo "=== BIND Log Analiz Raporu - $REPORT_DATE ==="
echo ""

echo "--- Top 10 Sorgulanan Domain ---"
grep -oP 'query: K[^ ]+' "$LOG_FILE" | 
    sed 's//.*$//' | 
    sort | uniq -c | sort -rn | head -10

echo ""
echo "--- NXDOMAIN Yanıtları (Top 10) ---"
grep "NXDOMAIN" "$LOG_FILE" | 
    grep -oP 'query: K[^ ]+' | 
    sed 's//.*$//' | 
    sort | uniq -c | sort -rn | head -10

echo ""
echo "--- Saatlik Sorgu Dağılımı ---"
grep -oP 'd{2}:d{2}:d{2}' "$LOG_FILE" | 
    cut -d: -f1 | 
    sort | uniq -c

echo ""
echo "--- En Aktif İstemciler ---"
grep "query:" "$LOG_FILE" | 
    grep -oP 'client K[^#]+' | 
    sort | uniq -c | sort -rn | head -10

Scripti çalıştırılabilir yapın ve kullanın:

chmod +x dns-log-analyzer.sh
./dns-log-analyzer.sh

# Cron ile her gece çalıştırın
echo "0 6 * * * /usr/local/bin/dns-log-analyzer.sh > /var/log/dns-daily-report.txt" | crontab -

Gerçek Dünya Senaryosu: DNS Amplification Saldırısı Tespiti

Bir gün sunucumun bant genişliğinin aniden yüzde seksen artış gösterdiğini fark ettim. BIND loglarına baktığımda şunu gördüm:

# Güvenlik logunu analiz et
grep "query" /var/log/named/security.log | 
    awk '{print $4}' | cut -d# -f1 | 
    sort | uniq -c | sort -rn | head -5

Çıktıda yüzlerce farklı IP’den saniyede binlerce sorgu geldiğini gördüm, hepsi küçük boyutlu sorgular gönderip büyük DNS yanıtları tetiklemeye çalışıyordu. Klasik DNS amplification saldırısı.

Müdahale adımları:

# Rate limiting ekle - named.conf options bloğuna
options {
    rate-limit {
        responses-per-second 5;
        window 5;
        slip 2;
        exempt-clients { 192.168.0.0/24; };
    };
};

# Recursive sorguları sadece iç networke kısıtla
options {
    allow-recursion { 192.168.0.0/24; 127.0.0.1; };
    allow-query-cache { 192.168.0.0/24; 127.0.0.1; };
};

# Değişiklikleri uygula
named-checkconf && rndc reload

# Saldırı devam ediyorsa iptables ile engelle
iptables -A INPUT -p udp --dport 53 -m hashlimit 
    --hashlimit-above 20/sec 
    --hashlimit-burst 100 
    --hashlimit-mode srcip 
    --hashlimit-name dns_limit 
    -j DROP

Zone Dosyası Hataları ve Teşhis

Zone dosyasındaki hatalar BIND’ın başlamasını engelleyebilir veya zone’un yüklenmemesine yol açabilir. Bu hataları nasıl tespit edip çözeceğinizi görelim:

# Zone dosyasını kontrol et
named-checkzone example.com /var/named/example.com.zone

# Tüm zone dosyalarını toplu kontrol et
for zone in /var/named/*.zone; do
    domain=$(basename "$zone" .zone)
    echo -n "Kontrol ediliyor: $domain ... "
    named-checkzone "$domain" "$zone" > /dev/null 2>&1 && 
        echo "OK" || echo "HATA!"
done

# named.conf'u kontrol et
named-checkconf -z /etc/named.conf

# Belirli bir zone'u zorla yeniden yükle
rndc reload example.com

# Zone yükleme durumunu kontrol et
rndc zonestatus example.com

Bir zone dosyasında SOA kaydı sorunuydu. Log şunu söylüyordu:

zone example.com/IN: loaded serial 2024010100
zone example.com/IN: not loaded due to errors.
dns_rdata_fromtext: /var/named/example.com.zone:15: near 'mailserver': not a valid number
  1. satıra gidince MX kaydında öncelik numarasının eksik olduğunu gördüm:
# Yanlış
mail.example.com.  IN  MX  mailserver.example.com.

# Doğru
mail.example.com.  IN  MX  10  mailserver.example.com.

# Düzeltme sonrası
named-checkzone example.com /var/named/example.com.zone && rndc reload example.com

Performance Monitoring ile Log Analizi

BIND’ın statistics-channels özelliği, web tabanlı istatistik erişimi sağlar ve logları tamamlayıcı niteliktedir:

# named.conf'a statistics channel ekle
statistics-channels {
    inet 127.0.0.1 port 8053 allow { 127.0.0.1; };
};

# İstatistiklere eriş
curl -s http://127.0.0.1:8053/xml/v3/server | xmllint --format - | head -50

# rndc stats ile de alabilirsiniz
rndc stats
cat /var/named/data/named_stats.txt | grep -A10 "++ Name Server Statistics ++"

Önemli metriklere bakın:

# Cache hit oranını hesapla
rndc stats && cat /var/named/data/named_stats.txt | 
    grep -E "queries resulted in|cache hits|cache misses" 

# Sorgu tiplerini analiz et
cat /var/named/data/named_stats.txt | 
    grep -A30 "++ Incoming Queries ++"

# SERVFAIL oranına bak
cat /var/named/data/named_stats.txt | 
    grep -E "SERVFAIL|REFUSED|NXDOMAIN"

Log Rotation Yapılandırması

Aktif bir DNS sunucusunda log dosyaları hızla büyür. Logrotate ile bunu yönetin:

# /etc/logrotate.d/named dosyası oluşturun
cat > /etc/logrotate.d/named << 'EOF'
/var/log/named/*.log {
    daily
    missingok
    rotate 30
    compress
    delaycompress
    notifempty
    create 0644 named named
    sharedscripts
    postrotate
        /usr/sbin/rndc reconfig 2>/dev/null || true
    endscript
}
EOF

# Logrotate'i test et
logrotate -d /etc/logrotate.d/named

# Manuel olarak çalıştır
logrotate -f /etc/logrotate.d/named

Debug Senaryosu: Yavaş DNS Çözümleme

Bir kullanıcı belirli domainlerin çok yavaş çözümlendiğini bildirdi. Sistematik yaklaşım:

# Önce genel sorgu süresini ölç
time dig @localhost slowdomain.com A

# Trace ile adım adım takip et
dig +trace slowdomain.com A 2>&1 | tee /tmp/trace_output.txt

# BIND'ın resolver log'una bak
grep "slowdomain.com" /var/log/named/default.log | tail -20

# Forwarder varsa kontrol et
dig @8.8.8.8 slowdomain.com A
dig @1.1.1.1 slowdomain.com A

# Forwarder yanıt sürelerini ölç
for dns in 8.8.8.8 1.1.1.1 9.9.9.9; do
    echo -n "$dns: "
    time dig @$dns slowdomain.com A +short 2>&1 | tail -1
done

Sorunun TTL değeri çok düşük ayarlanmış bir upstream zone’dan kaynaklandığını gördüm. Cache’e alınamayan sorgular her seferinde upstream’e gidiyordu. Çözüm olarak min-cache-ttl ayarını kullandım:

# named.conf options bloğuna ekle
options {
    min-cache-ttl 300;        # minimum 5 dakika cache
    min-ncache-ttl 60;        # negatif yanıtlar için minimum 1 dakika
    max-cache-ttl 86400;      # maksimum 24 saat cache
};

Sonuç

BIND log analizi, DNS altyapısının sağlıklı çalışması için vazgeçilmez bir beceridir. Bu yazıda ele aldıklarımızı özetleyecek olursak:

  • İyi yapılandırılmış loglama, sorunları hızla tespit etmenizi sağlar. Kategorilere göre ayrılmış log dosyaları, hangi sorunu nerede arayacağınızı netleştirir.
  • rndc ve named-checkconf araçları, servisi yeniden başlatmadan hata ayıklama yapmanıza olanak tanır. Üretim ortamında hayat kurtarıcıdır.
  • Otomatik log analiz scriptleri yazmak, günlük operasyonel yükü ciddi ölçüde azaltır. Sabah ilk işiniz log okumak olmak zorunda değil.
  • Güvenlik logları düzenli incelenmeli, rate limiting ve recursion kısıtlamaları mutlaka uygulanmalıdır.
  • named-checkzone ve named-checkconf her değişiklikten önce çalıştırılmalı. Bu iki araç, zone dosyası hatalarının production’a geçmesini engelleyen en önemli savunma hattıdır.

DNS sorunlarının yüzde doksanı sistematik bir log analizi ile çözülebilir. Panik yapmadan, adım adım logları okuyun ve dig, rndc gibi araçları aktif kullanın. Zaman içinde hangi mesajın neyi ifade ettiğini içgüdüsel olarak tanır hale geleceksiniz.

Yorum yapın