精华内容
下载资源
问答
  • Java获取请求客户端的真实IP地址

    万次阅读 多人点赞 2016-08-03 12:26:17
    整理网友的材料,最后有源码,亲测能解决所有java获取IP真实地址的问题 整理的这里: ...但是在通过了Apache,Squid等反向代理软件就不能获取客户端的真实IP地址了。 如果使用了反向代理软件,将 http

    整理网友的材料,最后有源码,亲测能解决所有java获取IP真实地址的问题

    整理的这里:

    1、链接1 

    2、链接2

    JSP里,获取客户端的IP地址的方法是:

    request.getRemoteAddr()

    ,这种方法在大部分情况下都是有效的。但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。

    如果使用了反向代理软件,将

    http://192.168.1.110:2046/

    的URL反向代理为

    http://www.javapeixun.com.cn /

    的URL时,用

    request.getRemoteAddr()

    方法获取的IP地址是:127.0.0.1 或 192.168.1.110,而并不是客户端的真实IP。

    ISAPI过滤器也会对request对象进行再包装,附加一些WLS要用的头信息。实际的iisforward附加头如下:

    [code]WL-Proxy-Client-IP=211.161.1.239  
    Proxy-Client-IP=211.161.1.239  
    X-Forwarded-For=211.161.1.239  
    WL-Proxy-Client-Keysize=   
    WL-Proxy-Client-Secretkeysize=   
    X-WebLogic-Request-ClusterInfo=true  
    X-WebLogic-KeepAliveSecs=30  
    X-WebLogic-Force-JVMID=-327089098  
    WL-Proxy-SSL=false

     


    经过代理以后,由于在客户端和服务之间增加了中间层,因此服务器无法直接拿到客户端的IP,服务器端应用也无法直接通过转发请求的地址返回给客户端。但是在转发请求的HTTP头信息中,增加了X-FORWARDED-FOR信息。用以跟踪原有的客户端IP地址和原来客户端请求的服务器地址。当我们访问

    http://www.javapeixun.com.cn /index.jsp/

    时,其实并不是我们浏览器真正访问到了服务器上的index.jsp文件,而是先由代理服务器去访问

    http://192.168.1.110:2046/index.jsp

    ,代理服务器再将访问到的结果返回给我们的浏览器,因为是代理服务器去访问index.jsp的,所以index.jsp中通过

    request.getRemoteAddr()

    的方法获取的IP实际上是代理服务器的地址,并不是客户端的IP地址。

    于是可得出获得客户端真实IP地址的方法一:

    [code]public String getRemortIP(HttpServletRequest request) { 
      if (request.getHeader("x-forwarded-for") == null) { 
       return request.getRemoteAddr(); 
      } 
      return request.getHeader("x-forwarded-for"); 
     }

     


    可是当我访

    问http://www.5a520.cn /index.jsp/

    时,返回的IP地址始终是unknown,也并不是如上所示的127.0.0.1 或 192.168.1.110了,而我访问

    http://192.168.1.110:2046/index.jsp

    时,则能返回客户端的真实IP地址,写了个方法去验证。原因出在了Squid上。squid.conf 的配制文件 forwarded_for 项默认是为on,如果 forwarded_for 设成了 off  则:

    X-Forwarded-For: unknown


    于是可得出获得客户端真实IP地址的方法二:

    [code]public String getIpAddr(HttpServletRequest request) { 
           String ip = request.getHeader("x-forwarded-for"); 
           if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
               ip = request.getHeader("Proxy-Client-IP"); 
           } 
           if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
               ip = request.getHeader("WL-Proxy-Client-IP"); 
           } 
           if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
               ip = request.getRemoteAddr(); 
           } 
           return ip; 
       }

     


    可是,如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP值,究竟哪个才是真正的用户端的真实IP呢?

    答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。

    如:X-Forwarded-For:192.168.1.110, 192.168.1.120, 192.168.1.130, 192.168.1.100用户真实IP为: 192.168.1.110

    以上方法还不行的话就采用如下方法:

    [code]/** 
         * 获取当前网络ip 
         * @param request 
         * @return 
         */  
        public String getIpAddr(HttpServletRequest request){  
            String 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") || ipAddress.equals("0:0:0:0:0: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(","));  
                    }  
                }  
                return ipAddress;   
        }

    展开全文
  • 服务器获取客户端IP客户端IP变化

    千次阅读 2017-02-24 11:53:56
    1.服务端获取客户端请求IP等信息...request.getRemoteAddr() 获取客户端请求IP地址 request.getRemotePort() 获取客户端请求端口 request.getRemoteHost() 获取客户端请求的合法名称 request.getRemoteUs

    1.服务端获取客户端请求的IP等信息request = javax.servlet.http.HttpServletRequest

    request.getRemoteAddr() 获取客户端请求IP地址

    request.getRemotePort() 获取客户端请求端口

    request.getRemoteHost() 获取客户端请求的合法名称

    request.getRemoteUser()   a String specifying the login of the user making this request, or null if the user login is not known

    request.getUserPrincipal()   a java.security.Principal containing the name of the user making this request; null if the user has not been authenticated
    request.getCharacterEncoding()  获取字符编码


    2.手机每连一次4G,IP及端口都会对应变更一次


    3.具有固定IP的局域网通过路由器可设置对外网的访问路径及端口。路由器上设置对外的端口PORT,再映射到局域网内某台电脑A及该台电脑的某个端口A_port,那么外网访问该固定IP+对外PORT时,即可访问到A的A_port路径上。

    展开全文
  • 服务器获取真实客户端 IP

    千次阅读 2018-12-08 06:59:48
    0x01 先查个问题 测试环境微信支付通道提示网络环境未能通过安全验证,请稍后再试,出现这种情况一般首要 想到可能是双方网络...可能获取真实IP方式错误 getenv('HTTP_CLIENT_IP') getenv('HTTP_X_FORWARDED_FOR')...

    0x01 先查个问题

    测试环境微信支付通道提示网络环境未能通过安全验证,请稍后再试,出现这种情况一般首要
    想到可能是双方网络交互中微信方验参与我们出现不一致,翻了下手册确定是这类问题开始排查环节

    1. 可能获取真实IP方式错误

      1. getenv('HTTP_CLIENT_IP')
      2. getenv('HTTP_X_FORWARDED_FOR')
      3. getenv('REMOTE_ADDR')
      4. filter_var($remote_ip, FILTER_VALIDATE_IP)
      5. 已经依次获取并过滤
      6. 固程序没有任何问题,往上发散
    2. 是否反向代理

      经过反向代理后,由于在客户端和web服务器之间增加了中间层,因此web服务器无法直接拿到客户端的ip,只能通过$remote_addr变量拿到的将是反向代理服务器的ip地址,检查不存在此类问题,再往上,擅长网络通信工程的同学表示绝不认输

    3. 可能NAT分配出口IP,或负载均衡服务分发出现异常

      1. 先拿到我本地内网外网IP 方便之后问题排查

        # 本机IP
        ifconfig | grep -A 1 "en" | grep broadcast | cut -d " " -f 2
        # 外网IP
        curl --silent http://icanhazip.com
      2. 检查与80端口建立连接目标都有谁

         netstat -tn|grep 80|akw '{print $5}'|awk -F '{print $1}' | grep [本地IP]

        这里出现问题,竟然没有我的IP,再以nginx $remote_addr拿到的IP作为参考,这是nginx最后一次握手的IP,$remote_addr = 10.168.0.0/16

        nginx处打印$remote_addr,并在server_name添加当前机器ip,分别以负载均衡IP与本地IP做测试,最终确定问题出现在负载均衡服务器出现异常


    0x02 LNMP栈拿真实IP

    LNMP栈内PHP所有获得到的TCP操作信息都是由前面Nginx通过fastcgi传递给它的,就比如$_SERVER['REMOTE_ADDR']include fastcgi.conf;引进,其等于nginx$remote_addr

    Nginx中的几个变量:

    • $remote_addr

      代表客户端的IP,但它的值不是由客户端提供的,而是服务端根据客户端的ip指定的,icanhazip的原理也是这样, 当你的浏览器访问某个网站时,假设中间没有任何代理,那么网站的web服务器就会把remote_addr设为你在公网暴露的IP,如果你用了某个代理,那么你的浏览器会先访问这个代理,然后再由这个代理转发到网站,这样web服务器就会把remote_addr设为这台代理机器的IP, 除非代理将你的IP附在请求header中一起转交给web服务器。

    • $proxy_add_x_forwarded_for

      $proxy_add_x_forwarded_for变量包含客户端请求头中的"X-Forwarded-For",与$remote_addr两部分,他们之间用逗号分开。X-Forwarded-For(简称XFF),X-Forwarded-For 是一个 HTTP 扩展头部。RFC 2616 协议并没有对它的定义,它最开始是由 Squid 这个缓存代理软件引入,用来表示 HTTP 请求端真实 IP。如今它已经成为事实上的标准,被各大HTTP 代理、负载均衡等转发服务广泛使用,并被写入 RFC 7239(Forwarded HTTP Extension` 标准之中。

    • $proxy_set_header

      已在排查问题中说明,可设置代理后 header

        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;
    • X-Real-IP

      一般比如X-Real-IP这一个自定义头部字段,通常被 HTTP 代理用来表示与它产生TCP 连接的设备 IP,这个设备可能是其他代理,也可能是真正的请求端,这个要看经过代理的层级次数或是是否始终将真实IP一路传下来。(牢记:任何客户端传上来的东西都是不可信的)

    当多层代理或使用CDN时,如果代理服务器不把用户的真实IP传递下去,那么服务器将永远不可能获取到用户的真实IP。

    0x03 用户的真实IP从何而来

    1. 宽带供应商提供独立IP
      比如家里电信宽带上网,电信给分配了公网ip,那么一个请求经过的ip路径如下:

      这种情况下,119.147.19.234 会把得到的116.1.2.3附加到头信息中传给10.168.0.0/32,因此这种情况下,我们取得的用户ip则为:116.1.2.3
      如果119.110.0.0/16没有把116.1.2.3附加到头信息中传给业务服务器,业务服务器就只能取上上一级ip地址
    2. 宽带供应商不能提供独立IP

      宽带提供商没有足够的公网ip,分配的是个内网ip,比如长宽等小的isp。请求路径则可能如下:

      这种情况下得到的用户ip,就是211.162.78.1。 这种情况下,就可能出现一个ip对应有数十上百个用户的情况了

    3. 手机2g上网

      网络提供商没法直接提供ip给单个用户终端,以中国移动cmwap上网为例,因此请求路径可能为:

      这种情况下得到的用户ip,就是202.96.75.1。2008年的时候整个广东联通就三个手机上网的公网ip,因此这种情况下,同一ip出现数十万用户也是正常的。

    4. 有几万或数十万员工的公司
      这种也会出现来自同一ip的超多用户,可能达到几万人,但出口IP可能就那么几个。

    0x04 NAT [Network Address Translation]

    中文意思是网络地址转换,它允许一个整体机构以一个公用IP地址出现在Internet上。

    NATOSI参考模型的网络层 (第3层), 它是一种把内部私有网络地址(IP地址)翻译成合法网络IP地址的技术。NAT可以让那些使用私有地址的内部网络连接到Internet或其它IP网络上。NAT路由器在将内部网络的数据包发送到公用网络时,在IP包的报头把私有地址转换成合法的IP地址。

    RFC1918 规定了三块专有的地址,作为私有的内部组网使用

    • A类:10.0.0.0 — 10.255.255.255 10.0.0.0/8
    • B类:172.16.0.0 — 172.31.255.255 172.16.0.0/12
    • C类:192.168.0.0 — 192.168.255.255 192.168.0.0/16

    这三块私有地址本身是可路由的,只是公网上的路由器不会转发这三块私有地址的流量;当一个公司内部配置了这些私有地址后,内部的计算机在和外网通信时,公司的边界路由会通过NAT或者PAT技术,将内部的私有地址转换成外网IP,外部看到的源地址是公司边界路由转换过的公网IP地址,这在某种意义上也增加了内部网络的安全性

    这个过程是通过NAT中的本地址与全局地址映射条目来实现的,所以事先要在NAT路由器上配置这样的映射条目。


    通过这种方式一个公网 IP 底下可以发私有的 IP 地址。


    0x05 IPV6 来了?

    写这篇文章的时候看到有个推送,表示阿里全面应用IPV6,这件事的意义还挺重大的

    我们知道,一段 IPv4 标准的 IP 地址,一共由 4 X 8 = 32 位二进制数字组成,理论上存在 2^32 个 IP 地址。等于 4,294,967,29642 亿多个 IPv4 的地址。

    参考世界互联网用户统计报告,全球现在大概有4,208,571,287人在上网,也就是说已经快到ipv4地址设计的最大IP数了

    不过不用担心,前面提到的 NAT,让 IPv4 公网 IP 哪怕用完了也能凑合过。

    到了 IPv6 ,相比 IPv4 最大的提升,就是位数大大增加,变成了 8 个 4 位的十六进制数字。也就是说有 2^128IPv6 地址。地球上的每粒沙子都分一个也管够

    存储2^128字节理论上什么概念呢,在当今的量子水平下,假设计算设备能够操作在原子一级,每公斤质量可存储大约10的25次方bits,存储2的128次方的字节大约需要272 trillion = 2720000亿公斤

    最后,周末愉快,北京联通已经支持ipv6了,我在望京测试,可以拿到 ipv6地址

    展开全文
  • nginx做反向负载均衡后端服务器获取真实客户端IPNginx代理站点配置nginx会在把请求转向后台real-server前把http报头中的ip地址进行替换.

    nginx做反向负载均衡后端服务器获取真实客户端IP

    Nginx代理站点配置

    nginx会在把请求转向后台real-server前把http报头中的ip地址进行替换;这样操作完成后,real-server也需要做一些操作;

    upstream serverName {    
        server  127.0.0.1:8080  weight=1;    
        }
    
    server {
        listen       80;
        server_name  www.domain.com w-search.domain.com.cn w-member.domain.com
    展开全文
  • 那为什么 Web 服务器只有通过 X-Forwarded-For 头才能获取真实的 IP?这里用 PHP 语言来说明,不明白原理的开发者为了获取客户 IP,会使用 $_SERVER['REMOTE_ADDR'] 变量,这个服务器变量表示和 ...
  • java服务器获取客户端IP地址

    千次阅读 2015-08-28 09:13:41
    在开发工作中,我们常常需要获取...原因:由于在客户端和服务之间增加了中间代理,因此服务器无法直接拿到客户端IP,服务器端应用也无法直接通过转发请求的地址返回给客户端。 现在图示代理上网和IP的关系:  第一种情况
  • servlet如何获取请求客户端IP地址

    千次阅读 2019-03-01 19:57:20
    基本逻辑:先取得配置的IP列表,然后通过request....但是在通过了Apache,Squid等反向代理软件就不能获取客户端的真实IP地址了。 如果使用了反向代理软件,将http://192.168.1.110:2046/的URL反向代理为http:...
  • 代理http请求获取客户端IP

    万次阅读 2016-07-22 11:10:08
    外界流传的JAVA/PHP服务器获取客户端IP都是这么取的: 伪代码: 1)ip = request.getHeader("X-FORWARDED-FOR ") 2)如果该值为空或数组长度为0或等于"unknown",那么: ip = request.getHeader("Proxy-Client...
  • 请求Requst中获取访问请求客户端IP

    千次阅读 2016-11-03 16:48:53
    请求Requst中获取访问请求客户端IP 在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的。但是在通过了Apache,Squid,nginx等反向代理软件就不能获取到客户端的...
  • 在JSP里,获取客户端IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的。但是在通过了Apache,Squid等反向代理软件就不能获取客户端的真实IP地址了。 如果使用了反向代理软件,将...
  • php获取客户端IP和php获取服务器端IP

    千次阅读 2017-12-17 12:29:22
    1.php获取客户端IP 在PHP获取客户端IP时,常使用 $_SERVER["REMOTE_ADDR"] 。但如果客户端是使用代理服务器来访问,那取到的是代理服务器的 IP 地址,而不是真正的客户端 IP 地址。要想透过代理服务器取得...
  • node.js 服务器获取客户端ip的方法

    千次阅读 2018-06-19 17:37:02
    获取发送AJAX请求客户端ip:server = http.createServer(function(req, res) { var ip = req.headers['x-forwarded-for'] || req.ip || req.connection.remoteAddress || req.socket.remoteAddress || req....
  • 一般在单机版的tomcat获取请求来源的ip,可以使用下面方式这么干。 String remoteAddr = request.getRemoteAddr(); 但是如果了使用反向代理例如niginx,由于对客户请求的代理,此时request.getRemoteAddr()获取要么...
  • 一、.net core 获取客户端IP获取完整URL C#代码 string ip = HttpContext.Connection.RemoteIpAddress.ToString(); string url = Request.GetDisplayUrl(); 说明:上面两行代码我们都知道,但是如果你是...
  • JSP从服务器获取客户端访问IP

    千次阅读 2008-07-16 20:31:00
    在很多应用下都可能有需要将用户的真实IP记录下来,这时就要获得用户的真实IP地址,在JSP里,获取客户端IP地址的方法是: request.getRemoteAddr(),这种方法在大部分情况下都是有效的。但是在通过了Apache,Squid...
  • 获取客户端IP获取公网IP、验证IP是否内网1、获取客户端IP在开发工作中,我们常常需要获取客户端的IP。一般获取客户端的IP地址的方法是:request.getRemoteAddr();但是在通过了Apache,Squid等反向代理软件就不能获取...
  • 创建HTTP服务器 在Node.js中,可以很方便地创建一个...在createServer方法中,可以使用一个可选参数,参数值为一个回调函数,用于指定当接收到客户端请求时所需执行的处理,该回调函数的指定方法如下所示。 functi...
  • 客户端ip:  Request.ServerVariables.Get("Remote_Addr").ToString();  客户端主机名: Request.ServerVariables.Get("Remote_Host").ToString();  客户端浏览器IE: Request.Browser.Browser;  客户端浏览器 ...
  • php获取客户端ip服务器端ip

    千次阅读 2015-10-20 12:10:52
    php获取服务端与客户端ip
  • 获取远程客户端IP地址

    千次阅读 2014-01-27 10:36:13
    /** * * Web 服务器反向代理中用于存放客户端原始 IP 地址的 Http header 名字 * */ private static final String[] PROXY_REMOTE_IP_...* 获取请求客户端IP 地址。若应用服务器前端配有反向代理的 Web 服务器
  • 这几天搞了用java获取ip地址,由于测试方法不对,一直没有成功,昨天终于想通了并不是方法不对,而是我的测试方法不对,下面这个方法,完全可以得到客户端的公网ip地址 但是在测试的时候注意:我用的是weblogic测试...
  • 一、背景:https ELB后端nginx获取不到真实客户端IP 使用aws elb服务器来做websocket负载均衡时,只能使用tcp模式。 https 协议不在也可以选择tcp模式,都有后端获取不到真实客户端IP问题,获取都是elb IP地址 ...
  • java 服务器获取请求IP方法之总结

    千次阅读 2017-04-25 12:49:44
    项目中需要和第三方平台接口,加了来源IP鉴权功能,测试时发现没有问题,但是...其基本逻辑为先取得配置的IP列表,然后通过request.getRemoteAddr()取得客户端IP地址,做鉴权和校验,逻辑没问题,那么肯定是request.
  • 获取客户端真实IP(支持代理服务器)

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 459,112
精华内容 183,644
关键字:

服务器获取请求的客户端ip