Windows DNS Ageing ve Scavenging ile Eski Kayıtları Temizleme

DNS ortamınızda zamanla biriken hayalet kayıtlar, hem güvenlik açısından hem de operasyonel karmaşıklık açısından ciddi sorunlara yol açar. Bir istemci IP adresi değiştiğinde, DHCP kiraları sona erdiğinde veya makineler domain’den ayrıldığında eski DNS kayıtları genellikle geride kalır. Windows DNS Ageing ve Scavenging mekanizması tam olarak bu sorunu çözmek için tasarlanmış olsa da yanlış yapılandırıldığında geçerli kayıtları silebilir. Bu yazıda konuyu hem teorik hem de pratik açıdan ele alacağız.

Ageing ve Scavenging Nedir, Neden Önemlidir?

Windows DNS Server, dinamik olarak güncellenen kayıtları (Dynamic DNS – DDNS) takip etmek için zaman damgası kullanır. Ageing, her kayda bir “timestamp” atayarak bu kaydın en son ne zaman güncellendiğini izleme sürecidir. Scavenging ise belirli bir eşik değerini aşan eski kayıtları otomatik olarak silen temizleme işlemidir.

Neden bu kadar kritik? Büyük bir kurumsal ortamda çalıştıysanız şunu bizzat görmüşsünüzdür: DHCP’den IP alan bir makine domain’den ayrılıyor, sonraki 6 ay boyunca DNS’de eski IP adresiyle görünmeye devam ediyor. Başka bir makine aynı IP’yi alıyor, ama DNS hala eski makineyi gösteriyor. Bu durum authentication hatalarına, erişilemeyen servislere ve troubleshooting süreçlerinde saatlerce kayıp zamana neden olur.

Daha da kötüsü, bazı ortamlarda DNS veritabanı binlerce stale kayıt birikiyor ve sunucu performansı düşmeye başlıyor. Zone transfer süreleri uzuyor, DNS sorgularına verilen yanıtlar yanlış oluyor.

Temel Kavramlar: No-Refresh ve Refresh Intervalleri

Ageing mekanizmasını anlamak için iki kritik zaman dilimini kavramak gerekiyor:

No-Refresh Interval: Bir kaydın oluşturulduktan veya son güncellendikten sonra yenilenmeyeceği süre. Varsayılan 7 gündür. Bu süre zarfında aynı istemciden gelen timestamp yenileme istekleri yoksayılır. Bu, gereksiz zone değişikliklerini ve replikasyon trafiğini önler.

Refresh Interval: No-Refresh süresi dolduktan sonra, kaydın silinmeden önce ne kadar süre daha bekleyeceği. Varsayılan yine 7 gündür. Bu süre içinde istemci kaydını yenilemezse, scavenging işlemi sırasında kayıt silinir.

Yani toplam yaşam döngüsü şöyle işler: Bir kayıt oluşturulduğunda timestamp alır. İlk 7 gün (No-Refresh) boyunca kayıt güncellenemez. Sonraki 7 gün (Refresh) içinde istemci timestamp’i güncellemelidir. Toplamda 14 gün boyunca güncellenmeyen kayıt silinmeye adaydır.

Bu değerleri ortamınıza göre ayarlamanız gerekir. DHCP kira süresi 8 gün olan bir ortamda varsayılan değerler sorun yaratabilir. DHCP kira süresi, No-Refresh Interval’den küçük olmamalıdır.

Scavenging’i Aktif Etmeden Önce: Durum Analizi

Hiçbir zaman scavenging’i faaliyete geçirmeden önce mevcut durumu analiz etmeden yapılandırmayın. İlk adım mevcut kayıtların timestamp durumunu incelemek olmalıdır.

PowerShell ile tüm zone’lardaki static ve dinamik kayıtları listeleyebilirsiniz:

# Belirli bir zone'daki tüm A kayıtlarını timestamp bilgisiyle getir
Get-DnsServerResourceRecord -ZoneName "sirketim.local" -RRType "A" |
    Select-Object HostName, RecordType, TimeToLive,
    @{Name="Timestamp";Expression={$_.TimeStamp}} |
    Where-Object {$_.Timestamp -ne $null} |
    Sort-Object Timestamp |
    Format-Table -AutoSize
# Timestamp'i olmayan (static) kayıtları bul
Get-DnsServerResourceRecord -ZoneName "sirketim.local" -RRType "A" |
    Where-Object {$_.TimeStamp -eq $null} |
    Select-Object HostName, RecordType, TimeToLive |
    Export-Csv -Path "C:DNS_Static_Records.csv" -NoTypeInformation

Timestamp’i olmayan kayıtlar statik kayıtlardır ve scavenging tarafından asla silinmez. Bu önemli bir nokta: kritik sunucularınızın kayıtlarını statik tutmak istiyorsanız timestamp’lerini sıfırlamanız gerekir.

Şimdi ne kadar “yaşlı” kayıt olduğunu görelim:

# 30 günden eski kayıtları listele
$threshold = (Get-Date).AddDays(-30)
Get-DnsServerResourceRecord -ZoneName "sirketim.local" -RRType "A" |
    Where-Object {$_.TimeStamp -ne $null -and $_.TimeStamp -lt $threshold} |
    Select-Object HostName,
    @{Name="Timestamp";Expression={$_.TimeStamp}},
    @{Name="GunSayisi";Expression={(New-TimeSpan -Start $_.TimeStamp -End (Get-Date)).Days}} |
    Sort-Object GunSayisi -Descending |
    Export-Csv -Path "C:DNS_Stale_Records.csv" -NoTypeInformation

Write-Host "Rapor C:DNS_Stale_Records.csv dosyasına kaydedildi."

Bu raporu alın, CSV’yi açın ve hangi kayıtların gerçekten stale olduğunu gözden geçirin. Bazıları backup sunucular, bazıları tatilde olan laptop’lar olabilir. Bunu yapmadan scavenging açarsanız geçerli kayıtları silme riskiyle karşılaşırsınız.

Ageing ve Scavenging Yapılandırması

Zone Seviyesinde Ageing Aktifleştirme

Ageing iki seviyede yapılandırılır: sunucu seviyesi ve zone seviyesi. Her ikisi de aktif olmalıdır.

Önce zone’da ageing’i aktif edelim:

# Tek bir zone için ageing aktifleştir
Set-DnsServerZoneAging -Name "sirketim.local" -Aging $true -NoRefreshInterval 7.00:00:00 -RefreshInterval 7.00:00:00

# Yapılandırmayı doğrula
Get-DnsServerZoneAging -Name "sirketim.local" | Format-List

Birden fazla zone varsa hepsini tek seferde yapılandırabilirsiniz:

# Primary zone'ların tamamında ageing aktifleştir
Get-DnsServerZone | Where-Object {$_.ZoneType -eq "Primary" -and $_.IsAutoCreated -eq $false} | ForEach-Object {
    $zoneName = $_.ZoneName
    Set-DnsServerZoneAging -Name $zoneName -Aging $true -NoRefreshInterval 7.00:00:00 -RefreshInterval 7.00:00:00
    Write-Host "$zoneName zone'unda ageing aktifleştirildi."
}

Sunucu Seviyesinde Scavenging Yapılandırması

# Scavenging periyodunu yapılandır ve aktifleştir
Set-DnsServerScavenging -ScavengingState $true -ScavengingInterval 7.00:00:00 -ApplyOnAllZones

# Mevcut yapılandırmayı görüntüle
Get-DnsServerScavenging | Format-List

ScavengingInterval: Scavenging işleminin kaç günde bir çalışacağı. 7 gün makul bir değerdir.

ApplyOnAllZones: Bu parametreyi dikkatli kullanın. Sadece belirli zone’larda scavenging istiyorsanız bu parametreyi kullanmayın, zone bazında ayrı ayrı ayarlayın.

Manuel Scavenging: Önce Test Edin

Otomatik scavenging’i devreye almadan önce mutlaka manuel bir test çalıştırın. Bu, hangi kayıtların silineceğini önceden görmenizi sağlar.

DNS Manager GUI üzerinden: DNS Server üzerinde sağ tık -> Scavenge Stale Resource Records. Bu işlem hemen gerçekleştirir, preview sunmaz.

PowerShell ile daha kontrollü yaklaşım:

# Scavenging işlemini başlat (gerçek silme yapar, dikkatli olun)
Start-DnsServerScavenging -Force

# Belirli bir zone için scavenging
Invoke-DnsServerZoneScavenging -ZoneName "sirketim.local" -Force

Gerçek ortamda silme yapmadan önce ne silineceğini anlamak için şu yaklaşımı kullanabilirsiniz: No-Refresh ve Refresh interval toplamını geçmiş timestamp’lere sahip kayıtları manuel olarak listeleyin ve bu listeyi değerlendirin.

# Scavenging tarafından silinecek adayları hesapla
$zoneAging = Get-DnsServerZoneAging -Name "sirketim.local"
$noRefresh = $zoneAging.NoRefreshInterval
$refresh = $zoneAging.RefreshInterval
$scavengeThreshold = (Get-Date).Subtract($noRefresh + $refresh)

Write-Host "Scavenging eşik tarihi: $scavengeThreshold"

$candidates = Get-DnsServerResourceRecord -ZoneName "sirketim.local" -RRType "A" |
    Where-Object {$_.TimeStamp -ne $null -and $_.TimeStamp -lt $scavengeThreshold}

Write-Host "Silinecek kayıt adayı sayısı: $($candidates.Count)"
$candidates | Select-Object HostName, @{Name="Timestamp";Expression={$_.TimeStamp}} |
    Export-Csv -Path "C:DNS_ScavengingCandidates.csv" -NoTypeInformation

Kritik Kayıtları Koruma Altına Alma

Bazı kayıtların scavenging tarafından silinmemesi gerekir. Domain controller’lar, kritik sunucular, yazıcılar, ağ cihazları gibi. Bu kayıtları statik hale getirmenin yolu timestamp’lerini temizlemektir.

# Bir kaydı statik yap (timestamp'i sıfırla)
$record = Get-DnsServerResourceRecord -ZoneName "sirketim.local" -Name "kritik-sunucu" -RRType "A"
$newRecord = $record.Clone()
$newRecord.TimeStamp = $null

Set-DnsServerResourceRecord -ZoneName "sirketim.local" -OldInputObject $record -NewInputObject $newRecord
Write-Host "Kayıt statik hale getirildi."

Toplu olarak belirli prefix’e sahip kayıtları statik yapma:

# "srv-" ile başlayan tüm kayıtları statik yap
$records = Get-DnsServerResourceRecord -ZoneName "sirketim.local" -RRType "A" |
    Where-Object {$_.HostName -like "srv-*" -and $_.TimeStamp -ne $null}

foreach ($record in $records) {
    $newRecord = $record.Clone()
    $newRecord.TimeStamp = $null
    Set-DnsServerResourceRecord -ZoneName "sirketim.local" -OldInputObject $record -NewInputObject $newRecord
    Write-Host "$($record.HostName) statik hale getirildi."
}

Gerçek Dünya Senaryosu: Büyük Bir Kurumda Temizlik Operasyonu

Geçen yıl 800’den fazla istemcisi olan bir kurumsal ortamda DNS temizliği yapmak durumunda kaldım. Yıllarca ageing ve scavenging hiç yapılandırılmamıştı. Sonuç olarak yaklaşık 2400 stale A kaydı birikmiş, bunların büyük çoğunluğu yıl önce domain’den ayrılmış makinelere aitti.

Yaklaşımım şöyle oldu:

İlk olarak mevcut tüm kayıtları export ettim ve IP yönetim sistemiyle (IPAM) karşılaştırdım. Hangi IP’lerin aktif olarak DHCP tarafından dağıtıldığını, hangilerinin boşta olduğunu tespit ettim. Sonra ağ ekibinden ping testi yaptırdım: stale aday olarak işaretlediğim IP’lere ICMP gönderdik, yanıt vermeyenler kesin aday listesine girdi.

Sonra ageing’i aktif ettim ama scavenging’i henüz aktifleştirmedim. No-Refresh ve Refresh interval’lerini 14’er gün olarak ayarladım, normalden yüksek tutarak geçiş döneminde risk almadım. 30 gün bekledim. Bu süre içinde aktif makineler kayıtlarını yeniledi, ölü kayıtlar yerinde kaldı. 30 gün sonra scavenging çalıştırdım.

Sonuç: 2400 stale kayıttan 1890 tanesi silindi. Geriye kalan 510 kayıt aktif makinelere aitti ve kendilerini başarıyla yenilemişlerdi.

Event Log ile İzleme

Scavenging işlemlerini takip etmek için Windows Event Log’u kullanmalısınız:

# DNS scavenging ile ilgili eventleri getir
Get-WinEvent -LogName "DNS Server" -MaxEvents 100 |
    Where-Object {$_.Id -in @(2501, 2502, 2503, 2504)} |
    Select-Object TimeCreated, Id, Message |
    Format-List

Önemli Event ID’leri:

  • 2501: Scavenging tamamlandı, X kayıt silindi
  • 2502: Scavenging başladı
  • 2503: Zone scavenging başladı
  • 2504: Zone scavenging tamamlandı

Bu eventleri izlemek için basit bir monitoring scripti:

# Son scavenging sonucunu raporla
$lastScavenging = Get-WinEvent -LogName "DNS Server" |
    Where-Object {$_.Id -eq 2501} |
    Select-Object -First 1

if ($lastScavenging) {
    Write-Host "Son Scavenging: $($lastScavenging.TimeCreated)"
    Write-Host "Detay: $($lastScavenging.Message)"
} else {
    Write-Host "Henüz scavenging çalışmamış ya da log temizlenmiş."
}

Yaygın Hatalar ve Dikkat Edilmesi Gerekenler

Sadece sunucu seviyesinde aktifleştirmek yeterli değil. Hem zone’da ageing hem de sunucuda scavenging aktif olmalıdır. İkisinden biri eksikse çalışmaz.

No-Refresh Interval’i DHCP kira süresinden küçük ayarlamamak. Eğer DHCP kira süresi 8 gün, No-Refresh Interval 7 gün ise istemci IP’yi yenilemeden önce kayıt refresh dönemine girmiş olabilir. Bu durumda teorik olarak kayıt silinme adayı haline gelebilir.

Secondary zone’larda scavenging çalıştırmamak. Scavenging sadece Primary zone’larda çalışır ve çalışmalıdır. Secondary zone’larda ageing aktifleştirmeyin.

Active Directory integrated zone’larda dikkat. AD integrated zone’larda her DC scavenging yapabilir. Sadece bir DC’nin scavenging yapmasını istiyorsanız diğerlerinde scavenging’i devre dışı bırakın. Aksi takdirde aynı kaydın farklı DC’ler tarafından silme yarışına girdiği garip senaryolar yaşanabilir.

Reverse lookup zone’larını unutmamak. Forward zone’da ageing aktifleştirince reverse zone’u da unutuyoruz çoğu zaman. Her ikisini de yapılandırın.

# Tüm zone'ların ageing durumunu kontrol et
Get-DnsServerZone | Where-Object {$_.ZoneType -eq "Primary"} | ForEach-Object {
    $aging = Get-DnsServerZoneAging -Name $_.ZoneName
    [PSCustomObject]@{
        ZoneName = $_.ZoneName
        AgingEnabled = $aging.AgingEnabled
        NoRefreshInterval = $aging.NoRefreshInterval
        RefreshInterval = $aging.RefreshInterval
    }
} | Format-List

Sonuç

DNS Ageing ve Scavenging, doğru yapılandırıldığında DNS ortamınızı uzun vadede temiz ve sağlıklı tutar. Yanlış yapılandırıldığında ise geçerli kayıtları silerek ciddi kesintilere neden olur. Bu yüzden aceleden kaçının.

Yapılandırmadan önce mutlaka mevcut durumu analiz edin, stale kayıt adaylarını listeleyin ve kritik kayıtları statik yapın. No-Refresh ve Refresh interval’lerini DHCP kira sürelerinizle uyumlu olacak şekilde belirleyin. İlk scavenging çalışması öncesinde ne silineceğini tahmin eden script’i çalıştırın ve listeyi gözden geçirin. Scavenging sonrası event log’ları düzenli olarak izleyin.

Bu mekanizmanın en büyük değeri uzun vadede ortaya çıkar. Yılda bir temizlik yapmak yerine sistem kendini otomatik olarak temizler hale gelir. DNS veritabanı küçülür, zone transfer süreleri kısalır ve en önemlisi troubleshooting sırasında DNS’e güvenebilir hale gelirsiniz.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir