Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 59043|回复: 0

[jsp学习]jsp论坛防Flood攻击

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-2 02:37:34 | 显示全部楼层 |阅读模式
    Flood攻击,俗称洪水攻击,所谓拒绝服务攻击中的一种。

         它利用TCP协议的设计上的缺陷,通过特定方式发送大量的TCP请求从而导致受攻击的一方CPU超负荷或内存不足。 使用防火墙是防御Flood攻击的最有效的方法之一。

          在学习论坛mvnforum-1.1源码时,发现其中有防Flood攻击的处理,它是通过限制每个IP每小时的HTTP请求数来防止Flood攻击的。

        其原理也用来防止其它的攻击论坛的手段如:不停的发贴,一个iP注册多个账号等。
       

       下面来看看具体的源码。
       
      
       
       
         
       

         
       
      
       一、首先在MVNForumGlobal.java中定义一些全局变量,用来表示需要防止的动作:
    public final static Integer FLOOD_ID_NEW_POST_PER_IP = new Integer(1000);
    public final static Integer FLOOD_ID_NEW_MEMBER_PER_IP = new Integer(1001);
    public final static Integer FLOOD_ID_LOGIN_PER_IP = new Integer(1002);
    public final static Integer FLOOD_ID_NEW_MESSAGE_PER_IP = new Integer(1003);
    public final static Integer FLOOD_ID_NEW_POST_PER_MEMBER = new Integer(1004);
    public final static Integer FLOOD_ID_HTTP_REQUEST_PER_IP = new Integer(1005);//http请求动作

    在MVNForumConfig.java中设置了值,论坛启动时会加载。  FloodControl.setOption(MVNForumGlobal.FLOOD_ID_NEW_MEMBER_PER_IP, maxMembersPerHourPerIP);
    FloodControl.setOption(MVNForumGlobal.FLOOD_ID_NEW_POST_PER_IP, maxPostsPerHourPerIP);
    FloodControl.setOption(MVNForumGlobal.FLOOD_ID_NEW_POST_PER_MEMBER, maxPostsPerHourPerMember);
    FloodControl.setOption(MVNForumGlobal.FLOOD_ID_LOGIN_PER_IP, maxLoginsPerHourPerIP);
    FloodControl.setOption(MVNForumGlobal.FLOOD_ID_NEW_MESSAGE_PER_IP, maxMessagesPerHourPerIP);
    FloodControl.setOption(MVNForumGlobal.FLOOD_ID_HTTP_REQUEST_PER_IP, maxHttpRequestsPerHourPerIP);


    二、在web.xml文件中注册一个Servlet控制器ForumUserServlet,任何用户对论坛的访问都要经过它的检验。
    <servlet>
       <servlet-name>ForumUserServlet</servlet-name>
       <servlet-class>com.mvnforum.user.ForumUserServlet</servlet-class>
    </servlet>

    <servlet-mapping>
       <servlet-name>ForumUserServlet</servlet-name>
       <url-pattern>/mvnforum/*</url-pattern>
    </servlet-mapping>

    下面是ForumUservlet.java中的代码:

         String currentIP = request.getRemoteAddr();//获取客户端的IP

         // Control the HTTP request, we dont want user to try too many request
         //检查这个IP是否发出了太多的请求。
       try {
          FloodControl.ensureNotReachMaximum(MVNForumGlobal.FLOOD_ID_HTTP_REQUEST_PER_IP, currentIP);
        } catch (FloodException fe) {
         getServletContext().getRequestDispatcher("/mvnplugin/mvnforum/max_http_request.jsp").forward(request, response);
         return;
       }

       //增加一个请求计数
       FloodControl.increaseCount(MVNForumGlobal.FLOOD_ID_HTTP_REQUEST_PER_IP, currentIP);

    三、主要是这个文件:
    1. package net.myvietnam.mvncore.security;
    2. import java.util.*;
    3. import org.apache.commons.logging.Log;
    4. import org.apache.commons.logging.LogFactory;
    5. import net.myvietnam.mvncore.exception.FloodException;
    6. import net.myvietnam.mvncore.util.DateUtil;
    7. /**
    8. * This class is used to control the number of actions per hour. This is usually
    9. * used to prevent the flood of any action. You should call FloodControl.setOption()
    10. * when your application is inited.
    11. * Note that the action id from 0 to 999 is belong to mvnCore, application used it
    12. * should not use the value in this range
    13. */

    14. public class FloodControl {
    15.     private static Log log = LogFactory.getLog(FloodControl.class);
    16.     /** The value from 0 to 999 should belong to mvnCore */
    17.     public static int MAX_MVNCORE_ACTION_ID = 999;
    18.     private static Map actionControlMap = new TreeMap();
    19.     static final long REMOVE_INTERVAL = DateUtil.MINUTE * 2;//2 minutes
    20.     private FloodControl() {
    21.     }
    22.        
    23.     /**
    24.      * To set the mamximum number of actions per hour for an action.
    25.      * If the caller does not call this method, the the action has no limit
    26.      * @param action Integer the action that want to set the option
    27.      * @param actionsPerHour int the maximum number of actions per hour
    28.      */
    29.          
    30.     public static void setOption(Integer action, int actionsPerHour) {
    31.         getControlledAction(action).setActionsPerHour(actionsPerHour);
    32.     }
    33.     public static int getActionsPerHour(Integer action) {
    34.         return getControlledAction(action).getActionsPerHour();
    35.     }
    36.     /**
    37.      * Check that an action of an IP has reach the maximum number of allowed times
    38.      * @param action Integer the action to check
    39.      * @param strIP String the IP to check
    40.      * @return boolean true if it has reached the maximum
    41.      */
    42.          
    43.     public static boolean reachMaximum(Integer action, String strIP) {
    44.         return getControlledAction(action).reachMaximum(strIP);
    45.     }
    46.     /**
    47.      * This is a utility method to ensure that the action has not reached the mamximum.
    48.      * It calls the method reachMaximum and throw an exception if it reached the maximum.
    49.      * A program could use this method to use the default error message, otherwise
    50.      * it has to use reachMaximum
    51.      * @param action Integer the action to ensure
    52.      * @param strIP String the IP to ensure
    53.      * @throws FloodException if it reached the maximum
    54.      * @see FloodControl#reachMaximum(Integer, String)
    55.      */
    56.     public static void ensureNotReachMaximum(Integer action, String strIP) throws FloodException {
    57.         if (reachMaximum(action, strIP)) {
    58.          log.info("Attempt to exceed the maximum number of actions: ActionID = " + action + " and IP = " + strIP);
    59.             //@todo : localize me
    60.          throw new FloodException("You have reached the maximum number of actions for this page
    61.            (actionID = " + action + "). Please try this page later. This is to prevent forum from being flooded.");
    62.         }
    63.     }
    64.     /**
    65.      * Increase the number of action. This method should be called the the program
    66.      * has done this action. Forget to call this method will void the reachMaximum method.
    67.      * @param action Integer the action to increase the number of times
    68.      * @param strIP String the IP to increase the number of times
    69.      */
    70.     public static void increaseCount(Integer action, String strIP) {
    71.         getControlledAction(action).increaseCount(strIP);
    72.     }
    73.     /**
    74.      * Reset the action history. This method is useful in such a case in the login
    75.      * process that after login successfully, the value should be reset. Please note
    76.      * that this is just an example and usually no need to use this method.
    77.      * @param action Integer
    78.      * @param strIP String
    79.      */
    80.     public static void resetActionHistory(Integer action, String strIP) {
    81.         getControlledAction(action).resetActionHistory(strIP);
    82.     }
    83.     /**
    84.      * Return the instance of ControlledAction for the action. It will create
    85.      * new instance if no previous instance for this action exist.
    86.      * @param action Integer
    87.      * @return ControlledAction
    88.      */
    89.     private static synchronized ControlledAction getControlledAction(Integer action) {
    90.         ControlledAction controlledAction = (ControlledAction)actionControlMap.get(action);
    91.         if (controlledAction == null) {
    92.             controlledAction = new ControlledAction();
    93.             actionControlMap.put(action, controlledAction);
    94.         }
    95.         return controlledAction;
    96.     }
    97. }
    98. /**
    99. * For one action that handles a list of all IP
    100. */
    101. class ControlledAction {
    102.     private int actionsPerHour = 0;//缺省情况下,对每小时的动作数不作限制。
    103.     private Map ipMap = new TreeMap();
    104.     private long lastRemoveTime = 0;
    105.     void setActionsPerHour(int actionsPerHour) {
    106.         if (actionsPerHour >= 0) {
    107.             this.actionsPerHour = actionsPerHour;
    108.         }
    109.     }
    110.     int getActionsPerHour() {
    111.         return actionsPerHour;
    112.     }
    113.     boolean reachMaximum(String strIP) {
    114.         removeTimeoutControlledIP();
    115.         return getControlledIP(strIP).reachMaximum();
    116.     }
    117.     void increaseCount(String strIP) {
    118.         removeTimeoutControlledIP();
    119.         getControlledIP(strIP).increaseCount();
    120.     }
    121.     void resetActionHistory(String strIP) {
    122.         removeTimeoutControlledIP();
    123.         getControlledIP(strIP).resetActionHistory();
    124.     }
    125.     private synchronized ControlledIP getControlledIP(String strIP) {
    126.         ControlledIP controlledIP = (ControlledIP)ipMap.get(strIP);
    127.         if (controlledIP == null) {
    128.             controlledIP = new ControlledIP(actionsPerHour);
    129.             ipMap.put(strIP, controlledIP);
    130.         } else {
    131.             // there is a ControlledIP, update the actionsPerHour
    132.             controlledIP.setActionsPerHour(actionsPerHour);
    133.         }
    134.         return controlledIP;
    135.     }
    136.     private synchronized void removeTimeoutControlledIP() {
    137.         long now = System.currentTimeMillis();
    138.         if ((now - lastRemoveTime) > FloodControl.REMOVE_INTERVAL) {
    139.             lastRemoveTime = now;
    140.             Collection ipList = ipMap.values();
    141.             for (Iterator iter = ipList.iterator(); iter.hasNext(); ) {
    142.                 ControlledIP currentControlledIP = (ControlledIP)iter.next();
    143.                 if (now - currentControlledIP.getLastIncrementTime() > DateUtil.HOUR) {
    144.                     iter.remove();
    145.                 }
    146.             }
    147.         }
    148.     }
    149. }
    150. /**
    151. * For one action per one IP
    152. */
    153. class ControlledIP {
    154.     private int actionsPerHour = 0;//缺省不作限制。
    155.     private long lastRemoveTime = 0;
    156.     private long lastIncrementTime = 0;
    157.     private ArrayList actionHistoryList = new ArrayList();
    158.     ControlledIP(int actionsPerHour) {
    159.         if (actionsPerHour >= 0) {
    160.             this.actionsPerHour = actionsPerHour;
    161.         }
    162.     }
    163.     void setActionsPerHour(int actionsPerHour) {
    164.         if (actionsPerHour >= 0) {
    165.             this.actionsPerHour = actionsPerHour;
    166.         }
    167.     }
    168.     long getLastIncrementTime() {
    169.         return lastIncrementTime;
    170.     }
    171.     void increaseCount() {
    172.         long now = System.currentTimeMillis();
    173.         lastIncrementTime = now;
    174.         actionHistoryList.add(new Long(now));
    175.     }
    176.     void resetActionHistory() {
    177.         lastRemoveTime = 0;
    178.         lastIncrementTime = 0;
    179.         actionHistoryList.clear();
    180.     }
    181.     boolean reachMaximum() {
    182.         if (actionsPerHour == 0) {//unlimited 没有限制。
    183.             return false;
    184.         }
    185.         if (actionHistoryList.size() < actionsPerHour) {
    186.             return false;
    187.         }
    188.         // now try to remove timeout actions
    189.         removeTimeoutActions();
    190.         return (actionHistoryList.size() >= actionsPerHour);
    191.     }
    192.     private synchronized void removeTimeoutActions() {
    193.         long now = System.currentTimeMillis();
    194.         if (now - lastRemoveTime > FloodControl.REMOVE_INTERVAL) {
    195.             lastRemoveTime = now;
    196.             for (Iterator iter = actionHistoryList.iterator(); iter.hasNext(); ) {
    197.                 Long currentAction = (Long)iter.next();
    198.                 if ((now - currentAction.longValue()) > DateUtil.HOUR) {
    199.                     iter.remove();
    200.                 }
    201.             } //for
    202.         }
    203.     }
    204. }
    复制代码


      
      
       
       

         
       

         
       
      
    复制代码

    源码下载:http://file.javaxxz.com/2014/10/2/023733938.zip
    回复

    使用道具 举报

    该用户从未签到

    发表于 2015-9-15 11:14:57 | 显示全部楼层
    很好的思路,感谢分享
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-25 00:55 , Processed in 0.386560 second(s), 48 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表