Master-Slave BIND Yapılandırması ile DNS Yedekleme

DNS altyapınızda tek bir sunucu çalıştırmak, küçük bir test ortamı için kabul edilebilir olabilir. Ancak production ortamında bu yaklaşım, felaket reçetesi yazmaktan farksızdır. Sunucu çöktüğünde, ağ bağlantısı kesildiğinde ya da bakım yapmanız gerektiğinde tüm alan adı çözümlemeleriniz durur ve bu da kullanıcılarınızın hiçbir şeye erişememesi anlamına gelir. İşte bu noktada Master-Slave BIND yapılandırması devreye girer.

Bu yazıda, gerçek bir production ortamında nasıl sağlam bir DNS yedekleme mimarisi kurulacağını adım adım anlatacağım. Hem master hem de slave tarafındaki yapılandırmaları, zone transfer mekanizmasını, güvenlik önlemlerini ve izleme stratejilerini ele alacağız.

Master-Slave DNS Mimarisi Nasıl Çalışır?

Temel mantığı anlamadan yapılandırmaya dalmak, ileride sorun giderme süreçlerinde sizi çok zorlayabilir. O yüzden kısa bir teorik zemin oluşturalım.

Master DNS sunucusu (ya da RFC 2136 ile gelen terminolojiye göre “Primary”), zone dosyalarının yetkili kopyasını barındırır. Yöneticiler tüm DNS kayıtlarını burada düzenler. Slave DNS sunucusu (“Secondary” olarak da bilinir) ise bu zone verilerini master’dan alır ve kendi üzerinde tutar. Bu işleme zone transfer denir.

Zone transfer iki şekilde gerçekleşir:

  • AXFR (Full Zone Transfer): Tüm zone dosyası sıfırdan aktarılır. İlk kurulumda ve zone verisi tamamen değiştiğinde kullanılır.
  • IXFR (Incremental Zone Transfer): Yalnızca son transferden bu yana değişen kayıtlar aktarılır. Büyük zone dosyaları için çok daha verimlidir.

Master sunucu, zone dosyasında değişiklik olduğunda slave sunuculara NOTIFY mesajı gönderir. Slave sunucu bu mesajı aldığında SOA kaydını kontrol eder ve serial numarası arttıysa zone transfer başlatır.

Senaryo ve Lab Ortamı

Bu yazı boyunca şu ortamı kullanacağız:

  • Master DNS: 192.168.1.10 (ns1.ornekfirma.com)
  • Slave DNS: 192.168.1.20 (ns2.ornekfirma.com)
  • Alan adı: ornekfirma.com
  • İşletim sistemi: Ubuntu 22.04 LTS (her iki sunucu için)

Gerçek dünyada bu iki sunucunun farklı veri merkezlerinde veya en azından farklı switch’lere bağlı olması gerekir. Aynı fiziksel rack’teki iki sunucuyu master-slave yapmanız, o rack’in güç kaybetmesi durumunda sizi kurtarmaz.

BIND Kurulumu

Her iki sunucuya da BIND9 kurmanız gerekiyor. Bu adım her iki taraf için aynı:

sudo apt update && sudo apt upgrade -y
sudo apt install bind9 bind9utils bind9-doc dnsutils -y

# Servisi başlat ve otomatik başlatmayı etkinleştir
sudo systemctl enable --now named

# Durumu kontrol et
sudo systemctl status named

BIND’ın IPv4 modunda çalışması için başlangıç ayarlarını da düzenleyelim. Özellikle IPv6 yapılandırması olmayan ortamlarda bu önemlidir:

sudo nano /etc/default/named

Dosyanın içeriğini şu şekilde ayarlayın:

# Sadece IPv4 kullan
OPTIONS="-u bind -4"

Master Sunucu Yapılandırması

Master sunucuda yapacağımız işler üç ana kategoriye ayrılır: ana yapılandırma dosyası, zone tanımlamaları ve zone dosyalarının kendisi.

named.conf.options Ayarları

sudo nano /etc/bind/named.conf.options
acl "trusted" {
    192.168.1.0/24;    # İç ağ
    127.0.0.1;          # Localhost
    192.168.1.20;       # Slave DNS sunucusu
};

options {
    directory "/var/cache/bind";

    # Yalnızca güvenilir IP'lerden sorgu kabul et
    allow-query { trusted; };

    # Zone transferine yalnızca slave'in erişmesine izin ver
    allow-transfer { 192.168.1.20; };

    # Slave'e değişiklikleri bildir
    notify yes;
    also-notify { 192.168.1.20; };

    # Recursion sadece iç ağdan
    recursion yes;
    allow-recursion { trusted; };

    # DNSSEC doğrulama
    dnssec-validation auto;

    # Dinleme adresleri
    listen-on { 192.168.1.10; 127.0.0.1; };
    listen-on-v6 { none; };

    # Versiyon bilgisini gizle (güvenlik)
    version "not disclosed";
};

Bu yapılandırmada dikkat etmeniz gereken birkaç kritik nokta var. allow-transfer direktifi, zone transferinin yalnızca slave sunucunuzdan gelebileceğini garanti eder. Eğer bunu kısıtlamazsanız, herhangi bir kişi zone dosyanızın tamamını çekebilir; bu da ağ topolojinizi ifşa eder.

Zone Tanımlamaları

sudo nano /etc/bind/named.conf.local
# İleri (forward) zone tanımı
zone "ornekfirma.com" {
    type master;
    file "/etc/bind/zones/db.ornekfirma.com";
    allow-transfer { 192.168.1.20; };
    also-notify { 192.168.1.20; };
    notify yes;
};

# Geri (reverse) zone tanımı
zone "1.168.192.in-addr.arpa" {
    type master;
    file "/etc/bind/zones/db.192.168.1";
    allow-transfer { 192.168.1.20; };
    also-notify { 192.168.1.20; };
    notify yes;
};

Zone Dosyalarının Oluşturulması

Önce zone dosyaları için bir dizin oluşturalım:

sudo mkdir /etc/bind/zones

Şimdi forward zone dosyasını oluşturalım:

sudo nano /etc/bind/zones/db.ornekfirma.com
$TTL    86400
@       IN      SOA     ns1.ornekfirma.com. admin.ornekfirma.com. (
                        2024011501  ; Serial (YYYYMMDDnn formatı)
                        3600        ; Refresh - Slave ne sıklıkla kontrol etsin (1 saat)
                        1800        ; Retry - Transfer başarısız olursa ne kadar sonra tekrar denesin (30 dk)
                        604800      ; Expire - Master erişilemezse slave ne kadar süre veri sunsun (1 hafta)
                        86400 )     ; Negative Cache TTL (1 gün)

; Name server kayıtları
@       IN      NS      ns1.ornekfirma.com.
@       IN      NS      ns2.ornekfirma.com.

; Name server IP adresleri (glue records)
ns1     IN      A       192.168.1.10
ns2     IN      A       192.168.1.20

; A kayıtları
@       IN      A       192.168.1.100
www     IN      A       192.168.1.100
mail    IN      A       192.168.1.110
ftp     IN      A       192.168.1.120

; MX kaydı
@       IN      MX      10      mail.ornekfirma.com.

; CNAME kayıtları
webmail IN      CNAME   mail.ornekfirma.com.

SOA kaydındaki serial numarasına özellikle dikkat edin. Her zone değişikliğinde bu numarayı artırmanız zorunludur. Aksi takdirde slave sunucu değişikliklerin farkına varmaz ve eski verileri sunmaya devam eder. Ben genellikle YYYYMMDDnn formatını kullanırım; tarih tabanlı olduğu için yönetimi kolaylaşır.

Reverse zone dosyasını da oluşturalım:

sudo nano /etc/bind/zones/db.192.168.1
$TTL    86400
@       IN      SOA     ns1.ornekfirma.com. admin.ornekfirma.com. (
                        2024011501  ; Serial
                        3600        ; Refresh
                        1800        ; Retry
                        604800      ; Expire
                        86400 )     ; Negative Cache TTL

@       IN      NS      ns1.ornekfirma.com.
@       IN      NS      ns2.ornekfirma.com.

; PTR kayıtları
10      IN      PTR     ns1.ornekfirma.com.
20      IN      PTR     ns2.ornekfirma.com.
100     IN      PTR     www.ornekfirma.com.
110     IN      PTR     mail.ornekfirma.com.
120     IN      PTR     ftp.ornekfirma.com.

Yapılandırmayı Test Etme ve Servisi Yeniden Başlatma

Herhangi bir syntax hatası yapmış olabileceğinizi düşünürsek, doğrulama adımını atlamak büyük bir hata olur:

# Genel yapılandırmayı kontrol et
sudo named-checkconf

# Zone dosyalarını kontrol et
sudo named-checkzone ornekfirma.com /etc/bind/zones/db.ornekfirma.com
sudo named-checkzone 1.168.192.in-addr.arpa /etc/bind/zones/db.192.168.1

# Hata yoksa servisi yeniden başlat
sudo systemctl restart named

# Log'ları kontrol et
sudo journalctl -u named -f

named-checkzone komutu başarılı olduğunda OK çıktısı göreceksiniz. Herhangi bir hata varsa, satır numarası ile birlikte hangi sorun olduğunu açıkça belirtir.

Slave Sunucu Yapılandırması

Slave tarafındaki yapılandırma daha basittir çünkü zone verilerini kendiniz oluşturmazsınız; bunlar master’dan otomatik olarak gelir.

named.conf.options (Slave)

sudo nano /etc/bind/named.conf.options
acl "trusted" {
    192.168.1.0/24;
    127.0.0.1;
    192.168.1.10;   # Master DNS sunucusu
};

options {
    directory "/var/cache/bind";

    allow-query { trusted; };

    # Slave sunucu zone transfer başlatmaz, sadece alır
    allow-transfer { none; };

    recursion yes;
    allow-recursion { trusted; };

    dnssec-validation auto;

    listen-on { 192.168.1.20; 127.0.0.1; };
    listen-on-v6 { none; };

    version "not disclosed";
};

Zone Tanımlamaları (Slave)

sudo nano /etc/bind/named.conf.local
zone "ornekfirma.com" {
    type slave;
    file "/var/cache/bind/db.ornekfirma.com";
    masters { 192.168.1.10; };
};

zone "1.168.192.in-addr.arpa" {
    type slave;
    file "/var/cache/bind/db.192.168.1";
    masters { 192.168.1.10; };
};

Dikkat ederseniz slave’de zone dosyalarının konumu /var/cache/bind/ altında. Bu, BIND’ın çalışma zamanında yazabileceği bir dizindir. Master’dan alınan zone dosyaları buraya kaydedilir ve sunucu yeniden başlatıldığında diskten okunur; bu sayede master erişilemez olsa bile slave yeniden başlatma sonrasında veri sunmaya devam edebilir.

Slave’de yapılandırmayı kontrol edip servisi başlatın:

sudo named-checkconf
sudo systemctl restart named
sudo journalctl -u named -f

Log’larda şuna benzer bir çıktı görmelisiniz:

zone ornekfirma.com/IN: Transfer started.
zone ornekfirma.com/IN: transferred serial 2024011501
zone ornekfirma.com/IN: sending notifies (serial 2024011501)

TSIG ile Zone Transfer Güvenliği

Yukarıdaki yapılandırma IP tabanlı kısıtlama kullanıyor. Bu iyi bir başlangıç olmakla birlikte, IP spoofing saldırılarına karşı savunmasız olabilir. TSIG (Transaction Signature) kullanmak, zone transferlerini kriptografik olarak imzalamanızı sağlar.

Master sunucuda TSIG anahtarı oluşturun:

# Master sunucuda çalıştırın
sudo tsig-keygen -a hmac-sha256 tsig-key

Bu komut aşağıdaki gibi bir çıktı verir:

key "tsig-key" {
    algorithm hmac-sha256;
    secret "buraya-otomatik-olusturulan-base64-anahtar-gelir==";
};

Bu çıktıyı hem master hem de slave’de /etc/bind/named.conf.local dosyasına ekleyin. Ardından zone tanımlarınızı güncelleyin:

# Master'da named.conf.local'e ekle
key "tsig-key" {
    algorithm hmac-sha256;
    secret "buraya-otomatik-olusturulan-base64-anahtar-gelir==";
};

zone "ornekfirma.com" {
    type master;
    file "/etc/bind/zones/db.ornekfirma.com";
    allow-transfer { key tsig-key; };
    also-notify { 192.168.1.20; };
};
# Slave'de named.conf.local'e ekle
key "tsig-key" {
    algorithm hmac-sha256;
    secret "buraya-otomatik-olusturulan-base64-anahtar-gelir==";
};

zone "ornekfirma.com" {
    type slave;
    file "/var/cache/bind/db.ornekfirma.com";
    masters { 192.168.1.10 key tsig-key; };
};

Zone Güncelleme Sonrası Yapılması Gerekenler

Bir zone kaydını her güncellediğinizde şu süreci takip etmelisiniz. Bunu bir checklist olarak aklınıza kazıyın:

# 1. Zone dosyasını düzenle
sudo nano /etc/bind/zones/db.ornekfirma.com

# 2. Serial numarasını artır (çok önemli!)
# Örnek: 2024011501 -> 2024011502

# 3. Syntax kontrolü yap
sudo named-checkzone ornekfirma.com /etc/bind/zones/db.ornekfirma.com

# 4. BIND'ı yeniden yükle (restart değil, reload!)
sudo rndc reload ornekfirma.com

# 5. Zone transfer'ın gerçekleştiğini doğrula
sudo rndc reload
dig @192.168.1.20 ornekfirma.com SOA

reload ile restart arasındaki farka dikkat edin. restart servisi tamamen durdurup yeniden başlatır; bu sürede DNS yanıt vermez. reload ise mevcut bağlantıları kesmeden yapılandırmayı yeniden yükler.

Yapılandırmayı Doğrulama ve Test

Her şeyi kurduktan sonra sisteminizin beklendiği gibi çalıştığını doğrulamanız gerekir:

# Master'dan sorgulama
dig @192.168.1.10 ornekfirma.com SOA
dig @192.168.1.10 www.ornekfirma.com A

# Slave'den sorgulama (aynı sonuçları vermeli)
dig @192.168.1.20 ornekfirma.com SOA
dig @192.168.1.20 www.ornekfirma.com A

# Serial numaralarının eşleştiğini kontrol et
dig @192.168.1.10 ornekfirma.com SOA +short
dig @192.168.1.20 ornekfirma.com SOA +short

# Reverse zone testi
dig @192.168.1.10 -x 192.168.1.100
dig @192.168.1.20 -x 192.168.1.100

# Zone transfer'ı doğrudan test et (güvenlik için üretimde bunu kısıtlayın)
dig @192.168.1.10 ornekfirma.com AXFR

İki sunucudaki SOA kaydının serial numarası eşleşmiyorsa, zone transfer henüz tamamlanmamış ya da bir sorun var demektir. Log dosyalarını incelemeniz gerekir:

# Master log'ları
sudo tail -f /var/log/syslog | grep named

# Ya da journalctl ile
sudo journalctl -u named -n 50

Firewall Kuralları

DNS güvenliğinin kritik bir parçası olan firewall yapılandırmasını da unutmayalım:

# Her iki sunucuda DNS sorgularına izin ver (UDP ve TCP)
sudo ufw allow from 192.168.1.0/24 to any port 53 proto udp
sudo ufw allow from 192.168.1.0/24 to any port 53 proto tcp

# Master sunucuda: Slave'den gelen zone transfer isteklerine izin ver
# (TCP 53 zaten açık, ek kural gerekmez genellikle)

# UFW'yi etkinleştir
sudo ufw enable
sudo ufw status

Slave’in Bağımsız Çalışması

Gerçek bir felaket senaryosunu test etmek iyi bir alışkanlıktır. Master sunucuyu durdurun ve slave’in hala yanıt verip vermediğini kontrol edin:

# Master sunucuda BIND'ı durdur
sudo systemctl stop named

# Slave sunucudan sorgu yap
dig @192.168.1.20 www.ornekfirma.com A

# Yanıt gelmeli! SOA'daki Expire süresi dolana kadar slave veri sunmaya devam eder

SOA kaydındaki Expire değeri (bizim örneğimizde 604800 saniye, yani 1 hafta), master erişilemez olsa bile slave’in ne kadar süre zone verilerini yetkili kabul edeceğini belirler. Bu süre dolduğunda slave artık bu zone için yanıt vermez. Production ortamınızda bu değeri dikkatli seçin; çok kısa tutarsanız kısa süreli master kesintilerinde bile sorun yaşarsınız.

İzleme ve Uyarı Sistemi

Kurduğunuz sistemin sağlıklı çalıştığından emin olmak için basit bir izleme scripti yazalım. Bu scripti her iki sunucuda da cron ile çalıştırabilirsiniz:

sudo nano /usr/local/bin/dns-monitor.sh
#!/bin/bash

MASTER="192.168.1.10"
SLAVE="192.168.1.20"
ZONE="ornekfirma.com"
EMAIL="[email protected]"
LOG="/var/log/dns-monitor.log"

timestamp() {
    date "+%Y-%m-%d %H:%M:%S"
}

# Master ve Slave'den SOA serial'larını al
MASTER_SERIAL=$(dig @$MASTER $ZONE SOA +short | awk '{print $3}')
SLAVE_SERIAL=$(dig @$SLAVE $ZONE SOA +short | awk '{print $3}')

echo "$(timestamp) - Master Serial: $MASTER_SERIAL, Slave Serial: $SLAVE_SERIAL" >> $LOG

# Serial uyuşmazlığı kontrolü
if [ "$MASTER_SERIAL" != "$SLAVE_SERIAL" ]; then
    MSG="UYARI: $ZONE zone'u icin serial uyusmazligi! Master: $MASTER_SERIAL, Slave: $SLAVE_SERIAL"
    echo "$(timestamp) - $MSG" >> $LOG
    echo "$MSG" | mail -s "DNS Zone Transfer Sorunu" $EMAIL
fi

# Slave erişilebilirlik kontrolü
if ! dig @$SLAVE $ZONE SOA +short &>/dev/null; then
    MSG="KRITIK: Slave DNS sunucusu ($SLAVE) erisilemir!"
    echo "$(timestamp) - $MSG" >> $LOG
    echo "$MSG" | mail -s "Slave DNS Erisilemez" $EMAIL
fi

# Master erişilebilirlik kontrolü
if ! dig @$MASTER $ZONE SOA +short &>/dev/null; then
    MSG="KRITIK: Master DNS sunucusu ($MASTER) erisilemir!"
    echo "$(timestamp) - $MSG" >> $LOG
    echo "$MSG" | mail -s "Master DNS Erisilemez" $EMAIL
fi
sudo chmod +x /usr/local/bin/dns-monitor.sh

# Cron'a ekle - her 5 dakikada bir çalıştır
echo "*/5 * * * * root /usr/local/bin/dns-monitor.sh" | sudo tee -a /etc/cron.d/dns-monitor

Sık Yapılan Hatalar ve Çözümleri

Yıllar içinde gördüğüm en yaygın sorunları ve çözümlerini paylaşayım:

Serial numarasını güncellemek unutmak: Slave sunucu değişikliği almadığında ilk bakılacak yer budur. Her zaman zone dosyasını düzenledikten sonra serial’ı artırın.

named-checkzone yapmadan reload: Hatalı bir zone dosyası tüm zone’un yanıt vermemesine yol açar. Her zaman önce kontrol edin.

Güvenlik duvarında TCP 53’ü kapatmak: Zone transfer TCP üzerinden çalışır. Sadece UDP 53’ü açmak zone transferini engeller. Her iki protokolün de açık olduğundan emin olun.

Slave zone dosyası dizin izinleri: /var/cache/bind/ dizini bind kullanıcısı tarafından yazılabilir olmalıdır. Aksi takdirde zone dosyaları diske kaydedilemez.

# İzin sorununu kontrol et ve düzelt
ls -la /var/cache/bind/
sudo chown -R bind:bind /var/cache/bind/

Refresh süresini çok uzun tutmak: Eğer NOTIFY çalışmıyorsa slave, Refresh süresi dolana kadar güncelleme almaz. Test ortamında Refresh’i düşük tutup production’da makul bir değere alın.

Sonuç

Master-Slave BIND yapılandırması, DNS altyapınızın omurgasını oluşturur. Doğru kurulduğunda tek bir noktanın çökmesi tüm DNS hizmetinizi etkilemez; slave sunucu devreye girer ve kullanıcılarınız hiçbir şeyin farkına varmaz.

Bu yazıda ele aldığımız konuları özetlersek: BIND kurulumunu her iki sunucuda tamamladık, master tarafında zone dosyaları ve güvenli transfer ayarlarını yapılandırdık, slave tarafında otomatik zone senkronizasyonunu kurduk, TSIG ile transfer güvenliğini güçlendirdik ve basit bir izleme mekanizması oluşturduk.

Bundan sonraki adımlarınız için şunları öneririm: DNSSEC ile zone imzalamayı öğrenin, birden fazla slave sunucu ekleyerek coğrafi dağılım sağlayın ve Nagios, Zabbix ya da Prometheus gibi profesyonel izleme araçlarını entegre edin. DNS altyapınız ne kadar sağlam olursa, geceleri o kadar rahat uyursunuz.

Yorum yapın