论X-Forwarded-For伪装代理请求与获取真实ip(springboot项目)

以下项目均是基于springboot2.x构建

1、使用X-Forwarded-For 伪装代理

之前做了一个项目,关于xxx抢购,当时是用spring boot做的,主要功能就是实现模拟真实用户登录、抢购等一整套自动化流程。

刚开始可以多任务执行,后面可能是被发现了,导致从服务器发出的抢购请求被限制(因为同一个出口ip),后来为了解决这个问题,找到了X-Forwarded-For 这个 配置, 即在请求头里增加一条X-Forwarded-For记录,该值为一个ip地址,通过伪造请求头,服务端再接收到这个请求后,就会解析X-Forwarded-For里面的值,获取到ip地址,因为我写了一个动态随机生成ip的方法,所以每次获取的ip都不一样,这样就可以欺骗服务器,让它认为是不通客户端的请求。

2、如何防御X-Forwarded-For伪造ip

后面的话,又做了一个项目,这个项目与上一个项目恰恰相反---它是需要获取客户端的真实请求ip的(用于防止伪装请求),因为上一个项目让我知道这个ip是可以伪造的,所以我在网上查了一查如何获取真实IP的方法,以下代码为网上搜素:

/**
	 * 获取请求的ip
	 * @param request
	 * @return
	 */
	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
					try {
						ipAddress = InetAddress.getLocalHost().getHostAddress();
					} catch (UnknownHostException e) {
						e.printStackTrace();
					}
				}
			}
			// 通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
			if (ipAddress != null) {
				if (ipAddress.contains(",")) {
					return ipAddress.split(",")[0];
				} else {
					return ipAddress;
				}
			} else {
				return "";
			}
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		}
	}

那么其实上面一段代码,正常没有经过nginx反向代理服务器的话, 如果客户端通过 X-Forwarded-For 伪造ip,那么基本上就是没有用的了,因为在一开始 ipAddress = request.getHeader("x-forwarded-for"); 这里获取到的ip已经是伪造过的ip了

那么如何识别客户端的真实ip呢,这里面有两个处理方式:

1)无代理

如果只是普通的web项目的话,通过 String ip = request.getRemoteAddr(); (HttpServletRequest 类型) 即可获取到客户端的真实ip

2)Nginx代理

在有代理的情况下,由于任何请求首先经过Nginx,故通过request.getRemoteAddr()获取的其实是Nginx的IP,并非真实的客户端IP;此时通过x-forwarded-for获取的IP为:"客户端,代理1,代理2,..."或者"伪造IP,客户端,代理1,代理2,...",故不能获取到准确的客户端IP,此时需要配置Nginx TCP客户端连接的真实IP,通过代理配置获取真实IP,可以通过$remote_addr获取客户端IP,Nginx配置如下:

location / {
   //追加如下代码
   proxy_set_header X-Real-IP $remote_addr;
   proxy_set_header Host $host;
   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

}

 然后服务端通过: String ip = request.getHeader("X-Real-IP");    即可获取到客户端的真实ip

猜你喜欢

转载自blog.csdn.net/rao356/article/details/105128619