众所周知,当网站接入CDN加速后,部分程序例如Typecho获取到的IP就不再是访客真实IP了。在这种情况下,如果需要获得访客的真实IP,应该如何处理呢?
Main
本博客接入了Cloudflare,然而我早就忘记了接入各大CDN后都会遇到的一个坑(见上文),而CF在这方面又有一定的特性,于是就记录一下解决问题的过程。
在config.inc.php
中添加如下代码:
/** 设置真实IP */
if(isset($_SERVER['HTTP_CF_CONNECTING_IP']))$_SERVER['REMOTE_ADDR']=$_SERVER['HTTP_CF_CONNECTING_IP'];
else if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))$_SERVER['REMOTE_ADDR']=end(explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']));
压行功底见长 Orz
简单解说:
CDN服务按照行业规范一般会设置$_SERVER['HTTP_X_FORWARDED_FOR']
,保存来源IP,当层数多于一层时以半角逗号,
分隔。
CF有一个特性,即它还会发送$_SERVER['HTTP_CF_CONNECTING_IP']
保存请求IP。由于我用的是CF,所以我优先获取这个参数保存的IP。
Warning
CF特有的$_SERVER['HTTP_CF_CONNECTING_IP']
相对安全,而$_SERVER['HTTP_X_FORWARDED_FOR']
则有一定的安全隐患。下面应用Python进行一点测试。
尝试篡改CF-CONNECTING-IP
这两个参数都是由请求头提交的,即我们可以构造请求头。参考下面的Python3代码:
import requests
import json
headers={'CF-CONNECTING-IP':'0.0.0.0'}
rs=requests.get('https://www.wuxian.gq/test-ip.php',headers=headers)
print(rs.text)
然而CF并不上当,直接丢出警告:
相对安全。
尝试篡改X-FORWARDED-FOR
同样构造请求头:
import requests
import json
headers={'X-FORWARDED-FOR':'0.0.0.0'}
rs=requests.get('https://www.wuxian.gq/test-ip.php',headers=headers)
print(rs.text)
这一次的情况并不容乐观:
可以看见我们构造的0.0.0.0
成功传入了$_SERVER['HTTP_X_FORWARDED_FOR']
预定义变量,即常规的直接把$_SERVER['HTTP_X_FORWARDED_FOR']
当做真实IP的做法并不可取甚至有SQL注入风险,需要格外注意。
总结
Web编程的原则是不能相信用户提交的数据,一定要在各个环节做好过滤,即使是对于IP地址也决不可放松。
如果CDN有其特有的访客IP储存方式,且相对安全,应当首先利用CDN的特性,避免不必要的麻烦。
版权声明:本文是原创文章,版权归 无限UCW 所有。
本文链接:https://ucw.moe/archives/cloudflare-real-client-ip.html
本站所有原创文章采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可。
您可以自由地转载和修改,但请务必注明文章来源并且不可用于商业目的。