使用nginx作为代理之后,如何配置可以得到用户的真实ip地址?

你的笑靥 发表于: 2020-04-17   最后更新时间: 2020-04-17  

如标题所述

  1. 服务器使用的是ubuntu16.04,nginx版本为1.10.3

  2. 在代码中通过request去尝试获取ip地址,但是获取到的是服务器的ip或者是服务器的网关地址

    String addr = httpServletRequest.getRemoteAddr();    //addr的值获取到之后为服务器本地的地址    192.168.68.128
    String forwarded = httpServletRequest.getHeader("X-Forwarded-For");    //此时这个值获取到之后是服务器的网关地址    192.168.68.1
    //使用自己写的工具类通过获取请求头"X-Forwarded-For"的值获取到的也是服务器的网关地址    192.168.68.1
    
  3. 我在nginx的配置文件default中location配置块中配置信息如下:

    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_set_header  X-Forwarded-Proto $scheme;
    
  1. 我现在想得到是用户在别处通过页面请求服务时可以得到用户自己的ip地址,而不是nginx部署机器的ip地址.我该改进哪里呢?


您需要解锁本帖隐藏内容请: 点击这里
本帖隐藏的内容




上一条: 到头了!
下一条: nginx在搭建完成之后通过内网IP可以访问,但是通过公网ip不能访问时什么原因?

  • nginx配置没问题。

    // 配置此处用于获取客户端的真实IP
    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_set_header X-Forwarded-Proto $scheme;
    proxy_pass http://localhost:8080;
    

    java获取地方你改改,网上比较流行的

    package com.moyutang.common.utils;
    import javax.servlet.http.HttpServletRequest;
    import java.net.InetAddress;
    import java.net.UnknownHostException;
    
    public class IpUtil {
        public static String getIpAddr(HttpServletRequest request) {
            String ipAddress = null;
            try {
                ipAddress = request.getHeader("x-forwarded-for");
                if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                    ipAddress = request.getHeader("Proxy-Client-IP");
                }
                if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                    ipAddress = request.getHeader("WL-Proxy-Client-IP");
                }
                if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                    ipAddress = request.getRemoteAddr();
                    if (ipAddress.equals("127.0.0.1")) {
                        // 根据网卡取本机配置的IP
                        InetAddress inet = null;
                        try {
                            inet = InetAddress.getLocalHost();
                        } catch (UnknownHostException e) {
                            e.printStackTrace();
                        }
                        ipAddress = inet.getHostAddress();
                    }
                }
                // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
                if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length()
                    // = 15
                    if (ipAddress.indexOf(",") > 0) {
                        ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
                    }
                }
            } catch (Exception e) {
                ipAddress="";
            }
            return ipAddress;
        }
    }
    
    • 实不相瞒,这个工具类就是我现在正在使用的工具类,我在代码中使用工具类获取到的ip地址和String forwarded = httpServletRequest.getHeader("X-Forwarded-For"); 这句代码获取到的ip地址是一样的.

        • /opt/nginx/sbin/nginx -t
          

          检测配置文件,得到的结果为:

          nginx: the configuration file /opt/nginx/conf/nginx.conf syntax is ok
          nginx: configuration file /opt/nginx/conf/nginx.conf test is successful
          

          nginx.conf中配置内容为:

                      root   /opt/nginx/html/dist;
                      index  index.html index.htm;
          location /dist/ {
                      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_set_header X-Forwarded-Proto $scheme;
                      proxy_pass http://localhost:8080;
                 }
          

          访问 http://192.168.68.128 可以正常访问.
          代码中打印请求头,部分信息如下:

          referer为:http://192.168.68.128/
          x-forwarded-host为:192.168.68.128:9001
          x-forwarded-for为:192.168.68.1
          host为:192.168.68.128:7008
          

          这样配置应该没啥问题了吧.

            • 得到信息如下:

              nginx version: nginx/1.8.1
              built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.12) 
              built with OpenSSL 1.0.1i 6 Aug 2014
              TLS SNI support enabled
              configure arguments: --prefix=/opt/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_gzip_static_module --with-http_stub_status_module --with-http_realip_module --pid-path=/var/run/nginx.pid --with-pcre=/opt/software/pcre-8.35 --with-zlib=/opt/software/zlib-1.2.11 --with-openssl=/opt/software/openssl-1.0.1i
              
                • 大佬,是不是我配置文件有问题啊?当我在nginx.conf中这么配置的时候

                  server {
                      listen       8080;
                      server_name  localhost; 
                      location / {
                              root   /opt/nginx/html/dist;
                              index  index.html index.htm;
                              proxy_set_header remote-user-ip $remote_addr;
                              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_set_header X-Forwarded-Proto $scheme;
                              proxy_pass http://localhost:8080/;
                  

                  或者是

                  # proxy_pass http://localhost:8080;
                      }
                      error_page   500 502 503 504  /50x.html;
                      location = /50x.html {
                          root   html;
                      }
                  }
                  

                  打开主页 http://192.168.68.128:8080/ 页面报 500 Internal Server Error
                  去看error.log中查看提示打开太多文件

                  2020/04/23 10:22:04 [crit] 3724#0: accept4() failed (24: Too many open files)
                  2020/04/23 10:22:04 [crit] 3724#0: accept4() failed (24: Too many open files)
                  2020/04/23 10:22:05 [crit] 3724#0: accept4() failed (24: Too many open files)
                  2020/04/23 10:22:05 [alert] 3724#0: *12352 socket() failed (24: Too many open files) while connecting to upstream, client: 127.0.0.1, server: localhost, request: "GET / HTTP/1.0", upstream: "http://127.0.0.1:8080/", host: "192.168.68.128:8080"
                  2020/04/23 10:22:05 [crit] 3724#0: *12352 open() "/opt/nginx/html/50x.html" failed (24: Too many open files), client: 127.0.0.1, server: localhost, request: "GET / HTTP/1.0", upstream: "http://127.0.0.1:8080/", host: "192.168.68.128:8080"
                  

                  可是我确定只有我一人在访问.
                  当我把location / {}配置块中的proxy_pass指令去掉之后可以正常访问http://192.168.68.128:8080/.

                  是不是我的配置出了问题

                    • 大佬,我还是想问一下,既然加载了为什么我的请求头中没有xff这个字段呢,我最终的IP获取是从工具类中
                      ipAddress = request.getRemoteAddr();
                      这句代码中获取到的.