BIND Güvenliği: TSIG ile Zone Transfer Şifreleme

DNS altyapınızın en kritik güvenlik açıklarından biri, yetkisiz zone transfer işlemlerine karşı korunmamış olmaktır. Bir saldırgan zone transfer yapabilirse, tüm DNS kayıtlarınızı ele geçirir ve ağ topolojinizi öğrenir. TSIG (Transaction SIGnature) tam da bu noktada devreye girerek hem zone transferlerini şifreler hem de DNS sunucular arasındaki iletişimi kriptografik olarak doğrular. Bu yazıda BIND üzerinde TSIG’i sıfırdan kurarak production ortamına hazır bir DNS güvenlik altyapısı oluşturacağız.

TSIG Nedir ve Neden Kullanmalısınız?

TSIG, RFC 2845 ile tanımlanan bir DNS güvenlik mekanizmasıdır. Temel olarak shared secret key kullanan HMAC tabanlı bir imzalama sistemidir. DNS mesajlarını şifrelemez ama kriptografik olarak imzalar ve doğrular. Bunu şöyle düşünebilirsiniz: iki tarafın da bildiği bir parola ile mesajları imzalarsınız, karşı taraf bu imzayı doğrulayamazsa isteği reddeder.

TSIG olmadan zone transfer durumunu düşünün. Herhangi bir IP adresi, BIND sunucunuza dig AXFR isteği atabilir ve tüm zone veritabanınızı çekebilir. Bu veritabanında mail sunucularınız, dahili servisleriniz, VPN gateway’leriniz, hatta yanlışlıkla unutulmuş test sunucularınız bile olabilir. Bir penetrasyon tester için bu adeta altın madenidir.

TSIG’in sunduğu korumalar:

  • Kimlik doğrulama: Zone transfer isteğinin gerçekten yetkili secondary sunucudan geldiğini doğrular
  • Bütünlük: Transfer edilen verinin yolda değiştirilmediğini garanti eder
  • Replay koruması: Zaman damgası kullanarak eski mesajların tekrar oynatılmasını engeller
  • Yetkilendirme: Sadece anahtara sahip taraflar işlem yapabilir

Ortam Hazırlığı

Bu yazıda aşağıdaki senaryoyu kullanacağız:

  • Primary DNS: 192.168.1.10 (ns1.example.com)
  • Secondary DNS: 192.168.1.20 (ns2.example.com)
  • Domain: example.com
  • İşletim Sistemi: Ubuntu 22.04 / Rocky Linux 9

Önce her iki sunucuda da BIND9’un kurulu olduğundan emin olalım:

# Ubuntu/Debian için
apt update && apt install -y bind9 bind9utils bind9-doc dnsutils

# RHEL/Rocky Linux için
dnf install -y bind bind-utils

# Servis durumunu kontrol et
systemctl status named

TSIG Anahtarı Oluşturma

TSIG anahtarı oluştururken kullanabileceğiniz üç algoritma vardır: HMAC-MD5, HMAC-SHA256 ve HMAC-SHA512. MD5 artık güvenli kabul edilmediği için SHA256 veya SHA512 kullanmanızı öneririm. Production ortamda SHA512 tercih edin.

Anahtar oluşturmak için tsig-keygen veya eski yöntem olan dnssec-keygen kullanabilirsiniz. Modern BIND sürümlerinde tsig-keygen çok daha pratiktir:

# Primary sunucuda anahtar oluştur
# tsig-keygen [algoritma] [anahtar-adı]
tsig-keygen -a hmac-sha512 ns1-ns2-transfer-key

# Çıktı şu formatta olacak:
# key "ns1-ns2-transfer-key" {
#     algorithm hmac-sha512;
#     secret "uzun-base64-encoded-secret";
# };

Bu komutu çalıştırdığınızda terminal ekranında anahtar bloğunu göreceksiniz. Bu çıktıyı hemen bir dosyaya yönlendirin:

tsig-keygen -a hmac-sha512 ns1-ns2-transfer-key > /etc/bind/tsig-keys.conf

# Dosya içeriğini kontrol et
cat /etc/bind/tsig-keys.conf

# Güvenlik için dosya izinlerini ayarla
chown root:bind /etc/bind/tsig-keys.conf
chmod 640 /etc/bind/tsig-keys.conf

Şimdi bu dosyanın içeriğine bakarsanız şuna benzer bir şey göreceksiniz:

# /etc/bind/tsig-keys.conf içeriği (örnek)
key "ns1-ns2-transfer-key" {
    algorithm hmac-sha512;
    secret "Bu+KIsatilmis+Bir+Ornek+Secret+Deger+Buraya+Gelir+AAAA==";
};

Kritik nokta: Bu anahtar dosyasını güvenli bir şekilde secondary sunucuya kopyalamanız gerekiyor. SCP veya SFTP kullanın, asla email veya HTTP ile göndermeyin.

# Primary'den secondary'ye güvenli kopyalama
scp /etc/bind/tsig-keys.conf [email protected]:/etc/bind/tsig-keys.conf

# Secondary sunucuda izinleri ayarla
ssh [email protected] "chown root:bind /etc/bind/tsig-keys.conf && chmod 640 /etc/bind/tsig-keys.conf"

Primary Sunucu Konfigürasyonu

Primary sunucuda named.conf dosyasına TSIG anahtarını ve transfer politikasını eklememiz gerekiyor. BIND’da konfigürasyon genellikle birden fazla dosyaya bölünür. Ubuntu’da /etc/bind/named.conf.options, /etc/bind/named.conf.local ve /etc/bind/named.conf.default-zones şeklinde ayrılmıştır.

Önce ana konfigürasyona anahtar dosyasını include edelim:

# /etc/bind/named.conf dosyasına ekle
# Ubuntu'da bu dosya zaten var, aşağıdaki satırı ekle
cat >> /etc/bind/named.conf << 'EOF'

// TSIG anahtarları
include "/etc/bind/tsig-keys.conf";
EOF

Şimdi /etc/bind/named.conf.local dosyasını düzenleyelim. Bu dosyada zone tanımlamalarınız ve ACL’ler yer alır:

# /etc/bind/named.conf.local
# Bu dosyayı tamamen aşağıdaki içerikle güncelleyin

# Secondary sunucu IP'si için ACL
acl "secondary-servers" {
    192.168.1.20;
};

# Zone transfer için özel ACL - TSIG ile birlikte
acl "tsig-allowed-transfers" {
    key "ns1-ns2-transfer-key";
};

zone "example.com" IN {
    type master;
    file "/etc/bind/zones/db.example.com";
    
    # TSIG key ile sadece belirtilen sunucuya transfer izni
    allow-transfer {
        key "ns1-ns2-transfer-key";
    };
    
    # Notify mesajlarını da TSIG ile imzala
    also-notify {
        192.168.1.20 key "ns1-ns2-transfer-key";
    };
    
    # Zone güncelleme bildirimleri
    notify yes;
};

zone "1.168.192.in-addr.arpa" IN {
    type master;
    file "/etc/bind/zones/db.192.168.1";
    
    allow-transfer {
        key "ns1-ns2-transfer-key";
    };
    
    also-notify {
        192.168.1.20 key "ns1-ns2-transfer-key";
    };
    
    notify yes;
};

named.conf.options dosyasında da genel transfer kısıtlaması ekleyelim:

# /etc/bind/named.conf.options
options {
    directory "/var/cache/bind";
    
    # Varsayılan olarak tüm zone transferlerini engelle
    # Sadece TSIG key ile izin verilecek (zone tanımlarında belirtildi)
    allow-transfer { none; };
    
    # Recursive query sadece yerel ağdan
    allow-recursion {
        127.0.0.1;
        192.168.1.0/24;
    };
    
    # Version bilgisini gizle
    version "not disclosed";
    
    # DNSSEC doğrulama
    dnssec-validation auto;
    
    listen-on { 192.168.1.10; 127.0.0.1; };
    listen-on-v6 { ::1; };
};

Secondary Sunucu Konfigürasyonu

Secondary sunucuda da anahtar dosyası zaten kopyalandı. Şimdi named.conf.local dosyasını yapılandıralım:

# /etc/bind/named.conf.local (Secondary - 192.168.1.20)

# Ana konfigürasyona anahtar include
# named.conf içinde zaten include ettiysek bu satır gerekmez
# include "/etc/bind/tsig-keys.conf";

zone "example.com" IN {
    type slave;
    file "/var/cache/bind/db.example.com";
    
    # Primary sunucuya TSIG key ile bağlan
    masters {
        192.168.1.10 key "ns1-ns2-transfer-key";
    };
    
    # Bu sunucudan daha fazla transfer yapılmasın
    allow-transfer { none; };
    
    # Secondary üzerinden notify gönderme
    notify no;
};

zone "1.168.192.in-addr.arpa" IN {
    type slave;
    file "/var/cache/bind/db.192.168.1";
    
    masters {
        192.168.1.10 key "ns1-ns2-transfer-key";
    };
    
    allow-transfer { none; };
    notify no;
};

Secondary’nin named.conf dosyasına da anahtar include satırını ekleyin:

echo 'include "/etc/bind/tsig-keys.conf";' >> /etc/bind/named.conf

Konfigürasyonu Test Etme

Her iki sunucuda da konfigürasyonu doğrulayalım:

# Syntax kontrolü
named-checkconf /etc/bind/named.conf

# Zone dosyası kontrolü
named-checkzone example.com /etc/bind/zones/db.example.com

# BIND'ı yeniden başlat
systemctl restart named

# Log takibi (ayrı terminal)
tail -f /var/log/syslog | grep named
# RHEL için: tail -f /var/log/messages | grep named

Şimdi TSIG’in çalışıp çalışmadığını test edelim. Önce yetkisiz bir transfer denemesi yapalım:

# Yetkisiz transfer denemesi - bu REDDEDİLMELİ
dig @192.168.1.10 example.com AXFR

# Beklenen çıktı:
# ; Transfer failed.
# ya da
# ; TSIG error with server: tsig indicates error

Şimdi TSIG anahtarı ile yetkili transfer yapalım:

# TSIG key ile zone transfer testi
# Önce key bilgisini bir değişkene alalım
KEY_SECRET=$(grep secret /etc/bind/tsig-keys.conf | awk '{print $2}' | tr -d '";')

# TSIG ile transfer
dig @192.168.1.10 example.com AXFR 
    -y "hmac-sha512:ns1-ns2-transfer-key:${KEY_SECRET}"

# Alternatif: key dosyası belirterek
dig @192.168.1.10 example.com AXFR 
    -k /etc/bind/tsig-keys.conf

Gerçek Dünya Senaryosu: Çoklu Secondary Sunucu

Büyük bir kurumda genellikle birden fazla secondary DNS sunucusu olur. Her secondary için ayrı TSIG anahtarı kullanmak en iyi pratiktir. Bu sayede bir secondary sunucu ele geçirilirse sadece o sunucunun anahtarını iptal edebilirsiniz.

# Her secondary için ayrı anahtar oluştur
tsig-keygen -a hmac-sha512 ns1-to-ns2-key > /etc/bind/keys/ns2.key
tsig-keygen -a hmac-sha512 ns1-to-ns3-key > /etc/bind/keys/ns3.key
tsig-keygen -a hmac-sha512 ns1-to-ns4-key > /etc/bind/keys/ns4.key

# Tüm key dosyalarını ana conf'a include et
cat >> /etc/bind/named.conf << 'EOF'
include "/etc/bind/keys/ns2.key";
include "/etc/bind/keys/ns3.key";
include "/etc/bind/keys/ns4.key";
EOF

Birden fazla secondary için zone konfigürasyonu:

# named.conf.local - Primary sunucu, çoklu secondary
zone "example.com" IN {
    type master;
    file "/etc/bind/zones/db.example.com";
    
    # Her secondary kendi anahtarıyla erişebilir
    allow-transfer {
        key "ns1-to-ns2-key";
        key "ns1-to-ns3-key";
        key "ns1-to-ns4-key";
    };
    
    # Notify mesajları her secondary'ye kendi anahtarıyla gönderilir
    also-notify {
        192.168.1.20 key "ns1-to-ns2-key";
        192.168.2.10 key "ns1-to-ns3-key";
        10.0.0.100   key "ns1-to-ns4-key";
    };
    
    notify yes;
};

TSIG Anahtar Rotasyonu

Güvenlik politikanıza göre TSIG anahtarlarını belirli aralıklarla değiştirmeniz gerekebilir. Bu işlemi downtime olmadan yapmak için double-TSIG yöntemi kullanılır: önce yeni anahtar eklenir, tüm sunuculara dağıtılır, sonra eski anahtar kaldırılır.

# Yeni anahtar oluştur
tsig-keygen -a hmac-sha512 ns1-ns2-transfer-key-v2 > /etc/bind/tsig-keys-new.conf

# Her iki anahtarı da geçici olarak aktif tut
# named.conf.local'a geçici olarak ekle:
# allow-transfer {
#     key "ns1-ns2-transfer-key";      # eski anahtar
#     key "ns1-ns2-transfer-key-v2";   # yeni anahtar
# };

# Yeni anahtarı secondary'ye kopyala
scp /etc/bind/tsig-keys-new.conf [email protected]:/etc/bind/

# Secondary'yi yeni anahtarla güncelle, test et
# Başarılı olduktan sonra eski anahtarı kaldır

Anahtar rotasyonu için basit bir shell script:

#!/bin/bash
# /usr/local/bin/rotate-tsig-key.sh

KEY_NAME="ns1-ns2-transfer-key"
KEY_DIR="/etc/bind/keys"
SECONDARY_HOST="192.168.1.20"
DATE=$(date +%Y%m%d)
NEW_KEY_NAME="${KEY_NAME}-${DATE}"

echo "[*] Yeni TSIG anahtarı oluşturuluyor: ${NEW_KEY_NAME}"
tsig-keygen -a hmac-sha512 "${NEW_KEY_NAME}" > "${KEY_DIR}/${NEW_KEY_NAME}.key"
chmod 640 "${KEY_DIR}/${NEW_KEY_NAME}.key"
chown root:bind "${KEY_DIR}/${NEW_KEY_NAME}.key"

echo "[*] Yeni anahtar secondary'ye kopyalanıyor..."
scp "${KEY_DIR}/${NEW_KEY_NAME}.key" "root@${SECONDARY_HOST}:/etc/bind/keys/"
ssh "root@${SECONDARY_HOST}" "chown root:bind /etc/bind/keys/${NEW_KEY_NAME}.key && chmod 640 /etc/bind/keys/${NEW_KEY_NAME}.key"

echo "[*] BIND konfigürasyonu güncelleniyor..."
echo "include "${KEY_DIR}/${NEW_KEY_NAME}.key";" >> /etc/bind/named.conf

echo "[*] BIND yeniden yükleniyor..."
named-checkconf && rndc reload

echo "[+] Anahtar rotasyonu tamamlandı. Manuel olarak zone konfigürasyonunu güncelleyin."
echo "[!] Eski anahtarı kaldırmayı unutmayın: ${KEY_NAME}"

Log Analizi ve Sorun Giderme

TSIG hatalarını teşhis etmek bazen zorlu olabilir. İşte en sık karşılaşılan sorunlar ve çözümleri:

Saat farkı sorunu: TSIG mesajları zaman damgası içerir ve sunucular arasında 5 dakikadan fazla fark varsa doğrulama başarısız olur.

# Sunucu saatlerini kontrol et
date
timedatectl status

# NTP senkronizasyonunu zorla
chronyc makestep
# veya
ntpdate -u pool.ntp.org

# Servis durumu
systemctl status chronyd

BIND log seviyesini artırma:

# named.conf'a ekle
logging {
    channel tsig_log {
        file "/var/log/named/tsig.log" versions 3 size 5m;
        severity dynamic;
        print-time yes;
        print-severity yes;
        print-category yes;
    };
    
    category security { tsig_log; };
    category xfer-in { tsig_log; };
    category xfer-out { tsig_log; };
};

# Log dizinini oluştur
mkdir -p /var/log/named
chown bind:bind /var/log/named

# Canlı log takibi
tail -f /var/log/named/tsig.log

Yaygın hata mesajları ve anlamları:

  • “tsig indicates error”: Anahtar eşleşmiyor veya yanlış algoritma kullanılıyor
  • “clock skew too great”: Sunucular arasında saat farkı 5 dakikayı aşıyor
  • “NOTAUTH”: Transfer isteği yetkilendirilmedi, key eksik veya yanlış
  • “REFUSED”: IP bazlı ACL engeli, key doğru olsa bile IP izin listesinde yoksa reddedilir
# TSIG hatası debug örneği
# Sunucu logunda şunu görürseniz:
# client @0x... 192.168.1.20#54321: zone transfer 'example.com/AXFR/IN' denied

# named.conf'da loglama açık değilse syslog'a bak
journalctl -u named -f --since "1 hour ago"
grep -i "tsig|transfer|refused" /var/log/syslog

AppArmor ve SELinux Uyumluluğu

Ubuntu’da AppArmor, RHEL/Rocky’de SELinux BIND’ın dosya erişimlerini kısıtlar. TSIG key dosyaları için ek izinler gerekebilir.

# SELinux için (RHEL/Rocky)
# Key dosyasına doğru context ata
semanage fcontext -a -t named_conf_t "/etc/bind/keys(/.*)?"
restorecon -Rv /etc/bind/keys/

# AppArmor için (Ubuntu)
# /etc/apparmor.d/usr.sbin.named dosyasına ekle:
# /etc/bind/keys/** r,
# Sonra profili yeniden yükle:
apparmor_parser -r /etc/apparmor.d/usr.sbin.named

Güvenlik Sertleştirme Kontrol Listesi

TSIG kurulumunu tamamladıktan sonra şu maddeleri kontrol edin:

  • allow-transfer { none; } global olarak tanımlandı mı, sadece belirli zone’larda TSIG ile override ediliyor mu
  • TSIG key dosyalarının izinleri 640 ve sahibi root:bind olarak ayarlı mı
  • Her secondary sunucu için ayrı TSIG anahtarı kullanılıyor mu
  • NTP servisinin çalıştığı ve sunucular arası saat farkının 5 dakika altında olduğu doğrulandı mı
  • TSIG anahtarları için rotasyon takvimi planlandı mı
  • Log dosyaları düzenli olarak izleniyor mu, anomali tespiti var mı
  • Zone transfer logları güvenlik SIEM sistemine gönderiliyor mu
  • TSIG key içeriği versiyon kontrol sistemine (Git vb.) asla commit edilmedi mi

Sonuç

TSIG kurulumu ilk bakışta karmaşık görünse de adımları takip ettiğinizde oldukça anlaşılır bir yapısı olduğunu göreceksiniz. Esas mesele anahtar yönetimini disiplinli sürdürmektir. Oluşturduğunuz anahtarların yedeğini alın, rotasyon planı yapın ve log izlemeyi ihmal etmeyin.

Gerçek hayatta karşılaştığım en yaygın hata şu oluyor: sistem yöneticisi TSIG’i kuruyor ama allow-transfer { none; } direktifini global olarak eklemeyi unutuyor. Böyle bir durumda TSIG olmadan da transfer mümkün olmaya devam ediyor. Bu yüzden kurulumdan hemen sonra mutlaka yetkisiz dig AXFR komutuyla test yapın.

TSIG tek başına yeterli bir DNS güvenlik çözümü değildir. DNSSEC ile birlikte kullanıldığında çok daha sağlam bir altyapı elde edersiniz: TSIG sunucular arası iletişimi korurken DNSSEC son kullanıcıya kadar olan zinciri güvence altına alır. DNS güvenliğini katmanlı düşünün ve her katmanı ayrı ayrı sağlamlaştırın.

Yorum yapın