WordPress’te Cloudflare Arkasında Gerçek IP Adresi Alma
Cloudflare arkasında çalışan bir WordPress siteniz varsa ve access loglarınıza baktığınızda tüm ziyaretçilerin aynı IP adresinden geliyormuş gibi göründüğünü fark ettiyseniz, yalnız değilsiniz. Bu, Cloudflare’e geçen hemen her WordPress yöneticisinin karşılaştığı klasik bir sorun. Loglarınızda 104.16.x.x veya 172.64.x.x gibi Cloudflare’e ait IP adresleri görüyorsanız, sunucunuz gerçek ziyaretçi IP’lerini değil, Cloudflare’in proxy IP’lerini kaydediyor demektir. Bu durumu düzeltmek hem güvenlik hem de analitik açısından kritik önem taşır.
Sorun Neden Oluşur?
Cloudflare bir reverse proxy olarak çalışır. Ziyaretçi sitenize bağlanmak istediğinde, istek önce Cloudflare’in sunucularına ulaşır, oradan işlenerek sizin web sunucunuza iletilir. Sunucunuz bu isteği gördüğünde, isteği yapan tarafın Cloudflare olduğunu düşünür ve bağlantının kaynak IP’si olarak Cloudflare’in IP adresini kaydeder.
Gerçek kullanıcı IP adresi aslında kaybolmuş değil. Cloudflare, orijinal ziyaretçi IP’sini CF-Connecting-IP adlı özel bir HTTP başlığı ile birlikte isteğin içine ekler. Bunun yanı sıra standart X-Forwarded-For başlığını da doldurur. Sorun, Apache veya Nginx’in varsayılan yapılandırmasının bu başlıkları okuyup kullanmamasından kaynaklanır.
Bu sorunun pratik sonuçları şunlardır:
- Güvenlik logları anlamsızlaşır: Brute force saldırısı yapan IP’yi ban edemezsiniz
- Fail2ban çalışmaz: Cloudflare IP’lerini engelleyerek siteyi kendiniz kapatırsınız
- WooCommerce sipariş adresleri yanlış: Müşteri lokasyon bazlı kısıtlamalar işe yaramaz
- WordPress güvenlik eklentileri hatalı çalışır: Wordfence, iThemes Security gibi eklentiler yanlış IP’leri görür
- Rate limiting uygulanamaz: Herkesi aynı IP’den geliyormuş gibi görür
Apache ile Gerçek IP Alma
Apache kullanıyorsanız mod_remoteip modülü bu işi halletmek için biçilmiş kaftandır. Ubuntu/Debian tabanlı sistemlerde genellikle kurulu gelir ama aktif olmayabilir.
mod_remoteip Aktivasyonu
# Modülü etkinleştir
sudo a2enmod remoteip
# Mevcut durumu kontrol et
apache2ctl -M | grep remoteip
# Yapılandırma dizinine geç
cd /etc/apache2/conf-available/
Şimdi Cloudflare IP aralıklarını tanımlayan bir yapılandırma dosyası oluşturacağız. Cloudflare’in IPv4 ve IPv6 IP aralıklarını https://www.cloudflare.com/ips/ adresinden güncel olarak alabilirsiniz.
sudo nano /etc/apache2/conf-available/cloudflare-remoteip.conf
Dosyaya şu içeriği ekleyin:
# Cloudflare IPv4 aralıkları
RemoteIPHeader CF-Connecting-IP
RemoteIPTrustedProxy 173.245.48.0/20
RemoteIPTrustedProxy 103.21.244.0/22
RemoteIPTrustedProxy 103.22.200.0/22
RemoteIPTrustedProxy 103.31.4.0/22
RemoteIPTrustedProxy 141.101.64.0/18
RemoteIPTrustedProxy 108.162.192.0/18
RemoteIPTrustedProxy 190.93.240.0/20
RemoteIPTrustedProxy 188.114.96.0/20
RemoteIPTrustedProxy 197.234.240.0/22
RemoteIPTrustedProxy 198.41.128.0/17
RemoteIPTrustedProxy 162.158.0.0/15
RemoteIPTrustedProxy 104.16.0.0/13
RemoteIPTrustedProxy 104.24.0.0/14
RemoteIPTrustedProxy 172.64.0.0/13
RemoteIPTrustedProxy 131.0.72.0/22
# Cloudflare IPv6 aralıkları
RemoteIPTrustedProxy 2400:cb00::/32
RemoteIPTrustedProxy 2606:4700::/32
RemoteIPTrustedProxy 2803:f800::/32
RemoteIPTrustedProxy 2405:b500::/32
RemoteIPTrustedProxy 2405:8100::/32
RemoteIPTrustedProxy 2a06:98c0::/29
RemoteIPTrustedProxy 2c0f:f248::/32
Yapılandırmayı aktif edip Apache’yi yeniden başlatın:
sudo a2enconf cloudflare-remoteip
sudo systemctl restart apache2
# Log formatını kontrol et
sudo tail -f /var/log/apache2/access.log
Nginx ile Gerçek IP Alma
Nginx kullanıyorsanız ngx_http_realip_module modülünü kullanmanız gerekir. Bu modül Nginx’in çoğu paket dağıtımında derlenmiş olarak gelir.
# Modülün mevcut olup olmadığını kontrol et
nginx -V 2>&1 | grep real_ip
Nginx yapılandırma dosyasına Cloudflare bloğunu ekleyin. Genellikle /etc/nginx/conf.d/ dizininde ayrı bir dosya oluşturmak daha temiz bir yaklaşımdır:
sudo nano /etc/nginx/conf.d/cloudflare-realip.conf
# Cloudflare gerçek IP yapılandırması
set_real_ip_from 173.245.48.0/20;
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 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 131.0.72.0/22;
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;
# CF-Connecting-IP başlığını kullan
real_ip_header CF-Connecting-IP;
Nginx yapılandırmasını test edip yeniden yükleyin:
sudo nginx -t
sudo systemctl reload nginx
# Access logunu izle
sudo tail -f /var/log/nginx/access.log
WordPress Tarafında Çözüm
Sunucu tarafında yapılandırmayı düzelttiniz ama WordPress’in PHP ortamı hala yanlış IP okuyabilir. Bu özellikle shared hosting kullanıyorsanız ya da sunucu yapılandırmasına erişiminiz yoksa önemlidir. wp-config.php dosyasına ekleyeceğiniz birkaç satırla PHP ortamında da gerçek IP’yi doğru şekilde alabilirsiniz.
sudo nano /var/www/html/wp-config.php
wp-config.php dosyasında / That's all, stop editing! / satırından önce şunu ekleyin:
# wp-config.php içine eklenecek PHP kodu
# (nano ile düzenlerken PHP açma etiketi zaten mevcut olacak)
// Cloudflare gerçek IP tespiti
if (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) {
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_CF_CONNECTING_IP'];
$_SERVER['HTTP_CLIENT_IP'] = $_SERVER['HTTP_CF_CONNECTING_IP'];
}
// Güvenlik için Cloudflare IP aralıklarını doğrula
function is_cloudflare_ip($ip) {
$cloudflare_ips = array(
'173.245.48.0/20', '103.21.244.0/22', '103.22.200.0/22',
'103.31.4.0/22', '141.101.64.0/18', '108.162.192.0/18',
'190.93.240.0/20', '188.114.96.0/20', '197.234.240.0/22',
'198.41.128.0/17', '162.158.0.0/15', '104.16.0.0/13',
'104.24.0.0/14', '172.64.0.0/13', '131.0.72.0/22'
);
foreach ($cloudflare_ips as $range) {
list($subnet, $bits) = explode('/', $range);
$ip_long = ip2long($ip);
$subnet_long = ip2long($subnet);
$mask = -1 << (32 - $bits);
if (($ip_long & $mask) === ($subnet_long & $mask)) {
return true;
}
}
return false;
}
// Yalnızca gerçekten Cloudflare'den geliyorsa IP'yi değiştir
if (isset($_SERVER['HTTP_CF_CONNECTING_IP']) &&
isset($_SERVER['REMOTE_ADDR']) &&
is_cloudflare_ip($_SERVER['REMOTE_ADDR'])) {
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_CF_CONNECTING_IP'];
}
Cloudflare IP Listesini Otomatik Güncelleme
Cloudflare zaman zaman IP aralıklarını günceller. Manuel takip yerine bu işi bir cron job’a bırakmak daha sağlıklıdır. Hem Apache hem de Nginx için çalışan bir script yazalım:
sudo nano /usr/local/bin/update-cloudflare-ips.sh
#!/bin/bash
# Cloudflare IP listesini otomatik güncelle
# /usr/local/bin/update-cloudflare-ips.sh
WEBSERVER="nginx" # veya "apache" olarak değiştirin
NGINX_CONF="/etc/nginx/conf.d/cloudflare-realip.conf"
APACHE_CONF="/etc/apache2/conf-available/cloudflare-remoteip.conf"
LOG_FILE="/var/log/cloudflare-ip-update.log"
echo "[$(date)] Cloudflare IP listesi güncelleniyor..." >> $LOG_FILE
# IPv4 listesini çek
IPV4_LIST=$(curl -s https://www.cloudflare.com/ips-v4)
IPV6_LIST=$(curl -s https://www.cloudflare.com/ips-v6)
if [ -z "$IPV4_LIST" ] || [ -z "$IPV6_LIST" ]; then
echo "[$(date)] HATA: Cloudflare IP listesi alınamadı!" >> $LOG_FILE
exit 1
fi
if [ "$WEBSERVER" == "nginx" ]; then
# Nginx yapılandırmasını oluştur
echo "# Cloudflare Gerçek IP - Otomatik güncellendi: $(date)" > $NGINX_CONF
echo "" >> $NGINX_CONF
for ip in $IPV4_LIST; do
echo "set_real_ip_from $ip;" >> $NGINX_CONF
done
for ip in $IPV6_LIST; do
echo "set_real_ip_from $ip;" >> $NGINX_CONF
done
echo "" >> $NGINX_CONF
echo "real_ip_header CF-Connecting-IP;" >> $NGINX_CONF
# Nginx yapılandırmasını test et ve yeniden yükle
if nginx -t 2>/dev/null; then
systemctl reload nginx
echo "[$(date)] Nginx yapılandırması başarıyla güncellendi." >> $LOG_FILE
else
echo "[$(date)] HATA: Nginx yapılandırması geçersiz!" >> $LOG_FILE
exit 1
fi
elif [ "$WEBSERVER" == "apache" ]; then
echo "# Cloudflare Gerçek IP - Otomatik güncellendi: $(date)" > $APACHE_CONF
echo "RemoteIPHeader CF-Connecting-IP" >> $APACHE_CONF
echo "" >> $APACHE_CONF
for ip in $IPV4_LIST; do
echo "RemoteIPTrustedProxy $ip" >> $APACHE_CONF
done
for ip in $IPV6_LIST; do
echo "RemoteIPTrustedProxy $ip" >> $APACHE_CONF
done
if apachectl configtest 2>/dev/null; then
systemctl reload apache2
echo "[$(date)] Apache yapılandırması başarıyla güncellendi." >> $LOG_FILE
else
echo "[$(date)] HATA: Apache yapılandırması geçersiz!" >> $LOG_FILE
exit 1
fi
fi
Script’i çalıştırılabilir yapın ve cron’a ekleyin:
chmod +x /usr/local/bin/update-cloudflare-ips.sh
# Crontab'a ekle - her Pazar sabahı 03:00'da çalışsın
echo "0 3 * * 0 root /usr/local/bin/update-cloudflare-ips.sh" | sudo tee -a /etc/cron.d/cloudflare-ip-update
# İlk çalıştırmayı manuel yap
sudo /usr/local/bin/update-cloudflare-ips.sh
Fail2ban ile Entegrasyon
Sunucu tarafında gerçek IP’leri doğru şekilde aldıktan sonra Fail2ban tekrar düzgün çalışmaya başlayacaktır. Ama dikkat etmeniz gereken önemli bir nokta var: Cloudflare IP’lerini asla Fail2ban ile engellemeyin. Bunun için bir whitelist oluşturun:
sudo nano /etc/fail2ban/jail.local
[DEFAULT]
# Cloudflare IP'lerini whitelist'e al
ignoreip = 127.0.0.1/8 ::1
173.245.48.0/20
103.21.244.0/22
103.22.200.0/22
103.31.4.0/22
141.101.64.0/18
108.162.192.0/18
190.93.240.0/20
188.114.96.0/20
197.234.240.0/22
198.41.128.0/17
162.158.0.0/15
104.16.0.0/13
104.24.0.0/14
172.64.0.0/13
131.0.72.0/22
[wordpress-auth]
enabled = true
port = http,https
filter = wordpress-auth
logpath = /var/log/nginx/access.log
maxretry = 5
bantime = 3600
findtime = 600
Yapılandırmayı Test Etme
Tüm değişiklikleri yaptıktan sonra gerçekten çalışıp çalışmadığını doğrulamak için şu yöntemleri kullanabilirsiniz:
# Gerçek IP'nin log'a düşüp düşmediğini kontrol et
sudo tail -n 50 /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn
# PHP ile test sayfası oluştur (test sonrası SİL!)
echo '<?php echo "Gerçek IP: " . $_SERVER["REMOTE_ADDR"] . "<br>";
echo "CF-IP: " . $_SERVER["HTTP_CF_CONNECTING_IP"] . "<br>";
echo "X-Forwarded-For: " . $_SERVER["HTTP_X_FORWARDED_FOR"];
?>' | sudo tee /var/www/html/ip-test.php
# Tarayıcıdan test ettikten sonra dosyayı hemen sil
sudo rm /var/www/html/ip-test.php
# Apache mod_remoteip durumu kontrol
apache2ctl -M 2>/dev/null | grep -i remoteip
WordPress yönetim panelinden de kontrol edebilirsiniz. Wordfence gibi bir güvenlik eklentisi kuruluysa, Dashboard üzerindeki “Live Traffic” bölümünden gelen IP adreslerinin artık Cloudflare aralıklarında değil gerçek kullanıcı IP’lerinde olduğunu görebilirsiniz.
WooCommerce ve Üçüncü Parti Eklentiler
Bazı WooCommerce eklentileri, özellikle coğrafi konum bazlı vergi hesaplaması yapanlar, IP adresini $_SERVER['REMOTE_ADDR'] yerine kendi yöntemleriyle alır. Bu eklentilerin doğru çalışması için WordPress functions.php‘ye şu kodu ekleyebilirsiniz:
// functions.php veya özel bir mu-plugin'e ekleyin
add_filter('pre_option_woocommerce_default_customer_address', function($value) {
return 'geolocation';
});
// WooCommerce için gerçek IP filtresi
add_filter('woocommerce_geolocation_ip_address', function($ip_address) {
if (!empty($_SERVER['HTTP_CF_CONNECTING_IP'])) {
return sanitize_text_field($_SERVER['HTTP_CF_CONNECTING_IP']);
}
return $ip_address;
});
Sık Karşılaşılan Hatalar
Yapılandırma sırasında karşılaşabileceğiniz yaygın sorunları ve çözümlerini şöyle özetleyebilirim:
- “Hala Cloudflare IP görüyorum” sorunu: PHP-FPM ile çalışıyorsanız FastCGI parametrelerini de güncellemeniz gerekebilir. Nginx’in FastCGI konfigürasyonuna
fastcgi_param REMOTE_ADDR $realip_remote_addr;satırını ekleyin.
- LiteSpeed veya OpenLiteSpeed kullanıyorsanız:
.htaccessyöntemleri çalışmayabilir. LiteSpeed’in kendi kontrol panelinden “Cloudflare IPs” ayarını aktif etmeniz gerekir.
- Plesk veya cPanel ortamında: Direkt sunucu yapılandırmasına erişiminiz olmayabilir. Bu durumda yalnızca
wp-config.phpyöntemi ve Cloudflare’in “Authenticated Origin Pulls” özelliği işe yarar.
- Önbellek eklentisi çakışması: W3 Total Cache veya WP Super Cache, IP bazlı önbellek ayırma yapıyorsa Cloudflare IP’leri nedeniyle tek bir büyük önbellek dosyası oluşturabilir. Yapılandırmayı düzelttikten sonra önbelleği temizleyin.
- CloudFlare Rocket Loader çakışması: IP tespiti için JavaScript kullanan bazı eklentiler Rocket Loader ile sorun çıkarabilir. Cloudflare panelinden Rocket Loader’ı devre dışı bırakabilir ya da ilgili script için
data-cfasync="false"niteliği ekleyebilirsiniz.
Cloudflare Authenticated Origin Pulls
Güvenliği bir adım daha öteye taşımak istiyorsanız, Cloudflare’in “Authenticated Origin Pulls” özelliğini aktif edebilirsiniz. Bu özellik sayesinde sunucunuza yalnızca Cloudflare üzerinden gelen istekler kabul edilir; birisi Cloudflare’i bypass ederek direkt sunucu IP’nize bağlanmaya çalışırsa bağlantı reddedilir. Nginx için yapılandırma şöyledir:
# Cloudflare Origin Pull sertifikasını indir
sudo wget -O /etc/nginx/cloudflare-origin-pull-ca.pem
https://developers.cloudflare.com/ssl/static/authenticated_origin_pull_ca.pem
# Nginx server bloğuna eklenecek ayarlar
# /etc/nginx/sites-available/siteniz.conf içine:
# ssl_client_certificate /etc/nginx/cloudflare-origin-pull-ca.pem;
# ssl_verify_client on;
Bu yapılandırma tamamlandıktan sonra Cloudflare panelinde SSL/TLS > Origin Server bölümünden “Authenticated Origin Pulls”u aktif edin.
Sonuç
Cloudflare arkasındaki WordPress sitelerinde gerçek IP adresi almak, tek seferlik yapılan ve sonra unutulan bir işlem değil. IP aralıkları değişebileceğinden otomatik güncelleme scriptini mutlaka devreye alın. Yapılandırmanın hangi katmanda yapıldığı önemlidir: ideal senaryo hem web sunucusu düzeyinde (mod_remoteip veya ngx_http_realip_module) hem de WordPress/PHP düzeyinde yapılandırmanın birlikte çalışmasıdır.
En kritik hatırlatma: sunucu tarafında yapılandırmayı doğru yapmadan yalnızca wp-config.php yöntemine güvenmeyin. Bu yöntem, herhangi bir saldırganın CF-Connecting-IP başlığını taklit ederek sahte IP göndermesine kapı açabilir. Cloudflare IP whitelist doğrulamasını içeren güvenli PHP kodunu kullanın ya da işi doğrudan web sunucusuna bırakın. Web sunucusu seviyesinde doğru yapılandırıldığında, sunucu yalnızca güvenilir Cloudflare proxy’lerinden gelen başlıklara inanacak ve güvenlik açığı oluşmayacaktır.
