DNS altyapısı, bir sistemin en kritik bileşenlerinden biridir ve yüksek trafikli ortamlarda yanlış yapılandırılmış bir DNS sunucusu tüm hizmetlerin çökmesine yol açabilir. PowerDNS, esnekliği ve modüler yapısıyla kurumsal ortamlarda yaygın olarak tercih edilen bir çözüm olmakla birlikte, varsayılan ayarlarla çalıştırdığınızda orta ölçekli bir yük altında bile beklenmedik darboğazlar yaşayabilirsiniz. Bu yazıda, saniyede binlerce sorgu alan ortamlarda PowerDNS’i nasıl optimize edeceğinizi, hangi parametrelere dikkat etmeniz gerektiğini ve gerçek dünya senaryolarından öğrendiklerimizi paylaşacağım.
Performans Sorunlarını Anlamak
Bir PowerDNS sunucusunda performans sorunu yaşadığınızda ilk yapmanız gereken şey mevcut durumu ölçmektir. Tahmin yürütmek yerine veriyi konuşturun.
PowerDNS, oldukça zengin bir istatistik arayüzü sunar. pdns_control komutu ile anlık metriklere ulaşabilirsiniz:
# Temel istatistikleri görüntüle
pdns_control show *
# Saniyedeki sorgu sayısını izle
watch -n 1 'pdns_control show udp-queries'
# Gecikme istatistikleri
pdns_control show latency
pdns_control show query-cache-hit
pdns_control show query-cache-miss
Bu çıktıları düzenli aralıklarla kayıt altına almak, sorunun ne zaman başladığını ve hangi metriğin anormal değerlere ulaştığını anlamanızı sağlar. Örneğin, cache hit oranı %60’ın altına düşüyorsa önbellek yapılandırmanızda ciddi bir sorun var demektir. Tipik olarak yüksek trafikli bir DNS sunucusunda bu oran %85-95 arasında olmalıdır.
Temel Yapılandırma Dosyası Optimizasyonu
PowerDNS’in ana yapılandırma dosyası genellikle /etc/pdns/pdns.conf veya /etc/powerdns/pdns.conf konumunda bulunur. Varsayılan değerler küçük ölçekli ortamlar için belirlenmiştir ve üretim ortamında mutlaka değiştirilmesi gerekir.
# Mevcut yapılandırmayı yedekle
cp /etc/powerdns/pdns.conf /etc/powerdns/pdns.conf.backup
# Yapılandırma dosyasını düzenle
nano /etc/powerdns/pdns.conf
Temel performans parametrelerini şu şekilde ayarlayabilirsiniz:
# Thread ve işlemci ayarları
receiver-threads=4
distributor-threads=3
# Sorgu önbelleği
cache-ttl=60
query-cache-ttl=20
negquery-cache-ttl=60
# Paket tamponu
udp-truncation-threshold=1680
# Bağlantı zaman aşımı
tcp-idle-timeout=5
# Maksimum TCP bağlantısı
max-tcp-connections=1000
# Loglama seviyesini düşür (production ortamında)
loglevel=3
log-dns-queries=no
log-dns-details=no
receiver-threads: UDP paketlerini dinleyen thread sayısını belirtir. Sunucunuzdaki fiziksel CPU çekirdek sayısının yarısına eşit ayarlamak iyi bir başlangıç noktasıdır.
distributor-threads: Backend veritabanı sorgularını işleyen thread sayısıdır. Bu değer, veritabanı bağlantı havuzunuzla orantılı olmalıdır.
cache-ttl: Yanıtların önbellekte tutulma süresi. Çok düşük ayarlamak backend yükünü artırır, çok yüksek ayarlamak ise DNS değişikliklerinin geç yayılmasına neden olur.
Önbellek Stratejileri
Önbellek, yüksek trafikli ortamlarda performansın kalbidir. PowerDNS’te üç farklı önbellek mekanizması bulunur ve her biri farklı senaryolar için optimize edilmelidir.
Sorgu Önbelleği
# pdns.conf içinde
cache-ttl=120
query-cache-ttl=30
max-cache-entries=2000000
max-packet-cache-entries=1000000
max-cache-entries değerini belirlerken her girişin yaklaşık 1KB yer kapladığını göz önünde bulundurun. 2 milyon giriş için yaklaşık 2GB RAM ayırmanız gerekebilir.
Önbellek etkinliğini izlemek için şu scripti kullanabilirsiniz:
#!/bin/bash
# dns_cache_monitor.sh
while true; do
HITS=$(pdns_control show query-cache-hit)
MISS=$(pdns_control show query-cache-miss)
TOTAL=$((HITS + MISS))
if [ $TOTAL -gt 0 ]; then
RATIO=$(echo "scale=2; $HITS * 100 / $TOTAL" | bc)
echo "$(date): Cache Hit Rate: ${RATIO}% (Hits: $HITS, Miss: $MISS)"
fi
sleep 10
done
Negatif Önbellek
Var olmayan domainler için yapılan sorgular da önemli bir yük oluşturur. Özellikle botnet trafiği veya yanlış yapılandırılmış uygulamalar, sürekli aynı hatalı domainleri sorgulayabilir.
# Negatif yanıtları önbellekte tut
negquery-cache-ttl=60
Bu değeri fazla yüksek ayarlamak, yeni eklenen kayıtların geç görünmesine neden olabilir. 60-120 saniye arasında tutmak çoğu senaryo için idealdir.
Backend Veritabanı Optimizasyonu
PowerDNS’in performansı büyük ölçüde kullandığı backend’e bağlıdır. MySQL, PostgreSQL veya SQLite gibi veritabanı tabanlı backend’lerde yanlış indeksleme, yüksek trafikte felakete yol açabilir.
MySQL/MariaDB Backend
# MySQL bağlantı ayarları pdns.conf içinde
launch=gmysql
gmysql-host=127.0.0.1
gmysql-port=3306
gmysql-dbname=pdns
gmysql-user=pdns
gmysql-password=guvenli_sifre
gmysql-dnssec=no
Veritabanı tarafında kritik indekslerin varlığını kontrol edin:
# MySQL'e bağlan ve indeksleri kontrol et
mysql -u pdns -p pdns -e "
SHOW INDEX FROM records;
SHOW INDEX FROM domains;
"
Eksik indeksleri oluşturmak için:
mysql -u pdns -p pdns << 'EOF'
-- En kritik indeksler
ALTER TABLE records ADD INDEX rec_name_type_idx (name, type);
ALTER TABLE records ADD INDEX nametype_index (name, type);
ALTER TABLE domains ADD INDEX search_key (name);
-- Sorgu performansını optimize etmek için
ALTER TABLE records ENGINE=InnoDB ROW_FORMAT=COMPRESSED;
ANALYZE TABLE records;
ANALYZE TABLE domains;
EOF
MySQL bağlantı havuzu için de özel ayarlar yapmanız gerekebilir:
# pdns.conf - MySQL bağlantı havuzu
gmysql-socket=/var/run/mysqld/mysqld.sock
# Unix socket kullanmak TCP'den çok daha hızlıdır
PostgreSQL Backend
PostgreSQL kullananlar için benzer optimizasyonlar şu şekilde yapılır:
# PostgreSQL ayarları pdns.conf içinde
launch=gpgsql
gpgsql-host=127.0.0.1
gpgsql-dbname=pdns
gpgsql-user=pdns
gpgsql-password=guvenli_sifre
# Bağlantı havuzu boyutu
# Her distributor-thread için bir bağlantı açılır
İşletim Sistemi Düzeyinde Tuning
PowerDNS ne kadar iyi yapılandırılmış olursa olsun, işletim sistemi düzeyindeki kısıtlamalar performansı sınırlayabilir.
Ağ Tamponu Ayarları
# Kernel parametrelerini ayarla
cat >> /etc/sysctl.conf << 'EOF'
# UDP tampon boyutlarını artır
net.core.rmem_max=26214400
net.core.rmem_default=1048576
net.core.wmem_max=26214400
net.core.wmem_default=1048576
# Bağlantı kuyruğunu genişlet
net.core.somaxconn=65535
net.core.netdev_max_backlog=65535
# TCP zaman damgalarını etkinleştir
net.ipv4.tcp_timestamps=1
# Ephemeral port aralığını genişlet
net.ipv4.ip_local_port_range=1024 65535
EOF
# Değişiklikleri uygula
sysctl -p
Dosya Tanımlayıcısı Limitleri
Yüksek trafikli ortamlarda dosya tanımlayıcısı limitlerine çarpmak oldukça yaygındır:
# Mevcut limiti kontrol et
ulimit -n
cat /proc/$(pgrep pdns_server)/limits | grep "open files"
# /etc/security/limits.conf dosyasına ekle
cat >> /etc/security/limits.conf << 'EOF'
pdns soft nofile 65535
pdns hard nofile 65535
root soft nofile 65535
root hard nofile 65535
EOF
# systemd servisi için de ayarla
mkdir -p /etc/systemd/system/pdns.service.d/
cat > /etc/systemd/system/pdns.service.d/limits.conf << 'EOF'
[Service]
LimitNOFILE=65535
EOF
systemctl daemon-reload
systemctl restart pdns
CPU Affinity Ayarları
Çok çekirdekli sistemlerde CPU affinity ayarları, önbellek performansını önemli ölçüde artırabilir:
# PowerDNS process'inin PID'ini bul
PDNS_PID=$(pgrep pdns_server)
# Belirli CPU çekirdeklerine bağla (0-7 arası 8 çekirdek)
taskset -cp 0-7 $PDNS_PID
# NUMA sistemlerde node'a göre bağlama
numactl --cpunodebind=0 --membind=0 /usr/sbin/pdns_server --daemon
Yük Dengeleme ve Yatay Ölçeklendirme
Tek bir sunucu yeterli gelmediğinde yatay ölçeklendirme kaçınılmaz olur. PowerDNS, birden fazla sunucuyla çalışacak şekilde tasarlanmıştır.
Anycast DNS Yapılandırması
Büyük ölçekli ortamlarda anycast, DNS sorgularını en yakın sunucuya yönlendirmek için idealdir. BGP konfirgürasyonu ağ ekibiyle koordineli yürütülmeli, PowerDNS tarafında ise şu ayarlar yapılmalıdır:
# Her sunucuda aynı sanal IP'yi dinle
local-address=192.0.2.1,10.0.0.1
# Her sunucu aynı yapılandırmayı çalıştırır
# Veritabanı senkronizasyonu için replikasyon kurulur
Slave-Master Replikasyon
# Master sunucu ayarları
master=yes
slave=no
also-notify=192.168.1.10,192.168.1.11
# Slave sunucu ayarları
slave=yes
master=no
slave-cycle-interval=60
Replikasyon durumunu izlemek için:
# Slave sunucuda
pdns_control retrieve example.com
pdns_control show slave-updates-run
# Zone transfer durumunu kontrol et
pdns_control show udp-answers
Monitoring ve Alerting
Sorun büyümeden fark etmek, sysadmin’in en önemli görevlerinden biridir. PowerDNS için kapsamlı bir monitoring kurulumu şu metrikleri takip etmelidir:
#!/bin/bash
# pdns_health_check.sh
# Bu scripti cron'a ekleyin: */5 * * * * /usr/local/bin/pdns_health_check.sh
ALERT_EMAIL="[email protected]"
THRESHOLD_LATENCY=10 # milisaniye
THRESHOLD_CACHE_HIT=70 # yüzde
# Latency kontrolü
LATENCY=$(pdns_control show latency | awk -F= '{print $2}')
if [ "$LATENCY" -gt "$THRESHOLD_LATENCY" ]; then
echo "UYARI: DNS latency yüksek: ${LATENCY}ms" |
mail -s "PowerDNS Latency Alert" $ALERT_EMAIL
fi
# Cache hit oranı kontrolü
HITS=$(pdns_control show query-cache-hit)
MISS=$(pdns_control show query-cache-miss)
TOTAL=$((HITS + MISS))
if [ $TOTAL -gt 0 ]; then
RATIO=$((HITS * 100 / TOTAL))
if [ $RATIO -lt $THRESHOLD_CACHE_HIT ]; then
echo "UYARI: Cache hit oranı düşük: ${RATIO}%" |
mail -s "PowerDNS Cache Alert" $ALERT_EMAIL
fi
fi
# Servis durumu kontrolü
if ! systemctl is-active --quiet pdns; then
echo "KRİTİK: PowerDNS servisi çalışmıyor!" |
mail -s "PowerDNS DOWN" $ALERT_EMAIL
systemctl restart pdns
fi
Prometheus ve Grafana kullanıyorsanız, PowerDNS’in dahili metrics endpoint’ini etkinleştirin:
# pdns.conf
webserver=yes
webserver-address=127.0.0.1
webserver-port=8081
webserver-password=guvenli_sifre
api=yes
api-key=api_anahtariniz
Gerçek Dünya Senaryosu: E-ticaret Platformu
Bir e-ticaret platformunda yaşanan gerçek bir senaryoyu paylaşayım. Saniyede yaklaşık 15.000 DNS sorgusu alan bir ortamda, kampanya dönemlerinde bu rakam 45.000’e kadar çıkıyordu. Varsayılan PowerDNS yapılandırmasıyla sistem çöküyor, yanıt süreleri 500ms’nin üzerine çıkıyordu.
Sorunun analizi sonucunda üç temel problem tespit edildi:
- Veritabanı bağlantı havuzu yetersizdi, her sorgu yeni bağlantı açıyordu
- Cache TTL değerleri çok düşük ayarlanmıştı (5 saniye)
- Kernel UDP tampon boyutları yetersizdi
Uygulanan çözümler:
# Optimize edilmiş pdns.conf
receiver-threads=8
distributor-threads=6
cache-ttl=300
query-cache-ttl=60
negquery-cache-ttl=120
max-cache-entries=5000000
max-packet-cache-entries=2000000
loglevel=2
log-dns-queries=no
Veritabanı bağlantısı için PgBouncer gibi bir connection pooler eklendi:
# pgbouncer.ini özet konfigürasyonu
[databases]
pdns = host=127.0.0.1 port=5432 dbname=pdns
[pgbouncer]
pool_mode=transaction
max_client_conn=500
default_pool_size=50
Bu değişikliklerden sonra ortalama yanıt süresi 8ms’ye düştü, cache hit oranı %92’ye çıktı.
Rate Limiting ve DDoS Koruması
Yüksek trafikli ortamlarda kötü niyetli trafik de önemli bir sorun oluşturabilir. PowerDNS’te temel rate limiting şu şekilde yapılandırılır:
# pdns.conf - Rate limiting
max-udp-queries-per-round=10000
# Belirli IP'leri engelle
# /etc/pdns/deny-list.conf
Daha kapsamlı koruma için sistem seviyesinde iptables/nftables kuralları eklenmelidir:
# Saniyede 100'den fazla sorgu yapan IP'leri geçici olarak engelle
iptables -A INPUT -p udp --dport 53 -m hashlimit
--hashlimit-name dns
--hashlimit-above 100/sec
--hashlimit-mode srcip
--hashlimit-burst 200
-j DROP
# TCP için de benzer kural
iptables -A INPUT -p tcp --dport 53 -m hashlimit
--hashlimit-name dns-tcp
--hashlimit-above 20/sec
--hashlimit-mode srcip
--hashlimit-burst 50
-j DROP
# Kuralları kaydet
iptables-save > /etc/iptables/rules.v4
Düzenli Bakım ve Optimizasyon Rutini
Performansı sürdürmek için düzenli bakım şarttır. Aşağıdaki rutini haftalık veya aylık olarak uygulamanızı öneririm:
#!/bin/bash
# pdns_maintenance.sh
echo "=== PowerDNS Bakım Scripti ==="
echo "Tarih: $(date)"
# İstatistikleri kaydet
pdns_control show * > /var/log/pdns/stats_$(date +%Y%m%d).txt
# Önbelleği temizle (gerekirse)
# pdns_control purge
# Veritabanı istatistiklerini güncelle
mysql -u pdns -p"$DB_PASS" pdns -e "ANALYZE TABLE records; ANALYZE TABLE domains;"
# Disk kullanımını kontrol et
df -h /var/lib/mysql
# Log dosyalarını döndür
find /var/log/pdns/ -name "*.log" -mtime +30 -delete
echo "Bakım tamamlandı."
Zone transfer sayısını ve başarısız transferleri de düzenli olarak kontrol edin:
# Son 24 saatteki zone transfer hatalarını kontrol et
grep "AXFR" /var/log/pdns/pdns.log | grep -i "fail|error" | tail -50
Sonuç
PowerDNS’i yüksek trafikli ortamlarda başarıyla çalıştırmak, birden fazla katmandaki optimizasyonun bir arada yürütülmesini gerektirir. Sadece pdns.conf dosyasındaki parametreleri değiştirmek yetmez; veritabanı indeksleri, kernel parametreleri, dosya tanımlayıcısı limitleri ve monitoring altyapısı bir bütün olarak ele alınmalıdır.
En önemli çıkarımlar şunlardır: önce ölç, sonra değiştir. Tahmine dayalı optimizasyon çoğu zaman sorunu çözmek yerine farklı bir soruna yol açar. Cache hit oranı, latency ve sorgu başarı oranı üçlüsünü sürekli izleyin. Değişiklikleri tek tek uygulayın ki hangi değişikliğin ne kadar etki ettiğini bilin.
Kampanya, lansman veya beklenmedik viral trafik gibi ani yük artışlarına karşı hazırlıklı olmak için kapasite planlaması yapın. Mevcut sisteminizin %70 yükünde çalışması, ani artışlar için size tampon alan sağlar. DNS altyapısı göz ardı edildiğinde tüm hizmetleri etkileyen sessiz bir katil haline gelir; düzenli bakım ve proaktif izlemeyle bunu önlemek tamamen mümkündür.