背景介绍
假定局域网环境中,我们在 80
端口部署一个 PHP
网站,并且使用 Cloudflare Tunnel
将内网地址 http://127.0.0.1
转发至外网。然而,这种设置会导致所有访客的访问请求都显示为 Tunnel
所在的内网IP地址(如 127.0.0.1
)。
为了获取访客的真实 IP,Cloudflare
提供了 CF-Connecting-IP
这个 HTTP 请求头。通过调整 OpenResty
配置,我们可以提取并使用这个头中的真实 IP。
解决方案
以下是修改后的 OpenResty
配置文件:
server {
listen 80 ;
server_name your.domain.com;
index index.php;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
+ # 设置 Cloudflare 的真实 IP 地址
+ set_real_ip_from 127.0.0.1/32; # Cloudflare Tunnel 的 IP 地址
+ real_ip_header CF-Connecting-IP;
location ^~ /.well-known/acme-challenge {
allow all;
root /usr/share/nginx/html;
}
error_page 404 /404.html;
location ~ [^/]\.php(/|$) {
fastcgi_pass 127.0.0.1:9000;
include fastcgi-php.conf;
include fastcgi_params;
set $real_script_name $fastcgi_script_name;
if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") {
set $real_script_name $1;
set $path_info $2;
}
fastcgi_param SCRIPT_FILENAME $document_root$real_script_name;
fastcgi_param SCRIPT_NAME $real_script_name;
fastcgi_param PATH_INFO $path_info;
+ fastcgi_param REMOTE_ADDR $remote_addr; # 传递真实 IP 地址给 PHP
}
}
配置说明
-
set_real_ip_from 127.0.0.1/32;
- 该指令用于指定哪些 IP 地址可以设置真实 IP。
127.0.0.1/32
表示本地地址,因为Cloudflare Tunnel
将流量转发到本地服务器。
-
real_ip_header CF-Connecting-IP;
- 指定包含真实客户端 IP 的 HTTP 头。
CF-Connecting-IP
是 Cloudflare 设置的头,包含原始访问者的 IP。
-
PHP FastCGI 配置
fastcgi_param REMOTE_ADDR $remote_addr;
将 OpenResty 的$remote_addr
传递给 FastCGI,确保 PHP 应用程序获取到正确的客户端 IP。
通过这些配置,即可在使用 Cloudflare Tunnel
时获取访客的真实 IP 地址。