Nginx多级反向代理,获取真实IP的2种姿势

背景

我们在实际开发过程中,经常会使用Nginx做反向代理,有时候甚至使用多级Nginx做反向代理,如果我们使用多级Nginx如何获取真实IP呢?下面我将通过两种姿势来解决

环境

  1. 服务器2台:安装Nginx和web服务
  2. 一个服务:springboot启动web服务
  3. 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;
        }
复制代码

原理分析

image

只有客户端直接请求到第一个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

总结

你学会了么?

Guess you like

Origin juejin.im/post/7067104289520353310