Cloudflare ile Zone Transfer ve Multi-Domain Yönetimi
Onlarca domain yönetmek zorunda kaldığınız bir ortamda, her alan adı için ayrı ayrı DNS kayıtlarını elle girmek hem zaman kaybı hem de hata riski demektir. Cloudflare bu problemi çözmek için oldukça güçlü araçlar sunuyor: Zone Transfer desteği ve API tabanlı multi-domain yönetimi. Bu yazıda hem küçük ajanslar hem de kurumsal ortamlar için gerçek dünya senaryolarıyla bu konuyu ele alacağız.
Zone Transfer Nedir ve Cloudflare’de Nasıl Çalışır?
Zone Transfer, bir DNS zone’undaki tüm kayıtların bir nameserver’dan diğerine kopyalanması işlemidir. Geleneksel BIND ortamlarında AXFR (tam transfer) veya IXFR (artımlı transfer) protokolleriyle yapılır. Cloudflare’in bu konudaki yaklaşımı biraz farklı; Cloudflare hem kaynak hem de hedef olabilir.
Cloudflare Secondary DNS özelliğiyle, mevcut birincil DNS sunucunuzdan Cloudflare’e zone transfer yapabilirsiniz. Bu sayede Cloudflare sadece bir proxy değil, aynı zamanda yetkili bir ikincil DNS sunucusu görevi görür. Öte yandan Cloudflare Primary DNS kullanıyorsanız ve kendi secondary sunucularınıza zone transfer yapmak istiyorsanız, bu da mümkün.
Secondary DNS Kurulumu
Diyelim ki şirketinizin kendi BIND sunucusu var ve Cloudflare’i ikincil DNS olarak kullanmak istiyorsunuz. Bu senaryo büyük kurumsal yapılarda çok yaygın; hem kendi altyapınızın kontrolü sizde kalıyor hem de Cloudflare’in global ağından yararlanıyorsunuz.
Cloudflare tarafında önce zone’u “Secondary” modda eklemeniz gerekiyor. Bunu API üzerinden yapabilirsiniz:
curl -X POST "https://api.cloudflare.com/client/v4/zones"
-H "X-Auth-Email: [email protected]"
-H "X-Auth-Key: YOUR_API_KEY"
-H "Content-Type: application/json"
--data '{
"name": "example.com",
"account": {"id": "YOUR_ACCOUNT_ID"},
"type": "secondary",
"primary_ns_ip": "203.0.113.10"
}'
Bu isteği gönderdikten sonra Cloudflare size bir zone ID döndürecek. Bu ID’yi not edin, ilerleyen adımlarda kullanacaksınız.
BIND tarafında ise Cloudflare’in nameserver IP adreslerine zone transfer izni vermeniz gerekiyor. Cloudflare’in secondary DNS için kullandığı IP aralıkları değişebileceğinden, güncel listeyi her zaman Cloudflare dokümantasyonundan kontrol edin. named.conf dosyanıza şöyle bir blok eklemeniz gerekiyor:
zone "example.com" {
type master;
file "/etc/bind/zones/example.com.db";
allow-transfer {
173.245.59.0/24; # Cloudflare secondary DNS IP aralığı
108.162.193.0/24;
190.93.247.0/24;
};
notify yes;
also-notify {
173.245.59.1; # Cloudflare primary secondary IP
};
};
Değişiklikleri uyguladıktan sonra BIND’ı yeniden yükleyin:
sudo systemctl reload named
# veya
sudo rndc reload example.com
Zone Transfer Sağlığını Kontrol Etme
Zone transfer’ın düzgün çalışıp çalışmadığını kontrol etmek için şu komutu kullanabilirsiniz:
# BIND sunucunuzdan Cloudflare'e zone transfer test
dig @173.245.59.1 example.com AXFR
# SOA kaydını kontrol et - seri numarasının eşleştiğinden emin ol
dig @ns1.example.com example.com SOA
dig @ns1.cloudflare.com example.com SOA
SOA seri numaraları eşleşmiyorsa, zone transfer henüz tamamlanmamış demektir. BIND’ın log dosyalarına bakın:
tail -f /var/log/named/named.log | grep -E "(transfer|zone|notify)"
Cloudflare API ile Multi-Domain Yönetimi
İşte işlerin gerçekten eğlenceli hale geldiği yer burası. 50, 100, hatta 500 domain yönetiyorsanız, her birini tek tek Cloudflare panelinden yönetmek delilik. Cloudflare API v4, bu işi otomatize etmek için çok güçlü bir araç.
API Token Oluşturma
Önce doğru izinlere sahip bir API token oluşturun. Eski yöntem olan Global API Key yerine, scoped token kullanmak çok daha güvenli.
Cloudflare panelinde My Profile > API Tokens > Create Token yolunu izleyin ve şu izinleri verin:
- Zone:Zone:Read – Zone bilgilerini okumak için
- Zone:DNS:Edit – DNS kayıtlarını düzenlemek için
- Zone:Zone:Edit – Zone ayarlarını değiştirmek için
- Account:Cloudflare Pages:Edit – Eğer Pages kullanıyorsanız
Toplu Zone Listesi Çekme
Tüm zone’larınızı listelemek için:
#!/bin/bash
# Tüm zone'ları listele ve CSV'ye kaydet
CF_TOKEN="your_api_token_here"
OUTPUT_FILE="zones_$(date +%Y%m%d).csv"
echo "zone_id,zone_name,status,nameservers" > $OUTPUT_FILE
page=1
while true; do
response=$(curl -s -X GET
"https://api.cloudflare.com/client/v4/zones?page=${page}&per_page=50"
-H "Authorization: Bearer ${CF_TOKEN}"
-H "Content-Type: application/json")
# Zone sayısını kontrol et
count=$(echo $response | jq '.result | length')
if [ "$count" -eq "0" ]; then
break
fi
# Zone bilgilerini işle
echo $response | jq -r '.result[] | [.id, .name, .status, (.name_servers | join(";"))] | @csv' >> $OUTPUT_FILE
echo "Sayfa $page işlendi, $count zone bulundu"
page=$((page + 1))
done
echo "Toplam zone listesi $OUTPUT_FILE dosyasına kaydedildi"
Bu script’i çalıştırdığınızda elinizde tüm zone’larınızın bir envanteri olur. Bu listeyi sonraki işlemler için kullanacaksınız.
Toplu DNS Kaydı Ekleme
En çok ihtiyaç duyulan senaryo budur. Diyelim ki yeni bir mail sunucusu kuruyorsunuz ve 80 farklı domain için MX kayıtlarını güncellemeniz gerekiyor. Elle yapmak yerine:
#!/bin/bash
# Birden fazla domain için toplu MX kaydı güncelleme
CF_TOKEN="your_api_token_here"
DOMAINS_FILE="domains.txt" # Her satırda bir domain
NEW_MX="mail.newprovider.com"
MX_PRIORITY=10
while IFS= read -r domain; do
echo "İşleniyor: $domain"
# Zone ID'yi bul
zone_id=$(curl -s -X GET
"https://api.cloudflare.com/client/v4/zones?name=${domain}"
-H "Authorization: Bearer ${CF_TOKEN}"
-H "Content-Type: application/json" |
jq -r '.result[0].id')
if [ "$zone_id" == "null" ] || [ -z "$zone_id" ]; then
echo "HATA: $domain için zone bulunamadı"
continue
fi
# Mevcut MX kayıtlarını sil
existing_mx=$(curl -s -X GET
"https://api.cloudflare.com/client/v4/zones/${zone_id}/dns_records?type=MX"
-H "Authorization: Bearer ${CF_TOKEN}"
-H "Content-Type: application/json" |
jq -r '.result[].id')
for record_id in $existing_mx; do
curl -s -X DELETE
"https://api.cloudflare.com/client/v4/zones/${zone_id}/dns_records/${record_id}"
-H "Authorization: Bearer ${CF_TOKEN}"
-H "Content-Type: application/json" > /dev/null
echo " Eski MX kaydı silindi: $record_id"
done
# Yeni MX kaydını ekle
result=$(curl -s -X POST
"https://api.cloudflare.com/client/v4/zones/${zone_id}/dns_records"
-H "Authorization: Bearer ${CF_TOKEN}"
-H "Content-Type: application/json"
--data "{
"type": "MX",
"name": "${domain}",
"content": "${NEW_MX}",
"priority": ${MX_PRIORITY},
"ttl": 3600
}")
success=$(echo $result | jq -r '.success')
if [ "$success" == "true" ]; then
echo " OK: $domain için MX kaydı güncellendi"
else
echo " HATA: $domain - $(echo $result | jq -r '.errors[0].message')"
fi
# Rate limiting'e takılmamak için kısa bir bekleme
sleep 0.5
done < "$DOMAINS_FILE"
Terraform ile Cloudflare Zone Yönetimi
Modern bir ortamda DNS yönetimini de “Infrastructure as Code” kapsamında düşünmek gerekiyor. Terraform’un Cloudflare provider’ı bu konuda oldukça olgun bir araç.
# terraform/main.tf
terraform {
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 4.0"
}
}
}
provider "cloudflare" {
api_token = var.cloudflare_api_token
}
# Ana zone tanımı
resource "cloudflare_zone" "example_com" {
account_id = var.cloudflare_account_id
zone = "example.com"
plan = "free"
type = "full"
}
# A kaydı
resource "cloudflare_record" "www" {
zone_id = cloudflare_zone.example_com.id
name = "www"
value = "1.2.3.4"
type = "A"
proxied = true
ttl = 1 # Proxied kayıtlarda TTL otomatik
}
# SPF kaydı
resource "cloudflare_record" "spf" {
zone_id = cloudflare_zone.example_com.id
name = "@"
value = "v=spf1 include:_spf.google.com ~all"
type = "TXT"
ttl = 3600
}
Terraform ile zone yönetmenin en büyük avantajı, değişiklik geçmişini Git’te tutabilmeniz. Birisi yanlışlıkla bir kaydı silerse, git revert yapıp terraform apply ile birkaç dakika içinde geri dönersiniz.
Gerçek Dünya Senaryosu: Ajans Multi-Tenant Yapısı
Bir dijital ajans hayal edin. 150 müşterisi var, her birinin 2-3 domain’i var. Toplamda 300+ domain yönetiyorlar. Bu ortamda en kritik problem izolasyon ve güvenlik.
Cloudflare’in Multi-User ve Role-Based Access Control özellikleri burada devreye giriyor. Her müşteri için ayrı bir Cloudflare hesabı açıp bunları bir Enterprise Organization altında toplamak ideal çözüm. Ama bu Enterprise planı gerektiriyor. Ücretsiz/Pro kullanıcılar için alternatif yaklaşım, her müşteri zone’una ilgili müşterinin email adresini “Zone Admin” olarak eklemek:
#!/bin/bash
# Bir zone'a kullanıcı ekle
CF_TOKEN="your_api_token_here"
ZONE_ID="zone_id_buraya"
USER_EMAIL="[email protected]"
ROLE="dns_admin" # admin, dns_admin, cache_purge, log_push, worker_routes
curl -X POST
"https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/members"
-H "Authorization: Bearer ${CF_TOKEN}"
-H "Content-Type: application/json"
--data "{
"email": "${USER_EMAIL}",
"roles": ["${ROLE}"]
}"
Zone’lar Arası Ortak Ayarları Senkronize Etme
Tüm zone’larınızda aynı güvenlik ayarlarını uygulamak istiyorsunuz: DNSSEC açık, HTTPS redirect aktif, minimum TLS 1.2. Bunu tek tek yapmak yerine bir script ile toplu uygulayabilirsiniz:
#!/bin/bash
# Tüm zone'lara güvenlik ayarlarını uygula
CF_TOKEN="your_api_token_here"
# Tüm zone ID'lerini çek
zone_ids=$(curl -s -X GET
"https://api.cloudflare.com/client/v4/zones?per_page=100&status=active"
-H "Authorization: Bearer ${CF_TOKEN}"
-H "Content-Type: application/json" |
jq -r '.result[].id')
for zone_id in $zone_ids; do
zone_name=$(curl -s -X GET
"https://api.cloudflare.com/client/v4/zones/${zone_id}"
-H "Authorization: Bearer ${CF_TOKEN}"
-H "Content-Type: application/json" |
jq -r '.result.name')
echo "Ayarlar uygulanıyor: $zone_name ($zone_id)"
# HTTPS'ye zorunlu yönlendirme
curl -s -X PATCH
"https://api.cloudflare.com/client/v4/zones/${zone_id}/settings/always_use_https"
-H "Authorization: Bearer ${CF_TOKEN}"
-H "Content-Type: application/json"
--data '{"value": "on"}' > /dev/null
# Minimum TLS 1.2
curl -s -X PATCH
"https://api.cloudflare.com/client/v4/zones/${zone_id}/settings/min_tls_version"
-H "Authorization: Bearer ${CF_TOKEN}"
-H "Content-Type: application/json"
--data '{"value": "1.2"}' > /dev/null
# Security Level: Medium
curl -s -X PATCH
"https://api.cloudflare.com/client/v4/zones/${zone_id}/settings/security_level"
-H "Authorization: Bearer ${CF_TOKEN}"
-H "Content-Type: application/json"
--data '{"value": "medium"}' > /dev/null
echo " Tamamlandi: $zone_name"
sleep 1
done
echo "Tum zone'lar guncellendi!"
DNSSEC’i Toplu Aktifleştirme
DNSSEC, modern bir DNS altyapısında artık zorunlu olmalı. Ama 150 domain için tek tek aktifleştirmek yerine:
#!/bin/bash
# Tüm zone'larda DNSSEC aktifleştir
CF_TOKEN="your_api_token_here"
LOG_FILE="dnssec_activation_$(date +%Y%m%d_%H%M).log"
zone_ids=$(curl -s -X GET
"https://api.cloudflare.com/client/v4/zones?per_page=100&status=active"
-H "Authorization: Bearer ${CF_TOKEN}"
-H "Content-Type: application/json" |
jq -r '.result[].id')
for zone_id in $zone_ids; do
zone_name=$(curl -s -X GET
"https://api.cloudflare.com/client/v4/zones/${zone_id}"
-H "Authorization: Bearer ${CF_TOKEN}" |
jq -r '.result.name')
# DNSSEC durumunu kontrol et
dnssec_status=$(curl -s -X GET
"https://api.cloudflare.com/client/v4/zones/${zone_id}/dnssec"
-H "Authorization: Bearer ${CF_TOKEN}" |
jq -r '.result.status')
if [ "$dnssec_status" == "active" ]; then
echo "$zone_name: Zaten aktif" | tee -a $LOG_FILE
continue
fi
# DNSSEC aktifleştir
result=$(curl -s -X PATCH
"https://api.cloudflare.com/client/v4/zones/${zone_id}/dnssec"
-H "Authorization: Bearer ${CF_TOKEN}"
-H "Content-Type: application/json"
--data '{"status": "active"}')
ds_record=$(echo $result | jq -r '.result.ds')
echo "$zone_name: DNSSEC aktiflestirildi. DS Kaydi: $ds_record" | tee -a $LOG_FILE
sleep 0.5
done
Önemli not: DNSSEC aktifleştirdikten sonra, domain’inizin kayıtlı olduğu registrar’a DS kaydını eklemeniz gerekiyor. Bu adımı atlarsanız domain’iniz erişilemez hale gelebilir.
Zone Transfer Sorunlarını Giderme
Pratikte en sık karşılaşılan sorunlar ve çözümleri:
Transfer Gerçekleşmiyor
İlk kontrol edilecek şey firewall kuralları. BIND sunucunuzun 53. TCP portuna dışarıdan bağlantıya izin veriyor musunuz? Zone transfer TCP üzerinden çalışır, UDP değil.
# Firewall kontrolü - iptables
sudo iptables -L INPUT -n | grep "dport 53"
# TCP 53'e izin ver
sudo iptables -A INPUT -p tcp --dport 53 -s 173.245.59.0/24 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 53 -s 108.162.193.0/24 -j ACCEPT
# UFW kullanıyorsanız
sudo ufw allow from 173.245.59.0/24 to any port 53 proto tcp
SOA Seri Numarası Sorunu
BIND’da SOA seri numarası güncellenmezse Cloudflare yeni zone transfer başlatmaz. Standart pratik, seri numarasını YYYYMMDDNN formatında tutmaktır:
# SOA seri numarasını manuel güncelle ve zone'u yenile
sudo rndc reload example.com
# Cloudflare'i zone transfer için tetikle (API ile)
curl -X POST
"https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/secondary_dns/force_axfr"
-H "Authorization: Bearer ${CF_TOKEN}"
-H "Content-Type: application/json"
Monitoring ve Alerting
Bu kadar domain yönetirken bir şeylerin bozulması kaçınılmaz. Cloudflare API üzerinden zone durumlarını düzenli kontrol eden basit bir monitoring scripti:
#!/bin/bash
# Zone sağlık kontrolü - cron'a ekleyin: */30 * * * *
CF_TOKEN="your_api_token_here"
SLACK_WEBHOOK="https://hooks.slack.com/services/YOUR/WEBHOOK"
ALERT_FILE="/tmp/cf_zone_alerts.tmp"
problem_zones=()
zones=$(curl -s -X GET
"https://api.cloudflare.com/client/v4/zones?per_page=100"
-H "Authorization: Bearer ${CF_TOKEN}" |
jq -r '.result[] | "(.id):(.name):(.status)"')
while IFS=: read -r zone_id zone_name zone_status; do
if [ "$zone_status" != "active" ]; then
problem_zones+=("$zone_name (Durum: $zone_status)")
fi
done <<< "$zones"
if [ ${#problem_zones[@]} -gt 0 ]; then
message="Cloudflare Zone Uyarisi!n"
for zone in "${problem_zones[@]}"; do
message+="- $zonen"
done
curl -s -X POST "$SLACK_WEBHOOK"
-H "Content-Type: application/json"
--data "{"text": "$message"}" > /dev/null
echo "$(date): ${#problem_zones[@]} zone sorunu tespit edildi, uyari gonderildi" >> /var/log/cf_monitor.log
fi
Cloudflare CLI Aracı: flarectl
Cloudflare’in resmi CLI aracı olan flarectl, hızlı işlemler için API yazmaktan çok daha pratik.
# Kurulum
go install github.com/cloudflare/cloudflare-go/cmd/flarectl@latest
# Ortam değişkenlerini ayarla
export CF_API_TOKEN="your_token_here"
# Tüm zone'ları listele
flarectl zone list
# Belirli bir zone'un DNS kayıtlarını listele
flarectl dns list --zone example.com
# Hızlı A kaydı ekle
flarectl dns create --zone example.com --name test --type A --content 1.2.3.4 --proxy
# Kayıt güncelle
flarectl dns update --zone example.com --id RECORD_ID --content 5.6.7.8
Sonuç
Cloudflare ile multi-domain yönetimi, doğru araçları kullandığınızda gerçekten yönetilebilir bir hale geliyor. Zone Transfer özelliği mevcut altyapınızı korurken Cloudflare’in gücünden yararlanmanızı sağlıyor. API ve Terraform ile her şeyi kodla yönetmek ise hem güvenliği artırıyor hem de disaster recovery senaryolarını çok daha hızlı çözmenizi sağlıyor.
Pratikte önerdiğim yaklaşım şu: Önce envanterinizi çıkarın, hangi domain’in hangi kayıtlara sahip olduğunu bir veritabanına kaydedin. Sonra bu kayıtları Terraform’a taşıyın. Ardından zone güvenlik ayarlarını standartlaştıran otomasyonları devreye alın. Son adım olarak monitoring’i kurun.
Bu adımları tamamladığınızda, 500 domain’i yönetmek 5 domain’i yönetmekten çok da farklı olmayacak. Önemli olan sistematik yaklaşım ve iyi yazılmış otomasyonlar. Bir kere kuruyorsunuz, sonra kendiniz çalıştırıyor.
