如何取得wap和web用户的真实IP

2017-03-02  本文已影响0人  helphi

1 HTTP_X_FORWARDED_FOR, REMOTE_ADDR,HTTP_CLIENT_IP和HTTP_VIA的区别总结
在移动互联网中,如何才能取得用户真正的IP呢,其实我们在header中可以得到的四个参数分别为REMOTE_ADDR ,HTTP_VIA ,HTTP_X_FORWARDED_FOR ,HTTP_CLIENT_IP,这四个参数意义如下:

REMOTE_ADDR - 是你的客户端跟你的服务器“握手”时候的IP(访问客户端的 IP 地址)。如果使用了“匿名代理”,REMOTE_ADDR将显示代理服务器的IP,REMOTE_ADDR –访问客户端的 IP 地址,有可能是用户的IP,也有可能是代理的IP。

HTTP_CLIENT_IP - 是代理服务器发送的HTTP头,代理端的IP,可能存在,可伪造。如果是“超级匿名代理”,则返回none值。同样,REMOTE_ADDR也会被替换为这个代理服务器的IP。

HTTP_X_FORWARDED_FOR -简称XFF头,它代表客户端,也就是HTTP的请求端真实的IP,只有在通过了HTTP 代理(比如APACHE代理)或者负载均衡服务器时才会添加该项。它不是RFC中定义的标准请求头信息,在squid缓存代理服务器开发文档中可以找到该项的详细介绍。如果有该条信息, 说明您使用了代理服务器,地址就是后面的数值。可以伪造。标准格式如下:X-Forwarded-For: client1, proxy1, proxy2

HTTP_VIA - 如果有该条信息, 就证明您使用了代理服务器,代理服务器的地址就是后面的数值。

1)没有使用代理服务器的情况:

  REMOTE_ADDR = 您的 IP

  HTTP_VIA = 没数值或不显示

  HTTP_CLIENT_IP = 没数值或不显示

  HTTP_X_FORWARDED_FOR = 没数值或不显示

2)使用透明代理服务器的情况:TransparentProxies

  REMOTE_ADDR = 最后一个代理服务器 IP

  HTTP_VIA = 代理服务器 IP

  HTTP_CLIENT_IP = 代理服务器 IP

  HTTP_X_FORWARDED_FOR = 您的真实 IP ,经过多个代理服务器时,这个值类似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。

这类代理服务器还是将您的信息转发给您的访问对象,无法达到隐藏真实身份的目的。

3)使用普通匿名代理服务器的情况:AnonymousProxies

  REMOTE_ADDR = 最后一个代理服务器 IP

  HTTP_VIA = 代理服务器 IP

  HTTP_CLIENT_IP = 代理服务器 IP

  HTTP_X_FORWARDED_FOR = 代理服务器 IP ,经过多个代理服务器时,这个值类似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。

隐藏了您的真实IP,但是向访问对象透露了您是使用代理服务器访问他们的。

4)使用欺骗性代理服务器的情况:DistortingProxies

  REMOTE_ADDR = 代理服务器 IP

  HTTP_VIA = 代理服务器 IP

  HTTP_CLIENT_IP = 代理服务器 IP

  HTTP_X_FORWARDED_FOR = 随机的 IP ,经过多个代理服务器时,这个值类似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。

告诉了访问对象您使用了代理服务器,但编造了一个虚假的随机IP代替您的真实IP欺骗它。

5)使用高匿名代理服务器的情况:HighAnonymity Proxies (Elite proxies)

  REMOTE_ADDR = 代理服务器 IP

  HTTP_VIA = 没数值或不显示

  HTTP_CLIENT_IP = 没数值或不显示

  HTTP_X_FORWARDED_FOR = 没数值或不显示 ,经过多个代理服务器时,这个值类似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。

完全用代理服务器的信息替代了您的所有信息,就象您就是完全使用那台代理服务器直接访问对象。

注:Squid默认设置forwarded_for项默认是为on,如果 forwarded_for设成了 off 则:X-Forwarded-For: unknown

2 wap特有表头属性分析
Sky-Real-IP: Sky-Wapproxy的代理IP,是SKY WAP代理的请求

X-real-ip: 跟remote_addr一样,对nginx而言设置了则有不设置则无,一般nginx设置为 proxy_set_header X-real-ip $remote_addr;
x-network-info GPRS,10.139.155.216,13951615696,211.139.172.70,unsecured,移动的gprs网络信息,10.139.155.216和211.139.172.70都是WAP网关的IP,这次会话使用的是非安全的通信模式,即是没有使用安全服务层(TLS或者WTLS),13951615696是你们省网关的GT码

x-forwarded-for 10.139.155.216, 10.139.155.215 同HTTP_X_FORWARDED_FOR

x-source-id 连接模式,一般是本地局域网IP

client-ip:终端的IP即终端上网时动态分配的IP(clientip)有可能是内网IP

clientip: 使用UCWEB时uc带上的客户端IP

3 关于Proxy-Client-IP和WL-Proxy-Client-IP
在apache+WebLogic整合系统中,apache会对request对象进行再包装,附加一些WLS要用的头信息,两个信息如下:

Proxy-Client-IP 代理客服端IP

WL-Proxy-Client-IP WebLogic代理客服端IP(weblogic设置了才会有这个参数)

一般情况下Proxy-Client-IP和WL-Proxy-Client-IP的IP是一样的

在Linux加Squid的组合做为代理服务器的网络环境中,若Squid的配置forwarded_for 设成了 off则:X-Forwarded-For: unknown。此时在apache+WebLogic的系统中Proxy-Client-IP和WL-Proxy-Client-IP可以反应出用户的真实IP

4 如何取得用户真实的IP
综上所述:

正确的取得wap用户IP的逻辑应该是

  1.  判断clientip是否为空,若不为空则取
    
  2.  判断x-forwarded-for是否有值
    
  3.  若有值判断是否是“unknown”若不是则此时用户IP为x-forwarded-for中第一个不为unknown且不是当前内网的IP。
    
  4.  若x-forwarded-for无值或为“unknown”则看Proxy-Client-IP和WL-Proxy-Client-IP中是否有值,若有取此值,若无取REMOTE_ADDR作为用户IP
    

流程图如下:
[图片上传中。。。(1)]

下面是java代码:

package com.ecom;

import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**

public static boolean isInnerIP(String ipAddress) {
    boolean isInnerIp = false;
    long ipNum = getIpNum(ipAddress);
    isInnerIp = isInner(ipNum, aBegin, aEnd) || isInner(ipNum, bBegin, bEnd) || isInner(ipNum, cBegin, cEnd) || isInner(ipNum, saveBegin, saveEnd);
    return isInnerIp;
}

private static long getIpNum(String ipAddress) {
    String[] ip = ipAddress.split("\\.");
    long a = Integer.parseInt(ip[0]);
    long b = Integer.parseInt(ip[1]);
    long c = Integer.parseInt(ip[2]);
    long d = Integer.parseInt(ip[3]);

    long ipNum = a * 256 * 256 * 256 + b * 256 * 256 + c * 256 + d;
    return ipNum;
}

private static boolean isInner(long userIp, long begin, long end) {
    return (userIp >= begin) && (userIp <= end);
}


/**
 * 检验是否是合法的IP地址 * @param address String IP地址 * @return boolean IP地址是否合法
 */
public static boolean isIpAddress(String address) {
    if(StringUtils.isEmpty(address)) return false;
    String regex = "(((2[0-4]d)|(25[0-5]))|(1d{2})|([1-9]d)|(d))[.](((2[0-4]d)|(25[0-5]))|(1d{2})|([1-9]d)|(d))[.]"
            + "(((2[0-4]d)|(25[0-5]))|(1d{2})|([1-9]d)|(d))[.](((2[0-4]d)|(25[0-5]))|(1d{2})|([1-9]d)|(d))";
    Pattern p = Pattern.compile(regex);
    Matcher m = p.matcher(address);
    return m.matches();
}

}

上一篇下一篇

猜你喜欢

热点阅读