Cloudflare ile CDN Yapılandırması: Global Dağıtım Rehberi

Global trafiği tek bir sunucudan karşılamaya çalışmak, İstanbul’dan Los Angeles’a her paket için gidiş-dönüş yapmak gibidir. Kullanıcın sayfanın yüklenmesini beklerken sen de sunucunun nefes almasını beklersin. Cloudflare CDN, bu sorunu çözmek için dünyanın dört bir yanına dağılmış 300’den fazla PoP (Point of Presence) noktasıyla içeriği kullanıcılara en yakın lokasyondan sunar. Bu yazıda, Cloudflare CDN yapılandırmasını sıfırdan nasıl kuracağını, optimize edeceğini ve gerçek dünya senaryolarında nasıl yöneteceğini adım adım ele alacağız.

Cloudflare CDN Nasıl Çalışır

Cloudflare’i bir proxy olarak düşünebilirsin. DNS kayıtlarını Cloudflare’e taşıdığında ve “turuncu bulut” ikonunu aktif ettiğinde, tüm trafik önce Cloudflare’in edge sunucularından geçer. Cloudflare bu noktada birkaç şey yapar:

  • Statik içeriği yakın PoP noktasında önbelleğe alır
  • DDoS saldırılarını filtreler
  • SSL/TLS termination uygular
  • HTTP/2 ve HTTP/3 protokollerini devreye alır
  • Gereksiz istekleri origin sunucuya iletmeden yanıtlar

Bir kullanıcı Japonya’dan sitenize girdiğinde, istek Tokyo PoP noktasına düşer. Eğer içerik önbellekte varsa, sunucuna tek bir paket bile gitmez. Bu hem latency açısından hem de origin sunucunun yükü açısından devasa bir fark yaratır.

DNS Kayıtlarını Cloudflare’e Taşımak

Alan adını Cloudflare’e eklemeden önce mevcut DNS kayıtlarını not al. Cloudflare genellikle otomatik tarama yapar ama gözden kaçan kayıtlar olabilir.

# Mevcut DNS kayıtlarını çek
dig +short example.com A
dig +short example.com MX
dig +short example.com TXT
dig +short www.example.com CNAME

# Daha kapsamlı sorgulama için
dig example.com ANY +noall +answer

Cloudflare paneline girdikten sonra domain ekle ve nameserver değişikliğini yap. Nameserver değişikliği yayılana kadar 24-48 saat bekleyebilirsin ama genellikle birkaç saatte tamamlanır.

# Nameserver değişikliğinin yayıldığını kontrol et
nslookup -type=NS example.com 8.8.8.8

# Cloudflare'in aktif olup olmadığını doğrula
curl -I https://example.com | grep "cf-ray"
# CF-Ray header'ı görünüyorsa Cloudflare devrede demektir

Proxy Modu ve DNS-Only Modu Arasındaki Fark

Cloudflare’deki her DNS kaydının yanında turuncu veya gri bir bulut ikonu bulunur. Bu ikon kritik bir farkı temsil eder.

Turuncu bulut (Proxied): Trafik Cloudflare üzerinden geçer, CDN ve güvenlik özellikleri aktiftir. IP adresin gizlenir.

Gri bulut (DNS-Only): Cloudflare sadece DNS çözümlemesi yapar. Trafik doğrudan sunucuna gider. IP adresin ortaya çıkar.

Hangi kayıtları proxy etmeli, hangilerini etmemeli? Genel kural şu şekilde işler:

  • A ve CNAME kayıtları web trafiği için: Proxied
  • MX kayıtları (mail): DNS-Only, mail trafiği Cloudflare üzerinden geçemez
  • FTP alt alan adları: DNS-Only
  • SSH erişimi için kullanılan kayıtlar: DNS-Only, yoksa bağlanamaz kalırsın
# Cloudflare API ile kayıt listesini çek
curl -X GET "https://api.cloudflare.com/client/v4/zones/ZONE_ID/dns_records" 
  -H "Authorization: Bearer API_TOKEN" 
  -H "Content-Type: application/json"

# Belirli bir kaydı proxy moduna al
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/ZONE_ID/dns_records/RECORD_ID" 
  -H "Authorization: Bearer API_TOKEN" 
  -H "Content-Type: application/json" 
  --data '{"proxied": true}'

Cache Yapılandırması: Neyi Ne Kadar Süre Cache’leyelim

Cloudflare varsayılan olarak statik dosyaları cache’ler ama bu ayar çoğu zaman yeterli değildir. Cache yapılandırmasını özelleştirmek için Cache Rules kullanırsın.

Browser Cache TTL ve Edge Cache TTL

Browser Cache TTL, Cloudflare’in tarayıcıya söylediği süreyi belirler. Edge Cache TTL ise Cloudflare’in kendi sunucularında içeriği ne kadar tutacağını belirler.

# Cache durumunu kontrol et
curl -I https://example.com/style.css | grep -i "cf-cache-status"
# HIT: Cache'den geldi
# MISS: Origin'den geldi, artık cache'lendi
# EXPIRED: Süresi dolmuş, yeniden çekildi
# BYPASS: Cache atlandı

Page Rules ile Cache Kontrolü

Farklı URL pattern’leri için farklı cache davranışı tanımlayabilirsin. Örneğin statik asset’leri agresif cache’lerken API endpoint’lerini hiç cache’lememek isteyebilirsin.

# Cloudflare API ile Cache Rule oluştur
curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/pagerules" 
  -H "Authorization: Bearer API_TOKEN" 
  -H "Content-Type: application/json" 
  --data '{
    "targets": [
      {
        "target": "url",
        "constraint": {
          "operator": "matches",
          "value": "example.com/static/*"
        }
      }
    ],
    "actions": [
      {
        "id": "cache_level",
        "value": "cache_everything"
      },
      {
        "id": "edge_cache_ttl",
        "value": 2592000
      }
    ],
    "status": "active"
  }'

API endpoint’leri için cache’i tamamen devre dışı bırakmak:

curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/pagerules" 
  -H "Authorization: Bearer API_TOKEN" 
  -H "Content-Type: application/json" 
  --data '{
    "targets": [
      {
        "target": "url",
        "constraint": {
          "operator": "matches",
          "value": "example.com/api/*"
        }
      }
    ],
    "actions": [
      {
        "id": "cache_level",
        "value": "bypass"
      }
    ],
    "status": "active"
  }'

Origin Sunucuyu Korumak: Gerçek IP’yi Gizlemek

CDN kullanmanın önemli avantajlarından biri origin sunucunun IP adresini gizlemektir. Ama bu koruma birkaç açıktan delinebilir. Dikkat etmen gereken noktalar:

Mail header’larından IP sızması: Eğer sunucundan direkt mail gönderiyorsan, mail header’larında sunucu IP’si görünür. Bunun için bir mail servisi (SendGrid, Mailgun) kullan.

Alt alan adı açıkları: Eskiden kullanılan ve unutulan DNS kayıtları gerçek IP’yi ifşa edebilir.

SSL sertifika kayıtları: Certificate Transparency loglarını kontrol et:

# Geçmişte verilen sertifikaları kontrol et
curl "https://crt.sh/?q=%.example.com&output=json" | python3 -m json.tool | grep name_value

# Tarihi DNS kayıtlarına bak
# SecurityTrails veya Shodan gibi araçlar kullan

Origin sunucunda Cloudflare IP’lerinden gelen bağlantılara izin verip diğer her şeyi engelle:

# Cloudflare IPv4 listesini çek
curl https://www.cloudflare.com/ips-v4

# UFW ile sadece Cloudflare'e izin ver
for ip in $(curl -s https://www.cloudflare.com/ips-v4); do
  ufw allow from $ip to any port 80
  ufw allow from $ip to any port 443
done

# IPv6 için de aynısını yap
for ip in $(curl -s https://www.cloudflare.com/ips-v6); do
  ufw allow from $ip to any port 80
  ufw allow from $ip to any port 443
done

ufw enable

Nginx ile Gerçek Ziyaretçi IP’sini Almak

Cloudflare proxy arkasında çalışırken, sunucuna gelen tüm istekler Cloudflare’in IP’sinden geliyor görünür. Access log’larında ve uygulama katmanında gerçek kullanıcı IP’sini görmek için CF-Connecting-IP header’ını kullanman gerekir.

# /etc/nginx/nginx.conf veya site config dosyasına ekle
# Cloudflare IP'lerini gerçek IP kaynağı olarak tanımla

set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2a06:98c0::/29;
set_real_ip_from 2c0f:f248::/32;

real_ip_header CF-Connecting-IP;

# Nginx'i yeniden başlat
systemctl reload nginx

Bu ayarı yaptıktan sonra $remote_addr değişkeni artık Cloudflare IP’si yerine gerçek kullanıcı IP’sini döndürür.

Cloudflare Workers ile Edge Computing

Cloudflare Workers, JavaScript kodunu edge sunucularda çalıştırmana olanak tanır. Bu, her isteği origin sunucuya taşımadan edge’de mantık uygulayabilmek demektir.

Örnek senaryo: A/B testi yapmak istiyorsun ama sunucu tarafında bir şey değiştirmek istemiyorsun.

# Cloudflare Workers CLI kurulumu
npm install -g wrangler

# Yeni proje oluştur
wrangler init ab-test-worker

# wrangler.toml yapılandırması
cat > wrangler.toml << 'EOF'
name = "ab-test-worker"
main = "src/index.js"
compatibility_date = "2024-01-01"

[[routes]]
pattern = "example.com/*"
zone_name = "example.com"
EOF

# src/index.js - Basit A/B test worker
cat > src/index.js << 'EOF'
export default {
  async fetch(request, env, ctx) {
    const url = new URL(request.url);
    
    // Kullanıcının cookie'sine bak
    const cookie = request.headers.get('Cookie') || '';
    let variant = cookie.match(/ab_variant=([AB])/)?.[1];
    
    // Cookie yoksa rastgele ata
    if (!variant) {
      variant = Math.random() < 0.5 ? 'A' : 'B';
    }
    
    // B versiyonu için farklı URL'ye yönlendir
    if (variant === 'B' && url.pathname === '/') {
      url.pathname = '/landing-v2';
    }
    
    const response = await fetch(url.toString(), request);
    const newResponse = new Response(response.body, response);
    
    // Cookie set et
    if (!cookie.includes('ab_variant')) {
      newResponse.headers.append('Set-Cookie', 
        `ab_variant=${variant}; Path=/; Max-Age=86400`);
    }
    
    return newResponse;
  }
};
EOF

# Deploy et
wrangler deploy

Cache Purge Otomasyonu: CI/CD Entegrasyonu

Deploy sonrası eski cache’in temizlenmesi kritik bir adımdır. Bu işlemi CI/CD pipeline’ına entegre etmek gerekir.

# GitHub Actions örneği
cat > .github/workflows/deploy.yml << 'EOF'
name: Deploy ve Cache Temizle

on:
  push:
    branches: [main]

jobs:
  deploy-and-purge:
    runs-on: ubuntu-latest
    steps:
      - name: Deploy et
        run: |
          # Deploy komutların buraya
          echo "Deployment tamamlandi"
      
      - name: Cloudflare Cache Temizle
        run: |
          # Tüm cache'i temizle
          curl -X POST "https://api.cloudflare.com/client/v4/zones/${{ secrets.CF_ZONE_ID }}/purge_cache" 
            -H "Authorization: Bearer ${{ secrets.CF_API_TOKEN }}" 
            -H "Content-Type: application/json" 
            --data '{"purge_everything": true}'
          
          echo "Cache temizlendi"
EOF

# Belirli dosyaları purge etmek için
curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/purge_cache" 
  -H "Authorization: Bearer API_TOKEN" 
  -H "Content-Type: application/json" 
  --data '{
    "files": [
      "https://example.com/style.css",
      "https://example.com/app.js",
      "https://example.com/index.html"
    ]
  }'

Load Balancing ve Failover Yapılandırması

Cloudflare’in Load Balancing özelliği birden fazla origin sunucusu arasında trafiği dağıtır ve bir sunucu çöktüğünde otomatik failover yapar.

# Origin Pool oluştur
curl -X POST "https://api.cloudflare.com/client/v4/user/load_balancers/pools" 
  -H "Authorization: Bearer API_TOKEN" 
  -H "Content-Type: application/json" 
  --data '{
    "name": "primary-pool",
    "description": "Ana sunucu grubu",
    "enabled": true,
    "minimum_origins": 1,
    "monitor": "MONITOR_ID",
    "origins": [
      {
        "name": "origin-tr",
        "address": "185.1.2.3",
        "enabled": true,
        "weight": 1
      },
      {
        "name": "origin-de",
        "address": "185.4.5.6",
        "enabled": true,
        "weight": 1
      }
    ],
    "notification_email": "[email protected]"
  }'

# Health check monitoru oluştur
curl -X POST "https://api.cloudflare.com/client/v4/user/load_balancers/monitors" 
  -H "Authorization: Bearer API_TOKEN" 
  -H "Content-Type: application/json" 
  --data '{
    "type": "https",
    "description": "Ana health check",
    "method": "GET",
    "path": "/health",
    "interval": 60,
    "retries": 2,
    "timeout": 5,
    "expected_codes": "200",
    "follow_redirects": false,
    "allow_insecure": false
  }'

Analytics ve Monitoring

CDN yapılandırması yaptıktan sonra izleme kritiktir. Cloudflare’in Analytics API’sini kullanarak kendi dashboard’unu oluşturabilirsin.

# Zone analytics çek - son 24 saat
curl -X GET "https://api.cloudflare.com/client/v4/zones/ZONE_ID/analytics/dashboard?since=-1440&until=0" 
  -H "Authorization: Bearer API_TOKEN" 
  -H "Content-Type: application/json"

# Cache hit oranını hesapla
curl -X POST "https://api.cloudflare.com/client/v4/graphql" 
  -H "Authorization: Bearer API_TOKEN" 
  -H "Content-Type: application/json" 
  --data '{
    "query": "{ viewer { zones(filter: {zoneTag: "ZONE_ID"}) { httpRequests1dGroups(limit: 7, filter: {date_geq: "2024-01-01"}) { sum { cachedRequests requests } dimensions { date } } } } }"
  }'

# Basit cache hit ratio hesapla
python3 << 'PYEOF'
cached = 850000  # API'dan gelen değer
total = 1000000  # API'dan gelen değer
ratio = (cached / total) * 100
print(f"Cache Hit Ratio: {ratio:.1f}%")
print(f"Origin'e giden istek: {total - cached:,}")
PYEOF

Gerçek Dünya Senaryosu: E-ticaret Sitesi Optimizasyonu

Bir e-ticaret sitesi için CDN yapılandırması yaparken dikkat etmen gereken özel noktalar vardır. Ürün sayfaları cache’lenebilir ama sepet ve ödeme sayfaları asla cache’lenmemeli.

# E-ticaret için cache kuralları scripti
cat > ecommerce-cache-rules.sh << 'EOF'
#!/bin/bash

ZONE_ID="your_zone_id"
API_TOKEN="your_api_token"

# Statik asset'leri agresif cache'le
create_rule() {
  local pattern=$1
  local cache_level=$2
  local ttl=$3
  
  curl -X POST "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/pagerules" 
    -H "Authorization: Bearer ${API_TOKEN}" 
    -H "Content-Type: application/json" 
    --data "{
      "targets": [{
        "target": "url",
        "constraint": {
          "operator": "matches",
          "value": "${pattern}"
        }
      }],
      "actions": [
        {"id": "cache_level", "value": "${cache_level}"},
        {"id": "edge_cache_ttl", "value": ${ttl}}
      ],
      "status": "active"
    }"
  echo "Kural olusturuldu: ${pattern}"
}

# Sepet ve checkout'u asla cache'leme
create_rule "example.com/cart*" "bypass" 0
create_rule "example.com/checkout*" "bypass" 0
create_rule "example.com/account*" "bypass" 0

# Ürün sayfalarını kısa süreli cache'le
create_rule "example.com/products*" "cache_everything" 3600

# Statik dosyaları uzun süreli cache'le
create_rule "example.com/static/*" "cache_everything" 2592000

echo "Tum kurallar olusturuldu"
EOF

chmod +x ecommerce-cache-rules.sh
./ecommerce-cache-rules.sh

SSL/TLS Yapılandırması ve HTTPS Yönlendirme

Cloudflare birkaç farklı SSL modu sunar. Doğru modu seçmek güvenlik açısından kritiktir.

Flexible: Cloudflare ile kullanıcı arasında şifreli, Cloudflare ile origin arasında şifresiz. Kesinlikle önerilen bir mod değil, güvenlik açığı yaratır.

Full: Her iki bacakta da şifreli ama origin’deki sertifika doğrulanmaz, self-signed olabilir.

Full (Strict): Her iki bacakta da şifreli ve origin’deki sertifika geçerli bir CA tarafından imzalanmış olmalı. Önerilen mod budur.

# SSL modunu API üzerinden ayarla
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/ZONE_ID/settings/ssl" 
  -H "Authorization: Bearer API_TOKEN" 
  -H "Content-Type: application/json" 
  --data '{"value": "strict"}'

# HSTS aktif et
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/ZONE_ID/settings/security_header" 
  -H "Authorization: Bearer API_TOKEN" 
  -H "Content-Type: application/json" 
  --data '{
    "value": {
      "strict_transport_security": {
        "enabled": true,
        "max_age": 31536000,
        "include_subdomains": true,
        "preload": true
      }
    }
  }'

# HTTP to HTTPS yönlendirmesini aktif et
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/ZONE_ID/settings/always_use_https" 
  -H "Authorization: Bearer API_TOKEN" 
  -H "Content-Type: application/json" 
  --data '{"value": "on"}'

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

522 Connection Timed Out: Cloudflare origin sunucuya bağlanamıyor. Sunucunun 80 ve 443 portları açık mı? Firewall Cloudflare IP’lerini engelliyor mu?

# Cloudflare IP'lerinden bağlantıyı test et
# Bir VPN veya proxy üzerinden Cloudflare IP aralığından test yap
curl -v --resolve example.com:443:ORIGIN_IP https://example.com

# UFW kurallarını kontrol et
ufw status numbered | grep -E "(80|443)"

524 A Timeout Occurred: Cloudflare bağlantı kurdu ama origin 100 saniye içinde yanıt vermedi. Uzun süren işlemler için Workers veya async yaklaşım kullan.

Cache bypass problemi: Cookie veya Authorization header varsa Cloudflare default olarak cache’lemiyor. Bunu kontrol et.

# Cache'i bypass eden header'ları test et
curl -I -H "Cookie: session=test" https://example.com/page
# cf-cache-status: BYPASS görürsün

# Cache bypass kuralını override etmek için Cache Rules kullan

Sonuç

Cloudflare CDN yapılandırması sadece DNS’i işaret edip turuncu buluta tıklamaktan ibaret değil. Doğru yapılandırılmış bir CDN şu avantajları sağlar: origin sunucuya giden istek sayısını yüzde 70-90 oranında düşürür, küresel kullanıcılar için sayfa yükleme sürelerini dramatik olarak kısaltır ve DDoS saldırılarına karşı ilk savunma hattı oluşturur.

Yapılandırmayı tamamladıktan sonra düzenli olarak şunları takip et: cache hit ratio (yüzde 80 altındaysa bir şeyler yanlış gidiyor demektir), origin sunucu yük durumu, 5xx hata oranları ve SSL sertifika geçerlilik tarihleri. Cloudflare’in kendi Analytics Dashboard’u bu bilgilerin büyük çoğunluğunu sana sunar, ek olarak Grafana ve Prometheus entegrasyonuyla daha detaylı izleme yapabilirsin.

Bir sysadmin olarak söyleyebilirim ki, Cloudflare CDN’i doğru yapılandırdığında gece 3’te pager alert almak yerine uyku uyursun. Sunucu çöksün veya DDoS gelsin, kullanıcılar sitenin önbellekten yüklendiğini görmaya devam eder. Bu kadar pratik bir koruma katmanı bulmak gerçekten zor.

Bir yanıt yazın

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