Unbound ile Stub Zone ve Auth Zone Kullanımı

DNS altyapısını yönetirken en çok baş ağrıtan konulardan biri şu: Bazı zone’ları kendi yetkili sunucunuzdan çözümlemek istiyorsunuz, bazılarını ise belirli upstream sunuculara yönlendirmek istiyorsunuz. Unbound’un stub zone ve auth zone özellikleri tam olarak bu ihtiyacı karşılıyor. Ben yıllarca BIND kullandım, sonra Unbound’a geçtim ve bu iki özellik benim için gerçek oyun değiştirici oldu. Gelin bu konuyu derinlemesine inceleyelim.

Stub Zone ve Auth Zone Nedir, Farkları Ne?

Önce kavramları netleştirelim, çünkü ikisi de birbirine karıştırılıyor.

Stub Zone, Unbound’a şunu söyler: “Bu domain için sorgular geldiğinde, benim normal recursive çözümleme sürecimi kullanma. Git doğrudan şu name server’lara sor.” Yani bir tür yönlendirme mekanizması. Unbound, stub zone tanımladığınız domain için belirttiğiniz nameserver’lara direkt sorgu gönderir, oradan aldığı cevabı cache’ler ve client’a döner. Şirket içi DNS sunucularınız varsa, ya da bir iş ortağının private zone’larına erişmeniz gerekiyorsa stub zone biçilmiş kaftan.

Auth Zone ise farklı bir hayvan. Unbound’a diyorsunuz ki: “Bu zone’u dışarıya sormana gerek yok, ben sana zone dosyasını veriyorum, sen bu zone için yetkili gibi davran.” Unbound, auth zone olarak tanımladığınız zone için hem recursive resolver hem de authoritative kaynak gibi çalışıyor. Zone transfer yapabiliyor, ya da statik dosyadan okuyabiliyor.

Pratik ayrım şu:

  • Stub Zone: “Git şu sunuculara sor” der
  • Auth Zone: “Zone bilgisi zaten sende, sen cevap ver” der

Gerçek Dünya Senaryoları

Senaryo 1: Kurumsal İç DNS

Diyelim ki şirketinizin sirket.local domain’i var ve bunu yöneten iki adet Windows DNS sunucunuz mevcut. Bunların IP’leri 192.168.10.10 ve 192.168.10.11. İnternet’e bakan Unbound resolver’ınızın, sirket.local için olan sorguları doğrudan bu Windows sunuculara yönlendirmesini istiyorsunuz.

Senaryo 2: Split-Horizon DNS

example.com için internal ve external farklı kayıtlar tutmak istiyorsunuz. Internal kullanıcılar app.example.com‘a sorgu yaptığında private IP almalı, external kullanıcılar public IP almalı.

Senaryo 3: Root Zone Cache

Unbound’u root zone’u kendisi yükleyerek, root server’lara bağımlılığı azaltmak istiyorsunuz. Auth zone burada devreye giriyor.

Stub Zone Yapılandırması

Hadi elle kirletelim. Önce temel Unbound konfigürasyonunun doğru çalıştığını varsayıyorum. Stub zone eklemek için /etc/unbound/unbound.conf dosyasına ya da /etc/unbound/conf.d/ altına ayrı bir dosya ekliyoruz.

# /etc/unbound/conf.d/stub-zones.conf

stub-zone:
    name: "sirket.local"
    stub-addr: 192.168.10.10
    stub-addr: 192.168.10.11
    stub-prime: no
    stub-first: no

Buradaki parametreleri açıklayayım:

  • name: Stub zone’un domain adı
  • stub-addr: Sorguların gönderileceği nameserver IP adresleri. Port belirtmek isterseniz 192.168.10.10@5353 şeklinde yazabilirsiniz
  • stub-prime: yes yaparsanız Unbound, stub sunucularına NS sorgusu yaparak nameserver listesini güncellemeye çalışır. Genel olarak no bırakın
  • stub-first: yes yaparsanız stub başarısız olursa normal recursive çözümlemeye düşer. Güvenlik açısından dikkatli kullanın

Reverse zone için de stub tanımlamak gerekebilir:

stub-zone:
    name: "10.168.192.in-addr.arpa"
    stub-addr: 192.168.10.10
    stub-addr: 192.168.10.11
    stub-prime: no

Yapılandırmayı doğrulayıp yeniden yükleyelim:

unbound-checkconf /etc/unbound/unbound.conf
systemctl reload unbound

# Test edelim
dig @127.0.0.1 web01.sirket.local A
dig @127.0.0.1 -x 192.168.10.50

Stub Zone ile DNSSEC

Eğer iç DNS sunucularınız DNSSEC desteklemiyorsa (Windows DNS genelde sorun çıkarır bu konuda), stub zone için DNSSEC doğrulamasını kapatmanız gerekebilir:

stub-zone:
    name: "sirket.local"
    stub-addr: 192.168.10.10
    stub-addr: 192.168.10.11
    stub-prime: no

# server bölümüne ekleyin
server:
    domain-insecure: "sirket.local"
    domain-insecure: "10.168.192.in-addr.arpa"

Bu satırlar olmadan DNSSEC doğrulaması yapılamayan zone’lar için SERVFAIL alırsınız. Çok yaygın bir sorun, beni saatlerce uğraştırmıştı.

Auth Zone Yapılandırması

Auth zone kurulumu biraz daha karmaşık ama çok daha güçlü. İki yöntemle besleyebilirsiniz: zone transfer (AXFR) veya statik dosya.

Statik Dosyadan Auth Zone

Küçük ve nadiren değişen zone’lar için statik dosya idealdir:

# Önce zone dosyasını oluşturalım
# /etc/unbound/zones/internal.example.com.zone

$ORIGIN internal.example.com.
$TTL 3600

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

@       IN  NS  ns1.internal.example.com.
ns1     IN  A   192.168.1.1
app     IN  A   192.168.1.100
db      IN  A   192.168.1.101
api     IN  A   192.168.1.102

Şimdi Unbound konfigürasyonu:

# /etc/unbound/conf.d/auth-zones.conf

auth-zone:
    name: "internal.example.com"
    zonefile: "/etc/unbound/zones/internal.example.com.zone"
    for-downstream: yes
    for-upstream: yes
    fallback-enabled: no

Parametreler:

  • name: Zone adı
  • zonefile: Zone dosyasının tam yolu
  • for-downstream: Bu zone için gelen client sorgularını bu zone’dan cevapla
  • for-upstream: Recursive çözümleme sırasında bu zone’u kullan
  • fallback-enabled: Auth zone başarısız olursa upstream’e düşsün mü? Genelde no bırakıyorum

Zone Transfer ile Auth Zone

Upstream nameserver’dan AXFR çekerek güncel tutmak çok daha sağlıklı:

auth-zone:
    name: "internal.example.com"
    master: 10.0.0.53
    master: 10.0.0.54
    zonefile: "/var/lib/unbound/internal.example.com.zone"
    for-downstream: yes
    for-upstream: yes
    fallback-enabled: no
    zonemd-check: no
    zonemd-reject-absence: no

Zone transfer için master nameserver’ın Unbound’un IP’sine AXFR iznini vermesi gerekiyor. BIND üzerinde şöyle yapılır:

# named.conf içinde
zone "internal.example.com" {
    type master;
    file "internal.example.com.zone";
    allow-transfer { 10.0.1.5; };  # Unbound'un IP'si
    also-notify { 10.0.1.5; };
};

Unbound zone’u otomatik yenileme aralıklarını da belirleyebilirsiniz:

auth-zone:
    name: "internal.example.com"
    master: 10.0.0.53
    zonefile: "/var/lib/unbound/internal.example.com.zone"
    for-downstream: yes
    for-upstream: yes
    fallback-enabled: no

SOA record’undaki refresh değerleri zone transfer zamanlamasını belirler. Unbound bunları okur ve buna göre hareket eder.

Root Zone Auth Zone Olarak Kullanmak

Bu benim favori kullanım senaryolarından biri. Root zone’u Unbound’a yükleyerek root server’lara olan bağımlılığı azaltabilirsiniz. Özellikle internet bağlantısı zaman zaman sorun çıkaran ortamlarda çok işe yarıyor.

auth-zone:
    name: "."
    master: 199.9.14.201        # b.root-servers.net
    master: 192.33.4.12         # c.root-servers.net
    master: 199.7.91.13         # d.root-servers.net
    fallback-enabled: yes
    for-downstream: no
    for-upstream: yes
    zonefile: "/var/lib/unbound/root.zone"

Burada for-downstream: no dikkat edin. Root zone’u client’lara doğrudan cevap vermek için değil, Unbound’un kendi recursive çözümlemesinde kullanmasını istiyoruz. fallback-enabled: yes ise zone transfer başarısız olursa root server’lara sorgu atmaya devam etmesini sağlıyor.

İlk zone yüklemesini elle tetikleyelim:

# Unbound'u başlatın, zone transfer otomatik olacak
systemctl restart unbound

# Zone yüklendi mi kontrol edelim
unbound-control list_auth_zones

# Ya da log'a bakalım
journalctl -u unbound -n 50 | grep -i "auth zone"

Gelişmiş Yapılandırma: Stub ve Auth Zone Birlikte

Gerçek ortamlarda çoğu zaman ikisini birden kullanırsınız. Örneğin bir yapılandırma şöyle görünebilir:

# /etc/unbound/conf.d/company-dns.conf

# Merkez ofis iç zone'u - auth zone olarak local'de tutuyoruz
auth-zone:
    name: "merkez.sirket.com.tr"
    zonefile: "/etc/unbound/zones/merkez.zone"
    for-downstream: yes
    for-upstream: yes
    fallback-enabled: no

# İstanbul şubesi - oradaki DNS'e stub ile yönlendiriyoruz
stub-zone:
    name: "istanbul.sirket.com.tr"
    stub-addr: 10.10.1.53
    stub-addr: 10.10.1.54
    stub-prime: no
    stub-first: no

# Ankara şubesi
stub-zone:
    name: "ankara.sirket.com.tr"
    stub-addr: 10.20.1.53
    stub-prime: no

# Tüm iç zone'lar için reverse
stub-zone:
    name: "10.in-addr.arpa"
    stub-addr: 10.10.1.53
    stub-addr: 10.20.1.53
    stub-prime: no

# İzmir şubesi henüz DNS sunucusu yok, elle yazıyoruz
auth-zone:
    name: "izmir.sirket.com.tr"
    zonefile: "/etc/unbound/zones/izmir.zone"
    for-downstream: yes
    for-upstream: yes
    fallback-enabled: no

Sorun Giderme

Sıkça Karşılaşılan Hatalar

SERVFAIL alıyorum ama stub zone tanımladım:

İlk kontrol edilecek şey DNSSEC. domain-insecure tanımınızı eklediniz mi? İkincisi, stub sunucusuna erişimi kontrol edin:

# Stub sunucusuna direkt test
dig @192.168.10.10 web01.sirket.local A

# Unbound'un ne yaptığını görmek için verbosity artırın
unbound-control verbosity 2
dig @127.0.0.1 web01.sirket.local A
unbound-control verbosity 1

Auth zone yüklenmiyor:

Zone dosyası sözdizimini kontrol edin:

# named-checkzone ile zone dosyasını doğrulayın (bind-utils paketi)
named-checkzone internal.example.com /etc/unbound/zones/internal.example.com.zone

# Unbound log'larına bakın
journalctl -u unbound -f

Zone transfer çalışmıyor:

# Elle AXFR testi yapın
dig @10.0.0.53 internal.example.com AXFR

# Unbound'u zone'u yenilemeye zorlamak için
unbound-control auth_zone_reload internal.example.com

# Zone transfer loglarını görmek için
unbound-control verbosity 3
unbound-control auth_zone_transfer internal.example.com

Unbound Control ile Zone Yönetimi

unbound-control aracı çok kullanışlı. Günlük operasyonlarda sık kullandığım komutlar:

# Tüm auth zone'ları listele
unbound-control list_auth_zones

# Belirli bir zone'u yeniden yükle (dosyadan)
unbound-control auth_zone_reload internal.example.com

# Zone transfer başlat
unbound-control auth_zone_transfer internal.example.com

# Stub zone'lar için cache'i temizle
unbound-control flush_zone sirket.local

# Genel cache durumu
unbound-control stats | grep -i "num.cache"

Performans ve Güvenlik Notları

Auth zone kullanırken birkaç önemli nokta:

Bellek kullanımı: Auth zone olarak yüklenen her zone Unbound’un belleğine alınır. Büyük zone’larla dikkatli olun. Root zone yaklaşık 2-3 MB, büyük şirket zone’ları çok daha küçük olur genelde.

Zone dosyası izinleri: Unbound genellikle unbound kullanıcısıyla çalışır. Zone dosyalarının okunabilir olduğundan emin olun:

chown -R unbound:unbound /etc/unbound/zones/
chmod 644 /etc/unbound/zones/*.zone

Stub zone güvenliği: Stub zone tanımladığınız nameserver’lar güvenilir mi? Eğer stub sunucu tehlikeye girerse, tüm o domain için poisoning riski var. Stub zone için ayrı access-control ve local-zone tanımları düşünün.

TSIG ile güvenli zone transfer: Production ortamında zone transfer TSIG ile şifrelenmiş olmalı. Unbound auth zone için TSIG desteği kısıtlı, bu durumda stunnel ya da WireGuard tüneli üzerinden zone transfer daha güvenli bir yaklaşım.

Yapılandırmayı Test Etmek

Tüm yapılandırmayı devreye almadan önce sistematik test önemli:

# Syntax kontrolü
unbound-checkconf /etc/unbound/unbound.conf

# Reload ve servis durumu kontrolü
systemctl reload unbound
systemctl status unbound

# Stub zone testi - cevap stub'dan mı geliyor?
dig @127.0.0.1 web01.sirket.local A +norecurse

# Auth zone testi - AA flag olmalı
dig @127.0.0.1 app.internal.example.com A

# Negative cevap testi - var olmayan kayıt
dig @127.0.0.1 yokolanhost.sirket.local A

# Performans testi
for i in {1..100}; do dig @127.0.0.1 app.internal.example.com A +short; done | sort | uniq -c

Auth zone’dan gelen cevaplarda aa (Authoritative Answer) flag’ı görmeniz gerekiyor. Stub zone’dan gelen cevaplarda bu flag olmayacak.

Sonuç

Stub zone ve auth zone, Unbound’u sadece basit bir caching resolver olmaktan çıkarıp kurumsal DNS altyapısının güçlü bir parçası yapan özellikler. Stub zone ile mevcut iç DNS sunucularınızı entegre edebilir, auth zone ile ise Unbound’u doğrudan zone sahibi yapabilirsiniz.

Benim tavsiyem şu: Eğer zaten iş başında Windows DNS ya da BIND çalışıyorsa, stub zone ile başlayın. Basit, az konfigürasyon, hızlı devreye alınıyor. Eğer küçük bir zone’u tamamen Unbound üzerinde yönetmek istiyorsanız ya da root zone önbelleğini optimize etmek istiyorsanız, auth zone’a geçin.

İkisini birleştirdiğinizde ise gerçekten esnek bir DNS mimarisi elde ediyorsunuz. Büyük zone’ları yetkili sunuculardan AXFR ile çekip cache’te tutabilir, küçük ve statik zone’ları dosyadan yükleyebilir, aynı zamanda dış internet trafiği için normal recursive çözümleme yapabilirsiniz. Tek bir Unbound instance’ı, doğru yapılandırıldığında tüm bu rolleri üstlenebilir.

Son bir not: Her yapılandırma değişikliğini versiyon kontrolüne alın. DNS konfigürasyonları küçük görünür ama bir satır hata tüm ağın DNS’ini patlatabilir. Git ile yönetmek ve değişiklikleri test ortamında denemek, gece telefonlarınızı azaltacaktır.

Bir yanıt yazın

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