Cloudflare 取得用戶真實 IP 的方式

2022092512:20
本文是針對自家網站有使用 CDN Cloudflare 時
如何記錄用戶真實 IP 的方法
 

Apache httpd 記錄用戶真實 IP

LogFormat "%h %l %u %t \"%r\" %>s %b" common
 改為
LogFormat "%h %l %u %t \"%r\" %>s %b %{X-Forwarded-For}i" common




 

nginx 記錄用戶真實 IP

nginx 記錄用戶真實 IP 方法一:

使用 x_forwarded_for
(remote_addr 仍會是 Cloudflare 的 IP)
nginx.conf 
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                     '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

原版的設定中,最後一欄即可記錄 X-Forwarded-For 資料
https://www.loadbalancer.org/blog/nginx-and-x-forwarded-for-header/

Cloudflare 有提供各種 web server 記錄真實 IP 的方式:
Restoring original visitor IPs
https://support.cloudflare.com/hc/en-us/articles/200170786-Restoring-original-visitor-IPs
 

nginx 記錄用戶真實 IP 方法二:

使用  ngx_http_realip_module 模組設定正確的 client IP
將 remote_addr 改為用戶真實 IP
(使用 nginx -V 可查看是否內建 ngx_http_realip_module  模組)

新增檔案
$ vim /etc/nginx/conf.d/nginx-cloudflase-realip.conf
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;

 real_ip_header CF-Connecting-IP; 

# 以上是 Cloudflare IP  https://www.cloudflare.com/ips/ 

restart nginx 後
remote_addr 就會是 user IP

參考:
http://nginx.org/en/docs/http/ngx_http_realip_module.html


 

PHP 取的用戶真實 IP 的方式 (Cloudflare)

 
一般取得真實 IP 會用這個方式,
但 HTTP_X_FORWARDED_FOR 的資料是可以偽造的
  $_SERVER['HTTP_X_FORWARDED_FOR'];

Cloudflare 提供另一個變數,可以取得真實的用戶 IP
這資料無法偽造
  $_SERVER['HTTP_CF_CONNECTING_IP'] 

$_SERVER['HTTP_X_FORWARDED_FOR'] 取得的資料,會類似這樣:
107.167.188.8

107.167.188.8, 162.158.179.199
第一組(左)是user IP,
第二組(右)是 proxy/cdn 疊加上去的 IP (如Cloudflare IP)
(通常 HTTP_X_FORWARDED_FOR 只有一組 IP,若經過多個 proxy/cdn 就會記錄多組 IP)

user 可以偽造 HTTP_X_FORWARDED_FOR 資料
$_SERVER['HTTP_X_FORWARDED_FOR']  有可能變這樣:
168.95.1.1, 107.167.188.8, 162.158.179.199
第一組是user 偽造, 第二組是user IP, 第三組是 Cloudflare IP

或者 user 這樣偽造:
8.8.8.8, 168.95.1.1, 107.167.188.8, 162.158.179.199
前兩組都是user 偽造,
 

瀏覽器輕鬆偽造 HTTP_X_FORWARDED_FOR  資料

Firefox 套件:X-Forwarded-For Header
Chrome 套件:X-Forwarded-For Header