网站配置了Cloudflare代理后,如何配置Nginx获取的真实客户端IP地址?

网站配置了Cloudflare代理后,如何配置Nginx获取的真实客户端IP地址?

这是一个很简单的问题,如何在后台获取真实的访问者IP地址? 网站为了避免有些不怀好意的访问者,不得不自动分析一下客户端访问信息,比如同一个IP一秒钟访问了一千次,正常人哪有这么快的手速,直接认定为程序所为(恶意攻击、爬虫等),今天分享下如何在日志中记录访问者的真实IP地址,以及如何配置一些简单的防止访问频率过高的限制。

第一步:获取代理IP段信息

Cloudflare提供了其所有代理主机的IP段(ipv4/ipv6),我们需要提前获取这些IP段来识别哪些访问是通过Cloudflare发送到服务器的。

Cloudflare提供的获取方式如下:

  • IPv4地址段: https://www.cloudflare.com/ips-v4
  • IPv6地址段: https://www.cloudflare.com/ips-v6

比如,我们使用如下命令获取ipv4段信息:

$ curl https://www.cloudflare.com/ips-v4
173.245.48.0/20
103.21.244.0/22
....
131.0.72.0/22

如果需要IPv6地址段,方法同理的。

第二步:生成nginx配置信息

nginx配置文件支持模块化导入,因此我们只需要单独将 Cloudflare配置内容生成一个配置文件即可,不需要额外修改nginx的其他配置文件。

Nginx对应的配置格式如下:

$ cat /etc/nginx/conf.d/cloudflare.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 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 X-Forwarded-For;

因此,我们按照上面格式生成对应配置即可, 最后获取真实IP地址的是最后一行real_ip_header,可以有如下两种方法:

# real_ip_header CF-Connecting-IP;
real_ip_header X-Forwarded-For;

其中的client1就是真实的访问者IP地址,而proxy1和proxy2都是中间经过的代理转发节点,这里有个匿名代理的知识点,简单说一下:

普通代理: 不匿名,可以通过X-Forwarded-For字段获取真实IP地址
高匿名代理: X-Forwarded-For 只包含代理服务器地址,没有客户端地址,这样就无法得知真实的访问者IP地址了。

第三步:脚本自动化生成配置

接下来,我们编写脚本,自动化这个配置文件生成的过程,因为Cloudflare的IP段是定期更新的,我们也要定期更新这个配置。

#!/usr/bin/env bash
# 功能: 生成 cloudflare 代理IP列表,用户配置nginx获取客户端真实IP地址

cf_ipv4="https://www.cloudflare.com/ips-v4"
cf_ipv6="https://www.cloudflare.com/ips-v6"
mod_cffile="/etc/nginx/conf.d/cloudflare.conf"

get_cfipinfo() {
    # 生成nginx配置记录格式: set_real_ip_from 103.21.244.0/22;
    curl $cf_ipv4 2>/dev/null | grep -v '#' | grep -v '^$' | sed 's/^/set_real_ip_from /g;s/$/;/g'
    curl $cf_ipv6 2>/dev/null | grep -v '#' | grep -v '^$' | sed 's/^/set_real_ip_from /g;s/$/;/g'
    
    echo
    # echo "real_ip_header CF-Connecting-IP;"
    echo "real_ip_header X-Forwarded-For;"
    echo
}

get_cfipinfo  | tee $mod_cffile

关于Zeno Chen

本人涉及的领域较多,杂而不精 程序设计语言: Perl, Java, PHP, Python; 数据库系统: MySQL,Oracle; 偶尔做做电路板的开发,主攻STM32单片机
此条目发表在Linux分类目录。将固定链接加入收藏夹。