土豆不好吃

使用Cloudflare时如何获取访客的真实IP?

文章目录[显示]
这篇文章在 2023年04月21日20:51:37 更新了哦~

前段时间搭建了一个图床站,然后很自然的套上了一层Cloudflare。但是几天前突然发现大量垃圾评论,想要有针对性的处理一下。于是问题来了,获取不到访客的真实IP,只能看到Cloudflare的IP,想要对IP进行封杀似乎有些问题。

经过十分钟的探索,我总结出来以下几种办法

通过X-Forwarded-For 或 CF-Connecting-IP 标头

Cloudflare会按照行业标准把访问者的真实IP包含在这两个访问头中。那么我们就可以通过提取这个内容来获取到真实IP,不过这个头是可以伪造的,所以实际上还需要进行进一步的处理。

用PHP的话,以下两者之一就可以获取到真实IP:

$_SERVER["HTTP_CF_CONNECTING_IP"]
$_SERVER["HTTP_X_FORWARDED_FOR"]

简单的判断一下是这样的:

user_ip = (isset($_SERVER["HTTP_CF_CONNECTING_IP"])$_SERVER["HTTP_CF_CONNECTING_IP"]:$_SERVER['REMOTE_ADDR']);

但是这样其实有些不方便,需要我们手动改代码,在使用某些开源程序时对应的位置可能不太好找。

多说一句:

有些时候我们的应用可能是由Nginx反代的,这个时候Nginx会记录访客的IP,但是我们的应用记录的只可能是127.0.0.1,这个时候应用想获取到真实IP该怎么办呢?Nginx中可以这样配置:

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

我们用x-real-ip就能拿到用户的IP啦,x-forwarded-for能看到每层连接的IP(自然也包括真实IP了)

使用一些插件

对于类似WordPress这类成熟的CMS,有些插件可以提供类似的功能,比如说https://wordpress.org/plugins/real-ip-and-geo-for-cloudflare/

这个可以搜索下看看,同样也需要注意,headers是可以被伪造的

通过Nginx http_realip_module

gx_http_realip_module默认是不被编译的,所以我们需要重新编译Nginx。

参考这篇《为 Nginx 开启 tls 1.3 支持,顺便编译 openssl1.1.1a》,编译参数增加一个--with-http_realip_module

之后创建一个配置文件cloudflare.conf,IP地址来源于Cloudflare官网

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 104.16.0.0/12;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2c0f:f248::/32;
set_real_ip_from 2a06:98c0::/29;

# use any of the following two
real_ip_header CF-Connecting-IP;
#real_ip_header X-Forwarded-For;

然后在对应站点的配置文件中,或者是nginx.conf中添加一行include cloudflare.conf;即可。

这样Web应用就会获取到正确的IP了,日志里的记录也是正确的IP

这样看谁不爽就添加到黑名单好了。

如何伪造X-Forwarded-For等请求头

用curl的话可以这样:

curl http://example.com -H 'X-Forwarded-For: 1.1.1.1' -H 'X-Real-IP: 2.2.2.2'

或者Postman中设置Headers也一样。

需要注意的是:

  1. 如果由Nginx直连的应用,那么REMOTE_ADDR一定是真实IP,要不怎么进行TCP握手呢
  2. 如果由Nginx反代,那么需要我们配置合理的proxy_set_header设置请求头,此时REMOTE_ADDR会变成Nginx所属的那台服务器的IP
  3. 由于请求头是可以伪造的、不可控的,所以用X-Forwarded-For时总得校验下是不是IP吧,要不可能会出现注入,跨站等安全风险。

参考资料

https://support.cloudflare.com/hc/zh-cn/articles/200170706-%E4%BD%BF%E7%94%A8-Nginx-%E6%97%B6%E5%A6%82%E4%BD%95%E6%81%A2%E5%A4%8D%E5%8E%9F%E5%A7%8B%E8%AE%BF%E9%97%AE%E8%80%85%E7%9A%84-IP-

https://stackoverflow.com/questions/14985518/cloudflare-and-logging-visitor-ip-addresses-via-in-php


文章版权归原作者所有丨本站默认采用CC-BY-NC-SA 4.0协议进行授权|
转载必须包含本声明,并以超链接形式注明原作者和本文原始地址:
https://dmesg.app/cloudlare-real-ip.html
退出移动版