Cloudflare ile Origin Sunucu IP Adresini Gizleme

Yıllarca sunucu yönetimi yapan biri olarak şunu net söyleyeyim: IP adresinizi gizlememek, evinizin kapısına “Ben buradayım, gel vur” yazan bir tabela asmakla eşdeğerdir. Cloudflare arkasına geçmek harika bir başlangıç, ama çoğu sysadmin burada kritik bir hata yapıyor: Cloudflare’i aktive ediyor, sonra origin sunucusunun IP’sinin hala dışarıya sızdığını fark etmiyor. Bu yazıda Cloudflare ile origin sunucu gizlemeyi, gerçek dünya senaryolarıyla ve elle tutulur yapılandırmalarla ele alacağız.

Neden Origin IP Gizlemek Bu Kadar Önemli

Cloudflare’in proxy özelliği etkinleştirildiğinde, ziyaretçiler sitenize Cloudflare’in edge node’ları üzerinden ulaşır. Teoride kimse sizin gerçek sunucu IP’nizi bilmez. Ancak pratikte bu koruma çok daha kırılgan olabilir.

Saldırganlar origin IP’nizi ele geçirdiğinde ne olur? Cloudflare’i tamamen bypass ederek doğrudan sunucunuza DDoS saldırısı düzenleyebilirler. WAF korumanız, rate limiting kurallarınız, hepsi işe yaramaz hale gelir. 2022 yılında popüler bir e-ticaret platformunun Cloudflare arkasındayken DDoS yemesi tam da bu yüzden olmuştu; origin IP bir eski DNS kaydında hâlâ görünür durumdaydı.

Origin IP’sinin sızdığı yaygın senaryolar şunlardır:

  • MX kayıtları: Mail sunucusu aynı IP üzerindeyse direkt ifşa eder
  • Eski DNS kayıtları: Subdomain’ler proxy’den geçmeden “A” kaydı olarak kalmış olabilir
  • SSL sertifika logları: Certificate Transparency loglarında eski IP’ler görünebilir
  • Outbound bağlantılar: Sunucunuz dışarıya istek yaparken IP’sini ele verir
  • Email başlıkları: Sunucudan gönderilen maillerde “Received” header’ları IP’yi açıklar
  • Uygulama hataları: Verbose hata mesajları, sunucu IP’sini içerebilir

Cloudflare DNS Yapılandırmasının Temelleri

Cloudflare’e domain ekledikten sonra DNS yönetim paneline girdiğinizde her kaydın yanında turuncu bir bulut ikonu görürsünüz. Bu bulutun turuncu renkte olması proxy’nin aktif olduğu, gri renkte olması ise DNS-only modunda çalıştığı anlamına gelir.

Hangi kayıtların proxy’den geçmesi gerektiğini belirlemek kritik. Temel kural şu: HTTP/HTTPS trafiği taşıyan tüm kayıtlar turuncu bulut altında olmalıdır.

Tipik bir yapılandırma şöyle görünmeli:

# Cloudflare API üzerinden mevcut DNS kayıtlarını listeleyelim
curl -X GET "https://api.cloudflare.com/client/v4/zones/ZONE_ID/dns_records" 
     -H "Authorization: Bearer API_TOKEN" 
     -H "Content-Type: application/json" | jq '.result[] | {name: .name, type: .type, proxied: .proxied, content: .content}'

Bu komutun çıktısında "proxied": false gördüğünüz HTTP kayıtları varsa, bunlar potansiyel sızıntı noktalarıdır.

Origin IP Sızıntısını Tespit Etme

Önce mevcut durumu analiz edelim. Kendi domaininiz için IP sızıntısı testi yapmak istiyorsanız birkaç yöntem kullanabilirsiniz.

Shodan ve Censys üzerinden tarihsel veri kontrolü:

# subfinder ile subdomain enumeration
subfinder -d example.com -o subdomains.txt

# httpx ile her subdomainin gerçek IP'ye yönlenip yönlenmediğini kontrol et
cat subdomains.txt | httpx -ip -silent | grep -v "104.16|104.17|104.18|104.19|104.20|104.21|104.22|172.64|172.65|172.66|172.67|172.68|172.69|172.70|172.71"

Yukarıdaki komut Cloudflare IP aralıkları dışında kalan sonuçları filtreler. Eğer herhangi bir subdomain Cloudflare IP’si yerine başka bir IP döndürüyorsa, o bir sızıntı noktasıdır.

DNS geçmişini kontrol etme:

# dig ile tüm kayıt tiplerini sorgula
dig example.com ANY +short
dig mail.example.com A +short
dig smtp.example.com A +short
dig ftp.example.com A +short

# MX kayıtlarının IP'lerini çek
dig example.com MX +short | awk '{print $2}' | while read host; do dig $host A +short; done

Certificate Transparency loglarında eski kayıtlar:

# crt.sh üzerinden sertifika geçmişine bak
curl -s "https://crt.sh/?q=%.example.com&output=json" | 
  jq -r '.[].name_value' | 
  sort -u | 
  grep -v "^*"

Bu komut daha önce SSL sertifikası alınmış tüm subdomain’leri listeler. Bunların her birini kontrol etmeniz gerekir.

Güvenli Origin Sunucu Yapılandırması

Firewall Kuralları ile Cloudflare’i Zorunlu Kılma

Origin sunucunuzu yalnızca Cloudflare IP’lerinden gelen trafiği kabul edecek şekilde yapılandırmak, en kritik adımdır. Cloudflare’i bypass etmeye çalışan her türlü direkt bağlantı bu şekilde engellenmiş olur.

#!/bin/bash
# cloudflare_whitelist.sh - Sadece Cloudflare IP'lerinden gelen trafiğe izin ver

# Mevcut kuralları temizle (dikkatli kullan!)
iptables -F INPUT
iptables -P INPUT DROP
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# SSH erişimi için kendi IP'ni ekle (bu satırı kendi IP'nle değiştir)
iptables -A INPUT -s YONETIM_IP/32 -p tcp --dport 22 -j ACCEPT

# Cloudflare IPv4 aralıkları
CF_IPS=$(curl -s https://www.cloudflare.com/ips-v4)
for ip in $CF_IPS; do
    iptables -A INPUT -s $ip -p tcp --dport 80 -j ACCEPT
    iptables -A INPUT -s $ip -p tcp --dport 443 -j ACCEPT
done

# Cloudflare IPv6 aralıkları
CF_IPS6=$(curl -s https://www.cloudflare.com/ips-v6)
for ip in $CF_IPS6; do
    ip6tables -A INPUT -s $ip -p tcp --dport 80 -j ACCEPT
    ip6tables -A INPUT -s $ip -p tcp --dport 443 -j ACCEPT
done

echo "Cloudflare whitelist uygulandı"
iptables -L INPUT -n --line-numbers

Bu scripti cron’a ekleyerek Cloudflare IP listesinin güncel kalmasını sağlayın:

# /etc/cron.d/cloudflare-whitelist
0 3 * * 1 root /usr/local/bin/cloudflare_whitelist.sh >> /var/log/cf_whitelist.log 2>&1

UFW Kullananlar İçin Alternatif

#!/bin/bash
# ufw ile Cloudflare whitelist

ufw --force reset
ufw default deny incoming
ufw default allow outgoing

# SSH için yönetim IP'si
ufw allow from YONETIM_IP to any port 22

# Cloudflare IP'lerini ekle
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

ufw --force enable
ufw status verbose

Nginx Yapılandırması ile Ek Koruma

Firewall katmanına ek olarak web sunucusu seviyesinde de gerçek IP konfigürasyonu yapılmalıdır. Bu hem doğru loglama sağlar hem de ekstra güvenlik katmanı oluşturur.

# /etc/nginx/conf.d/cloudflare_realip.conf

# Cloudflare gerçek IP modülü
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;
real_ip_recursive on;

Nginx’in Cloudflare dışından gelen bağlantıları reddetmesi için server bloğuna ekleyebileceğiniz ek güvenlik:

# /etc/nginx/sites-available/example.com
server {
    listen 80;
    listen 443 ssl;
    server_name example.com www.example.com;
    
    # Cloudflare olmayan IP'lerden gelen istekleri reddet
    # Bu kural firewall'dan sonra ek bir katman sağlar
    if ($http_cf_ray = "") {
        return 444;
    }
    
    # ... geri kalan yapılandırma
}

Subdomain Yönetimi ve Gizli Kayıtlar

Authenticated Origin Pulls

Cloudflare’in Authenticated Origin Pulls özelliği, origin sunucunuzun yalnızca Cloudflare’den gelen istekleri kabul etmesini kriptografik olarak doğrular. Bu sayede birisi Cloudflare IP’si gibi görünerek sunucunuza istek göndermeye çalışsa bile sertifika doğrulaması devreye girer.

# Cloudflare'in CA sertifikasını indir
wget https://developers.cloudflare.com/ssl/static/authenticated_origin_pull_ca.pem 
     -O /etc/nginx/certs/cloudflare_ca.pem

# Nginx yapılandırmasına ekle
cat >> /etc/nginx/sites-available/example.com << 'EOF'
    ssl_client_certificate /etc/nginx/certs/cloudflare_ca.pem;
    ssl_verify_client on;
EOF

Gizli Subdomain’lerin Tespiti ve Düzeltilmesi

Bir müşterimin sisteminde yaptığım audit’te şunu keşfettim: dev.example.com ve staging.example.com subdomain’leri yıllardır DNS-only modunda çalışıyordu. Production IP’si ile aynı sunucu olduğu için IP gizlemenin tüm etkisi sıfırlanmıştı.

#!/bin/bash
# dns_audit.sh - Proxy olmayan DNS kayıtlarını bul

ZONE_ID="ZONE_ID_BURAYA"
API_TOKEN="API_TOKEN_BURAYA"

echo "=== Proxy Edilmeyen DNS Kayıtları ==="
curl -s -X GET "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records?per_page=100" 
  -H "Authorization: Bearer ${API_TOKEN}" 
  -H "Content-Type: application/json" | 
  jq -r '.result[] | select(.proxied == false) | "(.type)t(.name)t(.content)"' | 
  column -t

echo ""
echo "=== Bu kayitlari gozden gecirin ==="
echo "A ve CNAME kayitlarinin proxied=true olmasi gerekiyor"

Cloudflare Tunnel ile Tam Gizlilik

Eğer IP gizleme konusunda paranoyak seviyesinde güvenlik istiyorsanız (ki bu övgü sayılır), Cloudflare Tunnel (eski adıyla Argo Tunnel) mükemmel bir çözümdür. Bu yöntemde sunucunuzun 80 ve 443 portlarını dışarıya açmanıza bile gerek kalmaz.

# cloudflared kurulumu (Ubuntu/Debian)
wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
dpkg -i cloudflared-linux-amd64.deb

# Kimlik doğrulama
cloudflared tunnel login

# Yeni tunnel oluştur
cloudflared tunnel create my-origin-tunnel

# Tunnel yapılandırması
mkdir -p ~/.cloudflared
cat > ~/.cloudflared/config.yml << 'EOF'
tunnel: TUNNEL_ID_BURAYA
credentials-file: /root/.cloudflared/TUNNEL_ID.json

ingress:
  - hostname: example.com
    service: http://localhost:80
  - hostname: www.example.com
    service: http://localhost:80
  - hostname: api.example.com
    service: http://localhost:8080
  - service: http_status:404
EOF

# DNS kaydı oluştur
cloudflared tunnel route dns my-origin-tunnel example.com

# Systemd servisi olarak kur
cloudflared service install
systemctl enable cloudflared
systemctl start cloudflared

Cloudflare Tunnel kullandığınızda sunucunuza inbound bağlantı gelmez. Sunucu Cloudflare’e outbound bağlantı açar ve tüm trafik bu tünel üzerinden akar. Firewall’da 80/443 portlarını tamamen kapatabilirsiniz.

Email Sızıntısını Önleme

Email konfigürasyonu, IP sızıntısının en çok göz ardı edilen kaynağıdır. Web sunucunuzu ne kadar iyi gizlemiş olursanız olun, aynı IP’den mail gönderiyorsanız her email başlığında IP adresiniz görünür.

# Mail sunucusunu ayrı bir IP veya hosting üzerine taşıyın
# Ya da üçüncü parti mail servisleri kullanın (SendGrid, Mailgun vb.)

# Mevcut mail başlıklarını kontrol et
# Gönderilen bir mailin raw header'ına bakın:
# Received: from mail.example.com (mail.example.com [SUNUCU_IP])

# Postfix'te outbound mail için farklı IP kullanma
# /etc/postfix/main.cf
smtp_bind_address = AYRI_MAIL_IP

Cloudflare Email Routing kullanıyorsanız MX kayıtlarınız Cloudflare üzerinden geçer ama bu giden mailleri kapsamaz. Giden mailler için mutlaka ayrı bir servis veya IP kullanın.

Cloudflare API ile Otomatik Güvenlik Denetimi

Büyük bir altyapı yönetiyorsanız her değişiklikten sonra manuel kontrol yapmak pratik değildir. Aşağıdaki script tüm DNS kayıtlarını tarıyarak güvenlik sorunlarını raporlar:

#!/bin/bash
# cf_security_check.sh

ZONE_ID="ZONE_ID"
API_TOKEN="API_TOKEN"
ALERT_EMAIL="[email protected]"

check_dns_records() {
    local issues=0
    local report=""
    
    # Tüm A ve CNAME kayıtlarını çek
    records=$(curl -s -X GET 
        "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records?type=A&per_page=100" 
        -H "Authorization: Bearer ${API_TOKEN}" 
        -H "Content-Type: application/json")
    
    # Proxy edilmeyen A kayıtlarını bul
    while IFS= read -r line; do
        name=$(echo "$line" | jq -r '.name')
        content=$(echo "$line" | jq -r '.content')
        proxied=$(echo "$line" | jq -r '.proxied')
        
        if [ "$proxied" = "false" ]; then
            # Cloudflare IP'si mi kontrol et
            if ! echo "$content" | grep -qE "^(104.|172.6[4-9].|172.7[0-1].)"; then
                report+="UYARI: ${name} -> ${content} proxy edilmiyor!n"
                issues=$((issues + 1))
            fi
        fi
    done < <(echo "$records" | jq -c '.result[]')
    
    if [ $issues -gt 0 ]; then
        echo -e "Cloudflare DNS Guvenlik Raporu:n$report" | 
            mail -s "DNS Guvenlik Uyarisi: $issues sorun bulundu" "$ALERT_EMAIL"
        echo -e "$report"
        exit 1
    fi
    
    echo "Tum A kayitlari guvenli gorünüyor."
}

check_dns_records

Gerçek Dünya Senaryosu: E-ticaret Sitesi Güvenlik Hardening

Geçen yıl bir e-ticaret müşterisi için yaptığım güvenlik denetiminde şu durumla karşılaştım: Site Cloudflare arkasındaydı, SSL vardı, her şey yolunda görünüyordu. Ancak şunları tespit ettim:

  • cdn.example.com subdomain’i ayrı bir sunucuya işaret ediyordu ve proxy edilmiyordu
  • Eski beta.example.com kaydı silinmemiş, aynı origin IP’yi gösteriyordu
  • Woocommerce’in gönderdiği sipariş emaillerinin başlığında origin IP açıkça görünüyordu
  • Bir monitoring servisi için açık bırakılan status.example.com subdomaini DNS-only modundaydı

Bu dört sorunun herhangi biri, origin IP’nin tespiti için yeterliydi. Cloudflare Tunnel’a geçtikten sonra bu sorunların tamamı çözüldü çünkü sunucunun artık hiçbir portu dışarıya açık değildi.

Yapılan değişikliklerin ardından aylık saldırı girişim sayısı dramatik biçimde düştü. Saldırganlar Cloudflare’i bypass etmeye çalışıyor, başaramayınca çoğunlukla vazgeçiyor.

Monitoring ve Sürekli Kontrol

Güvenlik tek seferlik bir işlem değil, sürekli devam eden bir süreçtir. IP sızıntısı için düzenli monitoring kurmanız gerekir:

#!/bin/bash
# ip_leak_monitor.sh - Periyodik IP sızdırma kontrolü

DOMAIN="example.com"
ORIGIN_IP="GERCEK_SUNUCU_IP"
SLACK_WEBHOOK="https://hooks.slack.com/services/..."

check_ip_leak() {
    local current_ip
    current_ip=$(dig +short "$DOMAIN" | head -1)
    
    # Cloudflare IP aralıklarını kontrol et
    cf_ips=$(curl -s https://www.cloudflare.com/ips-v4)
    
    is_cloudflare=false
    for cidr in $cf_ips; do
        if python3 -c "
import ipaddress, sys
try:
    if ipaddress.ip_address('$current_ip') in ipaddress.ip_network('$cidr'):
        sys.exit(0)
except:
    pass
sys.exit(1)
"; then
            is_cloudflare=true
            break
        fi
    done
    
    if [ "$is_cloudflare" = "false" ]; then
        message="KRITIK: $DOMAIN icin IP sizintisi tespit edildi! IP: $current_ip"
        curl -s -X POST "$SLACK_WEBHOOK" 
            -H "Content-Type: application/json" 
            -d "{"text": "$message"}"
        echo "$message"
        exit 1
    fi
    
    echo "$(date): $DOMAIN Cloudflare arkasinda gorünüyor. IP: $current_ip"
}

check_ip_leak

Bu scripti 5 dakikada bir çalışacak şekilde cron’a ekleyin:

*/5 * * * * /usr/local/bin/ip_leak_monitor.sh >> /var/log/ip_leak_monitor.log 2>&1

Sonuç

Cloudflare’i aktive etmek, güvenlik yolculuğunun başlangıcıdır, sonu değil. Gerçek origin IP gizleme için şu adımları mutlaka tamamlayın:

  • Firewall katmanı: Sunucunuza yalnızca Cloudflare IP’lerinden HTTP/HTTPS trafiği gelsin
  • Subdomain denetimi: Her subdomain’in proxy durumunu düzenli kontrol edin
  • Email ayrımı: Giden mailler için origin sunucuyu kullanmayın
  • Cloudflare Tunnel: Maksimum gizlilik için en güvenilir çözüm
  • Authenticated Origin Pulls: Kriptografik doğrulama katmanı ekler
  • Otomatik monitoring: IP sızıntısı için alarm mekanizması kurun

En önemli nokta şu: Sızıntı kaynakları genellikle “önemsiz” görünen subdomain’lerden gelir. dev, staging, old, test, cdn gibi isimler taşıyan kayıtlar her zaman şüpheyle bakılacak adaylar olmalıdır. Düzenli DNS audit’i bu nedenle kritiktir.

Sistemi bir kez doğru kurduğunuzda ve monitoring’i otomatize ettiğinizde, bu konu için ayrıca kafa yormanıza gerek kalmaz. Saldırganlar Cloudflare’i bypass etmeye çalışır, başaramaz ve başka hedeflere geçer. Bu kadar basit.

Bir yanıt yazın

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