Nginx 多级代理下获取客户端真实IP地址
引言
在使用Nginx作为反向代理时,特别是在多级代理的场景下,获取客户端的真实IP地址是一个常见需求。本文将详细介绍如何在Nginx多级代理配置中获取客户端的真实IP,并通过日志记录来验证配置效果。
Nginx日志格式
首先,我们来看一下Nginx中常用的日志格式配置。Nginx允许我们自定义日志格式,以便记录所需的信息。以下是一个示例日志格式配置:
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
1
2
3
其中,main是日志格式的别名,在使用时可以直接引用这个别名。日志格式中包含了客户端IP地址、用户、请求时间、请求行、状态码、发送的字节数、引用页、用户代理以及X-Forwarded-For头信息。
日志文件切割
随着时间的推移,日志文件会越来越大,严重影响服务器效率。因此,需要定时对日志文件进行切割。以下是一个按分钟切割日志文件的示例配置(实际生产中通常按天切割):
access_log /var/log/nginx/access.log main; # 使用main日志格式
1
配合外部的定时任务(如cron),可以实现日志文件的定时切割。
获取客户端真实IP地址
服务器资源分配
为了演示多级代理场景,我们分配了以下服务器资源:
10.1.9.98:充当客户端
10.0.3.137:一级代理
10.0.4.105:二级代理
10.0.4.129:三级代理
10.0.4.120:服务器端(这里使用一个Nginx充当服务器端,正常情况下可能是一个Web服务器如Tomcat)
各级代理配置
以下是各级代理的基本配置示例(仅展示关键部分):
一级代理(10.0.3.137)配置
server {
listen 80;
location / {
proxy_pass http://10.0.4.105; # 转发请求到二级代理
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
}
1
2
3
4
5
6
7
8
9
二级代理(10.0.4.105)配置
与一级代理类似,只是转发目标改为三级代理:
server {
listen 80;
location / {
proxy_pass http://10.0.4.129; # 转发请求到三级代理
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
}
1
2
3
4
5
6
7
8
9
三级代理(10.0.4.129)配置
三级代理直接转发请求到服务器端:
server {
listen 80;
location / {
proxy_pass http://10.0.4.120; # 转发请求到服务器端
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
}
1
2
3
4
5
6
7
8
9
服务器端(10.0.4.120)配置
服务器端记录客户端的真实IP地址:
server {
listen 80;
location / {
# 这里可以是实际的Web应用处理逻辑
access_log /var/log/nginx/access.log main;
}
}
1
2
3
4
5
6
7
8
日志记录结果
在以上配置下,当客户端10.1.9.98发起请求时,各级代理会依次转发请求,并在X-Forwarded-For头信息中追加客户端和各级代理的IP地址。以下是access.log中可能的一条记录:
10.0.4.129 - - [12/Oct/2023:12:00:01 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0" "10.1.9.98, 10.0.3.137, 10.0.4.105"
1
在这条记录中,X-Forwarded-For头信息包含了客户端10.1.9.98、一级代理10.0.3.137和二级代理10.0.4.105的IP地址。
总结与注意事项
X-Forwarded-For:
是一个追加的过程,后面的代理会把前面代理的IP追加到X-Forwarded-For尾部,用逗号分隔。
应用服务器(如10.0.4.120)可能无法直接从X-Forwarded-For中获取到与它直连的代理服务器(如10.0.4.129)的IP,此时可以使用$remote_addr。
至少有一个代理设置了X-Forwarded-For,否则后面的代理或应用服务器无法获得相关信息。
客户端可能伪造请求头,因此X-Forwarded-For中的第一个IP不一定是真实的客户端IP。
X-Real-IP:
是一个变量,后面的设置会覆盖前面的设置。
只需在第一个代理服务器上设置proxy_set_header X-Real-IP $remote_addr,然后在应用端直接引用$http_x_real_ip。
获取客户端真实IP的方法:
如果请求没有经过Nginx代理,可以使用request.getRemoteHost()(在Java中)。
如果请求经过了Nginx代理,且Nginx配置正确,可以从请求头中获取(如request.getHeader("x-real-ip"))。
对于其他反向代理软件(如Apache、Squid),同样是从请求头中获取真实IP,只是属性名可能不同。
通过本文的介绍,我们了解了如何在Nginx多级代理配置中获取客户端的真实IP地址,并通过日志记录来验证配置效果。希望本文对你有所帮助,如果有任何问题或建议,欢迎留言交流!
没有找到相关结果
0 个回复