方案:
1.客户端经过的所有代理都必须添加X-Forward-For头字段 ( 其中某一个环节没有,那么就无法提取到真是的IP地址)
2.Nginx RealIP模块来实现地址透传
1.根据X-Forward-For头字段 实现
- 环境准备
10.0.0.1 --> client ip.oldxu.com #用户
10.0.0.5 --> proxy-1 #一级代理
10.0.0.7 --> proxy-2 #二级代理
10.0.0.8 --> web #web服务
- proxy-1
[root@lb01 ~]# cat /etc/nginx/conf.d/proxy_ip.wyk.com.conf
server {
listen 80;
server_name ip.wyk.com;
location / {
proxy_pass http://10.0.0.7;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
- proxy-2
[root@web01 ~]# cat /etc/nginx/conf.d/proxy_ip.wyk.com.conf
server {
listen 80;
server_name ip.wyk.com;
location / {
proxy_pass http://10.0.0.8;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
- web
[root@web02 ~]# cat /etc/nginx/conf.d/ip.wyk.com.conf
server {
listen 80;
server_name ip.wyk.com;
root /php;
location / {
index index.php;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
web站点内容
[root@web02 ~]# mkdir /php
[root@web02 ~]# cat /php/index.php
<?php
$ip = getenv("HTTP_X_FORWARDED_FOR");
echo "获取X_FORWARDED_FOR的真实IP地址是: $ip";
?>
- 查看日志返回ip
通过最后日志发现:
10.0.0.7 - - [28/Apr/2020:15:06:09 +0800] "GET / HTTP/1.0" 200 "10.0.0.1, 10.0.0.5"
10.0.0.7 是web服务器上一层代理服务器
X-FORWARDED 第一个地址是真实IP,后面的全部都是经过的代理服务器地址
10.0.0.1 是真实的客户端地址,他后面的都是代理的地址
X-Forwarded-For提取真实IP的方式:
优点:一定能提取到真是的IP地址
缺点:必须所有经过的代理服务器都开启X-FORWARDED-FOR变量携带IP至后端
2.Nginx_RealIP模块实现:
- 环境准备
10.0.0.1 --> client ip.oldxu.com
10.0.0.5 --> proxy-1
10.0.0.7 --> proxy-2
10.0.0.8 --> web #只用修改他就可以了
[root@web02 ~]# cat /etc/nginx/conf.d/ip.wyk.com.conf
server {
listen 80;
server_name ip.wyk.com;
root /php;
#web前端所有的代理服务器地址,一个都不能少
set_real_ip_from 10.0.0.5;
set_real_ip_from 10.0.0.7;
real_ip_header X-Forwarded-For; #丛那个header头检索出需要的IP地址 ( 10.0.0.1, 10.0.0.5, 10.0.0.7)
real_ip_recursive on; #递归排除 set_real_ip_form里面出现的IP地址,剩下没有出现的IP则被认为是真实IP地址
# ( 10.0.0.1 ==$remote_addr )
location / {
index index.php;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
realip:直接使用就能提取到真实IP(日志的第一段就是真实ip),但缺陷是他需要知道沿途经过的所有IP地址 或 地址段