Unbound’da RPZ ile DNS Tabanlı İçerik Filtreleme
DNS filtreleme deyince aklınıza ne geliyor? Çoğu sysadmin “Pi-hole kurarım olur biter” diye düşünür. Pi-hole harika bir araç, bunu tartışmıyorum. Ama kurumsal bir ortamda, özellikle kendi Unbound altyapınız varsa, RPZ (Response Policy Zones) ile çok daha esnek ve güçlü bir filtreleme mekanizması kurabilirsiniz. Bu yazıda size Unbound’da RPZ’yi nasıl yapılandıracağınızı, gerçek dünya senaryolarında nasıl kullanacağınızı ve olası tuzaklardan nasıl kaçınacağınızı anlatacağım.
RPZ Nedir ve Neden Önemlidir?
RPZ, DNS sunucunuzun belirli alan adlarına verdiği cevapları manipüle etmenize olanak tanıyan bir mekanizmadır. IETF tarafından standartlaştırılan bu yapı, önce BIND’da hayat buldu, Unbound ise 1.14.0 sürümüyle birlikte RPZ desteğini getirdi.
Klasik DNS filtreleme yaklaşımlarına göre RPZ’nin avantajları şunlardır:
- Standart format: RPZ, DNS zone dosyası formatını kullandığı için farklı platformlar arasında taşınabilir
- Merkezi yönetim: Tek bir zone dosyasını güncelleyerek tüm filtreleme kurallarınızı yönetebilirsiniz
- Zengin aksiyon seçenekleri: Sadece “engelle” değil, yönlendir, NXDOMAIN döndür, NODATA döndür gibi farklı aksiyonlar tanımlayabilirsiniz
- Otomatik güncelleme: Zone transfer mekanizmasıyla filtreleme listelerinizi otomatik olarak güncelleyebilirsiniz
- Entegrasyon kolaylığı: Threat intelligence feed’leriyle doğrudan entegre edilebilir
Unbound’da RPZ Desteği: Ön Koşullar
Önce Unbound versiyonunuzu kontrol edin:
unbound -V | head -3
1.14.0 altındaki sürümlerde RPZ desteği yoktur. Eğer eski bir sürüm kullanıyorsanız, güncellemek zorundasınız. Ubuntu/Debian sistemlerde:
apt update && apt install unbound
unbound-checkconf
CentOS/RHEL sistemlerde EPEL reposunu etkinleştirmeniz gerekebilir:
dnf install epel-release
dnf update unbound
Unbound’un RPZ ile derlenip derlenmediğini doğrulamak için:
unbound -V | grep "rpz"
Bu komutun çıktısında rpz geçmiyorsa, Unbound’unuz RPZ desteği olmadan derlenmiş demektir. Bu durumda kaynaktan derleme ya da farklı bir repo kullanmak gerekir.
RPZ Zone Dosyası Yapısı
RPZ, standart bir DNS zone dosyasıdır. Fakat bazı özel kayıt türleri ve adlandırma kuralları içerir. Hadi sıfırdan bir RPZ zone dosyası oluşturalım:
mkdir -p /etc/unbound/rpz
cat > /etc/unbound/rpz/blocklist.rpz << 'EOF'
$ORIGIN rpz.local.
$TTL 300
@ SOA localhost. admin.localhost. (
2024010101 ; Serial
3600 ; Refresh
900 ; Retry
604800 ; Expire
300 ) ; Minimum TTL
; Name Server kaydı
@ NS localhost.
; Engellenen alan adları - NXDOMAIN döndür
malware-site.com.rpz.local. CNAME .
phishing-example.net.rpz.local. CNAME .
ads.tracker.io.rpz.local. CNAME .
; Wildcard ile tüm subdomain'leri engelle
*.malware-site.com.rpz.local. CNAME .
; NODATA döndür (alan adı var ama kayıt yok gibi davran)
analytics-heavy.com.rpz.local. CNAME *.
; Özel bir IP'ye yönlendir (walled garden)
blocked-content.org.rpz.local. A 192.168.1.100
EOF
Burada CNAME . (nokta) NXDOMAIN, CNAME *. ise NODATA aksiyonunu temsil eder. Bu RPZ’ye özgü sözleşmelerdir, normal DNS mantığıyla çalışmaz.
Unbound Yapılandırması
RPZ zone dosyanızı oluşturduktan sonra Unbound’a bunu tanıtmanız gerekiyor. /etc/unbound/unbound.conf dosyanıza ya da /etc/unbound/conf.d/ altına yeni bir dosya ekleyin:
cat > /etc/unbound/conf.d/rpz.conf << 'EOF'
rpz:
name: "rpz.local."
zonefile: "/etc/unbound/rpz/blocklist.rpz"
rpz-action-override: nxdomain
rpz-log: yes
rpz-log-name: "blocklist"
tags: ["default"]
EOF
Yapılandırmayı test edin ve servisi yeniden başlatın:
unbound-checkconf
systemctl restart unbound
Burada dikkat etmeniz gereken birkaç parametre var:
- rpz-action-override: Zone dosyasındaki aksiyon ne olursa olsun bu değeri uygular, debug için kullanışlı
- rpz-log: RPZ tarafından işlenen sorguları loglar
- rpz-log-name: Log mesajlarında görünecek etiket, birden fazla RPZ zone’u varsa ayırt etmenizi sağlar
Gerçek Dünya Senaryosu 1: Reklam ve İzleyici Engelleme
Şirketteki kullanıcılardan gelen şikayetler tanıdık geliyordur: “İnternet yavaş, sayfalar geç açılıyor.” Çoğu durumda sorun reklam ağlarından gelen onlarca DNS sorgusu. RPZ ile bu sorguları DNS seviyesinde kesebilirsiniz.
Popüler reklam engelleme listelerini RPZ formatına çeviren bir betik yazalım:
#!/bin/bash
# hosts formatındaki listeleri RPZ formatına çevirir
HOSTS_URL="https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts"
RPZ_FILE="/etc/unbound/rpz/ads.rpz"
RPZ_ZONE="ads.rpz.local."
SERIAL=$(date +%Y%m%d%H)
# Geçici dosya
TMP=$(mktemp)
# Header yaz
cat > "$RPZ_FILE" << HEADER
$ORIGIN ${RPZ_ZONE}
$TTL 300
@ SOA localhost. admin.localhost. (
${SERIAL}
3600
900
604800
300 )
@ NS localhost.
HEADER
# Hosts dosyasını indirip çevir
curl -s "$HOSTS_URL" |
grep "^0.0.0.0" |
grep -v "0.0.0.0 0.0.0.0" |
awk '{print $2}' |
grep -v "^#" |
grep -v "^$" |
sort -u |
while read domain; do
echo "${domain}.${RPZ_ZONE} CNAME ."
done >> "$RPZ_FILE"
echo "RPZ dosyası güncellendi: $(wc -l < $RPZ_FILE) satır"
rm -f "$TMP"
# Unbound'u yeniden yükle
unbound-control reload
Bu betiği cron’a ekleyin:
chmod +x /usr/local/bin/update-rpz-ads.sh
echo "0 3 * * * root /usr/local/bin/update-rpz-ads.sh >> /var/log/rpz-update.log 2>&1" > /etc/cron.d/rpz-update
Gerçek Dünya Senaryosu 2: Kurumsal Güvenlik Politikası
Bir finans şirketinde çalıştığınızı düşünün. Belirli kategorilerdeki siteleri engellemek zorunda olduğunuzu varsayalım: kumar siteleri, sosyal medya (mesai saatlerinde), veya bilinen zararlı yazılım dağıtım noktaları.
Burada farklı bir yaklaşım denenebilir: birden fazla RPZ zone’u tanımlamak ve öncelik sırasıyla çalıştırmak.
cat > /etc/unbound/conf.d/rpz-multi.conf << 'EOF'
# Öncelik 1: Güvenlik tehditleri - her zaman aktif
rpz:
name: "security.rpz.local."
zonefile: "/etc/unbound/rpz/security-threats.rpz"
rpz-log: yes
rpz-log-name: "security"
# Öncelik 2: Yasal zorunluluklar
rpz:
name: "legal.rpz.local."
zonefile: "/etc/unbound/rpz/legal-blocks.rpz"
rpz-log: yes
rpz-log-name: "legal"
# Öncelik 3: Kurumsal politika
rpz:
name: "policy.rpz.local."
zonefile: "/etc/unbound/rpz/corporate-policy.rpz"
rpz-log: yes
rpz-log-name: "policy"
EOF
Unbound, RPZ zone’larını yapılandırma dosyasında göründükleri sıraya göre değerlendirir. İlk eşleşen kural uygulanır. Bu nedenle güvenlik kurallarını her zaman önce tanımlayın.
Walled Garden: Engellenen Siteleri Özel Sayfaya Yönlendirme
NXDOMAIN döndürmek bazen kullanıcı deneyimi açısından kötü olabilir. Kullanıcı “Bu site neden açılmıyor, DNS mi bozuldu?” diye düşünebilir. Daha profesyonel bir yaklaşım, engellenen siteleri bir açıklama sayfasına yönlendirmektir.
Bunun için önce engelleme sunucunuzda bir web servisi kurmanız gerekiyor:
# Nginx ile basit bir engel sayfası
apt install nginx
cat > /etc/nginx/sites-available/blocked << 'EOF'
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/blocked;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
EOF
mkdir -p /var/www/blocked
cat > /var/www/blocked/index.html << 'HTML'
<!DOCTYPE html>
<html>
<head><title>Erişim Engellendi</title></head>
<body>
<h1>Bu içeriğe erişim kurumsal politika gereği engellenmiştir.</h1>
<p>Bilgi için IT departmanıyla iletişime geçin.</p>
</body>
</html>
HTML
ln -s /etc/nginx/sites-available/blocked /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
Şimdi RPZ zone dosyanızda A kaydıyla bu sunucuya yönlendirin:
cat > /etc/unbound/rpz/policy-walled.rpz << 'EOF'
$ORIGIN policy.rpz.local.
$TTL 300
@ SOA localhost. admin.localhost. (
2024010101
3600
900
604800
300 )
@ NS localhost.
; Engellenen siteler walled garden'a yönlenir
social-media-site.com.policy.rpz.local. A 192.168.1.200
*.social-media-site.com.policy.rpz.local. A 192.168.1.200
EOF
RPZ Loglarını İzleme ve Analiz
RPZ ne kadar iş yapıyor? Hangi domainler en çok engelleniyor? Bu soruların cevaplarını bulmak için log analizini otomatikleştirmek işinizi kolaylaştırır:
#!/bin/bash
# RPZ engelleme istatistikleri
# Çalıştırma: ./rpz-stats.sh [son kaç saat]
HOURS=${1:-24}
LOG_FILE="/var/log/unbound/unbound.log"
SINCE=$(date -d "${HOURS} hours ago" "+%b %e %H:%M:%S" 2>/dev/null ||
date -v-${HOURS}H "+%b %e %H:%M:%S")
echo "=== Son ${HOURS} saat RPZ İstatistikleri ==="
echo ""
echo "En çok engellenen 10 domain:"
grep "rpz applied" "$LOG_FILE" |
grep -v "^$" |
awk '{print $NF}' |
sort | uniq -c | sort -rn | head -10
echo ""
echo "Zone bazında engelleme sayıları:"
grep "rpz applied" "$LOG_FILE" |
grep -oP 'rpz-log-name: K[^,]+' |
sort | uniq -c | sort -rn
echo ""
echo "Saatlik engelleme grafiği:"
grep "rpz applied" "$LOG_FILE" |
awk '{print $1, $2, substr($3,1,2)}' |
sort | uniq -c |
awk '{printf "%s %s %s:00 -> %d engellemen", $2, $3, $4, $1}'
Zone Transfer ile Merkezi RPZ Yönetimi
Büyük ortamlarda her sunucuda ayrı ayrı RPZ dosyası güncellemek pratik değil. BIND ile birlikte kullanarak zone transfer mekanizmasından yararlanabilirsiniz. Master BIND sunucusu RPZ zone’unu barındırır, Unbound slave olarak çeker.
BIND tarafında (master):
# named.conf içine eklenecek zone tanımı
zone "rpz.example.com" {
type master;
file "/var/named/rpz.example.com.zone";
allow-transfer { 192.168.1.10; 192.168.1.11; }; # Unbound sunucularının IP'leri
notify yes;
};
Unbound tarafında zone transfer ayarları:
cat >> /etc/unbound/conf.d/rpz.conf << 'EOF'
rpz:
name: "rpz.example.com."
master: 192.168.1.1 # BIND master sunucusu
allow-notify: 192.168.1.1
rpz-log: yes
rpz-log-name: "central-rpz"
fallback-enabled: yes # RPZ erişilemezse normal çözümlemeye dön
EOF
fallback-enabled parametresine dikkat edin. Bu, RPZ zone’u güncellenemediğinde ya da bağlantı koptuğunda DNS çözümlemesinin tamamen durmasını önler. Kurumsal ortamlarda bu parametreyi mutlaka aktif edin.
Sık Karşılaşılan Sorunlar ve Çözümleri
Sorun 1: RPZ kuralları uygulanmıyor
İlk kontrol noktanız her zaman yapılandırma doğrulaması olmalı:
unbound-checkconf /etc/unbound/unbound.conf
# RPZ'nin aktif olup olmadığını kontrol et
unbound-control status | grep rpz
# Test sorgusu
dig @127.0.0.1 engellenmesi-gereken-site.com
Eğer hala çalışmıyorsa, zone dosyanızın söz dizimini kontrol edin. En yaygın hata, alan adlarının sonuna nokta koymamak ya da zone origin’i yanlış belirtmek.
Sorun 2: Meşru siteler engelleniyor (False Positive)
RPZ zone’unuza whitelist mekanizması ekleyebilirsiniz. Unbound’da RPZ zone’ları öncelik sırasına göre işlenir, bu nedenle en yüksek öncelikli zone’a izin verilen domainleri passthru aksiyonuyla ekleyin:
# whitelist.rpz dosyasına ekle
legitimate-but-blocked.com.whitelist.rpz.local. CNAME rpz-passthru.
rpz-passthru özel bir CNAME değeridir. Bu aksiyonla eşleşen domain diğer RPZ kurallarından muaf tutulur ve normal DNS çözümlemesine tabi olur.
Sorun 3: Yüksek CPU kullanımı
Çok büyük RPZ zone dosyaları (100.000+ kayıt) Unbound’un bellek ve CPU kullanımını artırabilir. Bu durumda:
- Zone dosyasını mantıksal parçalara bölün
- Wildcard kurallarını optimize edin, gereksiz subdomain listelerinden kaçının
- Unbound’un
num-threadsdeğerini artırın msg-cache-sizeverrset-cache-sizedeğerlerini gözden geçirin
Güvenlik Notları
RPZ güçlü bir araç ama yanlış ellerde sorun çıkarabilir. Zone dosyalarınıza erişimi kısıtlayın:
chown root:unbound /etc/unbound/rpz/
chmod 750 /etc/unbound/rpz/
chown root:unbound /etc/unbound/rpz/*.rpz
chmod 640 /etc/unbound/rpz/*.rpz
Zone transfer kullanıyorsanız TSIG anahtarları ile kimlik doğrulama ekleyin. Açık zone transfer, saldırganlara hangi siteleri engellediğiniz hakkında değerli bilgi verir.
Ayrıca RPZ’nin DNS over HTTPS veya DNS over TLS kullanan istemcileri etkilemeyeceğini unutmayın. Kurumsal ortamlarda bu alternatifleri engellemek ya da kendi DoH/DoT sunucunuzu kurmak gerekebilir.
Sonuç
Unbound’da RPZ ile DNS tabanlı içerik filtreleme, basit hosts dosyası tabanlı yaklaşımların çok ötesinde bir esneklik sunar. Birden fazla zone, farklı aksiyon türleri, merkezi yönetim ve otomatik güncellemeler ile kurumsal ölçekte güvenilir bir filtreleme altyapısı kurabilirsiniz.
Pratikte gördüğüm en yaygın kullanım senaryosu şu şekilde oluyor: tehdit istihbarat servisleri (örneğin abuse.ch, Spamhaus) zaten RPZ formatında feed sağlıyor, bunları doğrudan Unbound’a bağlayarak sıfır elle müdahaleyle güncel bir güvenlik katmanı elde ediyorsunuz. Buna kurumsal politika kurallarınızı, reklam engelleyicilerinizi ve whitelist’lerinizi ekleyince oldukça sağlam bir yapı ortaya çıkıyor.
Başlarken küçük tutun: tek bir zone, birkaç yüz kural, önce test ortamında. Logları inceleyin, false positive oranını sıfıra yaklaştırdıktan sonra production’a alın. DNS filtreleme, yanlış yapılandırıldığında kullanıcıları meşru sitelere erişemez hale getirebilir. fallback-enabled ve whitelist mekanizmalarını ihmal etmeyin.
