Zone Dosyası Nasıl Oluşturulur: BIND ile Örnek Yapılandırma

DNS yönetiminin kalbinde zone dosyaları yatar. Bir alan adının IP adresine nasıl çözümleneceğini, mail sunucusunun nerede olduğunu, SPF kayıtlarının ne olduğunu, hepsini zone dosyaları belirler. BIND ile çalışırken zone dosyalarını doğru yapılandırmak hem güvenlik hem de performans açısından kritik önem taşır. Bu yazıda sıfırdan bir zone dosyası oluşturacağız, her satırın ne anlama geldiğini açıklayacağız ve gerçek dünya senaryolarıyla pekiştireceğiz.

Zone Dosyası Nedir ve Neden Önemlidir?

Zone dosyası, bir DNS bölgesi için tüm kaynak kayıtlarını (Resource Records) içeren düz metin dosyasıdır. BIND bu dosyayı okuyarak gelen DNS sorgularına yanıt verir. Yanlış yapılandırılmış bir zone dosyası; mail trafiğinin kaybolmasına, web sitesinin erişilemez hale gelmesine, hatta güvenlik açıklarına yol açabilir.

Zone dosyalarını editörle elle yazmak eski usul ama en öğretici yöntemdir. Her satırın ne işe yaradığını kavradığınızda, herhangi bir DNS yönetim panelini ya da otomasyon aracını çok daha etkin kullanırsınız.

BIND Kurulumu ve Temel Dizin Yapısı

Önce BIND’ın sistemde kurulu olduğundan emin olalım. Debian/Ubuntu için:

sudo apt update
sudo apt install bind9 bind9utils bind9-doc -y

CentOS/RHEL için:

sudo dnf install bind bind-utils -y
sudo systemctl enable named --now

BIND’ın dizin yapısını anlamak önemlidir:

  • /etc/bind/: Ana yapılandırma dizini (Debian/Ubuntu)
  • /etc/named.conf: Ana yapılandırma dosyası (RHEL/CentOS)
  • /var/named/: Zone dosyalarının tutulduğu dizin (RHEL/CentOS)
  • /var/cache/bind/: Zone dosyaları (Debian/Ubuntu)
  • /var/log/named/: Log dosyaları

Sisteminizdeki mevcut yapılandırmayı kontrol edelim:

sudo named-checkconf /etc/bind/named.conf
sudo named-checkzone example.com /var/cache/bind/db.example.com

Bu iki komut zone dosyalarında çalışırken en çok kullanacağınız araçlar olacak. Syntax hatalarını anında yakalarlar.

named.conf İçinde Zone Tanımı

Zone dosyasını oluşturmadan önce BIND’a bu zone’un varlığından haberdar etmemiz gerekir. /etc/bind/named.conf.local dosyasına şu tanımı ekleriz:

zone "example.com" {
    type master;
    file "/var/cache/bind/db.example.com";
    allow-transfer { 192.168.1.2; };  # Slave DNS sunucusu
    notify yes;
};

Buradaki parametreleri açıklayalım:

  • type master: Bu sunucunun zone için yetkili (authoritative) sunucu olduğunu belirtir
  • file: Zone dosyasının tam yolu
  • allow-transfer: Hangi sunucuların zone transfer yapabileceğini kısıtlar (güvenlik için önemlidir)
  • notify yes: Zone güncellendiğinde slave sunucularına bildirim gönderilir

Reverse zone için de benzer bir tanım yapılır. 192.168.1.x bloğu için:

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

Zone Dosyasının Anatomisi: SOA Kaydı

Şimdi asıl zone dosyasını oluşturalım. /var/cache/bind/db.example.com dosyasını açın:

sudo nano /var/cache/bind/db.example.com

İlk olarak SOA (Start of Authority) kaydıyla başlıyoruz:

$TTL 86400
@   IN  SOA ns1.example.com. admin.example.com. (
            2024010101  ; Serial
            3600        ; Refresh
            900         ; Retry
            604800      ; Expire
            86400 )     ; Negative Cache TTL

Her değerin anlamını inceleyelim:

  • $TTL 86400: Varsayılan TTL değeri saniye cinsinden (24 saat). Kayıtların ne kadar süre cache’de tutulacağını belirler
  • @: Mevcut zone adını temsil eder (example.com.)
  • IN: Internet class, her zaman bu olur
  • SOA: Kayıt tipi
  • ns1.example.com.: Primary nameserver (sondaki nokta kritik! FQDN’i belirtir)
  • admin.example.com.: Zone yöneticisinin email adresi ([email protected] anlamına gelir, @ yerine nokta kullanılır)
  • Serial: Zone versiyonu. Slave sunucular bu numarayı karşılaştırarak güncelleme gerekip gerekmediğini anlar. YYYYMMDDNN formatını kullanmak en iyi pratiktir
  • Refresh: Slave sunucunun master’ı ne sıklıkla kontrol edeceği (saniye)
  • Retry: Refresh başarısız olursa ne kadar sonra tekrar deneneceği
  • Expire: Master’a ulaşılamazsa slave’in kendi zone bilgisini ne kadar süre geçerli sayacağı
  • Negative Cache TTL: NXDOMAIN yanıtlarının ne kadar cache’leneceği

NS ve A Kayıtları

SOA’dan sonra nameserver kayıtlarını tanımlarız:

; Nameserver kayıtları
@       IN  NS  ns1.example.com.
@       IN  NS  ns2.example.com.

; Nameserver A kayıtları (glue records)
ns1     IN  A   203.0.113.1
ns2     IN  A   203.0.113.2

; Ana domain A kaydı
@       IN  A   203.0.113.10
www     IN  A   203.0.113.10

; IPv6 AAAA kayıtları
@       IN  AAAA    2001:db8::1
www     IN  AAAA    2001:db8::1

Burada dikkat edilmesi gereken önemli bir nokta var: NS kayıtlarında kullandığınız nameserver isimlerinin A kayıtları da aynı zone dosyasında tanımlanmalıdır. Buna glue record denir ve döngüsel DNS çözümleme sorununu önler.

MX Kayıtları: Mail Sunucusu Yapılandırması

Çoğu sysadmin’in en çok uğraştığı kısım mail kayıtlarıdır. Yanlış MX kaydı direkt olarak mail trafiğinin kesilmesi anlamına gelir:

; MX kayıtları (öncelik değeri düşük olan önce denenir)
@       IN  MX  10  mail1.example.com.
@       IN  MX  20  mail2.example.com.

; Mail sunucuları için A kayıtları
mail1   IN  A   203.0.113.20
mail2   IN  A   203.0.113.21

MX öncelik değerleri (priority) hakkında bilmeniz gerekenler:

  • Düşük sayı = yüksek öncelik: 10 değeri 20’den önce denenir
  • Aynı öncelik değeri verilebilir, bu durumda round-robin yapılır
  • Genellikle 10, 20, 30 gibi onlu artışlarla gitmek esneklik sağlar, araya yeni sunucu eklemeniz kolaylaşır

TXT Kayıtları: SPF, DKIM ve DMARC

Modern mail altyapısı için bu kayıtlar artık zorunlu sayılabilir. Spam engelleyici sistemler bu kayıtlara bakarak mailinizin meşru olup olmadığına karar verir:

; SPF kaydı
@       IN  TXT "v=spf1 ip4:203.0.113.20 ip4:203.0.113.21 include:_spf.google.com ~all"

; DMARC kaydı
_dmarc  IN  TXT "v=DMARC1; p=quarantine; rua=mailto:[email protected]; ruf=mailto:[email protected]; sp=reject; pct=100"

; DKIM kaydı (mail sunucunuzun oluşturduğu public key buraya gelir)
mail._domainkey IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC..."

TXT kayıtlarında dikkat edilmesi gereken bazı noktalar:

  • 255 karakter sınırı: Tek bir TXT string’i 255 karakterle sınırlıdır. Daha uzun değerler için birden fazla string kullanılabilir ve DNS bunları birleştirir
  • Tırnak işaretleri: TXT değerleri çift tırnak içine alınmalıdır
  • Boşluk yönetimi: Uzun DKIM anahtarlarını birden fazla stringe bölmek gerekebilir

CNAME Kayıtları ve Kullanım Senaryoları

CNAME (Canonical Name) kayıtları bir ismi başka bir isme yönlendirir:

; Subdomain yönlendirmeleri
ftp         IN  CNAME   www.example.com.
blog        IN  CNAME   sites.wordpress.com.
shop        IN  CNAME   stores.shopify.com.
autodiscover IN CNAME  autodiscover.outlook.com.

; Google Search Console doğrulama
googleXXXXXXXXXXXXXXXX IN CNAME google.com.

CNAME kullanırken kritik kurallar:

  • Zone apex’te CNAME kullanamazsınız: @ için CNAME tanımlanamaz. example.com doğrudan CNAME olamaz, bunun için ALIAS veya ANAME kaydı gerekir (BIND bunu native desteklemez)
  • MX ve NS hedefi olamaz: MX ve NS kayıtları CNAME’e işaret etmemeli, direkt A kaydına bakmalıdır
  • CNAME zinciri oluşturmaktan kaçının: a.example.com -> b.example.com -> c.example.com performansı düşürür

SRV Kayıtları: Servis Bazlı DNS

SRV kayıtları özellikle VoIP, SIP ve Microsoft servisleri için kullanılır:

; SIP/VoIP için SRV kayıtları
_sip._tcp   IN  SRV 10 20 5060 sip.example.com.
_sip._udp   IN  SRV 10 20 5060 sip.example.com.

; Microsoft Teams/Skype for Business
_sipfederationtls._tcp  IN  SRV 100 1 5061 sipfed.online.lync.com.
_sip._tls               IN  SRV 100 1 443  sipdir.online.lync.com.

SRV kaydı formatı: _servis._protokol TTL IN SRV öncelik ağırlık port hedef

Tam Zone Dosyası Örneği

Şimdiye kadar öğrendiklerimizi bir araya getirerek production’da kullanılabilir tam bir zone dosyası oluşturalım:

$TTL 86400
; example.com zone dosyasi
; Son guncelleme: 2024-01-01
; Yoneticiler: [email protected]

@   IN  SOA ns1.example.com. admin.example.com. (
            2024010101  ; Serial
            3600        ; Refresh (1 saat)
            900         ; Retry (15 dakika)
            604800      ; Expire (1 hafta)
            3600 )      ; Negative Cache TTL (1 saat)

; ========== Nameserver Kayıtları ==========
@       IN  NS      ns1.example.com.
@       IN  NS      ns2.example.com.

; ========== Glue Records ==========
ns1     IN  A       203.0.113.1
ns2     IN  A       203.0.113.2

; ========== Ana Domain ==========
@       IN  A       203.0.113.10
@       IN  AAAA    2001:db8::10

; ========== Web Sunucuları ==========
www     IN  A       203.0.113.10
www     IN  AAAA    2001:db8::10
dev     IN  A       203.0.113.11
staging IN  A       203.0.113.12
api     IN  A       203.0.113.13

; ========== Mail Sunucuları ==========
@       IN  MX  10  mail1.example.com.
@       IN  MX  20  mail2.example.com.
mail1   IN  A       203.0.113.20
mail2   IN  A       203.0.113.21

; ========== TXT / Email Güvenlik ==========
@       IN  TXT "v=spf1 ip4:203.0.113.20 ip4:203.0.113.21 ~all"
_dmarc  IN  TXT "v=DMARC1; p=quarantine; rua=mailto:[email protected]"
mail._domainkey IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3..."

; ========== CNAME Kayıtları ==========
ftp     IN  CNAME   www.example.com.
blog    IN  CNAME   example.wordpress.com.
shop    IN  CNAME   example.myshopify.com.

; ========== Diğer Servisler ==========
vpn     IN  A       203.0.113.30
smtp    IN  A       203.0.113.20
imap    IN  A       203.0.113.20
pop3    IN  A       203.0.113.20

Reverse Zone Dosyası Oluşturma

Forward zone (isimden IP’ye) yeterli değildir. Özellikle mail servisleri için PTR kayıtları (IP’den isme) kritik önem taşır. /var/cache/bind/db.192.168.1 dosyasını oluşturalım:

$TTL 86400
@   IN  SOA ns1.example.com. admin.example.com. (
            2024010101
            3600
            900
            604800
            3600 )

@       IN  NS  ns1.example.com.
@       IN  NS  ns2.example.com.

; PTR kayıtları (sadece son oktet kullanılır)
1       IN  PTR ns1.example.com.
2       IN  PTR ns2.example.com.
10      IN  PTR example.com.
20      IN  PTR mail1.example.com.
21      IN  PTR mail2.example.com.

PTR kayıtlarını ISP’nizden veya hosting firmanızdan talep etmeniz gerekebilir. IP bloğunun sahibi kimse, reverse zone’u o yönetir.

Zone Dosyası Değişikliklerini Uygulama

Zone dosyasını her güncellediğinizde serial numarasını artırmayı unutmayın. Bu adım atlandığında slave sunucular güncellemeyi fark etmez:

# Syntax kontrolü yapalım
sudo named-checkzone example.com /var/cache/bind/db.example.com

# Her şey yolundaysa BIND'ı reload edelim
sudo rndc reload example.com

# Veya tüm zone'ları reload etmek için
sudo rndc reload

# BIND servisini tamamen yeniden başlatmak gerekirse
sudo systemctl reload bind9

Zone dosyası doğrulamasından sonra DNS’in düzgün çalıştığını test edelim:

# A kaydı sorgusu
dig @localhost example.com A

# MX kaydı sorgusu
dig @localhost example.com MX

# TXT kayıtları
dig @localhost example.com TXT

# Reverse lookup
dig @localhost -x 203.0.113.10

# BIND istatistikleri
sudo rndc stats
cat /var/cache/bind/named_stats.txt

Serial Numarası Yönetimi

Serial numarası yönetimi genellikle unutulan ama kritik bir konudur. Önerilen format YYYYMMDDNN‘dir:

  • 2024010101: 2024 yılı, Ocak ayı, 1. günü, o gündeki 1. değişiklik
  • 2024010102: Aynı gün yapılan 2. değişiklik

Scriptle otomatik serial güncelleme yapmak isteyebilirsiniz:

#!/bin/bash
# update_serial.sh - Zone dosyasındaki serial'i otomatik güncelle

ZONE_FILE="/var/cache/bind/db.example.com"
TODAY=$(date +%Y%m%d)

# Mevcut serial'i oku
CURRENT_SERIAL=$(grep -oP '(?<=(s{12})d+' "$ZONE_FILE" | head -1)
CURRENT_DATE=${CURRENT_SERIAL:0:8}
CURRENT_SEQ=${CURRENT_SERIAL:8:2}

if [ "$CURRENT_DATE" == "$TODAY" ]; then
    # Aynı gün, sequence'i artır
    NEW_SEQ=$(printf "%02d" $((10#$CURRENT_SEQ + 1)))
    NEW_SERIAL="${TODAY}${NEW_SEQ}"
else
    # Yeni gün, 01'den başla
    NEW_SERIAL="${TODAY}01"
fi

# Dosyayı güncelle
sed -i "s/$CURRENT_SERIAL/$NEW_SERIAL/" "$ZONE_FILE"
echo "Serial $CURRENT_SERIAL -> $NEW_SERIAL olarak güncellendi"

# Syntax kontrolü
named-checkzone example.com "$ZONE_FILE"
if [ $? -eq 0 ]; then
    rndc reload example.com
    echo "Zone başarıyla reload edildi"
else
    # Hata varsa eski haline döndür
    sed -i "s/$NEW_SERIAL/$CURRENT_SERIAL/" "$ZONE_FILE"
    echo "Syntax hatası! Değişiklik geri alındı"
fi

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

Zone dosyalarında yapılan hatalar genellikle belirli kategorilerde toplanır:

Nokta unutma (FQDN hatası): NS, MX ve PTR kayıtlarındaki hedeflerin sonunda nokta olmalıdır. ns1.example.com yerine ns1.example.com. yazılmalıdır. Nokta unutulursa BIND bunu ns1.example.com.example.com. olarak yorumlar.

Serial güncelleme atlatma: Zone dosyasını değiştirip serial’i artırmayı unutmak. Slave sunucular güncellemeyi almaz.

TTL değerlerinin yanlış hesaplanması: Saniye cinsinden değerler girilmeli. 1 saat = 3600, 1 gün = 86400, 1 hafta = 604800.

Büyük/küçük harf tutarsızlığı: DNS büyük/küçük harf duyarsızdır ama zone dosyası içinde tutarlı olmak okunabilirliği artırır.

Tab ve boşluk karışımı: Bazı BIND versiyonları tab ile boşluk karışımına toleranssızdır. Tutarlı girintileme kullanın.

BIND loglarını izleyerek hataları yakalamak için:

# Gerçek zamanlı log takibi
sudo tail -f /var/log/syslog | grep named

# Veya journalctl ile
sudo journalctl -u named -f

# Belirli bir zone için debug
sudo rndc trace

Sonuç

Zone dosyası oluşturmak başta karmaşık görünse de her kaydın mantığını kavradığınızda oldukça sistematik bir hal alıyor. SOA ile zone otoritesini tanımlıyorsunuz, NS ile nameserver’ları bildiriyorsunuz, A/AAAA ile IP eşleştirmelerini yapıyorsunuz, MX ile mail trafiğini yönlendiriyorsunuz ve TXT ile mail güvenliğini sağlıyorsunuz.

Pratikte en çok hatırlatmak istediğim şey: her değişiklikten önce backup alın, her değişiklikten sonra named-checkzone çalıştırın ve serial numarasını asla unutmayın. Bu üç kuralı uygularsanız DNS kaynaklı üretim sorunlarının büyük çoğunluğundan kaçınmış olursunuz.

Bir sonraki adım olarak DNSSEC (DNS Security Extensions) yapılandırmasını ve zone transfer güvenliğini inceleyebilirsiniz. Zone dosyalarını şifreleme altyapısıyla güçlendirmek, özellikle kurumsal ortamlarda artık neredeyse zorunlu hale geldi.

Yorum yapın