天天看點

C# 通過 HTTPModule 防範 DOS

直接上代碼:

    public class DosAttackModule : IHttpModule
    {
        void IHttpModule.Dispose() { }
 
        void IHttpModule.Init(HttpApplication context)
        {
            context.BeginRequest += new EventHandler(context_BeginRequest);
        }
 
        private static Dictionary<string, short> _IpAdresses = new Dictionary<string, short>();
        private static Stack<string> _Banned = new Stack<string>();
        private static Timer _Timer = CreateTimer();
        private static Timer _BannedTimer = CreateBanningTimer();
 
        private const int BANNED_REQUESTS = 1; //規定時間内通路的最大次數  
        private const int REDUCTION_INTERVAL = 1000; // 1 秒(檢查通路次數的時間段)  
        private const int RELEASE_INTERVAL = 5 * 60 * 1000; // 5 分鐘(清除一個禁止IP的時間段) 
 
        private void context_BeginRequest(object sender, EventArgs e)
        {
            string ip = HttpContext.Current.Request.UserHostAddress;
            if (_Banned.Contains(ip))
            {
                HttpContext.Current.Response.StatusCode = 403;
                HttpContext.Current.Response.End();
            }
 
            CheckIpAddress(ip);
        }
 
        /// <summary>  
        /// 檢查通路IP  
        /// </summary>  
        private static void CheckIpAddress(string ip)
        {
            if (!_IpAdresses.ContainsKey(ip)) //如果沒有目前通路IP的記錄就将通路次數設為1  
            {
                _IpAdresses[ip] = 1;
            }
            else if (_IpAdresses[ip] == BANNED_REQUESTS) //如果目前IP通路次數等于規定時間段的最大通路次數就拉于“黑名單”  
            {
                _Banned.Push(ip);
                _IpAdresses.Remove(ip);
            }
            else //正常通路就加次數 1  
            {
                _IpAdresses[ip]++;
            }
        }
 
        #region Timers
 
        /// <summary>  
        /// 建立計時器,從_IpAddress減去一個請求。  
        /// </summary>  
        private static Timer CreateTimer()
        {
            Timer timer = GetTimer(REDUCTION_INTERVAL);
            timer.Elapsed += new ElapsedEventHandler(TimerElapsed);
            return timer;
        }
 
        /// <summary>  
        /// 建立定時器,消除一個禁止的IP位址  
        /// </summary>  
        /// <returns></returns>  
        private static Timer CreateBanningTimer()
        {
            Timer timer = GetTimer(RELEASE_INTERVAL);
            timer.Elapsed += delegate { _Banned.Pop(); }; //消除一個禁止IP  
            return timer;
        }
 
        /// <summary>  
        /// 建立一個時間器,并啟動它  
        /// </summary>  
        /// <param name="interval">以毫秒為機關的時間間隔</param>  
        private static Timer GetTimer(int interval)
        {
            Timer timer = new Timer();
            timer.Interval = interval;
            timer.Start();
 
            return timer;
        }
 
        /// <summary>  
        /// 減去從集合中的每個IP位址的請求  
        /// </summary>  
        private static void TimerElapsed(object sender, ElapsedEventArgs e)
        {
            foreach (string key in _IpAdresses.Keys)
            {
                _IpAdresses[key]--;
                if (_IpAdresses[key] == 0)
                    _IpAdresses.Remove(key);
            }
        }
 
        #endregion
 
    }  

這個前提是用戶端沒有使用動态代理IP。。      

轉載于:https://www.cnblogs.com/m4LWJ/archive/2013/04/12/3016465.html