PowerDNS Kurulum ve Temel Yapılandırma Rehberi

DNS altyapısı, bir organizasyonun dijital omurgasının en kritik parçalarından birini oluşturur. Yanlış yapılandırılmış veya güvenilmez bir DNS sunucusu, tüm servislerinizi çökertebilir. PowerDNS, bu noktada öne çıkan, esnekliği ve performansıyla kendini kanıtlamış açık kaynaklı bir DNS çözümüdür. Bu yazıda PowerDNS’i sıfırdan kurup yapılandıracağız, gerçek dünya senaryolarını ele alacağız.

PowerDNS Nedir ve Neden Tercih Edilir?

PowerDNS, 2000’li yılların başından bu yana aktif geliştirilen, kurumsal düzeyde bir DNS sunucusu yazılımıdır. BIND’a kıyasla çok daha modern bir mimariye sahip olması, özellikle büyük ölçekli ortamlarda büyük avantaj sağlar.

PowerDNS’in iki temel bileşeni vardır:

  • PowerDNS Authoritative Server (pdns): Kendi zone’larınız için yetkili DNS sunucusu görevi görür
  • PowerDNS Recursor (pdns-recursor): İstemcilerin DNS sorgularını recursive olarak çözen bileşen

Bu iki bileşen birbirinden bağımsız çalışır. Çoğu kurumsal ortamda her ikisi de aynı altyapıda kullanılır fakat farklı portlarda çalışırlar.

PowerDNS’i BIND’dan ayıran en önemli özellik backend mimarisidir. Verilerinizi düz dosyalarda tutmak yerine MySQL, PostgreSQL, SQLite, LDAP gibi farklı backend’lerde saklayabilirsiniz. Bu, zone yönetimini API üzerinden otomatize etmeyi, web arayüzleri kullanmayı ve büyük zone koleksiyonlarını verimli yönetmeyi mümkün kılar.

Kurulum Öncesi Hazırlık

Önce ortamı hazırlayalım. Bu yazıda Ubuntu 22.04 LTS üzerinde çalışıyoruz. CentOS/RHEL kullanıcıları için farklılıklar olduğunda ayrıca belirteceğiz.

Sistemi güncel hale getirip gerekli ön gereksinimleri yükleyelim:

sudo apt update && sudo apt upgrade -y
sudo apt install -y curl gnupg2 software-properties-common

Önemli bir not: Ubuntu’nun kendi repolarındaki PowerDNS sürümü genellikle geride kalır. Resmi PowerDNS reposunu eklemek çok daha sağlıklıdır.

# PowerDNS resmi repo anahtarını ekle
curl -fsSL https://repo.powerdns.com/FD380FBB-pub.asc | sudo gpg --dearmor -o /usr/share/keyrings/pdns-archive-keyring.gpg

# Repo tanımını ekle
echo "deb [signed-by=/usr/share/keyrings/pdns-archive-keyring.gpg] http://repo.powerdns.com/ubuntu jammy-auth-48 main" | sudo tee /etc/apt/sources.list.d/pdns.list

# Repo önceliğini ayarla
cat << EOF | sudo tee /etc/apt/preferences.d/pdns
Package: pdns-*
Pin: origin repo.powerdns.com
Pin-Priority: 600
EOF

sudo apt update

Şimdi systemd-resolved ile ilgili bir sorun var. Ubuntu’da port 53 genellikle systemd-resolved tarafından kullanılır. Bunu devre dışı bırakmalıyız:

# systemd-resolved'u durdur
sudo systemctl stop systemd-resolved
sudo systemctl disable systemd-resolved

# /etc/resolv.conf dosyasını güncelle
sudo rm /etc/resolv.conf
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf
echo "nameserver 1.1.1.1" | sudo tee -a /etc/resolv.conf

PowerDNS Authoritative Server Kurulumu

Backend olarak MySQL kullanacağız. Bu, production ortamlarda en yaygın tercih edilen kombinasyondur.

# MySQL ve PowerDNS kurulumu
sudo apt install -y mysql-server pdns-server pdns-backend-mysql

# MySQL servisini başlat
sudo systemctl start mysql
sudo systemctl enable mysql

# MySQL güvenlik yapılandırması
sudo mysql_secure_installation

MySQL’de PowerDNS için veritabanı ve kullanıcı oluşturalım:

sudo mysql -u root -p << 'EOF'
CREATE DATABASE powerdns CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'pdns'@'localhost' IDENTIFIED BY 'GucluBirSifre123!';
GRANT ALL PRIVILEGES ON powerdns.* TO 'pdns'@'localhost';
FLUSH PRIVILEGES;
EOF

PowerDNS’in MySQL backend için şema dosyasını içe aktaralım:

# Şema dosyasını bul ve içe aktar
sudo mysql -u pdns -p powerdns < /usr/share/doc/pdns-backend-mysql/schema.mysql.sql

# Tablolar oluşturuldu mu kontrol et
mysql -u pdns -p powerdns -e "SHOW TABLES;"

Bu komut sonucunda comments, cryptokeys, domainmetadata, domains, records, supermasters, tsigkeys tablolarını görmelisiniz. Her şey yolundaysa yapılandırmaya geçebiliriz.

PowerDNS Yapılandırması

Ana yapılandırma dosyası /etc/powerdns/pdns.conf dosyasıdır. Varsayılan dosyayı yedekleyip temiz bir yapılandırma oluşturalım:

sudo cp /etc/powerdns/pdns.conf /etc/powerdns/pdns.conf.bak

sudo tee /etc/powerdns/pdns.conf << 'EOF'
# Temel ayarlar
setuid=pdns
setgid=pdns

# Hangi adreslerde dinleyeceğimiz
local-address=0.0.0.0
local-port=53

# API yapılandırması
api=yes
api-key=BurayayazacaginizGucluBirAPIAnahtari
webserver=yes
webserver-address=127.0.0.1
webserver-port=8081
webserver-allow-from=127.0.0.1,::1

# Backend yapılandırması
launch=gmysql
gmysql-host=127.0.0.1
gmysql-port=3306
gmysql-dbname=powerdns
gmysql-user=pdns
gmysql-password=GucluBirSifre123!
gmysql-dnssec=yes

# Loglama
log-dns-queries=no
log-dns-details=no
loglevel=4

# Güvenlik ayarları
allow-axfr-ips=
master=yes
slave=no

# Performans ayarları
cache-ttl=20
negquery-cache-ttl=60
max-cache-entries=1000000
EOF

Servisi başlatalım ve durum kontrolü yapalım:

sudo systemctl enable pdns
sudo systemctl start pdns
sudo systemctl status pdns

Eğer servis başlamıyorsa log’lara bakın:

sudo journalctl -u pdns -n 50 --no-pager

İlk Zone Oluşturma

Komut satırından pdnsutil aracıyla zone yönetimi yapabiliriz. Örnek olarak ornek.com domain’i için zone oluşturalım:

# Zone oluştur
sudo pdnsutil create-zone ornek.com

# Zone içeriğini düzenle
sudo pdnsutil edit-zone ornek.com

edit-zone komutu bir text editörü açar. Aşağıdaki gibi temel kayıtları ekleyin:

# Alternatif olarak doğrudan kayıt eklemek için
sudo pdnsutil add-record ornek.com @ SOA "ns1.ornek.com. hostmaster.ornek.com. 2024010101 3600 900 604800 300"
sudo pdnsutil add-record ornek.com @ NS ns1.ornek.com.
sudo pdnsutil add-record ornek.com @ NS ns2.ornek.com.
sudo pdnsutil add-record ornek.com @ A 203.0.113.10
sudo pdnsutil add-record ornek.com www A 203.0.113.10
sudo pdnsutil add-record ornek.com mail A 203.0.113.20
sudo pdnsutil add-record ornek.com @ MX "10 mail.ornek.com."
sudo pdnsutil add-record ornek.com ns1 A 203.0.113.1
sudo pdnsutil add-record ornek.com ns2 A 203.0.113.2

Zone kayıtlarını kontrol edelim:

sudo pdnsutil list-zone ornek.com

DNS sorgusu yaparak test edelim:

# Localhost'a sorgu gönder
dig @127.0.0.1 ornek.com A
dig @127.0.0.1 www.ornek.com A
dig @127.0.0.1 ornek.com MX

PowerDNS Recursor Kurulumu ve Yapılandırması

Authoritative server sadece bizim zone’larımız için yanıt verir. İstemcilerin genel internet sorgularını çözebilmesi için Recursor’a ihtiyacımız var.

sudo apt install -y pdns-recursor

Recursor yapılandırması:

sudo tee /etc/powerdns/recursor.conf << 'EOF'
# Dinleme adresi - farklı port kullanıyoruz
local-address=0.0.0.0
local-port=5300

# Forward zone ayarları - kendi zone'larımızı authoritative server'a yönlendir
forward-zones=ornek.com=127.0.0.1:53
forward-zones+=internal.sirket.com=127.0.0.1:53

# Erişim kontrolü - sadece yerel ağdan gelen sorgulara izin ver
allow-from=127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16

# API
api-key=RecursorAPIAnahtari
webserver=yes
webserver-address=127.0.0.1
webserver-port=8082

# Loglama
loglevel=4
log-common-errors=yes

# DNSSEC doğrulama
dnssec=validate

# Performans
max-cache-entries=1000000
cache-ttl=300
EOF
sudo systemctl enable pdns-recursor
sudo systemctl start pdns-recursor
sudo systemctl status pdns-recursor

# Test
dig @127.0.0.1 -p 5300 google.com A
dig @127.0.0.1 -p 5300 ornek.com A

Gerçek Dünya Senaryosu: Kurumsal İç Ağ DNS Yapısı

Diyelim ki bir şirkette çalışıyorsunuz. sirket.local domain’ini iç ağda kullanıyorsunuz, farklı departmanlar farklı subnet’lerde ve DHCP üzerinden DNS dağıtıyorsunuz.

Önce iç zone’u oluşturalım:

sudo pdnsutil create-zone sirket.local

# Temel kayıtlar
sudo pdnsutil add-record sirket.local @ SOA "ns1.sirket.local. admin.sirket.local. 2024010101 3600 900 604800 300"
sudo pdnsutil add-record sirket.local @ NS ns1.sirket.local.
sudo pdnsutil add-record sirket.local ns1 A 192.168.1.10

# Sunucu kayıtları
sudo pdnsutil add-record sirket.local dosya-sunucusu A 192.168.1.20
sudo pdnsutil add-record sirket.local mail-sunucusu A 192.168.1.30
sudo pdnsutil add-record sirket.local vpn A 192.168.1.40
sudo pdnsutil add-record sirket.local intranet A 192.168.1.50

# Departman subdomainleri
sudo pdnsutil add-record sirket.local muhasebe-nas A 192.168.10.5
sudo pdnsutil add-record sirket.local it-helpdesk A 192.168.20.5

Reverse DNS zone’u da oluşturalım. Bu, IP’den hostname’e çözümleme için gerekli:

# 192.168.1.0/24 için reverse zone
sudo pdnsutil create-zone 1.168.192.in-addr.arpa

sudo pdnsutil add-record 1.168.192.in-addr.arpa @ SOA "ns1.sirket.local. admin.sirket.local. 2024010101 3600 900 604800 300"
sudo pdnsutil add-record 1.168.192.in-addr.arpa @ NS ns1.sirket.local.

# PTR kayıtları
sudo pdnsutil add-record 1.168.192.in-addr.arpa 10 PTR ns1.sirket.local.
sudo pdnsutil add-record 1.168.192.in-addr.arpa 20 PTR dosya-sunucusu.sirket.local.
sudo pdnsutil add-record 1.168.192.in-addr.arpa 30 PTR mail-sunucusu.sirket.local.

DNSSEC Yapılandırması

DNSSEC, zone kayıtlarınızı kriptografik olarak imzalamanızı sağlar. PowerDNS ile DNSSEC aktivasyonu oldukça basit:

# Zone için DNSSEC aktif et
sudo pdnsutil secure-zone ornek.com

# Oluşturulan anahtarları görüntüle
sudo pdnsutil show-zone ornek.com

# DS kayıtlarını al (domain registrar'a verilecek)
sudo pdnsutil export-zone-ds ornek.com

Zone imzalamasını kontrol et:

# Zone'u kontrol et
sudo pdnsutil check-zone ornek.com

# DNSSEC imzasını doğrula
dig @127.0.0.1 ornek.com DNSKEY
dig @127.0.0.1 ornek.com +dnssec

export-zone-ds komutunun çıktısını domain registrar’ınızın yönetim paneline DS kaydı olarak eklemeniz gerekiyor. Bu adım olmadan DNSSEC zinciri tamamlanmaz.

API ile Zone Yönetimi

PowerDNS REST API, otomasyon için güçlü bir araçtır. Özellikle Ansible, Terraform veya kendi scriptlerinizle entegrasyon yaparken çok işe yarar.

# Tüm zone'ları listele
curl -s -H "X-API-Key: BurayayazacaginizGucluBirAPIAnahtari" 
  http://127.0.0.1:8081/api/v1/servers/localhost/zones | python3 -m json.tool

# Yeni zone oluştur
curl -s -X POST 
  -H "X-API-Key: BurayayazacaginizGucluBirAPIAnahtari" 
  -H "Content-Type: application/json" 
  -d '{"name": "yenidomain.com.", "kind": "Native", "nameservers": ["ns1.yenidomain.com.", "ns2.yenidomain.com."]}' 
  http://127.0.0.1:8081/api/v1/servers/localhost/zones

# Zone detaylarını görüntüle
curl -s -H "X-API-Key: BurayayazacaginizGucluBirAPIAnahtari" 
  http://127.0.0.1:8081/api/v1/servers/localhost/zones/ornek.com. | python3 -m json.tool

DNS kaydı eklemek için PATCH metodu kullanılır:

curl -s -X PATCH 
  -H "X-API-Key: BurayayazacaginizGucluBirAPIAnahtari" 
  -H "Content-Type: application/json" 
  -d '{
    "rrsets": [{
      "name": "api-test.ornek.com.",
      "type": "A",
      "ttl": 300,
      "changetype": "REPLACE",
      "records": [{"content": "203.0.113.100", "disabled": false}]
    }]
  }' 
  http://127.0.0.1:8081/api/v1/servers/localhost/zones/ornek.com.

Güvenlik Sertleştirmesi

Bir DNS sunucusu internete açıksa güvenlik konfigürasyonu kritik önem taşır.

Firewall kurallarını ayarlayalım:

# UFW ile temel kural seti
sudo ufw allow 53/tcp
sudo ufw allow 53/udp
sudo ufw allow 22/tcp

# API portu sadece localhost'tan erişilebilir olmalı
sudo ufw deny 8081/tcp
sudo ufw deny 8082/tcp

# Recursor sadece iç ağdan erişilebilir
sudo ufw allow from 192.168.0.0/16 to any port 5300

sudo ufw enable

Zone transfer güvenliği için pdns.conf’a ekleme yapın:

sudo tee -a /etc/powerdns/pdns.conf << 'EOF'
# AXFR sadece slave sunuculara izin ver
# allow-axfr-ips=192.168.1.11,192.168.1.12

# DNS amplification saldırılarına karşı
max-tcp-connections=20
max-udp-queries-per-round=1000
EOF

Rate limiting için Recursor tarafına da ekleyelim:

sudo tee -a /etc/powerdns/recursor.conf << 'EOF'
# Her IP için saniyede maksimum sorgu
max-qperq=50
max-total-msec=7000

# Açık resolver olarak kullanılmayı engelle
any-to-tcp=yes
EOF

İzleme ve Log Yönetimi

Production ortamda DNS sorgularını izlemek ve anormal aktiviteleri tespit etmek önemlidir.

# Anlık sorgu istatistikleri
sudo pdns_control show '*'

# Cache istatistikleri
sudo pdns_control show cache-hits
sudo pdns_control show cache-misses
sudo pdns_control show latency

# Recursor istatistikleri
sudo rec_control get all
sudo rec_control get questions
sudo rec_control get servfails

Özel bir izleme scripti oluşturalım:

sudo tee /usr/local/bin/pdns-monitor.sh << 'EOF'
#!/bin/bash

echo "=== PowerDNS Durum Raporu $(date) ==="
echo ""
echo "--- Authoritative Server ---"
echo "Servis durumu: $(systemctl is-active pdns)"
echo "Cache hits: $(sudo pdns_control show cache-hits 2>/dev/null)"
echo "Cache misses: $(sudo pdns_control show cache-misses 2>/dev/null)"
echo "Ortalama gecikme: $(sudo pdns_control show latency 2>/dev/null) microsaniye"
echo ""
echo "--- Recursor ---"
echo "Servis durumu: $(systemctl is-active pdns-recursor)"
echo "Toplam sorgu: $(sudo rec_control get questions 2>/dev/null)"
echo "SERVFAIL sayisi: $(sudo rec_control get servfails 2>/dev/null)"
echo "Cache boyutu: $(sudo rec_control get cache-entries 2>/dev/null)"
EOF

sudo chmod +x /usr/local/bin/pdns-monitor.sh

Crontab’a ekleyerek periyodik rapor alabilirsiniz:

echo "*/15 * * * * root /usr/local/bin/pdns-monitor.sh >> /var/log/pdns-monitor.log 2>&1" | sudo tee /etc/cron.d/pdns-monitor

Sık Karşılaşılan Sorunlar ve Çözümleri

Port 53 zaten kullanımda hatası: systemd-resolved devre dışı bırakıldıktan sonra bile ss -tulpn | grep :53 ile kontrol edin. Bazen başka bir süreç port’u tutuyor olabilir.

MySQL bağlantı hatası: pdns.conf dosyasındaki şifrenin MySQL’deki şifreyle birebir eşleştiğinden emin olun. Özel karakterler bazen sorun çıkarabilir, şifreyi tırnak içine alın.

Zone kayıtları sorgu yaparken görünmüyor: Serial numarasını artırmayı unutmuş olabilirsiniz. pdnsutil increase-serial ornek.com komutu kullanın.

DNSSEC doğrulama başarısız: Recursor’daki dnssec=validate ayarı etkinse ve zone imzalama sorunluysa, geçici olarak dnssec=off yapıp sorunu izole edin.

API yanıt vermiyor: webserver-allow-from ayarını kontrol edin. Uzak bir makineden erişmeye çalışıyorsanız IP adresinizi bu listeye eklemeniz gerekiyor.

Yedekleme Stratejisi

MySQL backend kullandığımız için zone verilerini yedeklemek kolay:

sudo tee /usr/local/bin/pdns-backup.sh << 'EOF'
#!/bin/bash
BACKUP_DIR="/var/backups/powerdns"
DATE=$(date +%Y%m%d_%H%M%S)

mkdir -p $BACKUP_DIR

# Veritabanı yedekle
mysqldump -u pdns -pGucluBirSifre123! powerdns > $BACKUP_DIR/powerdns_$DATE.sql

# Yapılandırma dosyalarını yedekle
tar -czf $BACKUP_DIR/pdns_config_$DATE.tar.gz /etc/powerdns/

# 30 günden eski yedekleri sil
find $BACKUP_DIR -name "*.sql" -mtime +30 -delete
find $BACKUP_DIR -name "*.tar.gz" -mtime +30 -delete

echo "Yedekleme tamamlandi: $DATE"
EOF

sudo chmod +x /usr/local/bin/pdns-backup.sh
echo "0 2 * * * root /usr/local/bin/pdns-backup.sh >> /var/log/pdns-backup.log 2>&1" | sudo tee /etc/cron.d/pdns-backup

Sonuç

PowerDNS, esnek backend mimarisi, güçlü REST API’si ve aktif geliştirme topluluğuyla kurumsal DNS altyapıları için sağlam bir seçimdir. MySQL backend ile kurduğumuz bu yapı, web arayüzü (PowerDNS-Admin gibi), Ansible entegrasyonu veya kendi yazdığınız otomasyon araçlarıyla kolayca genişletilebilir.

Özellikle birden fazla zone yöneten, DNS değişikliklerini otomatize etmek isteyen veya DNSSEC kullanmayı planlayan ekipler için PowerDNS, BIND’a göre çok daha az acı verici bir deneyim sunuyor. Kurulum sonrası mutlaka pdnsutil check-all-zones komutunu çalıştırın ve monitoring altyapınızı kurmadan servisi production’a almayın.

Bir sonraki yazıda PowerDNS-Admin web arayüzünün kurulumunu ve Master/Slave replikasyon yapılandırmasını ele alacağız.

Yorum yapın