DNS dünyasına yeni adım atan sysadminlerin kafasını en çok karıştıran konulardan biri, recursive ve authoritative DNS sunucuları arasındaki fark. “Neden iki farklı DNS sunucusu türü var? Aynı şeyi yapmıyorlar mı?” sorusu oldukça yaygın. Bu yazıda hem teorik farkı netleştireceğiz hem de BIND9 üzerinde her iki türü nasıl kurup yapılandıracağınızı adım adım göstereceğiz.
Recursive ve Authoritative DNS: Temel Fark Ne?
Önce şunu netleştirelim: Bu iki sunucu türü DNS ekosisteminde tamamen farklı roller üstlenir.
Authoritative DNS sunucusu, belirli bir DNS zone’u için kesin ve resmi cevap veren sunucudur. Örneğin example.com zone’unun authoritative sunucusu, www.example.com‘un hangi IP adresine işaret ettiğini kesin olarak bilir. Cevabını başka bir sunucudan sormaz, kendi zone dosyasına bakarak doğrudan verir.
Recursive DNS sunucusu ise istemcilerden gelen sorguları alır ve cevabı bulmak için DNS hiyerarşisinde gezinir. İstemci “google.com’un IP’si ne?” diye sorar, recursive sunucu root sunucularından başlayarak cevabı bulur ve istemciye iletir. Kendi başına hiçbir zone’a sahip değildir, aracı rolündedir.
Pratik dünyada şöyle düşünebilirsiniz: Authoritative sunucu bir sözlük gibidir, içindeki bilgilerin kaynağıdır. Recursive sunucu ise kütüphaneci gibidir, hangi sözlükte ne arayacağını bilir ve sizin için getirir.
Güvenlik Perspektifinden Bakış
Bu ayrımı neden önemsemek gerekir? Çünkü bir DNS sunucusunun hem recursive hem authoritative çalışması ciddi güvenlik riskleri doğurur. İnternetten gelen isteklere recursive cevap veren bir sunucu, DNS amplification saldırılarında kullanılabilir. Bu yüzden üretim ortamlarında bu iki rolü kesinlikle ayırmanız gerekir.
Ortam Hazırlığı
Bu yazıda Ubuntu 22.04 LTS üzerinde çalışacağız. Senaryo olarak küçük bir şirket ortamı kuracağız:
192.168.1.10– Authoritative DNS sunucusu (ns1.example.local)192.168.1.11– Recursive (caching) DNS sunucusu192.168.1.0/24– İç ağ
İlk olarak her iki sunucuya da BIND9 kuruyoruz:
sudo apt update && sudo apt install -y bind9 bind9utils bind9-doc
sudo systemctl enable --now named
sudo systemctl status named
Kurulum sonrası ana yapılandırma dosyasının yerini kontrol edelim:
ls -la /etc/bind/
# named.conf -> Ana yapılandırma
# named.conf.options -> Genel seçenekler
# named.conf.local -> Yerel zone tanımları
# named.conf.default-zones -> Root, localhost gibi varsayılan zone'lar
Authoritative DNS Sunucusu Yapılandırması
Authoritative sunucumuzda (192.168.1.10) önce named.conf.options dosyasını düzenliyoruz. Bu sunucu sadece kendi zone’larına cevap verecek, başkası adına recursive sorgu yapmayacak.
sudo nano /etc/bind/named.conf.options
options {
directory "/var/cache/bind";
# Recursive sorguları tamamen kapat
recursion no;
# Sadece kendi zone'larına authoritative cevap ver
allow-query { any; };
# Transfer sadece secondary sunucuya izin ver
allow-transfer { 192.168.1.12; };
# DNSSEC doğrulama
dnssec-validation auto;
# Versiyon bilgisini gizle (güvenlik)
version "not available";
listen-on { 192.168.1.10; };
listen-on-v6 { none; };
};
Şimdi named.conf.local dosyasına zone tanımlarımızı ekliyoruz:
sudo nano /etc/bind/named.conf.local
# Forward zone - example.local
zone "example.local" {
type master;
file "/etc/bind/zones/db.example.local";
allow-transfer { 192.168.1.12; };
notify yes;
};
# Reverse zone - 192.168.1.x için
zone "1.168.192.in-addr.arpa" {
type master;
file "/etc/bind/zones/db.192.168.1";
allow-transfer { 192.168.1.12; };
};
Zone dosyaları için dizin oluşturup forward zone dosyasını yazalım:
sudo mkdir -p /etc/bind/zones
sudo nano /etc/bind/zones/db.example.local
$TTL 86400
@ IN SOA ns1.example.local. admin.example.local. (
2024010101 ; Serial (YYYYMMDDSS formatı)
3600 ; Refresh - secondary ne sıklıkla kontrol etsin
1800 ; Retry - başarısız olursa ne kadar beklesin
604800 ; Expire - secondary ne kadar sonra zone'u geçersiz saysın
86400 ) ; Negative TTL
; Name Server kayıtları
@ IN NS ns1.example.local.
@ IN NS ns2.example.local.
; A kayıtları
ns1 IN A 192.168.1.10
ns2 IN A 192.168.1.12
gateway IN A 192.168.1.1
www IN A 192.168.1.20
mail IN A 192.168.1.30
app01 IN A 192.168.1.40
app02 IN A 192.168.1.41
; CNAME kayıtları
webmail IN CNAME mail.example.local.
intranet IN CNAME www.example.local.
; MX kaydı
@ IN MX 10 mail.example.local.
; TXT kaydı (SPF için örnek)
@ IN TXT "v=spf1 ip4:192.168.1.30 -all"
Reverse zone dosyasını da oluşturalım:
sudo nano /etc/bind/zones/db.192.168.1
$TTL 86400
@ IN SOA ns1.example.local. admin.example.local. (
2024010101
3600
1800
604800
86400 )
@ IN NS ns1.example.local.
@ IN NS ns2.example.local.
; PTR kayıtları (sadece son oktet)
1 IN PTR gateway.example.local.
10 IN PTR ns1.example.local.
12 IN PTR ns2.example.local.
20 IN PTR www.example.local.
30 IN PTR mail.example.local.
40 IN PTR app01.example.local.
41 IN PTR app02.example.local.
Yapılandırmayı doğrulayıp servisi başlatıyoruz:
# Syntax kontrolü
sudo named-checkconf
# Zone dosyası kontrolü
sudo named-checkzone example.local /etc/bind/zones/db.example.local
sudo named-checkzone 1.168.192.in-addr.arpa /etc/bind/zones/db.192.168.1
# Servisi yeniden başlat
sudo systemctl restart named
# Log kontrol
sudo journalctl -u named -f
Authoritative Sunucuyu Test Etme
# Authoritative cevap alıyoruz
dig @192.168.1.10 www.example.local A
# Cevabın authoritative olduğunu "aa" flag'iyle doğrulayın
# ;; flags: qr aa rd; QUERY: 1, ANSWER: 1
# Reverse lookup test
dig @192.168.1.10 -x 192.168.1.20
# Recursive sorgunun reddedildiğini test et
dig @192.168.1.10 google.com
# SERVFAIL ya da REFUSED dönmeli
dig çıktısında aa (Authoritative Answer) flag’ini görmeniz, sunucunun bu zone için kesin kaynak olduğunu doğrular. Eğer google.com sorgusu REFUSED dönüyorsa yapılandırmanız doğru demektir.
Recursive DNS Sunucusu Yapılandırması
İkinci sunucumuz (192.168.1.11) iç ağdaki istemcilerin DNS çözümleyicisi olacak. İnternetteki alan adlarını çözümleyecek ama kendi zone’u olmayacak. Öte yandan example.local için authoritative sunucuya yönlendireceğiz (forwarder olarak değil, conditional forwarding ile).
sudo nano /etc/bind/named.conf.options
options {
directory "/var/cache/bind";
# Recursive sorguları etkinleştir
recursion yes;
# Sadece iç ağdan gelen sorgulara izin ver - kritik güvenlik ayarı!
allow-query { 192.168.1.0/24; localhost; };
allow-recursion { 192.168.1.0/24; localhost; };
# Zone transferine izin verme
allow-transfer { none; };
# Dışarıya sormak yerine bu sunucuları kullan (isteğe bağlı)
forwarders {
8.8.8.8;
8.8.4.4;
1.1.1.1;
};
forward only;
# DNSSEC doğrulama
dnssec-validation auto;
# Cache boyutu (MB cinsinden)
max-cache-size 256m;
version "not available";
listen-on { 192.168.1.11; };
listen-on-v6 { none; };
};
named.conf.local dosyasına example.local için conditional forwarding ekliyoruz. Bu sayede iç ağ sorguları authoritative sunucumuza gidecek:
sudo nano /etc/bind/named.conf.local
# example.local sorguları authoritative sunucumuza yönlendir
zone "example.local" {
type forward;
forwarders { 192.168.1.10; };
forward only;
};
zone "1.168.192.in-addr.arpa" {
type forward;
forwarders { 192.168.1.10; };
forward only;
};
Servisi başlatıp test ediyoruz:
sudo named-checkconf
sudo systemctl restart named
# İç alan adı çözümlemesi - authoritative sunucuya gitmeli
dig @192.168.1.11 www.example.local A
# İnternet sorgusu - forwarder üzerinden çözülmeli
dig @192.168.1.11 github.com A
# Recursive sunucunun dışarıdan erişilemez olduğunu test et
# Başka bir ağdan:
dig @192.168.1.11 google.com
# REFUSED dönmeli
Gerçek Dünya Senaryosu: Split-Horizon DNS
Split-horizon (veya split-brain) DNS, aynı alan adının farklı ağlardan farklı IP adresleri döndürmesi gereken durumlarda kullanılır. Klasik senaryo: Şirket içinden www.example.com‘a erişenler iç IP’yi, dışarıdan erişenler ise public IP’yi görsün.
Authoritative sunucumuza bu senaryoyu uygulayalım:
sudo nano /etc/bind/named.conf.local
# ACL tanımları
acl "internal" {
192.168.1.0/24;
127.0.0.1;
};
acl "external" {
!192.168.1.0/24;
any;
};
# İç ağ view'ı
view "internal" {
match-clients { internal; };
recursion no;
zone "example.com" {
type master;
file "/etc/bind/zones/internal/db.example.com";
};
};
# Dış ağ view'ı
view "external" {
match-clients { external; };
recursion no;
zone "example.com" {
type master;
file "/etc/bind/zones/external/db.example.com";
};
};
İç zone dosyası iç IP’leri içerirken, dış zone dosyası public IP’leri içerir. Bu yapı kurumsal ortamlarda son derece yaygın kullanılan bir pattern.
Logging Yapılandırması
Üretim ortamında DNS loglarını düzgün tutmak şarttır. Her iki sunucuya da şu logging yapılandırmasını ekleyin:
sudo nano /etc/bind/named.conf
logging {
channel default_log {
file "/var/log/named/default.log" versions 3 size 10m;
severity dynamic;
print-time yes;
print-severity yes;
print-category yes;
};
channel queries_log {
file "/var/log/named/queries.log" versions 5 size 50m;
severity info;
print-time yes;
};
channel security_log {
file "/var/log/named/security.log" versions 3 size 10m;
severity dynamic;
print-time yes;
print-severity yes;
};
category default { default_log; };
category queries { queries_log; };
category security { security_log; };
category lame-servers { null; }; # Gereksiz uyarıları sustur
};
Log dizinini oluşturup izinleri ayarlayın:
sudo mkdir -p /var/log/named
sudo chown bind:bind /var/log/named
sudo chmod 755 /var/log/named
sudo systemctl restart named
Yaygın Sorunlar ve Çözümleri
Saha deneyiminden gelen birkaç önemli noktayı paylaşayım:
Serial numarası güncellemeyi unutmak, zone değişikliklerinin secondary sunuculara yayılmamasına yol açar. YYYYMMDDSS formatında serial kullanın ve her değişiklikte artırın.
allow-recursion ayarını yanlış yapmak, sunucunuzu açık bir DNS resolver haline getirir. Her zaman spesifik subnet tanımlayın, asla any kullanmayın.
named-checkconf ve named-checkzone araçlarını kullanmamak ise en yaygın hatalardan biri. Syntax hatası olan bir yapılandırmayla servisi restart etmek DNS kesintisinize yol açar.
# Hızlı sorun giderme komutları
sudo named-checkconf -p # Tüm yapılandırmayı parse edilmiş halde göster
sudo rndc status # Named'in mevcut durumu
sudo rndc dumpdb -cache # Cache içeriğini dök
sudo rndc flush # Cache'i temizle
sudo rndc reload example.local # Sadece bir zone'u yeniden yükle
Firewall ayarlarını ihmal etmek de sık karşılaşılan bir sorun. DNS için hem TCP hem UDP 53 portunu açmanız gerekir. UDP küçük sorgular için yeterli olsa da zone transferleri ve büyük cevaplar TCP kullanır.
# UFW ile firewall kuralları
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
# Authoritative sunucu için zone transfer portu
sudo ufw allow from 192.168.1.12 to any port 53 proto tcp
İzleme ve Performans İpuçları
Recursive sunucunuzun cache etkinliğini ölçmek için şu komutları kullanabilirsiniz:
# İstatistikleri güncelle
sudo rndc stats
# İstatistik dosyasını incele
cat /var/cache/bind/named_stats.txt | grep -E "cache|query"
Cache hit oranı düşükse max-cache-size değerini artırmayı düşünün. Belleğinizin yüzde yirmi beş ile otuz arasını DNS cache’e ayırmak makul bir başlangıç noktasıdır.
Zone dosyalarında $TTL değerlerini de dikkatli ayarlayın:
- Sık değişen kayıtlar için 300-600 saniye (5-10 dakika) uygundur.
- Stabil kayıtlar için 86400 saniye (1 gün) veya daha fazla kullanılabilir.
- Daha yüksek TTL değerleri recursive sunucunuzun cache yükünü azaltır ve sorgu süresini kısaltır.
Sonuç
Recursive ve authoritative DNS sunucularını aynı instance üzerinde çalıştırmak küçük test ortamları için tolere edilebilir olsa da üretimde bu iki rolü kesinlikle ayırmanız gerekiyor. Bu ayrım hem güvenlik hem de performans açısından kritik öneme sahip.
BIND9 bu konuda son derece esnek bir yapı sunuyor. view mekanizması, conditional forwarding ve granüler ACL’ler sayesinde karmaşık ağ topolojilerini de rahatlıkla yönetebilirsiniz. Özellikle split-horizon yapılandırması, hem iç hem dış DNS ihtiyaçlarını tek bir authoritative sunucudan karşılamanıza olanak tanıyor.
En önemli hatırlatma: DNS değişikliklerini her zaman önce test ortamında yapın, named-checkconf ve named-checkzone araçlarını alışkanlık haline getirin ve serial numaralarını asla güncellemeyi unutmayın. Bu üç kural, DNS yönetimindeki sorunların büyük çoğunluğunun önüne geçer.