跳转到内容
搜索文档

恢复原始访客 IP

最后更新 查看 MarkdownAgent 设置

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

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

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

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

mod_remoteip

Cloudflare 不再更新和支持 mod_cloudflare。但如果您使用的是 Apache Web 服务器,并且系统是 Ubuntu Server 18.04 或 Debian 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
    }
}

相关资源

这篇文档对您有帮助吗?