在使用Cloudflare的情况下,如何在后端Nginx中获取到真实的客户端IP地址呢?
Cloudflare作为代理服务,它的作用是让用户的请求通过Cloudflare的网络进行转发,
从而加速网站访问并提供一些安全防护措施,不会暴露后端真实服务器地址。
但这也导致了,后端的Nginx服务器看到的请求IP是Cloudflare的IP地址。
Cloudflare会把真实的客户端IP地址通过HTTP头部 CF-Connecting-IP 传递给后端真实服务,只需要在Nginx中提取该头部信息。
修改Nginx配置,获取Cloudflare转发的真实IP
在 /etc/nginx/conf.d/cloudflare.conf
文件中(记得在 nginx.conf 中引入该配置文件),加入以下内容:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
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/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 131.0.72.0/22;
real_ip_header CF-Connecting-IP;
|
配置解释:
set_real_ip_from
:Cloudflare的IP,可以从Cloudflare官方文档找到最新的IP地址列表。
获取Cloudflare的IPv4地址列表:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
$ curl https://www.cloudflare.com/ips-v4
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
|
real_ip_header
:告诉Nginx,从哪个HTTP头部中获取真实IP地址。Cloudflare提供的是 CF-Connecting-IP 这个头部。
配置完成后,重启Nginx服务即可。
如果是ipv6,则需要修改 /etc/nginx/conf.d/cloudflare.conf
文件,加入以下内容:
1
2
3
4
5
6
7
8
|
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;
real_ip_header CF-Connecting-IPv6;
|
获取Cloudflare的IPv4地址列表:
1
2
3
4
5
6
7
8
|
$ curl https://www.cloudflare.com/ips-v6
2400:cb00::/32
2606:4700::/32
2803:f800::/32
2405:b500::/32
2405:8100::/32
2a06:98c0::/29
2c0f:f248::/32
|
Cloudflare提供的是 CF-Connecting-IPv6 这个头部。
当然也可以使用 X-Forwarded-For 头部。X-Forwarded-For 头部可以设置多个值,多个值之间用逗号隔开。
X-Forwarded-For 头部格式:X-Forwarded-For: client, proxy1, proxy2
client 为用户实际访问的 IP 地址。proxy1, proxy2 为访问经过的代理服务的 IP 地址。
有了nginx配置后,只需要用脚本定时获取IP地址,更新nginx配置文件即可。
脚本参考 网站配置了Cloudflare代理后,如何配置Nginx获取的真实客户端IP地址?
gin框架中获取用户真实IP
根据nginx的配置,则可以在后端真实业务服务中获取用户真实 IP 地址。
比如在gin框架中,可以通过 c.Request.Header.Get("X-Forwarded-For")
或 c.ClientIP()
获取用户真实 IP 地址。
并且在gin框架中,已经提供了 TrustedPlatform
配置项,可以设置默认代理平台,设置后,c.ClientIP()
会自动获取对应平台的用户真实 IP 地址。
1
2
3
4
5
6
7
8
9
10
11
|
// Trusted platforms
const (
// PlatformGoogleAppEngine when running on Google App Engine. Trust X-Appengine-Remote-Addr
// for determining the client's IP
PlatformGoogleAppEngine = "X-Appengine-Remote-Addr"
// PlatformCloudflare when using Cloudflare's CDN. Trust CF-Connecting-IP for determining
// the client's IP
PlatformCloudflare = "CF-Connecting-IP"
// PlatformFlyIO when running on Fly.io. Trust Fly-Client-IP for determining the client's IP
PlatformFlyIO = "Fly-Client-IP"
)
|
在启动gin engine 的时候,设置IP地址获取方式即可,比如设置为 PlatformCloudflare。
1
2
3
4
5
6
|
var opt gin.OptionFunc = func(engine *gin.Engine) {
engine.TrustedPlatform = gin.PlatformCloudflare
}
// Creates a gin router with default middleware:
// logger and recovery (crash-free) middleware
r := gin.Default(opt)
|
配置Nginx安全访问
在获取到真实的IP地址后,也可以进行一些安全配置了。比如禁止IP访问,禁止爬虫访问,禁止非法访问等等。
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
http {
## 使用map动态匹配IP地址
map $http_cf_connecting_ip $blocked_ip {
default 0;
127.0.0.1 1;
}
server {
listen 80;
server_name example.com;
if ($blocked_ip) {
return 403;
}
## 禁止IP访问
deny 192.168.1.1;
## 禁止IP段访问
deny 192.168.1.0/24;
## 禁止爬虫访问
deny ~* (?i)crawler|spider|bot;
## 禁止非法访问
deny ~* (?i)php|cgi|pl|py|jsp|asp|js|css|ico|jpg|png|gif|swf|exe|mp3|mp4|rar|zip|tar|gz|7z|doc|docx|xls|xlsx|ppt|pptx|pdf|txt|xml|json|md|sql|log|htaccess|htpasswd|ftp|sftp|ssh|telnet|ftps|ssh|mysql|mariadb
## 禁止访问文件
deny ~* (?i)file.php|file.html|file.txt|file.doc|file.docx|file.xls|file.xlsx|file.ppt|file.pptx|file.pdf|file.zip|file.rar|file.7z|file.exe|file.mp3|file.mp4|file.avi|file.flv|file.wmv|file.jpg|file.png|file.gif|file.swf|file.ico|file.css|
## 禁止访问目录
deny ~* (?i)admin|config|logs|tmp|cache|backup|upload|download|files|media|static|public|node_modules|vendor|.git|.svn|.hg|.idea|.env|.env.example|.gitignore|.gitmodules|.gitattributes|.editorconfig|.travis.yml|.phpunit.xml|.env.testing|.env.local|.env.local.php|.env.testing.php|.env.php|.env
## 允许IP访问
allow 192.168.1.1;
location / {
## 引入特定的IP黑名单文件
include /etc/nginx/blocked_ips.conf;
## 允许其他所有 IP 访问
allow all;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:8080;
}
}
}
|
黑名单配置文件blocked_ips.conf
示例:
1
2
|
deny 192.168.1.1;
deny 192.168.1.0/24;
|
参考