BIND DNS Sunucusu Kurulum ve Temel Yapılandırma

Bir DNS sunucusu kurmak kulağa karmaşık gelebilir, ama aslında BIND ile bu iş oldukça sistematik bir şekilde ilerliyor. Yıllarca “neden kendi DNS sunucumu çalıştırayım ki?” diye düşündüm, ta ki production ortamında bir üçüncü taraf DNS sağlayıcısının çökmesiyle birlikte tüm servislerimin erişilemez hale geldiği güne kadar. O günden bu yana kendi BIND kurulumumu çalıştırıyorum ve bu konuda edindiğim deneyimi sizinle paylaşmak istiyorum.

BIND Nedir ve Neden Kullanmalıyız?

BIND (Berkeley Internet Name Domain), dünyanın en yaygın kullanılan açık kaynaklı DNS sunucu yazılımıdır. İnternetin omurgasını oluşturan DNS altyapısının büyük bir kısmı hâlâ BIND üzerine kurulu. ISC (Internet Systems Consortium) tarafından geliştirilen bu yazılım, hem küçük ofis ağlarında hem de büyük ölçekli kurumsal altyapılarda güvenle kullanılabiliyor.

Kendi DNS sunucunuzu çalıştırmanın size sağladığı avantajlar şunlar:

  • Tam kontrol: Hangi kayıtların ne zaman değişeceğine siz karar verirsiniz, propagasyon süresi beklemenize gerek kalmaz
  • Gizlilik: DNS sorgularınız üçüncü tarafların sunucularından geçmez
  • Özelleştirme: Split-horizon DNS, iç ağ için farklı yanıtlar gibi gelişmiş senaryoları uygulayabilirsiniz
  • Maliyet: Yüksek sorgu hacminde ücretli DNS servislerine kıyasla ciddi tasarruf sağlar
  • Öğrenme fırsatı: DNS’in gerçekte nasıl çalıştığını en iyi şekilde kendi sunucunuzu kurarak öğrenirsiniz

Kurulum Öncesi Hazırlık

Başlamadan önce birkaç şeyi netleştirmemiz gerekiyor. Bu yazıda Ubuntu 22.04 LTS üzerinde çalışacağız, ancak CentOS/RHEL kullanıcıları için paket adlarını ve servis yönetimini ayrıca belirteceğim.

Sunucunuzun hostname ve IP yapılandırması doğru olmalı. Önce bunları kontrol edelim:

# Hostname kontrolü
hostname -f

# IP adresini kontrol et
ip addr show

# /etc/hosts dosyasını düzenle
sudo nano /etc/hosts
# Şöyle bir satır ekle:
# 192.168.1.10  ns1.example.com  ns1

Firewall tarafında UDP ve TCP 53 numaralı portları açmanız gerekiyor. DNS öncelikli olarak UDP kullanır ama büyük yanıtlar için TCP’ye düşer:

# UFW ile port açma (Ubuntu)
sudo ufw allow 53/tcp
sudo ufw allow 53/udp
sudo ufw reload

# firewalld ile (CentOS/RHEL)
sudo firewall-cmd --permanent --add-service=dns
sudo firewall-cmd --reload

BIND Kurulumu

Ubuntu/Debian sistemlerde kurulum oldukça basit:

# Paket listesini güncelle
sudo apt update

# BIND9 ve yardımcı araçları kur
sudo apt install -y bind9 bind9utils bind9-doc dnsutils

# Servis durumunu kontrol et
sudo systemctl status bind9

# Sistem başlangıcında otomatik başlatmayı etkinleştir
sudo systemctl enable bind9

CentOS/RHEL sistemlerde ise:

# BIND kurulumu
sudo dnf install -y bind bind-utils

# Servis adı farklı: named
sudo systemctl enable named
sudo systemctl start named
sudo systemctl status named

Kurulum tamamlandıktan sonra temel dizin yapısını inceleyelim. Yapılandırma dosyaları genellikle /etc/bind/ altında bulunur:

  • /etc/bind/named.conf: Ana yapılandırma dosyası
  • /etc/bind/named.conf.options: Genel seçenekler
  • /etc/bind/named.conf.local: Yerel zone tanımları
  • /etc/bind/named.conf.default-zones: Varsayılan zone’lar
  • /var/cache/bind/: Zone veri dosyaları ve cache
  • /var/log/named/: Log dosyaları

Temel Yapılandırma: named.conf.options

İlk olarak genel seçenekleri ayarlayalım. Bu dosya BIND’ın davranışını genel olarak belirler:

sudo nano /etc/bind/named.conf.options

Dosyanın içeriğini şu şekilde düzenleyin:

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

    # Hangi IP'lerden sorgu kabul edileceği
    # Sadece localhost ve iç ağ için
    listen-on { 127.0.0.1; 192.168.1.10; };
    listen-on-v6 { ::1; };

    # Recursive sorgu yapabilecek ağlar
    allow-recursion {
        127.0.0.1;
        192.168.1.0/24;
    };

    # Zone transferi için izin verilen sunucular
    allow-transfer { none; };

    # Forwarder DNS sunucuları (bilinmeyen sorgular için)
    forwarders {
        8.8.8.8;
        8.8.4.4;
        1.1.1.1;
    };

    # Forward only modu - kendi recursive lookup yapmaz
    # forward only;

    # DNSSEC doğrulama
    dnssec-validation auto;

    # Version bilgisini gizle (güvenlik)
    version "not available";

    # Query logging (başlangıçta açık bırak, sonra kapat)
    querylog yes;
};

Bu yapılandırmada dikkat etmeniz gereken birkaç nokta var. allow-recursion direktifi çok önemli: Eğer bunu yanlış yapılandırırsanız, sunucunuz açık bir DNS resolver haline gelir ve DDoS saldırılarında kullanılır. Sadece güvendiğiniz ağları buraya ekleyin.

forwarders bölümü, BIND’ın kendi zone’larında bulamadığı sorguları nereye yönlendireceğini belirtir. Google ve Cloudflare DNS’ini ekledim ama siz iç ağınızdaki başka bir DNS sunucusunu da kullanabilirsiniz.

İlk Zone Oluşturma: Forward Zone

Şimdi gerçek bir senaryo üzerinden ilerleyelim. Diyelim ki example.local adında bir iç ağ domain’i yönetiyoruz. Önce zone tanımını named.conf.local dosyasına ekleyelim:

sudo nano /etc/bind/named.conf.local
# Forward zone tanımı
zone "example.local" {
    type master;
    file "/etc/bind/zones/db.example.local";
    allow-update { none; };
};

# Reverse zone tanımı (192.168.1.0/24 için)
zone "1.168.192.in-addr.arpa" {
    type master;
    file "/etc/bind/zones/db.192.168.1";
    allow-update { none; };
};

Zone dosyalarını tutacağımız dizini oluşturalım:

sudo mkdir -p /etc/bind/zones
sudo chown bind:bind /etc/bind/zones

Forward Zone Dosyası Oluşturma

Forward zone dosyası, domain adlarını IP adreslerine çevirir. Bu dosyayı oluşturalım:

sudo nano /etc/bind/zones/db.example.local
; example.local Forward Zone Dosyası
; Son güncelleme: 2024-01-15
$TTL    604800

; SOA (Start of Authority) kaydı
@   IN  SOA     ns1.example.local. admin.example.local. (
                    2024011501  ; Serial (YYYYMMDDSS formatı)
                    3600        ; Refresh - slave ne sıklıkta senkronize etsin
                    1800        ; Retry - başarısız senkronizasyon sonrası bekleme
                    604800      ; Expire - slave ne kadar süre geçerli saysın
                    86400 )     ; Negative Cache TTL

; Name Server kayıtları
@       IN  NS      ns1.example.local.
@       IN  NS      ns2.example.local.

; A kayıtları (hostname -> IP)
ns1     IN  A       192.168.1.10
ns2     IN  A       192.168.1.11
gateway IN  A       192.168.1.1

; Sunucular
web1    IN  A       192.168.1.20
web2    IN  A       192.168.1.21
db1     IN  A       192.168.1.30
db2     IN  A       192.168.1.31
mail    IN  A       192.168.1.40
vpn     IN  A       192.168.1.50

; CNAME kayıtları (alias)
www     IN  CNAME   web1.example.local.
ftp     IN  CNAME   web1.example.local.
smtp    IN  CNAME   mail.example.local.
imap    IN  CNAME   mail.example.local.

; MX kayıtları (mail sunucuları)
@       IN  MX  10  mail.example.local.

; TXT kayıtları
@       IN  TXT     "v=spf1 mx -all"

SOA kaydındaki Serial numarası çok önemli. Bu numarayı her zone güncellemesinde artırmanız gerekiyor, aksi takdirde slave sunucular güncellemeleri almaz. Ben genellikle YYYYMMDDSS formatını kullanıyorum: yıl, ay, gün ve o gün kaçıncı değişiklik olduğu.

Reverse Zone Dosyası Oluşturma

Reverse zone, IP adreslerini domain adlarına çevirir (PTR kayıtları). Özellikle mail sunucuları için kritik öneme sahip:

sudo nano /etc/bind/zones/db.192.168.1
; 192.168.1.0/24 Reverse Zone Dosyası
$TTL    604800

@   IN  SOA     ns1.example.local. admin.example.local. (
                    2024011501
                    3600
                    1800
                    604800
                    86400 )

; Name Server kayıtları
@       IN  NS      ns1.example.local.
@       IN  NS      ns2.example.local.

; PTR kayıtları (IP son okteti -> hostname)
10      IN  PTR     ns1.example.local.
11      IN  PTR     ns2.example.local.
20      IN  PTR     web1.example.local.
21      IN  PTR     web2.example.local.
30      IN  PTR     db1.example.local.
31      IN  PTR     db2.example.local.
40      IN  PTR     mail.example.local.
50      IN  PTR     vpn.example.local.

Yapılandırma Doğrulama ve Servisi Başlatma

Zone dosyalarını oluşturduktan sonra sözdizimi kontrolü yapmak şart. Bunu atlamayın; bir hata bütün DNS servisini çökertebilir:

# Ana yapılandırma dosyasını kontrol et
sudo named-checkconf

# Forward zone dosyasını kontrol et
sudo named-checkzone example.local /etc/bind/zones/db.example.local

# Reverse zone dosyasını kontrol et
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 bind9

# Servis durumunu kontrol et
sudo systemctl status bind9

named-checkconf hiçbir çıktı vermeden tamamlanırsa her şey yolunda demektir. named-checkzone ise başarılı olduğunda “OK” çıktısı verir.

DNS Sorgularını Test Etme

Kurulumun doğru çalıştığını test etmek için dig ve nslookup araçlarını kullanacağız:

# Forward lookup testi
dig @127.0.0.1 web1.example.local

# Kısa çıktı için
dig @127.0.0.1 web1.example.local +short

# Reverse lookup testi
dig @127.0.0.1 -x 192.168.1.20

# MX kaydı sorgulama
dig @127.0.0.1 example.local MX

# SOA kaydı sorgulama
dig @127.0.0.1 example.local SOA

# NS kayıtlarını sorgula
dig @127.0.0.1 example.local NS

# nslookup ile test
nslookup web1.example.local 127.0.0.1
nslookup 192.168.1.20 127.0.0.1

dig çıktısında dikkat etmeniz gereken yerler: ANSWER SECTION kısmında beklediğiniz kayıtlar görünmeli, status alanında NOERROR yazmalı.

Güvenlik Sertleştirmesi

Temel kurulum çalışır hale geldi, ama güvenlik tarafında yapabileceğimiz birkaç önemli iyileştirme var.

BIND kullanıcısını kısıtlayın:

# BIND'ın chroot ortamında çalışmasını sağla
# /etc/default/named dosyasını düzenle
sudo nano /etc/default/named

# Şu satırı ekle veya değiştir:
OPTIONS="-u bind -4"
# -4 sadece IPv4, IPv6 kullanmıyorsanız eklemenizi öneririm

Rate limiting yapılandırması – DNS amplification saldırılarına karşı:

sudo nano /etc/bind/named.conf.options

options bloğuna şunu ekleyin:

    # Rate limiting - DDoS koruması
    rate-limit {
        responses-per-second 15;
        window 5;
        log-only no;
        errors-per-second 5;
        nxdomains-per-second 5;
        slip 2;
    };

    # Recursion sadece belirli ağlardan
    recursion yes;
    allow-recursion {
        127.0.0.1;
        192.168.1.0/24;
        # İzin verilen ek ağlar buraya
    };

    # Zone transferi varsayılan olarak kapalı
    allow-transfer { none; };

    # Sunucu bilgilerini gizle
    version "DNS";
    hostname none;
    server-id none;

Log Yapılandırması

Sorun giderme ve güvenlik izleme için log yapılandırması önemli. /etc/bind/named.conf dosyasına logging bloğu ekleyelim:

sudo nano /etc/bind/named.conf

Dosyanın sonuna ekleyin:

logging {
    channel default_log {
        file "/var/log/named/named.log" versions 5 size 20m;
        print-time yes;
        print-severity yes;
        print-category yes;
        severity dynamic;
    };

    channel security_log {
        file "/var/log/named/security.log" versions 5 size 20m;
        print-time yes;
        print-severity yes;
        print-category yes;
        severity info;
    };

    channel query_log {
        file "/var/log/named/query.log" versions 10 size 50m;
        print-time yes;
        severity info;
    };

    category default { default_log; };
    category security { security_log; };
    category queries { query_log; };
    category lame-servers { null; };
};

Log dizinini oluşturun:

sudo mkdir -p /var/log/named
sudo chown bind:bind /var/log/named
sudo chmod 755 /var/log/named

# Servisi yeniden başlat
sudo systemctl restart bind9

# Log dosyasını izle
sudo tail -f /var/log/named/named.log

Yaygın Sorunlar ve Çözümleri

Yıllar içinde en sık karşılaştığım sorunları ve çözümlerini paylaşayım.

Servis başlamıyor: İlk yapmanız gereken şey log dosyalarını ve systemd journal’ını kontrol etmek:

sudo journalctl -u bind9 -n 50
sudo cat /var/log/named/named.log

En yaygın sebep zone dosyasındaki sözdizimi hatasıdır. named-checkconf ve named-checkzone komutlarını çalıştırın.

Sorgular yanıt vermiyor: Firewall kurallarını ve BIND’ın hangi arayüzde dinlediğini kontrol edin:

# BIND'ın 53. portu dinlediğini doğrula
sudo ss -tlnup | grep named
sudo netstat -tlnup | grep named

# Firewall kurallarını listele
sudo ufw status verbose

Serial numarası güncellemesi unutuldu: Zone dosyasını değiştirip serial numarasını artırmadan servisi yeniden başlatırsanız slave sunucular güncellemeyi almaz. Bu durumda önce serial numarasını artırın, sonra servisi yeniden yükleyin:

# Servisi yeniden başlatmadan zone'u yeniden yükle
sudo rndc reload example.local

# Tüm zone'ları yeniden yükle
sudo rndc reload

# Cache'i temizle
sudo rndc flush

Zone transferi çalışmıyor (Slave sunucu için): Master sunucunun allow-transfer direktifinde slave sunucunun IP’si olmalı. Slave tarafında zone tanımı şöyle olmalı:

zone "example.local" {
    type slave;
    file "/var/cache/bind/db.example.local";
    masters { 192.168.1.10; };
};

Bakım ve İzleme

Günlük operasyonlarda işinize yarayacak birkaç komut daha:

# BIND istatistiklerini görüntüle
sudo rndc stats
cat /var/run/named/named.stats

# Belirli bir domain için cache'i temizle
sudo rndc flushname web1.example.local

# BIND'ı durdurmadan yapılandırmayı yeniden yükle
sudo rndc reconfig

# Tüm zone'ları listele
sudo rndc zonestatus

# Sorgu istatistiklerini görüntüle
sudo rndc querylog on

Zone güncellemelerini otomatize etmek için küçük bir script yazabilirsiniz. Her zone değişikliğinde serial numarasını unutmamak için:

#!/bin/bash
# update_zone.sh - Zone dosyası güncelleme scripti

ZONE_FILE="/etc/bind/zones/db.example.local"
TODAY=$(date +%Y%m%d)
CURRENT_SERIAL=$(grep -E "^s+[0-9]{10}" $ZONE_FILE | awk '{print $1}')
CURRENT_DATE=${CURRENT_SERIAL:0:8}

if [ "$TODAY" = "$CURRENT_DATE" ]; then
    SEQ=$((${CURRENT_SERIAL:8:2} + 1))
    NEW_SERIAL="${TODAY}$(printf '%02d' $SEQ)"
else
    NEW_SERIAL="${TODAY}01"
fi

sudo sed -i "s/$CURRENT_SERIAL/$NEW_SERIAL/" $ZONE_FILE
echo "Serial güncellendi: $CURRENT_SERIAL -> $NEW_SERIAL"

# Doğrulama ve reload
sudo named-checkzone example.local $ZONE_FILE && sudo rndc reload example.local

Sonuç

BIND kurulumu başta göz korkutucu görünebilir, ama sistematik yaklaştığınızda oldukça anlaşılır bir yapısı var. Bu yazıda ele aldığımız konuları özetleyecek olursak:

  • BIND’ı Ubuntu/CentOS üzerine kurma
  • named.conf.options ile genel yapılandırma
  • Forward ve reverse zone dosyaları oluşturma
  • Güvenlik sertleştirmesi ve rate limiting
  • Log yapılandırması
  • Sorun giderme teknikleri

Bir sonraki adım olarak DNSSEC implementasyonunu, Dynamic DNS yapılandırmasını veya Split-horizon DNS kurulumunu incelemenizi öneririm. Özellikle split-horizon, iç ağ ve dış ağ için farklı DNS yanıtları gereken durumlarda çok işe yarıyor.

Unutmayın ki DNS altyapınız ne kadar kritik olursa olsun, yedekli bir yapı kurmak şart. En az bir slave DNS sunucusu olmadan production ortamına geçmeyin. Bir sunucu çöktüğünde tüm domain erişiminizin gitmesini istemezsiniz, bunu zor yoldan öğrenmek çok acı verici olabiliyor.

Yorum yapın