请通过浏览器功能收藏网页

Java编写web站点IP防护软核心,全内存操作 ,提供配置化(自己实现的 供大家参考) 实用小功能

发布时间:2020-04-29 17:25:00  作者:本站编辑  来源:本站原创  浏览次数:
www.javainfo.com.cn 上干货 欢迎收藏

基于Java编程的防护 可能速度达不到底层代码的速度,只是一个简单的编码实现 供大家鉴赏

项目框架及类分布   模拟页面分布

                                     image.png


开始讲解各个文件的功能:

ChangLiang.java   常量设置 (读取ipcore.properties文件里的配置)


 ipcore.properties  ip计数器的核心属性配置, 字段说明在 ChangLiang.java文件里有详细说明

        urlType=*.do    

        accessCount=10

        hour=1      

        safeIpCheckNum=5

        ipCount_minCount=15

        ipBlack_minCount=20

        ipCheck_minCount=25


public class ChangLiang {
	
	public static void main(String[] args) {
		ChangLiang a = new ChangLiang();
		System.out.println(a);
	}
	
	/**
	 * 标记防护的URL类型   *。jspx
	 */
	public static String urlType;
	/**
	 * 访问次数
	 * 
单位时间内访问次数     达到这个值    当前的IP会被加入黑名单
	 */
	public static Integer accessCount;
	/**
	 * 秒     task执行任务频率
	 */
	public static Integer ipCount_minCount;
	public static Integer ipBlack_minCount;
	public static Integer ipCheck_minCount;
	/**
	 * IP封禁小时数,及IP存储在黑名单里的时长,若超过hour小时则 自动解禁
	 */
	public static Integer hour;
	/**
	 * IP安全检查次数  ,若IP检查三次 后    访问量正常   则IPcount 自动清理改IP
	 */
	public static Integer safeIpCheckNum;
	
	public static final SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
	
	/**
	 * 获取当前时间点
	 * @return
	 */
	public static String getNowtime(){
		return sdf.format(new Date());
	}
	
	static{
		Properties pro = new Properties();
		FileInputStream in;
		try {
			String path = ChangLiang.class.getResource("/").getFile()+"com/fanghu/core/ipcore.properties";
			in = new FileInputStream(path);
			pro.load(in);
			in.close();
			urlType = pro.getProperty("urlType");
			accessCount = Integer.valueOf(pro.getProperty("accessCount"));
			ipCount_minCount = Integer.valueOf(pro.getProperty("ipCount_minCount"));
			ipBlack_minCount = Integer.valueOf(pro.getProperty("ipBlack_minCount"));
			ipCheck_minCount = Integer.valueOf(pro.getProperty("ipCheck_minCount"));
			hour = Integer.valueOf(pro.getProperty("hour"));
			safeIpCheckNum = Integer.valueOf(pro.getProperty("safeIpCheckNum"));
			
			System.out.println("urlType="+urlType+";accessCount="+accessCount+";ipCount_minCount="+ipCount_minCount+
					";ipBlack_minCount="+ipBlack_minCount+";ipCheck_minCount="+ipCheck_minCount+
					";hour="+hour+";safeIpCheckNum="+safeIpCheckNum );
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
}



客户端IP抓取   IPcatch.java:


/**
 * web客户 ip抓取 ,未特殊验证是否满足设计要求,一般直接访问 代理访问 都能拦截
 * @author 此方法来源网络,若有侵权请留言 *
 */
public class IPcatch {

	/** 
     * 获取用户真实IP地址,不使用request.getRemoteAddr()的原因是有可能用户使用了代理软件方式避免真实IP地址, 
     * 可是,如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP值 
     *  
     * @return ip
     */
    public String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for"); 
       // System.out.println("x-forwarded-for ip: " + ip);
        if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {  
            // 多次反向代理后会有多个ip值,第一个ip才是真实ip
            if( ip.indexOf(",")!=-1 ){
                ip = ip.split(",")[0];
            }
        }  
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
            ip = request.getHeader("Proxy-Client-IP");  
          //  System.out.println("Proxy-Client-IP ip: " + ip);
        }  
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
            ip = request.getHeader("WL-Proxy-Client-IP");  
            //System.out.println("WL-Proxy-Client-IP ip: " + ip);
        }  
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
            ip = request.getHeader("HTTP_CLIENT_IP");  
            //System.out.println("HTTP_CLIENT_IP ip: " + ip);
        }  
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");  
           // System.out.println("HTTP_X_FORWARDED_FOR ip: " + ip);
        }  
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
            ip = request.getHeader("X-Real-IP");  
            //System.out.println("X-Real-IP ip: " + ip);
        }  
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
            ip = request.getRemoteAddr();  
           // System.out.println("getRemoteAddr ip: " + ip);
        } 
       // System.out.println("获取客户端ip: " + ip);
        return ip;  
    }	
}


ip计数器 对于某类访问的客户IP进行技术统计,并读取白名单数据


ipwhite.txt ip白名单  用户避免一些具有网IP或必要的IP被拦截

    127.0.0.1

    127.0.0.3

    0:0:0:0:0:0:0:1


/**
 * IP访问量计数核心  对一类URI进行处理
 * @author WJ
 */
public class IPcount {
	/**
	 * 存储IP白名单 IP , 1 
	 */
	public static Map



IP动态维护任务 ipCheckingTask.java(核心)


/**
 * IP检查任务,标记哪些IP 应该移入黑名单,这样这个IP池 会自动维护,不用人工干预
 * @author Administrator
 */
public class IpCheckingTask {
	
	public static void IpCheckingMain(){
		try {
			System.out.println("开始启用IP防御核心 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。");
			ipCountCheck(); //启用IP计数器过滤线程
			ipBlackCheckTask(); //启用黑名单超时释放线程
			ipCountClearTask();  //启用safeIP清理线程
			System.out.println("IP防御核心 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。启动完成。。");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * IP校验计时器    IP 校验次数 
	 */
	static Map


IPcheckFilter.java     核心部署 依赖web的过滤器FILTER,上代码  哪些操作频繁需要防护可以在过滤器上调整

@WebFilter("/*")
public class IpCheckFilter implements Filter {
	
	private IPcatch ipCatch = null;

    /**
     * Default constructor. 
     */
    public IpCheckFilter() {
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see Filter#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub
	}

	/**
	 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub
		// place your code here
		//特殊请求 特殊处理,如提示访问频繁的界面
		HttpServletRequest req =   (HttpServletRequest)request;
		String url =  req.getRequestURL().toString();
		System.out.println("url: ------------- = "+url);
		if(url.indexOf("res403") > 0){
			chain.doFilter(request, response);
			return;
		}
		//截取访问客户端的IP
		String webUserIp = ipCatch.getIpAddr(req);
		System.out.println("filterWebUserIp=" + webUserIp);
		//IP通过防护核心的IP计数器 记录一下
		int rsInt =  IPcount.process(webUserIp);
		
		if(rsInt == 0){
		        //防护核心认为 可以通行
			chain.doFilter(request, response);
		}else{
		        //未通过防护核心
			HttpServletResponse res = (HttpServletResponse) response;
			res.setStatus(403);
			request.getRequestDispatcher("/res403.jsp").forward(request, response);
		}
	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
		//启动IP防御核心
		IpCheckingTask.IpCheckingMain();
		//启动IP抓取功能
		ipCatch = new IPcatch();
		System.out.println("filter OK ");
		System.out.println("IPcatch process OK ");
		
	}

}


全内存操作 速度还可以

测试打印如下,可以正常提供拦截服务

初始化IP白名单OK 3
url: ------------- = http://192.168.2.222/
filterWebUserIp=192.168.2.222
ipCoungMap detail --------------------- 192.168.2.222 count: 1
ipchecking: count=1   changLiangaccesscount=10
checkIpNums     ===init====192.168.2.222 saomiaoNum = 1
ipCountCheck       无须处理 。。。。 IPCOUNT TASK 
ipBlackCheckTask   ------------  无须处理 。。。。  TASK 
url: ------------- = http://192.168.2.222/
filterWebUserIp=192.168.2.222
ipCoungMap detail --------------------- 192.168.2.222 count: 2
url: ------------- = http://192.168.2.222/
filterWebUserIp=192.168.2.222
ipCoungMap detail --------------------- 192.168.2.222 count: 3
url: ------------- = http://192.168.2.222/
filterWebUserIp=192.168.2.222
ipCoungMap detail --------------------- 192.168.2.222 count: 4
url: ------------- = http://192.168.2.222/
filterWebUserIp=192.168.2.222
ipCoungMap detail --------------------- 192.168.2.222 count: 5
url: ------------- = http://192.168.2.222/
filterWebUserIp=192.168.2.222
ipCoungMap detail --------------------- 192.168.2.222 count: 6
url: ------------- = http://192.168.2.222/
filterWebUserIp=192.168.2.222
ipCoungMap detail --------------------- 192.168.2.222 count: 7
ipCountClearTask 2020-04-29 14:27:34
safeIpcheck  IP= 192.168.2.222 安全校验次数 1 ; 安全校验标准次数  5
safeIp 无须清理 ,没有满足条件的IP 
url: ------------- = http://192.168.2.222/
filterWebUserIp=192.168.2.222
ipCoungMap detail --------------------- 192.168.2.222 count: 8
url: ------------- = http://192.168.2.222/
filterWebUserIp=192.168.2.222
ipCoungMap detail --------------------- 192.168.2.222 count: 9
url: ------------- = http://192.168.2.222/
filterWebUserIp=192.168.2.222
ipCoungMap detail --------------------- 192.168.2.222 count: 10
url: ------------- = http://192.168.2.222/
filterWebUserIp=192.168.2.222
ipCoungMap detail --------------------- 192.168.2.222 count: 11
url: ------------- = http://192.168.2.222/
filterWebUserIp=192.168.2.222
ipCoungMap detail --------------------- 192.168.2.222 count: 12
url: ------------- = http://192.168.2.222/
filterWebUserIp=192.168.2.222
ipCoungMap detail --------------------- 192.168.2.222 count: 13
url: ------------- = http://192.168.2.222/
filterWebUserIp=192.168.2.222
ipCoungMap detail --------------------- 192.168.2.222 count: 14
ipchecking: count=14   changLiangaccesscount=10
ipCountMap     toblack ==================================192.168.2.222
ipCountMap[ipBlackMap checkIpNums]  remove[add remove]   192.168.2.222 timeLong = 1588141664184
ipBlackCheckTask   ------------  无须处理 。。。。  TASK 
ipCountCheck       无须处理 。。。。 IPCOUNT TASK 
ipCountClearTask 2020-04-29 14:27:59
safeIp 无须清理 ,没有满足条件的IP 
ipBlackCheckTask   ------------  无须处理 。。。。  TASK 
ipCountCheck       无须处理 。。。。 IPCOUNT TASK 
ipCountClearTask 2020-04-29 14:28:24
safeIp 无须清理 ,没有满足条件的IP 
ipCountCheck       无须处理 。。。。 IPCOUNT TASK 
ipBlackCheckTask   ------------  无须处理 。。。。  TASK 
ipCountCheck       无须处理 。。。。 IPCOUNT TASK 
封存时间已经超过了约定的时间,黑名单释放192.168.2.222 nowGetTime = 1588141729186 fff=60 toBlackTime=1588141664184
ipBlackMap 清理了 IP 192.168.2.222
ipCountClearTask 2020-04-29 14:28:49
safeIp 无须清理 ,没有满足条件的IP 
ipCountCheck       无须处理 。。。。 IPCOUNT TASK 
ipBlackCheckTask   ------------  无须处理 。。。。  TASK



如有疑问 请留言 欢迎提供建议

评论已有 0