Komutları üretim sunucusunda çalıştırmadan önce yedek alın ve mümkünse bir test ortamında deneyin. Yönetim erişiminizi (SSH, panel) kaybetmemek için ayar değişikliklerinde açık bir ikinci oturum bulundurun.
Bu rehberde ne yapacağız?
Sitenizin önüne bir CDN veya ters vekil (reverse proxy) koyduğunuzda web sunucusu gelen bağlantıların hepsini CDN'in IP adreslerinden görür. Sonuç olarak erişim günlüklerinde, PHP uygulamasında ve fail2ban gibi araçlarda gerçek ziyaretçi IP adresi yerine CDN adresleri görünür. Bu rehberde Nginx (ngx_http_realip_module) ve Apache (mod_remoteip) ile gerçek istemci IP adresini güvenli şekilde nasıl alacağınızı öğreneceksiniz.
Rehber, CDN, yük dengeleyici veya ters vekil kullanan sistem yöneticilerine hitap eder. Yapılandırma ve test yaklaşık 30 dakika sürer. Komutlar Debian/Ubuntu ve RHEL tabanlı (AlmaLinux, Rocky) sistemlerde çalışır. Örneklerde 203.0.113.0/24 aralığı güvenilen vekil ağı olarak kullanılmıştır; kendi CDN sağlayıcınızın yayımladığı gerçek IP aralıklarını resmî belgelerinden alıp yerine yazmalısınız.
Gereksinimler
- Nginx veya Apache çalıştıran bir web sunucusu ve sudo yetkili kullanıcı
- CDN veya ters vekil sağlayıcınızın güncel IP aralıkları listesi (sağlayıcının resmî belgesinde yayımlanır)
- Sağlayıcının gerçek istemci IP adresini hangi başlıkta gönderdiği bilgisi (X-Forwarded-For, X-Real-IP veya sağlayıcıya özel bir başlık)
- Test için sitenize erişebilen bir istemci
Adım adım gerçek istemci IP adresini alma
1. Sorunu ve başlığı doğrulayın
Önce web sunucusunun şu an ne gördüğünü kontrol edin. Erişim günlüğündeki IP adreslerinin hep aynı birkaç adres olması, sorunu doğrular.
sudo tail -n 5 /var/log/nginx/access.log
# Apache için
sudo tail -n 5 /var/log/apache2/access.log # Debian / Ubuntu
sudo tail -n 5 /var/log/httpd/access_log # AlmaLinux / RockyGerçek IP bilgisi, vekil tarafından genellikle X-Forwarded-For başlığında taşınır. Bu başlık zincir halinde olabilir: istemci, vekil1, vekil2 gibi virgülle ayrılmış adresler içerir.
2. Güvenilen vekil aralıklarını belirleyin
Bu adım güvenlik açısından kritiktir: yalnızca gerçekten CDN'e ait IP adreslerinden gelen isteklerde bu başlığa güvenin. Aksi halde herhangi bir istemci başlığı kendisi yazıp IP adresini taklit eder ve IP bazlı kısıtlamalarınızı, hız sınırlarınızı atlatır. Aralıkları kendi sağlayıcınızın resmî listesinden alın; bu liste zamanla değişebilir.
3. Nginx'te ngx_http_realip_module ayarı
Modül çoğu dağıtım paketinde hazır derlenmiş gelir. Aşağıdaki dosyayı /etc/nginx/conf.d/gercek-ip.conf olarak oluşturun. Her güvenilen vekil ağı için bir set_real_ip_from satırı ekleyin.
set_real_ip_from 203.0.113.0/24;
# İkinci güvenilen aralık varsa bir satır daha ekleyin
# set_real_ip_from 198.51.100.0/24;
real_ip_header X-Forwarded-For;
real_ip_recursive on;real_ip_header, hangi başlıktan IP okunacağını belirler; sağlayıcınız farklı bir başlık kullanıyorsa onu yazın. real_ip_recursive on ayarı, X-Forwarded-For içindeki zincirde güvenilen adresleri sağdan sola atlar ve ilk güvenilmeyen adresi gerçek istemci sayar. Ardından denetleyip yeniden yükleyin:
sudo nginx -t && sudo systemctl reload nginxNginx günlüğünde $remote_addr artık gerçek IP adresini gösterir. Ham vekil adresini de görmek isterseniz özel bir log_format içinde $realip_remote_addr değişkenini ekleyebilirsiniz.
4. Apache'de mod_remoteip ayarı
Apache 2.4'te bu iş mod_remoteip ile yapılır. Debian ve Ubuntu'da modülü açın, RHEL tabanlı sistemlerde modül varsayılan olarak yüklü gelir.
# Debian / Ubuntu
sudo a2enmod remoteipDebian için /etc/apache2/conf-available/gercek-ip.conf, RHEL için /etc/httpd/conf.d/gercek-ip.conf dosyasına şunu yazın:
RemoteIPHeader X-Forwarded-For
RemoteIPTrustedProxy 203.0.113.0/24
# İkinci aralık gerekirse
# RemoteIPTrustedProxy 198.51.100.0/24RemoteIPTrustedProxy tanımlı olmayan adreslerden gelen başlıklar dikkate alınmaz. Günlük kaydında gerçek IP adresi için LogFormat içindeki %h yerine %a kullanılmasına dikkat edin; çünkü %a, mod_remoteip tarafından düzeltilmiş istemci adresini yazar.
LogFormat "%a %l %u %t \"%r\" %>s %b" gercekip
CustomLog /var/log/apache2/access.log gercekipRHEL tabanlı sistemlerde günlük yolu /var/log/httpd/access_log olur. Sanal konakta zaten CustomLog varsa yenisini eklemeyin, onun biçimini değiştirin; yoksa satırlar çift yazılır. Uygulamadan sonra:
# Debian / Ubuntu
sudo a2enconf gercek-ip
sudo apachectl configtest && sudo systemctl reload apache2
# AlmaLinux / Rocky
sudo apachectl configtest && sudo systemctl reload httpd5. PHP uygulamasında IP adresi
Yukarıdaki modüller yapılandırıldığında PHP'de $_SERVER['REMOTE_ADDR'] değeri gerçek istemci adresine dönüşür; uygulama kodunda X-Forwarded-For başlığını ayrıca ayrıştırmanıza gerek kalmaz ve bu başlığı doğrudan okumamak daha güvenlidir. Bazı CMS ve çerçeveler kendi vekil güven ayarlarını ayrıca ister; bu durumda yine yalnızca CDN aralıklarını güvenilir olarak tanımlayın.
6. Kaynak sunucuyu yalnızca CDN'e açın
IP bilgisine güvenilen bir mimaride kaynak sunucuya doğrudan erişimi de kapatın; aksi halde saldırgan CDN'i atlayıp doğrudan sunucuya bağlanır. Güvenlik duvarında 80 ve 443 portlarını yalnızca CDN aralıklarına açmak bu iş için yeterlidir. Güvenlik duvarını değiştirmeden önce açık bir ikinci SSH oturumu bulundurun ve kural listesinde yönetim erişiminizi (SSH) engellemediğinizden emin olun.
# Debian / Ubuntu (ufw): önce izin, sonra genel kuralı silin
sudo ufw status numbered
sudo ufw allow from 203.0.113.0/24 to any port 443 proto tcp
sudo ufw delete allow 443/tcp
# AlmaLinux / Rocky (firewalld)
sudo firewall-cmd --list-all
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" port port="443" protocol="tcp" accept'
sudo firewall-cmd --permanent --remove-service=https
sudo firewall-cmd --reloadAynı işlemi 80 portu ve her CDN aralığı (IPv6 dahil) için tekrarlayın; ssh kuralına dokunmayın.
Doğrulama
İki şeyi doğrulamanız gerekir: gerçek IP'nin günlüğe düşmesi ve sahte başlığın etkisiz kalması. Önce kendi gerçek IP adresinizi öğrenin ve CDN üzerinden siteye bir istek gönderin:
curl -s https://example.com/ -o /dev/null
sudo tail -n 2 /var/log/nginx/access.logBeklenen sonuç: Günlükte CDN adresi değil, kendi IP adresinizin görünmesidir. Şimdi başlığı sahte yazarak aynı isteği gönderin:
curl -s -H 'X-Forwarded-For: 192.0.2.77' https://example.com/ -o /dev/null
sudo tail -n 2 /var/log/nginx/access.logCDN üzerinden giden bu istekte vekil zinciri sağdan işleneceği için günlükte yine gerçek adresiniz görünmeli, 192.0.2.77 görünmemelidir. Kaynak sunucuya CDN dışından doğrudan istek atabiliyorsanız, sahte başlığın oradan etkisiz kaldığını da kontrol edin: güvenilmeyen kaynaktan gelen başlık yok sayılmalı ve günlükte bağlantı kuran gerçek adres görünmelidir.
Sık karşılaşılan sorunlar
- Belirti: Günlükte hâlâ CDN adresleri görünüyor. Çözüm: set_real_ip_from veya RemoteIPTrustedProxy aralığının CDN'in gerçek kaynak adreslerini kapsadığını ve doğru başlığın seçildiğini kontrol edin; yapılandırma yeniden yüklenmemiş olabilir.
- Belirti: Günlükte virgüllü, birden fazla adres görünüyor. Çözüm: Nginx'te real_ip_recursive on ayarını açın; Apache'de güvenilen vekil listesine ara vekilleri de ekleyin.
- Belirti: Hız sınırı veya engelleme tüm ziyaretçileri etkiliyor. Çözüm: Bu araçlar muhtemelen CDN adresini görüyor; gerçek IP düzeltmesini önce web sunucusunda yapın, ardından fail2ban gibi araçlarda günlük biçiminin gerçek IP'yi içerdiğini doğrulayın.
- Belirti: Apache günlüğünde değişiklik yok. Çözüm: LogFormat içinde %h yerine %a kullandığınızdan ve doğru CustomLog satırının etkin olduğundan emin olun.
Güvenlik ve bakım notları
- Güvenilen vekil listesini boş bırakmayın veya tüm adreslere güvenmeyin; IP taklidine ve güvenlik kurallarının atlatılmasına yol açar.
- CDN sağlayıcınızın IP aralıkları zamanla değişebilir; resmî listeyi düzenli kontrol edin ve değişimi yapılandırmaya yansıtın.
- fail2ban, hız sınırlama ve IP izin listeleri gerçek istemci adresini kullanmalı; yoksa CDN adresini engelleyip tüm ziyaretçileri dışarıda bırakabilirsiniz.
Sık sorulan sorular
X-Forwarded-For başlığına doğrudan güvenebilir miyim?
Hayır. Bu başlığı herhangi bir istemci gönderebilir ve değerini istediği gibi yazabilir. Yalnızca güvenilen vekil adreslerinden gelen isteklerde dikkate almalısınız; bunu realip ve remoteip modülleri sağlar.
Nginx'te $remote_addr ile $realip_remote_addr farkı nedir?
realip modülü etkinleştirildiğinde $remote_addr gerçek istemci adresini, $realip_remote_addr ise bağlantıyı kuran gerçek vekil adresini taşır. Sorun giderme için ikisini birlikte günlüğe yazmak yararlıdır.
Proxy Protocol kullanmalı mıyım?
TCP seviyesinde çalışan yük dengeleyicilerde IP bilgisini başlık yerine bağlantı başında taşımak için kullanılabilir. Hem vekil hem de web sunucu bunu destekliyorsa seçenek olarak değerlendirin, ancak iki tarafın aynı biçimi beklediğinden emin olun; yanlış yapılandırma bağlantıların kopmasına yol açar.
İlgili sözlük terimleri
Bu kategorideki diğer rehberler
- MariaDB yavaş sorgu günlüğü ve temel optimizasyonMariaDB yavaş sorgu günlüğünü açın, yavaş sorguları dumpslow ile analiz edin, EXPLAIN ile indeks eksiklerini bulun ve temel optimizasyonla veritabanı yükünü güvenle azaltın.
- OPcache, gzip/brotli ve önbellek başlıklarıyla web performansıOPcache ile PHP başlangıç maliyetini düşürün, gzip ve brotli sıkıştırmasını Nginx ile Apache üzerinde açın ve doğru Cache-Control başlıklarıyla web performansını ölçülebilir biçimde artırın.
- php.ini güvenlik ayarlarıphp.ini güvenlik ayarlarını uygulayın: expose_php, disable_functions, open_basedir, hata gösterimi, oturum çerezleri ve dosya yükleme limitlerini PHP-FPM üzerinde güvenle sıkılaştırın.
- WordPress sertleştirme rehberi (hosting tarafından)WordPress sitelerini hosting tarafından sertleştirin: dosya izinleri, wp-config ayarları, yükleme dizininde PHP engeli, WP-CLI ile bütünlük kontrolü ve güncelleme düzeni.