Windows DNS Yedekleme ve Geri Yükleme

DNS sunucunuzu kaybettiğinizde ne olduğunu bir düşünün: iç ağdaki tüm isim çözümleme durur, uygulamalar birbirine bağlanamaz, kullanıcılar hiçbir şeye erişemez. Üstelik bu genellikle Cuma akşamı saat 17:30’da olur. Windows DNS yedekleme konusunu “ileride bakarım” listesinde tutuyorsanız, bu yazı tam size göre. Yıllar içinde onlarca DNS arızasının içinden çıktım ve şunu söyleyebilirim: düzgün bir yedekleme stratejisi olmadan DNS yönetmek, emniyet kemeri takmadan araba kullanmak gibi.

Windows DNS Yedeklemenin Anatomisi

Windows DNS Server, verilerini birkaç farklı yerde saklar. Bunları bilmeden yedekleme yaparsanız, geri yükleme anında “bu dosya nerede?” sorusuyla kendinizi boşlukta bulursunuz.

DNS Zone dosyaları: C:WindowsSystem32dns dizininde .dns uzantılı dosyalar olarak saklanır. Her zone için ayrı bir dosya vardır.

Registry kayıtları: DNS sunucu yapılandırması HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesDNS altında tutulur. Forwarder ayarları, dinleme adresleri, önbellek boyutları hep buradadır.

Active Directory ile entegre zone’lar: Eğer zone’larınız AD-integrated ise, veriler zone dosyalarında değil doğrudan Active Directory veritabanında saklanır. Bu durumda ntds.dit yedeği de kritik hale gelir.

Çoğu sysadmin sadece zone dosyalarını yedekler ve sonra AD-integrated zone’larını geri yükleyemediği için saçını başını yollar. İki senaryoya da hazırlıklı olmak gerekiyor.

Manuel Yedekleme Yöntemleri

Zone Dosyalarını Dosya Sistemi Üzerinden Yedekleme

En basit yöntem budur ama bir önemli nüansı var: zone dosyalarını kopyalamadan önce DNS servisini durdurmak ya da zone’ları dosyaya yazdırmak gerekir. Aksi halde tutarsız veri kopyalayabilirsiniz.

# DNS servisini durdur
net stop "DNS Server"

# Zone dosyalarını yedekle
xcopy /E /I /Y "C:WindowsSystem32dns" "D:BackupDNSzones"

# DNS servisini yeniden başlat
net start "DNS Server"

Ama production ortamında DNS’i durdurmak genellikle kabul edilemez. Daha iyi bir yol var.

DNS Server’ı Zone Dosyalarını Diske Yazmaya Zorlamak

DNS Management Console’dan ya da dnscmd ile zone verilerini diske yazabilirsiniz:

# Tüm zone'ları diske yaz (önbelleği de temizler)
dnscmd /clearcache

# Belirli bir zone'u dosyaya yaz
dnscmd /zonewriteback contoso.local

# Tüm zone'ları dosyaya yaz
dnscmd /writebackfiles

Bu komuttan sonra zone dosyaları güncel hale gelir, ardından kopyalama işlemi güvenle yapılabilir.

Registry Yedekleme

DNS yapılandırmasını registry’den yedeklemek için:

# DNS servis kayıtlarını dışa aktar
reg export "HKLMSYSTEMCurrentControlSetServicesDNS" "D:BackupDNSdns_registry_backup.reg" /y

# Tüm DNS yapılandırmasını dahil et
reg export "HKLMSOFTWAREMicrosoftWindows NTCurrentVersionDNS Server" "D:BackupDNSdns_settings.reg" /y

PowerShell ile Kapsamlı Yedekleme Scripti

İşte gerçek dünyada kullandığım, production’da çalıştırdığım bir script. Bu script hem zone dosyalarını hem registry’yi hem de zone konfigürasyonlarını yedekler:

# DNS-Backup.ps1
# Kapsamli Windows DNS yedekleme scripti

param(
    [string]$BackupPath = "D:BackupDNS",
    [string]$LogFile = "D:BackupDNSlogsdns_backup.log"
)

function Write-Log {
    param([string]$Message, [string]$Level = "INFO")
    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    $logEntry = "[$timestamp] [$Level] $Message"
    Write-Host $logEntry
    Add-Content -Path $LogFile -Value $logEntry
}

# Tarih damgali yedek klasoru olustur
$dateStamp = Get-Date -Format "yyyyMMdd_HHmmss"
$backupDir = Join-Path $BackupPath $dateStamp

New-Item -ItemType Directory -Path $backupDir -Force | Out-Null
New-Item -ItemType Directory -Path (Join-Path $BackupPath "logs") -Force | Out-Null

Write-Log "DNS yedekleme basliyor. Hedef klasor: $backupDir"

# DNS zone'larini diske yaz
Write-Log "Zone dosyalari diske yaziliyor..."
try {
    & dnscmd /writebackfiles
    Write-Log "Zone dosyalari basariyla diske yazildi."
} catch {
    Write-Log "Zone dosyalari diske yazilirken hata: $_" "ERROR"
}

# Zone dosyalarini kopyala
$zoneSource = "C:WindowsSystem32dns"
$zoneDest = Join-Path $backupDir "zones"
New-Item -ItemType Directory -Path $zoneDest -Force | Out-Null

Copy-Item -Path "$zoneSource*.dns" -Destination $zoneDest -Force
Copy-Item -Path "$zoneSource*.log" -Destination $zoneDest -Force -ErrorAction SilentlyContinue
Write-Log "Zone dosyalari kopyalandi: $zoneDest"

# Registry yedegi
$regDest = Join-Path $backupDir "registry"
New-Item -ItemType Directory -Path $regDest -Force | Out-Null

reg export "HKLMSYSTEMCurrentControlSetServicesDNS" `
    "$regDestdns_service.reg" /y 2>&1 | Out-Null
Write-Log "Registry yedegi alindi."

# Zone listesini ve konfigurasyonu kaydet
$dnsZones = Get-DnsServerZone
$zoneConfig = Join-Path $backupDir "zone_config.json"
$dnsZones | Select-Object ZoneName, ZoneType, IsDsIntegrated, IsReverseLookupZone, DynamicUpdate |
    ConvertTo-Json | Out-File $zoneConfig -Encoding UTF8
Write-Log "Zone konfigurasyon listesi kaydedildi: $($dnsZones.Count) zone."

# Forwarder'lari kaydet
$forwarders = Get-DnsServerForwarder
$forwarderConfig = Join-Path $backupDir "forwarders.json"
$forwarders | ConvertTo-Json | Out-File $forwarderConfig -Encoding UTF8
Write-Log "Forwarder konfigurasyonu kaydedildi."

# Eski yedekleri temizle (30 gunden eski)
$oldBackups = Get-ChildItem $BackupPath -Directory |
    Where-Object { $_.CreationTime -lt (Get-Date).AddDays(-30) -and $_.Name -match "^d{8}_" }
foreach ($old in $oldBackups) {
    Remove-Item $old.FullName -Recurse -Force
    Write-Log "Eski yedek silindi: $($old.Name)"
}

Write-Log "DNS yedekleme tamamlandi. Konum: $backupDir"
Write-Output $backupDir

Bu scripti Task Scheduler’a ekleyip gece çalıştırmak işin temelini oluşturur.

Active Directory Entegre Zone’ların Yedeklenmesi

AD-integrated zone’lar için hikaye biraz farklı. Bu zone’lar DomainDnsZones ya da ForestDnsZones uygulama partition’larında saklanır.

# AD-integrated zone'lari kontrol et
Get-DnsServerZone | Where-Object { $_.IsDsIntegrated -eq $true } |
    Select-Object ZoneName, ReplicationScope

# AD replikasyon partitionlarini goruntule
Get-ADReplicationPartnerMetadata -Target (hostname) -Partition "DC=DomainDnsZones,DC=contoso,DC=local"

AD-integrated zone’lar için en güvenilir yedekleme yöntemi, zone’u dosyaya dönüştürmek, yedeklemek, sonra tekrar AD-integrated yapmaktır. Ama daha pratik yol Windows Server Backup ile System State yedeği almaktır.

# System State yedegi al (Windows Server Backup kurulu olmasi gerekir)
$policy = New-WBPolicy
$systemState = New-WBSystemState
Add-WBSystemState -Policy $policy
$backupLocation = New-WBBackupTarget -VolumePath "D:"
Add-WBBackupTarget -Policy $policy -Target $backupLocation
Start-WBBackup -Policy $policy

System State yedeği ntds.dit, SYSVOL, registry ve DNS verilerini içerir. AD-integrated zone’larınız varsa bu yedek olmazsa olmazınızdır.

Geri Yükleme Senaryoları

Senaryo 1: Tek Bir Zone’un Silinmesi

Birisi yanlışlıkla bir zone’u sildi. Bu en sık karşılaşılan durum.

# Yedekten zone dosyasini geri yukle
$backupZoneFile = "D:BackupDNS20241115_020000zonescontoso.local.dns"
$dnsDest = "C:WindowsSystem32dnscontoso.local.dns"

Copy-Item -Path $backupZoneFile -Destination $dnsDest -Force

# Zone'u DNS sunucusuna ekle (Primary, dosyadan)
Add-DnsServerPrimaryZone -Name "contoso.local" `
    -ZoneFile "contoso.local.dns" `
    -DynamicUpdate NonsecureAndSecure

Write-Host "Zone geri yuklendi. DNS Management Console'dan kontrol edin."

Senaryo 2: Kayıt Silme veya Bozulma

Bir zone içindeki kayıtlar bozuldu ama zone’un kendisi sağlam.

# Mevcut zone'u sil ve yedekten geri yukle
$zoneName = "contoso.local"
$backupFile = "D:BackupDNS20241115_020000zonescontoso.local.dns"

# Mevcut zone'u kaldır
Remove-DnsServerZone -Name $zoneName -Force

# Zone dosyasini kopyala
Copy-Item -Path $backupFile -Destination "C:WindowsSystem32dns$zoneName.dns" -Force

# Zone'u yeniden olustur
Add-DnsServerPrimaryZone -Name $zoneName `
    -ZoneFile "$zoneName.dns" `
    -DynamicUpdate Secure

# Servisi yeniden baslat
Restart-Service -Name "DNS" -Force
Write-Host "Zone kayitlari yedekten geri yuklendi."

Senaryo 3: DNS Sunucusunun Komple Çökmesi

Yeni bir sunucu kuruldu, her şeyi sıfırdan kurmak gerekiyor. İşte tam geri yükleme prosedürü:

# Oncelikle DNS Server role'unu kur
Install-WindowsFeature -Name DNS -IncludeManagementTools

# Registry ayarlarini geri yukle
$regBackup = "D:BackupDNS20241115_020000registrydns_service.reg"
reg import $regBackup

# Zone dosyalarini kopyala
$backupZones = "D:BackupDNS20241115_020000zones"
Copy-Item -Path "$backupZones*.dns" -Destination "C:WindowsSystem32dns" -Force

# DNS servisini yeniden baslat
Restart-Service DNS

# Zone'lari dogrula
Start-Sleep -Seconds 5
$zones = Get-DnsServerZone
Write-Host "Yuklenen zone sayisi: $($zones.Count)"
$zones | Select-Object ZoneName, ZoneType | Format-Table -AutoSize

# Forwarder'lari geri yukle
$forwarderConfig = Get-Content "D:BackupDNS20241115_020000forwarders.json" | ConvertFrom-Json
foreach ($fwd in $forwarderConfig.IPAddress) {
    Add-DnsServerForwarder -IPAddress $fwd.IPAddressToString
}
Write-Host "Forwarder'lar geri yuklendi."

Otomatik Yedekleme Zamanlaması

Scripti Task Scheduler’a eklemek için:

# Zamanlanmis gorev olustur
$action = New-ScheduledTaskAction `
    -Execute "PowerShell.exe" `
    -Argument "-NonInteractive -ExecutionPolicy Bypass -File C:ScriptsDNS-Backup.ps1"

$trigger = New-ScheduledTaskTrigger -Daily -At "02:00AM"

$principal = New-ScheduledTaskPrincipal `
    -UserId "SYSTEM" `
    -LogonType ServiceAccount `
    -RunLevel Highest

$settings = New-ScheduledTaskSettingsSet `
    -ExecutionTimeLimit (New-TimeSpan -Hours 1) `
    -RestartCount 3 `
    -RestartInterval (New-TimeSpan -Minutes 5)

Register-ScheduledTask `
    -TaskName "DNS-DailyBackup" `
    -Action $action `
    -Trigger $trigger `
    -Principal $principal `
    -Settings $settings `
    -Description "Gunluk DNS yedekleme gorevi"

Write-Host "Zamanlanmis gorev olusturuldu: Her gece saat 02:00"

Yedeklemenin Doğrulanması

Yedek almak işin yarısı. Asıl kritik kısım yedeğin çalışıp çalışmadığını doğrulamak. Şu kontrolü haftalık çalıştırmayı öneririm:

# DNS-VerifyBackup.ps1
# Yedek dogrulama scripti

param(
    [string]$BackupPath = "D:BackupDNS"
)

$latestBackup = Get-ChildItem $BackupPath -Directory |
    Where-Object { $_.Name -match "^d{8}_" } |
    Sort-Object CreationTime -Descending |
    Select-Object -First 1

if (-not $latestBackup) {
    Write-Warning "Hic yedek bulunamadi! Kontrol edin."
    exit 1
}

$backupAge = (Get-Date) - $latestBackup.CreationTime
Write-Host "Son yedek: $($latestBackup.Name) ($([int]$backupAge.TotalHours) saat once)"

if ($backupAge.TotalHours -gt 25) {
    Write-Warning "UYARI: Son yedek 25 saatten eski! Zamanlanmis gorev kontrol edilmeli."
}

# Zone dosyalarini kontrol et
$zoneFiles = Get-ChildItem (Join-Path $latestBackup.FullName "zones") -Filter "*.dns" -ErrorAction SilentlyContinue
$currentZones = Get-DnsServerZone | Where-Object { -not $_.IsDsIntegrated -and $_.ZoneType -eq "Primary" }

Write-Host "Mevcut primary zone sayisi: $($currentZones.Count)"
Write-Host "Yedekteki zone dosyasi sayisi: $($zoneFiles.Count)"

if ($zoneFiles.Count -lt $currentZones.Count) {
    Write-Warning "UYARI: Yedekteki zone sayisi mevcut zone sayisindan az!"
    $missingZones = $currentZones | Where-Object {
        $_.ZoneName -notin ($zoneFiles.BaseName)
    }
    Write-Host "Eksik zone'lar:"
    $missingZones | ForEach-Object { Write-Host "  - $($_.ZoneName)" }
} else {
    Write-Host "Yedek dogrulama BASARILI: Tum zone'lar mevcut."
}

# Dosya boyutlarini kontrol et
foreach ($zf in $zoneFiles) {
    if ($zf.Length -lt 100) {
        Write-Warning "UYARI: $($zf.Name) dosyasi cok kucuk ($($zf.Length) byte). Bozuk olabilir."
    }
}

Dikkat Edilmesi Gereken Noktalar

Yıllar içinde öğrendiğim birkaç kritik nokta var:

  • Çoklu DNS sunucusu: Primary ve secondary sunucularınızın her ikisini de ayrı ayrı yedekleyin. Secondary zone’lar zone transfer ile gelir ama primary çökerse secondary’yi primary yapıp zone transferini kaybetmek istemezsiniz.
  • dnscmd vs PowerShell DNS modülü: Eski Windows Server sürümlerinde (2008, 2012) PowerShell DNS modülü ya yoktur ya da sınırlıdır. Scriptlerinizin hedef sunucu sürümüyle uyumlu olduğundan emin olun.
  • AD-integrated zone’larda dikkat: Bu zone’ları silip dosyadan geri yüklediğinizde AD üzerindeki replikasyon geçmişini kaybedersiniz. Mümkünse System State restore tercih edin.
  • Yedekleme dizininin izinleri: DNS servisinin çalıştığı hesabın yedekleme dizinine yazma izni olduğundan emin olun. SYSTEM hesabı genellikle yeterli ama ağ paylaşım hedeflerde sorun çıkabilir.
  • Test ortamında dene: Geri yükleme prosedürünüzü production’a dokunmadan önce test VM’de mutlaka deneyin. “Teoride çalışır” demek yetmez, kriz anında kafanız karışmadan adımları bilmeniz gerekir.
  • Zone transfer güvenliği: Secondary sunuculardan zone transfer ayarlarınızı da not edin ve belgeleyin. IP kısıtlamaları varsa bunları geri yükleme sonrasında yeniden yapılandırmanız gerekecek.

Sonuç

Windows DNS yedeklemesi göründüğünden biraz daha karmaşık ama bir kez doğru kurulunca bakımı kolay bir sistem. Özetlemek gerekirse: zone dosyalarını ve registry’yi günlük yedekleyin, AD-integrated zone’larınız varsa System State yedeğini ihmal etmeyin ve her şeyden önemlisi yedeğinizi düzenli olarak test edin.

Bu yazıdaki scriptleri kendi ortamınıza uyarlayın, yolları ve zone isimlerini güncelleyin. Özellikle doğrulama scriptini haftalık çalışacak şekilde zamanlamak, sizi büyük bir krizden kurtarabilir. DNS gibi kritik bir servis için “yedek aldım sanıyordum” demek kabul edilemez bir lüks. Şimdi biraz zaman ayırın, sonra saatler kazanın.

Bir yanıt yazın

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