blog / gadflysu

希望與熱烈的風
Talk is Cheap

当网站使用诸如 Cloudflare 的反代时,服务器默认只会得到来自反代服务地址的访客请求。此时需要做点什么来获取真实访客 IP。

ℹ️ [Note] 我使用 nginx 和 Cloudflare。本文适用于 Ubuntu 18.04 和 nginx (1.14.0)。

Cloudflare 将真实访客 IP 包含在 CF-Connecting-IPX-Forwarded-For 两个 HTTP 请求头中。

  • CF-Connecting-IP 提供真实 IP。
  • CF-Connecting-IP 提供代理地址和真实 IP:如果 Cloudflare 接收到的请求不含 X-Forwarded-For 头,X-Forwarded-For 会和 CF-Connecting-IP 有相同的值,否则 Cloudflare 会将代理地址追加到该请求头。

Cloudflare 建议使用 CF-Connecting-IP

对于 nginx,需要使用 ngx_http_realip_module 模块,该模块用于根据指定的 header 域修改客户端地址和端口(可选)。Ubuntu 上使用 apt 安装的 nginx 已包含该模块。

语法:

1
2
set_real_ip_from address | CIDR | unix:;
real_ip_header field | X-Real-IP | X-Forwarded-For | proxy_protocol;

上下文:httpserverlocation

具体配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# get ip list from https://www.cloudflare.com/ips-v4
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 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/12;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 131.0.72.0/22;
# get ip list from https://www.cloudflare.com/ips-v6
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
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;

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

其中 set_real_ip_from 定义告知正确替换地址(即真实访客 IP)的可信任地址,这里是 Cloudflare 的 IP(可能更新);real_ip_header 定义用于获取客户端地址的 hearder 域。

我将上述配置添加到 /etc/nginx/nginx.confhttp 块中,保存后按照惯例执行 sudo nginx -t && sudo nginx -s reload 即可。

📖 [Ref]

  1. Restoring original visitor IPs: Logging visitor IP addresses with mod_cloudflare – Cloudflare Support
  2. How does Cloudflare handle HTTP Request headers? – Cloudflare Support

Author : gadflysu
本文采用「知识共享署名 - 非商业性使用 - 相同方式共享 4.0 国际许可协议 (CC BY-NC-SA 4.0)」进行许可。你可自由分享演绎,惟须遵照:署名非商业性使用相同方式共享不得增加额外限制
Link to this article : https://blog.gadflysu.com/web/restoring-original-visitor-ips-using-nginx/

This article was last updated on days ago, and the information described in the article may have changed.