İletişime geç

Cloudflare Arkasında Gerçek Ziyaretçi IP Adresini Almak

Site Cloudflare'e alındıktan sonra loglarda ve uygulamada hep Cloudflare'in IP adresleri mi görünüyor? Apache, Nginx ve Laravel'de gerçek ziyaretçi IP'sini güvenli şekilde almanın yolu.

Cloudflare Arkasında Gerçek Ziyaretçi IP Adresini Almak Web & Altyapı

Bir siteyi Cloudflare'e aldıktan sonraki ilk günlerde genellikle aynı şey fark edilir: sunucu loglarındaki IP adresleri birbirine çok benziyor, iletişim formundaki spam koruması herkesi aynı kişi sanıp engelliyor, istatistiklerde bütün ziyaretçiler San Francisco'dan geliyor. Sebep basit: sunucunuza artık ziyaretçi değil, Cloudflare bağlanıyor.

Ziyaretçi, Cloudflare ve sunucu arasındaki istek akışı ve IP başlıklarını gösteren şema
Sunucu, bağlantıyı Cloudflare'in IP adresinden alır; ziyaretçinin adresi bir HTTP başlığında gelir.

Gerçek IP nerede?

Cloudflare, isteği sunucunuza iletirken ziyaretçinin gerçek IP adresini iki başlıkta gönderir:

  • CF-Connecting-IP: Tek bir IP adresi içerir. En güvenilir kaynak bu.
  • X-Forwarded-For: Standart başlık. İstek başka proxy'lerden de geçtiyse birden fazla adres içerebilir.

İlk akla gelen çözüm, uygulamada doğrudan bu başlığı okumak:

$ip = $_SERVER['HTTP_CF_CONNECTING_IP'] ?? $_SERVER['REMOTE_ADDR'];

Bu kod çalışır, ama ciddi bir güvenlik açığı bırakır.

Neden doğrudan başlığa güvenilmemeli?

HTTP başlıklarını isteği gönderen herkes istediği gibi yazabilir. Sunucunuzun gerçek IP adresini bilen biri, Cloudflare'i atlayıp doğrudan sunucuya bağlanabilir ve şöyle bir istek gönderebilir:

curl -H "CF-Connecting-IP: 1.2.3.4" http://SUNUCU_IP/iletisim

Uygulamanız bu durumda başlığa inanır. Giriş denemesi sınırlamaları, IP bazlı engellemeler ve loglar anlamını yitirir. Kural şu: bu başlıkları yalnızca istek gerçekten Cloudflare'in IP adreslerinden geliyorsa kabul edin.

Cloudflare'in güncel IP aralıkları cloudflare.com/ips adresinde yayınlanıyor. Aralıklar nadiren değişse de sunucu yapılandırmanıza ekledikten sonra yılda bir kontrol etmekte fayda var.

Apache: mod_remoteip

Apache'de en temiz çözüm, gerçek IP'yi daha uygulamaya ulaşmadan web sunucusu seviyesinde düzeltmek. Böylece hem loglar hem PHP'deki REMOTE_ADDR doğru adresi gösterir. cPanel sunucularda EasyApache 4 üzerinden mod_remoteip modülünü etkinleştirdikten sonra yapılandırmaya şunları ekleyin:

RemoteIPHeader CF-Connecting-IP
RemoteIPTrustedProxy 173.245.48.0/20
RemoteIPTrustedProxy 103.21.244.0/22
RemoteIPTrustedProxy 103.22.200.0/22
RemoteIPTrustedProxy 104.16.0.0/13
RemoteIPTrustedProxy 172.64.0.0/13
# ... cloudflare.com/ips listesindeki diğer IPv4 ve IPv6 aralıkları

Log formatında %h yerine %a kullanmayı unutmayın; yoksa erişim logları hâlâ Cloudflare'in adresini yazar. Eskiden kullanılan mod_cloudflare modülü artık geliştirilmiyor, yeni kurulumlarda tercih etmeyin.

Nginx: real_ip modülü

set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 172.64.0.0/13;
# ... diğer aralıklar
real_ip_header CF-Connecting-IP;

Bu satırlar http bloğuna eklenebilir. Nginx, istek yalnızca listedeki adreslerden geldiğinde başlığı dikkate alır.

Laravel: TrustProxies

Web sunucusu ayarına erişiminiz yoksa ya da ek bir güvence istiyorsanız, Laravel'in proxy güveni ayarı aynı işi uygulama seviyesinde yapar. Laravel 11 ve sonrasında bootstrap/app.php içinde:

->withMiddleware(function (Middleware $middleware) {
    $middleware->trustProxies(at: [
        '173.245.48.0/20', '103.21.244.0/22', '104.16.0.0/13', '172.64.0.0/13',
        // ... diğer aralıklar
    ]);
})

Bundan sonra $request->ip(), X-Forwarded-For başlığından gerçek adresi döndürür. Hız sınırlama (throttle) gibi IP'ye dayanan özellikler de doğru çalışmaya başlar.

trustProxies(at: '*') ayarı her kaynağa güvenir. Bu ancak sunucunuza Cloudflare dışından erişim tamamen kapalıysa kabul edilebilir. Bunu bir sonraki adımla birlikte yapmak gerekiyor.

Bir adım ileri: sunucuyu Cloudflare dışına kapatmak

En sağlam yöntem, sunucunun 80 ve 443 portlarını yalnızca Cloudflare IP aralıklarına açmak. Böylece hem başlık sahteciliği imkânsız hale gelir hem de Cloudflare'in sağladığı saldırı koruması doğrudan sunucu IP'sine yapılan saldırılarla atlatılamaz. CSF kullanan cPanel sunucularında bu kural csf.allow ve port ayarlarıyla, diğer sunucularda ise iptables ya da bulut sağlayıcının güvenlik duvarı ile yapılabilir.

Kontrol

Ayarları yaptıktan sonra kısa bir PHP dosyasıyla test edin ve işiniz bitince dosyayı silin:

<?php
echo $_SERVER['REMOTE_ADDR'], PHP_EOL;
echo $_SERVER['HTTP_CF_CONNECTING_IP'] ?? '-', PHP_EOL;

İki satır da aynı adresi, yani kendi IP'nizi gösteriyorsa yapılandırma doğru demektir. Kendi IP'nizi "ip adresim" araması yaparak öğrenebilirsiniz.