背景
我们在实际开发过程中,经常会使用Nginx做反向代理,有时候甚至使用多级Nginx做反向代理,如果我们使用多级Nginx如何获取真实IP呢?下面我将通过两种姿势来解决
环境
- 服务器2台:安装Nginx和web服务
- 一个服务:springboot启动web服务
- pc->14.23(nginx)->14.22(nginx)->14.22(web服务)
姿势一
14.23的nginx的配置文件
重要参数:proxy_set_header X-Forwarded-For $remote_addr; 第一层nginx获取客户端的IP
server {
listen 7050;
location /{
proxy_pass http://xx.xx.14.22:8081/TestServer;
proxy_set_header X-Real-PORT $remote_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
}
复制代码
14.22的nginx的配置文件
重要参数:proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
第二层nginx,在真是IP上+上一层nginx所在服务器的地址。
此刻X-Forwarded-For的值为: “真实IP,第一层Nginx的Ip”
server {
listen 8081;
listen [::]:8081 ipv6only=on;
location / {
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://xx.xx.14.22:8080;
}
}
复制代码
TestServer
@Autowired
HttpServletRequest request;
@GetMapping("/test")
public String test(){
//获取多个ip,用逗号隔开
String ips = request.getHeader("X-Forwarded-For");
//真正的ip为ips的第一个
String ip = ips.split(",")[0];
return ip;
}
复制代码
原理分析
只有客户端直接请求到第一个nginx能够拿到客户端的真实IP, 所以第一级nginx配置了 proxy_set_header X-Real-IP $remote_addr; 这个配置就会将客户端IP放到http的header里,这样到最后的应用里可以通过request.getHeader去拿到客户端真实IP了
姿势一的优点和缺点
- 优点:可以获取多级Nginx的ip
- 缺点:需要获取第一个ip为真实Ip
姿势二
14.23的nginx的配置文件
重要参数:proxy_set_header X-CustomnReal-IP $remote_addr; 第一层nginx获取客户端的IP,自定义X-CustomnReal-IP
server {
listen 7050;
location /{
proxy_pass http://xx.xx.14.22:8081/TestServer;
proxy_set_header X-CustomnReal-IP $remote_addr;
}
复制代码
14.22的nginx的配置文件
server {
listen 8081;
listen [::]:8081 ipv6only=on;
location / {
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_pass http://xx.xx.14.22:8080;
}
}
复制代码
TestServer
@GetMapping("/test2")
public String test2(){
//真正的ip
String ip = request.getHeader("X-CustomnReal-IP");
return ip;
}
复制代码
姿势一的优点和缺点
- 优点:直接获取真实IP
- 缺点:无法获取多级IP
总结
你学会了么?