跳转到内容
搜索文档

恢复原始访客 IP

最后更新 查看 MarkdownAgent 设置

将您的服务器配置为记录原始访客 IP 地址。 当您的网站流量通过 Cloudflare 网络路由时,我们会充当反向代理。这样 Cloudflare 就可以通过更高效地路由数据包和缓存静态资源(图片、JavaScript、CSS 等)来加快页面加载。由此,在响应请求和记录日志时,您的源服务器通常会记录一个 Cloudflare IP 地址

例如,如果您安装了依赖访客原始 IP 地址的应用程序,那么默认会记录 Cloudflare IP。原始访客 IP 会显示在追加的 HTTP 头字段 CF-Connecting-IP 中。按照我们的 Web 服务器说明,您可以在源站服务器上记录原始访客 IP。如果该 HTTP 头在请求到达源站时不可用,请检查您的 Transform RulesManaged Transforms 配置。

下图展示了启用和未启用 Cloudflare 时 IP 地址处理方式的不同。

该图展示了启用和未启用 Cloudflare 时 IP 地址处理方式的不同。

mod_remoteip

Cloudflare 不再更新和支持 mod_cloudflare。但如果您使用的是 Apache Web 服务器,并且系统是 Ubuntu Server 18.04Debian 9 Stretch,仍可使用 mod_remoteip 在源站记录访客的原始 IP。

由于该模块由第三方编写,我们无法为该插件相关问题提供技术支持。

在 Apache Web 服务器上安装 mod_remoteip 的步骤:

  1. 执行以下命令启用 mod_remoteip
sudo a2enmod remoteip
  1. 更新站点配置以包含 RemoteIPHeader CF-Connecting-IP,例如 /etc/apache2/sites-available/000-default.conf
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
ServerName remoteip.andy.support
RemoteIPHeader CF-Connecting-IP
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
  1. 修改 apache.conf 中的 combined 日志格式,将 LogFormat 中的 %h 替换为 %a。示例如下:
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined

更新为:

LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
  1. 创建 /etc/apache2/conf-available/remoteip.conf,写入以下内容并添加 Cloudflare IP 地址
RemoteIPHeader CF-Connecting-IP
RemoteIPTrustedProxy 192.0.2.1(示例 IP)
RemoteIPTrustedProxy 192.0.2.2(示例 IP)
# 为 Cloudflare 在 https://www.cloudflare.com/ips/ 上列出的全部 IP 地址重复添加一行
  1. 启用 Apache 配置:
sudo a2enconf remoteip
Enabling conf remoteip.
要启用新的配置,请运行:
service apache2 reload
  1. 测试 Apache 配置:
sudo apache2ctl configtest
Syntax OK
  1. 重启 Apache:
sudo systemctl restart apache2

mod_cloudflare

安装

安装 mod_cloudflare 有两种方式:从 GitHub 下载 Apache 扩展,或在源站服务器中手动添加代码。

从 GitHub 下载脚本或安装包

如果您使用 Apache Web 服务器,可以从 GitHub 下载 mod_cloudflare。

将代码添加到源站服务器

如果您无法安装 mod_cloudflare,或者所用内容管理系统没有可用的 Cloudflare 插件用于恢复原始访客 IP,可在需要原始访客 IP 的页面 body 标签前后任意位置添加如下代码:

<?php if (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_CF_CONNECTING_IP'];?>

此代码仅使需要的脚本可读取原始 IP,并不会将该 IP 写入您当前的服务器日志。

卸载

Apache

要移除 mod_cloudflare,请注释掉加载 mod_cloudflare 的 Apache 配置行。

不同 Linux 发行版路径会略有不同,但在大多数系统中,可在 /etc/apache2 中找到:

LoadModule cloudflare_module

注释或删除该行后重启 Apache,mod_cloudflare 即会移除。

如果您运行的是 Ubuntu 或 Debian,通常会看到文件:

/etc/apache2/mods-enabled/cloudflare.load

删除该文件可移除 mod_cloudflare,然后重启 Apache。

Nginx

对于 Nginx,不需要 mod_cloudflare。请改用 ngx_http_realip_module NGINX 模块,并按照 Web 服务器说明 中的参数进行配置。


Web 服务器说明

根据您的 Web 服务器类型,参考以下说明在源站服务器记录原始访客 IP:

Apache 2.4

  1. 确保已安装以下组件:
    • Red Hat/Fedora:sudo yum install httpd-devel libtool git
    • Debian/Ubuntu:sudo apt-get install apache2-dev libtool git
  2. 克隆最新版本的 mod_cloudflare 源码:
    • Red Hat/Fedora/Debian/Ubuntu:git clone https://github.com/cloudflare/mod_cloudflare.git; cd mod_cloudflare
  3. 使用 Apache 扩展工具将 .c 文件编译为模块:
    • Red Hat/Fedora/Debian/Ubuntu:apxs -a -i -c mod_cloudflare.c
  4. 重启并验证模块是否已启用:
    • Red Hat/Fedora:service httpd restart; httpd -M|grep cloudflare
    • Debian/Ubuntu:sudo apachectl restart; apache2ctl -M|grep cloudflare
  5. 如果源站后面有负载均衡器,请在 Apache 配置中(通常是 httpd.conf)添加以下内容,并将 123.123.123.123 替换为您的负载均衡器 IP:
<IfModule cloudflare_module>
CloudFlareRemoteIPHeader X-Forwarded-For
CloudFlareRemoteIPTrustedProxy [请替换为负载均衡器的 IP 地址]
DenyAllButCloudFlare
</IfModule>

Nginx

使用 ngx_http_realip_module Nginx 模块,并按如下参数配置:

# 示例 IP 地址
set_real_ip_from 192.0.2.1; 

# 使用以下任一配置

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

上述前缀列表需要定期更新,完整列表见 Cloudflare IP 地址

另请参考:Cloudflare 与 NGINX

EasyApache 和 cPanel

  1. 执行以下脚本,在 EasyApache 中安装 mod_cloudflare: bash <(curl -s https://raw.githubusercontent.com/cloudflare/mod_cloudflare/master/EasyApache/installer.sh)
  2. 安装完成后,您需要使用新的 mod_cloudflare 插件重新编译 Apache。
  3. 打开 Apache 配置文件。通常位于 /etc/apache2/apache2.conf/etc/httpd/httpd.conf/usr/local/apache/conf/httpd.conf 或其他位置。若不确定,请向托管服务商咨询。
  4. 在文件末尾添加:CloudflareRemoteIPTrustedProxy {LOOPBACK_ADDRESS}。例如服务器地址为 127.0.0.1 时,写为:CloudflareRemoteIPTrustedProxy 127.0.0.1
  5. 若要在受信任代理列表中添加多个服务器,可继续追加:CloudflareRemoteIPTrustedProxy 127.0.0.1 127.0.0.2

Lighttpd

LiteSpeed 服务器

  1. 打开 LiteSpeed Web 管理控制台。
  2. 在配置中启用 “在头部使用客户端 IP(Use Client IP in Header)”
  3. 启用后,访问日志将显示正确的 IP 地址;同时 PHP 的 $_SERVER['REMOTE_ADDR'] 变量也将包含客户端真实 IP,而不再是 Cloudflare IP。对于启用 Cloudflare 的 PHP 网站(如 WordPress 或 vBulletin)而言,这可解决大多数相关问题。

Microsoft IIS

IIS 7 - 8:

参考 Microsoft 社区文章

IIS 8.5 - 10:

从 IIS 8.5 起,支持内置自定义日志。请参阅 IIS 增强日志

  1. 在 IIS 管理器中,双击站点的 Logging(日志)(位于站点的 Actions(操作) 菜单)。
  2. 打开后选择 W3C 作为日志格式,再在 Log File(日志文件) 子页中格式下拉框旁点击 Select Fields(选择字段)
  3. 点击 Add Field(添加字段),添加 CF-Connecting-IP 头。
  4. 点击 OK(确定)。在 Custom Fields(自定义字段) 下应可见新增字段。返回 Logging(日志) 窗口后点击 Apply(应用)
  5. 如果成功,日志文件应出现新的字段(自定义字段部分)。
  6. 重启站点,再重启 W3SVC,必要时重启实例;若仍未更新,刷新配置。
  7. 使用 IIS 8.5+ 的增强日志时,默认情况下不会在应用层恢复原始访客 IP。

Tomcat 7

要让 Tomcat7 自动在访问日志和应用中恢复原始访客 IP,请在日志模式中添加 %{CF-Connecting-IP}i

例如,您可在 server.xml 中添加以下配置:

<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="%{CF-Connecting-IP}i - %h %u %t - &amp;quot;%r&amp;quot; - %s - %b - %{CF-RAY}i"/>

日志示例如下:

Visitor IP - Cloudflare IP - [04/Dec/2014:23:18:15 -0500] - "GET / HTTP/1.1" - 200 - 1895 - 193d704b85200296-SJC

Magento

请参阅第三方教程:使用 Magento 和 Cloudflare 恢复原始访客 IP

同样,Cloudflare 未编写该 Magento 插件,但部分客户反馈该插件有帮助。

由于该插件由第三方编写,我们无法为该插件相关问题提供技术支持。

IPB(Invision Power Board)

通过 Cloudflare 运行 Invision Power Board 3 时,按以下步骤开启正确的 IP 匹配:

登录您的 IPB 后台(ACP):

  1. 点击 System(系统)
  2. Overview(总览) 下点击 Security(安全)
  3. Security Center(安全中心) 下点击 Security Settings(安全设置)
  4. 勾选 Trust IP addresses provided by proxies?(由代理提供的 IP 地址是否可信) 为绿色。

IPB4:关于 Trust IP addresses provided by proxies?(由代理提供的 IP 地址是否可信)

如果您的网络环境通过代理处理请求(如公司/校园网内网或负载均衡集群),可能需要启用该设置以确保使用正确的 IP 地址。但是启用后,恶意用户可能利用该配置提交虚假 IP 地址。在大多数环境下,建议保持此项关闭。

PHPBB

如果您使用 Apache 服务器,我们建议安装 mod_remoteip 来恢复日志中的访客 IP。

如果您无权在服务器上安装模块,可尝试修改核心

MyBB 论坛

MyBB 的较新版本已包含 “Scrutinize User's IP address” 选项。

Admin CP > Configuration > Server and Optimization Options > Scrutinize User's IP address? > Yes

或者安装适用于 MyBB 1.6 的 Cloudflare management plugin

MyBB 1.6.0、1.6.1、1.6.2 或 1.6.3

  1. 打开 ./inc/functions.php
  2. 转到第 2790 行。
  3. if(isset($_SERVER['REMOTE_ADDR'])) 替换为 if(isset($_SERVER['HTTP_CF_CONNECTING_IP']))
  4. 再将 $ip = $_SERVER['REMOTE_ADDR']; 替换为 $ip = $_SERVER['HTTP_CF_CONNECTING_IP'];

Vanilla 论坛

Vanilla 团队成员编写了一个 Cloudflare 插件,用于在自托管站点的日志文件中恢复原始访客 IP。

由于该插件由第三方编写,我们无法为其相关问题提供技术支持。

MediaWiki

  1. 打开 includes/GlobalFunctions.php。大约在第 370 行,将 $forward = "\t(proxied via {$_SERVER['REMOTE_ADDR']}{$forward})" 改为 $forward = "\t(proxied via {$_SERVER['HTTP_CF_CONNECTING_IP']}{$forward})"
  2. 打开 includes/ProxyTools.php。大约在第 79 行,找到 if ( isset( $_SERVER['REMOTE_ADDR'] ) ){ 并替换为 if ( isset( $_SERVER['HTTP_CF_CONNECTING_IP'] ) ){ 第二步仅适用于 MediaWiki 1.18.0 及以下版本。更高版本已重写了 ProxyTools.php,该代码已不存在。
  3. 在约第 80 行查找 $ipchain = array( IP::canonicalize($_SERVER['REMOTE_ADDR']) ); 更改后保存并上传到源站服务器。

适用于 1.27.1 附近版本

  1. 打开 GlobalFunctions.php 的第 1232 行,将 REMOTE_ADDR 改为 HTTP_CF_CONNECTING_IP
  2. 然后打开 WebRequest.php,在第 1151 到 1159 行之间,将 REMOTE_ADDR 改为 HTTP_CF_CONNECTING_IP

XenForo

一位 XenForo 用户创建了一个 Cloudflare 插件

由于该插件由第三方编写,我们无法为其相关问题提供技术支持。

  1. 打开 library/config.php
  2. 在文件末尾添加: if (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) { $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_CF_CONNECTING_IP'];}
  3. 上传并覆盖文件。

PunBB

一位第三方开发者为 Cloudflare 与 PunBB 创建了一个 模块,可恢复原始访客 IP。

由于该模块由第三方编写,我们无法为其相关问题提供技术支持。

Cherokee 服务器

  1. 在服务器上启动 cherokee-admin
  2. 在浏览器中打开 Cherokee Administration interface(Cherokee 管理界面)
  3. 选择由 Cloudflare 代理的域名对应的 Virtual Server
  4. 在所选 Virtual Server(虚拟服务器)Logging(日志) 选项卡中,启用 Accept Forwarded IPs(接受转发的 IP)
  5. Accept from Hosts 框中填入 Cloudflare IP 地址

Livezilla

在 Livezilla 服务器配置中将 PHP IP Server Param 字段改为 HTTP_CF_CONNECTING_IP,即可修正 IP 地址。

Datalife Engine

恢复 Datalife Engine 中的访客 IP:

  1. 打开:/engine/inc/include/functions.inc.php,查找:$db_ip_split = explode( ".", $_SERVER['REMOTE_ADDR'] );,改为:$db_ip_split = explode(".", $_SERVER['HTTP_CF_CONNECTING_IP'] );
  2. 查找:$ip_split = explode( ".", $_SERVER['REMOTE_ADDR'] );,改为:$ip_split = explode(".", $_SERVER['HTTP_CF_CONNECTING_IP'] );
  3. 打开:/engine/modules/addcomments.php,查找:$_SERVER['REMOTE_ADDR'],,改为:$_SERVER['HTTP_CF_CONNECTING_IP'],
  4. 查找:$db_ip_split = explode( ".", $_SERVER['REMOTE_ADDR'] );,改为:$db_ip_split = explode( ".", $_SERVER['HTTP_CF_CONNECTING_IP'] );

TYPO3

一位第三方开发者创建了 TYPO3 的 Cloudflare 插件,可将原始访客 IP 恢复到日志中。该扩展还可清理 Cloudflare 缓存。

由于该插件由第三方编写,我们无法为其相关问题提供技术支持。

VestaCP

如果您使用 VestaCP 控制面板,服务器上通常同时运行 Nginx 与 Apache。请求通常先经过 Nginx 再到 Apache。

由于 Nginx 代理的存在,您需要按 Nginx 指南配置返回真实访客 IP。mod_remoteip 仅在关闭某些 Nginx 请求路径时才需要;若继续启用 Nginx,Apache 的 mod_remoteip 不会与 Nginx 配置冲突。

node.js

一位第三方开发者创建了用于恢复访客 IP 的模块:node_cloudflare

HAProxy

为从 X_FORWARDED_FOR 头提取原始客户端 IP,请按以下方式配置 HAProxy:

  1. 创建文本文件 CF_ips.lst,内容为 https://www.cloudflare.com/en-gb/ips/ 中的所有 IP 段。
  2. 在 HAProxy 中禁用 option forwardfor

HAProxy 配置:

acl from_cf src -f /path/to/CF_ips.lst
acl cf_ip_hdr req.hdr(CF-Connecting-IP) -m found
http-request set-header X-Forwarded-For %[req.hdr(CF-Connecting-IP)] if from_cf cf_ip_hdr

Envoy Gateway

要从 Envoy Gateway 提取原始客户端 IP,请将 Client Traffic Policy 配置为使用自定义 CF-Connecting-IP header

Truncated Client Traffic Policy exampletxt
clientIPDetection:
    customHeader:
        name: CF-Connecting-IP
        failClosed: true

更多详情请参考:Custom header original IP detection extension

Caddy

如果您的应用部署在 Caddy 后面且依赖 X-Forwarded-For 头,您可将其配置为使用 Cloudflare 的 CF-Connecting-IP header

我们建议同时只允许来自 Cloudflare IP 地址 的流量,否则该头可能被伪造。因此,第二个示例将该限制放入 Caddy 配置中。或者,您也可在防火墙层面处理,通常更容易自动化。如果您已有防火墙或其他措施限制来源,Caddyfile 可参考如下:

Caddyfiletxt
https://example.com {
    reverse_proxy localhost:8080 {
        # 将 X-Forwarded-For 设置为 Cloudflare 提供的 CF-Connecting-IP 值。
        header_up X-Forwarded-For {http.request.header.CF-Connecting-IP}
    }
}

如果您希望 Caddy 仅处理来自 Cloudflare IP 地址 的流量,可使用以下配置:

Caddyfiletxt
https://example.com {
    # Restrict access to Cloudflare IPs (https://www.cloudflare.com/ips/)
    @cloudflare {
        remote_ip 173.245.48.0/20 103.21.244.0/22 103.22.200.0/22 103.31.4.0/22 141.101.64.0/18 108.162.192.0/18 190.93.240.0/20 188.114.96.0/20 197.234.240.0/22 198.41.128.0/17 162.158.0.0/15 104.16.0.0/13 104.24.0.0/14 172.64.0.0/13 131.0.72.0/22 2400:cb00::/32 2606:4700::/32 2803:f800::/32 2405:b500::/32 2405:8100::/32 2a06:98c0::/29 2c0f:f248::/32
    }

    # Process requests from Cloudflare IPs
    handle @cloudflare {
        reverse_proxy localhost:8080 {
            # 将 X-Forwarded-For 设置为 Cloudflare 提供的 CF-Connecting-IP 值。
            header_up X-Forwarded-For {http.request.header.CF-Connecting-IP}
        }
    }

    # Deny requests from non-Cloudflare IPs
    handle {
        respond "Access Denied" 403
    }
}

相关资源

这篇文档对您有帮助吗?