Unbound DNS Sunucusunda Allowlist ve Blocklist Yönetimi ile Özelleştirilmiş Filtreleme

Ağ yönetiminde DNS filtreleme, hem güvenlik hem de performans açısından kritik bir rol oynar. Unbound DNS sunucusu, bu filtrelemeyi oldukça esnek bir şekilde yapmanıza olanak tanır. İster belirli alan adlarını tamamen engellemek, ister yalnızca belirli kaynaklara izin vermek isteyin, Unbound’un sunduğu yapılandırma seçenekleri bu ihtiyaçları karşılamak için yeterince güçlüdür. Bu yazıda, Unbound üzerinde allowlist ve blocklist yönetimini, özelleştirilmiş filtreleme tekniklerini ve bunları gerçek dünya senaryolarında nasıl uygulayabileceğinizi detaylıca ele alacağız.

Unbound’da Filtreleme Mantığı Nasıl Çalışır?

Unbound, DNS sorgularını işlerken birkaç farklı katmanda müdahale imkânı sunar. Bu katmanların mantığını anlamadan filtreleme yapmaya çalışmak, beklenmedik sonuçlar doğurabilir.

Temel olarak iki yaklaşım vardır:

  • local-zone direktifi: Belirli bir alan adı için yerel bir yanıt tanımlar. Bu yanıt “refuse”, “static”, “redirect”, “transparent” gibi farklı türlerde olabilir.
  • local-data direktifi: Belirli bir alan adı için özel bir DNS kaydı döndürür.
  • response-ip direktifi: Belirli IP adreslerinden gelen yanıtları filtreler.
  • rpz (Response Policy Zone): Daha gelişmiş politika tabanlı filtreleme için kullanılır.

Blocklist mantığında, engellemek istediğiniz alan adları için local-zone "example.com" refuse veya local-zone "example.com" static kullanırsınız. Allowlist mantığında ise belirli alan adlarını izin verilen listede tutarken geri kalanları engellersiniz.

Temel Blocklist Yapılandırması

En basit engelleme yöntemi, Unbound’un ana yapılandırma dosyasına local-zone direktifleri eklemektir. Ancak bunu doğrudan unbound.conf dosyasına yazmak yerine ayrı bir dosyaya alıp include ile çağırmak çok daha yönetilebilir bir yapı oluşturur.

Öncelikle blocklist dosyasını oluşturalım:

sudo mkdir -p /etc/unbound/lists
sudo touch /etc/unbound/lists/blocklist.conf

Blocklist dosyasının içeriği şu formatta olur:

cat /etc/unbound/lists/blocklist.conf
server:
    local-zone: "malware-site.com" refuse
    local-zone: "adtracker.net" refuse
    local-zone: "phishing-domain.org" refuse
    local-zone: "tracking.example.com" refuse

refuse türü, DNS sorgusuna REFUSED yanıtı döndürür. Alternatif olarak static kullanırsanız NXDOMAIN yanıtı döner, yani alan adı hiç yokmuş gibi davranır. Güvenlik perspektifinden refuse genellikle daha şeffaftır çünkü istemci bunun kasıtlı bir engelleme olduğunu anlayabilir.

Şimdi bu dosyayı ana yapılandırmaya dahil edelim:

sudo nano /etc/unbound/unbound.conf
include: "/etc/unbound/lists/blocklist.conf"

Yapılandırmayı test edip yeniden yükleyelim:

sudo unbound-checkconf
sudo systemctl reload unbound

Büyük Ölçekli Blocklist Yönetimi

Gerçek dünyada yüzlerce veya binlerce alan adını engellemek gerekebilir. Bu durumda listeyi elle yönetmek yerine otomatik güncelleme mekanizmaları kurmak gerekir. Pek çok güvenlik kuruluşu ve topluluk projesi, kötü amaçlı alan adlarının listelerini düzenli olarak yayınlar.

Aşağıdaki script, popüler blocklist kaynaklarından veri çekip Unbound formatına dönüştürür:

#!/bin/bash
# /usr/local/bin/update-blocklist.sh

BLOCKLIST_DIR="/etc/unbound/lists"
BLOCKLIST_FILE="$BLOCKLIST_DIR/auto-blocklist.conf"
TEMP_FILE=$(mktemp)

# Farklı kaynaklardan hostsfile formatında listeler indir
SOURCES=(
    "https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts"
    "https://someonewhocares.org/hosts/hosts"
)

echo "server:" > "$TEMP_FILE"

for SOURCE in "${SOURCES[@]}"; do
    echo "Indiriliyor: $SOURCE"
    curl -s "$SOURCE" | grep -E "^0.0.0.0" | awk '{print $2}' | 
    grep -v "^0.0.0.0$" | 
    grep -v "^localhost" | 
    grep -v "#" | 
    sort -u | while read domain; do
        echo "    local-zone: "$domain" refuse"
    done >> "$TEMP_FILE"
done

# Tekrar eden satırları temizle
sort -u "$TEMP_FILE" > "$BLOCKLIST_FILE"
rm "$TEMP_FILE"

# Yapılandırmayı doğrula ve yeniden yükle
if unbound-checkconf; then
    systemctl reload unbound
    echo "Blocklist guncellendi ve Unbound yeniden yuklendi."
else
    echo "HATA: unbound.conf gecersiz, guncelleme iptal edildi."
    exit 1
fi

Script’e çalıştırma izni verelim ve cron ile düzenli çalışmasını sağlayalım:

sudo chmod +x /usr/local/bin/update-blocklist.sh

# Crontab'a ekleyelim - her gece saat 02:00'de çalışsın
sudo crontab -e
0 2 * * * /usr/local/bin/update-blocklist.sh >> /var/log/blocklist-update.log 2>&1

Allowlist (İzin Listesi) Yapılandırması

Allowlist, blocklist’in tersi bir mantıkla çalışır. Burada iki farklı senaryo söz konusu olabilir:

Birinci senaryo: Genel erişimi açık bırakıp yalnızca belirli alan adlarının engellenmesine izin verirsiniz. Bu zaten standart blocklist yaklaşımıdır.

İkinci senaryo: Varsayılan olarak her şeyi engelleyip yalnızca belirli alan adlarına izin verirsiniz. Bu, özellikle kiosk sistemleri, okul ağları veya kurumsal kısıtlı ortamlar için idealdir.

İkinci senaryo için local-zone hiyerarşisini kullanırız. Önce tüm sorgular için bir varsayılan reddetme politikası belirlenir, ardından izin verilen alan adları ayrıca açılır:

cat /etc/unbound/lists/allowlist.conf
server:
    # Tum sorguları reddet (root zone'u blokla)
    local-zone: "." refuse

    # Izin verilen alan adlarini transparent yap
    local-zone: "google.com." transparent
    local-zone: "github.com." transparent
    local-zone: "ubuntu.com." transparent
    local-zone: "microsoft.com." transparent

    # Dahili DNS cozumlemesine izin ver
    local-zone: "internal.company.com." transparent
    local-zone: "10.in-addr.arpa." transparent
    local-zone: "168.192.in-addr.arpa." transparent

Burada transparent tipi, Unbound’un bu alan adı için normal recursive çözümleme yapmasına olanak tanır. "." ile root zone’u kapatmak tüm bilinmeyen alan adlarını etkiler.

Özel Yönlendirme ve Redirect Kullanımı

Bazen bir alan adını tamamen engellemek yerine başka bir adrese yönlendirmek isteyebilirsiniz. Örneğin, reklam sunucularından gelen istekleri kendi sunucunuzdaki bir karşılama sayfasına yönlendirebilirsiniz:

cat /etc/unbound/lists/redirect.conf
server:
    # Reklam ve takip sitelerini loopback'e yonlendir
    local-zone: "doubleclick.net" redirect
    local-data: "doubleclick.net A 0.0.0.0"

    local-zone: "googlesyndication.com" redirect
    local-data: "googlesyndication.com A 0.0.0.0"

    # Kendi "engellendi" sayfaniza yonlendirme
    local-zone: "banned-site.com" redirect
    local-data: "banned-site.com A 192.168.1.100"

    # AAAA kaydini da engelle (IPv6)
    local-data: "banned-site.com AAAA ::"

redirect tipi kullanıldığında, local-data ile verilen kayıt o alan adının tüm alt alan adlarına da uygulanır. Yani sub.doubleclick.net sorgusu da aynı IP’yi döndürür.

İstemci Bazlı Filtreleme

Unbound, farklı istemcilere farklı filtreleme politikaları uygulamanıza olanak tanır. Bu özellik, özellikle hem çocuklar hem de yetişkinler tarafından kullanılan ağlarda ya da farklı güvenlik gereksinimlerine sahip departmanlar arasında ayrım yapmak için kullanışlıdır.

Bunun için access-control ve view direktiflerini birlikte kullanırız:

cat /etc/unbound/unbound.conf
server:
    # Varsayilan erisim engeli
    access-control: 0.0.0.0/0 refuse
    access-control: ::0/0 refuse

    # Yerel agdan erişime izin ver
    access-control: 127.0.0.1 allow
    access-control: 192.168.1.0/24 allow_snoop
    access-control: 10.10.0.0/16 allow

    # View bazli erisim tanımla
    access-control-view: 192.168.1.0/24 "home-network"
    access-control-view: 10.10.1.0/24 "kids-network"
    access-control-view: 10.10.2.0/24 "corporate-network"

view:
    name: "home-network"
    local-zone: "malware-site.com" refuse

view:
    name: "kids-network"
    local-zone: "malware-site.com" refuse
    local-zone: "adult-content.com" refuse
    local-zone: "gambling-site.com" refuse
    include: "/etc/unbound/lists/kids-blocklist.conf"

view:
    name: "corporate-network"
    local-zone: "socialmedia.com" refuse
    local-zone: "streaming.com" refuse
    include: "/etc/unbound/lists/corporate-blocklist.conf"

Bu yapılandırmayla çocukların kullandığı ağ segmenti daha kapsamlı bir blocklist alırken, kurumsal ağ sosyal medya ve video streaming platformlarını engeller.

RPZ (Response Policy Zone) ile Gelişmiş Filtreleme

Unbound 1.16 ve sonrası, RPZ desteği sunar. RPZ, DNS filtrelemesini standartlaştırılmış bir zone formatında yönetmenizi sağlar ve büyük ölçekli ortamlarda çok daha güçlü bir yaklaşım sunar.

Önce RPZ zone dosyası oluşturalım:

cat /etc/unbound/rpz/blocklist.rpz
$ORIGIN rpz.example.com.
$TTL 3600
@   SOA  localhost. root.localhost. (
            1       ; serial
            3600    ; refresh
            900     ; retry
            604800  ; expire
            300     ; minimum TTL
        )
    NS   localhost.

; Engellenen alan adlari
malware-site.com.rpz-nsdname CNAME .
phishing.com.rpz-nsdname CNAME .
adtracker.net.rpz-nsdname CNAME .

; Engellenen IP araligina yonelen cevaplar
32.1.2.3.4.rpz-ip CNAME .

Unbound yapılandırmasına RPZ zone’u ekleyelim:

cat >> /etc/unbound/unbound.conf << 'EOF'
rpz:
    name: "rpz.example.com"
    zonefile: "/etc/unbound/rpz/blocklist.rpz"
    rpz-action-override: refuse
    rpz-log: yes
    rpz-log-name: "main-rpz"
EOF

RPZ ile birden fazla politika katmanı oluşturabilir, öncelik sırası belirleyebilir ve log takibini çok daha kolay yapabilirsiniz.

Filtreleme Etkinliğini Test Etme

Yapılandırmalarınızın doğru çalışıp çalışmadığını test etmek kritik önem taşır:

# Engellenen bir alan adini test et
dig @localhost malware-site.com

# Beklenen cikti REFUSED veya NXDOMAIN olmali
# Status: REFUSED gorulmeli

# Izin verilen bir alani test et
dig @localhost google.com

# Normal A kaydi donmeli

# Yonlendirilen adresi test et
dig @localhost doubleclick.net
# 0.0.0.0 donmeli

# Unbound istatistiklerini kontrol et
unbound-control stats_noreset | grep -i "query|cache|num"

# Gercek zamanli log takibi
tail -f /var/log/unbound/unbound.log | grep -E "REFUSED|NXDOMAIN|query"

Daha kapsamlı bir test için küçük bir script yazalım:

#!/bin/bash
# /usr/local/bin/test-blocklist.sh

DNS_SERVER="127.0.0.1"

# Test edilecek engellenmis alan adlari
BLOCKED_DOMAINS=(
    "malware-site.com"
    "adtracker.net"
    "phishing-domain.org"
)

# Test edilecek izin verilen alan adlari
ALLOWED_DOMAINS=(
    "google.com"
    "github.com"
    "ubuntu.com"
)

echo "=== ENGELLEME TESTLERI ==="
for domain in "${BLOCKED_DOMAINS[@]}"; do
    result=$(dig @"$DNS_SERVER" "$domain" +short 2>/dev/null)
    status=$(dig @"$DNS_SERVER" "$domain" +noall +comments 2>/dev/null | grep "status:" | awk '{print $4}' | tr -d ',')

    if [[ "$status" == "REFUSED" || "$status" == "NXDOMAIN" ]]; then
        echo "[OK] $domain - $status (Engellendi)"
    else
        echo "[HATA] $domain - $status (Engellenmedi! Kontrol et)"
    fi
done

echo ""
echo "=== ERISIM TESTLERI ==="
for domain in "${ALLOWED_DOMAINS[@]}"; do
    result=$(dig @"$DNS_SERVER" "$domain" +short 2>/dev/null | head -1)
    if [[ -n "$result" ]]; then
        echo "[OK] $domain - $result (Erisilebilir)"
    else
        echo "[HATA] $domain - Yanit alinamadi"
    fi
done

Loglama ve İzleme

Filtrelemenin etkinliğini ölçmek için Unbound’un log mekanizmasını yapılandırmak gerekir:

sudo nano /etc/unbound/unbound.conf
server:
    verbosity: 1
    log-queries: yes
    log-replies: yes
    log-tag-queryreply: yes
    logfile: "/var/log/unbound/unbound.log"

    # Her engellenen sorgu icin ek bilgi
    val-log-level: 1

Log dosyasından engelleme istatistiklerini çıkarmak için:

# Son 24 saat icinde en cok sorgulanan engellenen alanlar
grep "REFUSED" /var/log/unbound/unbound.log | 
    awk '{print $6}' | 
    sort | uniq -c | sort -rn | head -20

# Hangi istemcinin en cok engellemeyle karsilastigini bul
grep "REFUSED" /var/log/unbound/unbound.log | 
    awk '{print $4}' | 
    cut -d'@' -f2 | 
    sort | uniq -c | sort -rn | head -10

Beyaz Liste ile Blocklist Çakışmalarını Yönetmek

Bazen büyük bir blocklist kullanırken belirli alt alan adlarına erişim açmak gerekebilir. Örneğin google.com gibi büyük bir servisi engellemek istemiyorsunuz ama analytics.google.comu engellemek istiyorsunuz. Ya da tam tersi: genel bir blocklist fonts.googleapis.comu engelliyorsa ama siz buna izin vermek istiyorsunuzdur.

Unbound, daha spesifik eşleşmelere öncelik verir. Yani allowlist dosyanızda şunu yapabilirsiniz:

cat /etc/unbound/lists/exceptions.conf
server:
    # Blocklist "fonts.googleapis.com" i engelliyorsa bu satir onu acar
    local-zone: "fonts.googleapis.com." transparent

    # analytics alt alanini engelle ama ana alana dokunma
    local-zone: "analytics.example.com." refuse

    # Belirli bir subdomain'i farkli IP'ye yonlendir
    local-zone: "api.internal.com." redirect
    local-data: "api.internal.com. A 10.0.0.50"

Bu dosyayı unbound.conf‘a include ederken blocklist’ten sonra geldiğinden emin olun. Unbound yapılandırmada sonraki tanımları önce işler, bu yüzden sıralama önemlidir.

Kurumsal Ortamda Gerçek Dünya Senaryosu

Diyelim ki 200 kişilik bir şirkette DNS yöneticisisiniz. İnsan kaynakları departmanı sosyal medyaya erişebilecek ama üretim sunucuları kesinlikle sadece paket depolarına bağlanabilecek. Geliştirici makineleri ise genel erişime açık olacak.

Bunun için şu yapıyı kurabilirsiniz:

  • 10.10.1.0/24: Sunucu ağı – sadece paket repoları, update servisleri
  • 10.10.2.0/24: İdari ofis – sosyal medya dahil genel erişim, zararlı site engeli
  • 10.10.3.0/24: İK departmanı – LinkedIn gibi seçili sosyal medya açık

Her ağ segmenti için ayrı bir blocklist dosyası oluşturun, view direktifleriyle bu segmentlere atayın ve günlük otomatik güncellemelerle listeleri güncel tutun. Loglama ile hangi departmandan hangi alan adlarına istek geldiğini takip edin ve bu verilerle listeleri ince ayar yapın.

Sonuç

Unbound DNS sunucusunda allowlist ve blocklist yönetimi, ilk bakışta basit görünse de üretim ortamında dikkatli bir planlama gerektirir. local-zone direktiflerinin farklı tipleri, view yapısıyla segmentasyon, RPZ ile standartlaştırılmış politika yönetimi ve otomatik liste güncellemeleri birlikte kullanıldığında son derece güçlü bir filtreleme altyapısı ortaya çıkar.

En önemli nokta, yapılandırmalarınızı düzenli olarak test etmek ve loglama ile filtrelemenin etkinliğini ölçmektir. Engellediğinizi sandığınız bir alan adının aslında erişilebilir olması ya da yanlışlıkla kritik bir servisi engellemeniz, her ikisi de ciddi operasyonel sorunlara yol açabilir. unbound-checkconf komutunu her değişiklikten sonra çalıştırma alışkanlığı edinin ve büyük değişiklikleri önce test ortamında deneyin. Listeleri manuel yönetmek yerine script tabanlı otomatik güncelleme mekanizmaları kurmak, uzun vadede hem zaman kazandırır hem de güvenlik açıklarının zamanında kapatılmasını sağlar.

Bir yanıt yazın

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