/// <summary> /// 调整清除ReqCache对象的黑名单清除时间/警告等级等等 /// </summary> /// <param name="reqCache">当前ReqCache对象</param> /// <param name="isForever">是否永久移入黑名单IP</param> private static void ComputeNextResetIsBadIPDateAndSetProperty(ref ReqCache reqCache, ref bool isForever) { isForever = true; DateTime clearDate = DateTime.MaxValue; if (reqCache.Req_Warn_Count < AlgorithmUtility.Int_Fibo_MAX_FOR_APP) { reqCache.Req_Warn_Lv = AlgorithmUtility.GetFibonacci(reqCache.Req_Warn_Count); if (reqCache.Req_Warn_Count >= AppUtility.Cfg.Allow_Warn_Count || reqCache.Req_Warn_Count >= AlgorithmUtility.Int_Fibo_MAX_FOR_APP) { clearDate = DateTime.MaxValue; } else { try { isForever = false; clearDate = DateTime.Now.AddMinutes(reqCache.Req_Warn_Lv * 10); } catch { clearDate = DateTime.MaxValue; } } } reqCache.Req_Allow_Clear_IsBadIP_Date = clearDate; }
protected void Page_Load(object sender, EventArgs e) { this.cmd = Request.Params["cmd"]; this.reqId = Request.Params["reqID"]; this.domain = Request.Form["domain"]; __ = !string.IsNullOrEmpty(this.domain); this.domain = string.IsNullOrEmpty(this.domain) ? Request.Params["domain"] : this.domain; this.ipaddr = Request.Form["ipaddr"]; this.ipaddr = string.IsNullOrEmpty(this.ipaddr) ? Request.Params["ipaddr"] : this.ipaddr; this.ipaddr = string.IsNullOrEmpty(this.ipaddr) ? "::1" : this.ipaddr; if (!string.IsNullOrEmpty(this.domain) && !string.IsNullOrEmpty(this.ipaddr)) { reqID = MD5Utility.Encrypt(domain + ipaddr, MD5Mode.Default); // RequestUtility.GetSchemeHostAndPort(Request); reqCache = ReqCacheDbUtility.GetReqCache(reqID); } if (!string.IsNullOrEmpty(cmd) && !__) { bool result = (cmd == "del") ? ReqCacheDbUtility.DeleteReqCache(reqId) // 删除缓存 : (cmd == "set") ? ReqCacheDbUtility.RemoveReqCacheIsBadIP(reqId) // 移除黑名单 : (cmd == "set1") ? ReqCacheDbUtility.AddToIsBadIPForever(reqId) // 永久性黑名单 : (cmd == "set2") ? ReqCacheDbUtility.SetReqCacheIsValidIPForever(reqId) : false; // 永久性非黑名单 } }
/// <summary> /// 缓存ReqCache到Memcached中 /// </summary> /// <param name="request">HttpRequest对象</param> /// <param name="key">缓存键</param> /// <param name="reqCache">缓存值</param> /// <param name="isCached">是否是已经缓存过的值</param> /// <param name="isForever">是否永远缓存</param> internal static bool Set(HttpRequest request, string key, ReqCache reqCache, bool isCached, bool isForever) { StoreMode mode = StoreMode.Replace; if (!isCached) { mode = StoreMode.Add; reqCache.IP = RequestUtility.GetIP(request); } reqCache.Req_Pre_Date = DateTime.Now; return client.Store(mode, key, reqCache, DefaultReqCacheDbKernal.GetCacheTS(isForever)); }
/// <summary> /// 获取Memcached中的缓存的ReqCache对象,有缓存返回缓存的ReqCache,否则new ReqCache返回 /// </summary> /// <param name="key">缓存键</param> /// <param name="isCached">对象是否是缓存的(输出参数)</param> /// <returns></returns> internal static ReqCache Get(string key, out bool isCached) { ReqCache reqCache = client.Get<ReqCache>(key); isCached = reqCache != null; if (reqCache == null) { reqCache = new ReqCache(key) { Req_Warn_Lv = 1, Req_Wait_Count = 1, Req_Seconds_Count = 1, Req_Pre_Date = DateTime.Now, // 默认10分钟后才可以重置此请求的IsBadIP标识 Req_Allow_Clear_IsBadIP_Date = DateTime.Now.AddMinutes(AppUtility.Cfg.Allow_ClearIsBadIP_Wait_Minutes), }; } return reqCache; }
/// <summary> /// 校验客户端的请求是否合法 /// </summary> /// <param name="app">System.Web.HttpApplication上下文对象</param> /// <param name="reqCache">ReqCache对象,输出参数</param> /// <returns></returns> internal static bool IsValid(System.Web.HttpApplication app, out ReqCache reqCache) { bool isCached = false; bool isForever = false; string key = RequestUtility.GetReqID(app.Request); reqCache = AppUtility.Cfg.ReqCacheDb.Get(key, out isCached); AppUtility.Cfg.ReqCacheDb.AddReq_Wait_Count(ref reqCache, 1); AppUtility.Cfg.ReqCacheDb.AddReq_Seconds_Count(ref reqCache, 1); // 解除黑名单(尝试,如果用户属于黑名单IP用户) if (reqCache.IsBadIP && IsAllowResetIsBadIP(reqCache)) { AppUtility.Cfg.ReqCacheDb.RemoveBadIP(ref reqCache); ComputeNextResetIsBadIPDateAndSetProperty(ref reqCache, ref isForever); } AppUtility.Cfg.ReqCacheDb.Set(app.Request, key, reqCache, isCached, isForever); return AppUtility.Cfg.ReqCacheDb.IsValidIP(reqCache); }
/// <summary> /// /// </summary> /// <param name="reqCache"></param> public void SetIsValidIPForever(ref ReqCache reqCache) { DefaultReqCacheDbKernal.SetIsValidIPForever(ref reqCache); }
/// <summary> /// /// </summary> /// <param name="reqCache"></param> public void SetBadIPForever(ref ReqCache reqCache) { DefaultReqCacheDbKernal.RemoveBadIP(ref reqCache); }
/// <summary> /// /// </summary> /// <param name="reqCache"></param> /// <param name="isForce"></param> public void RemoveBadIP(ref ReqCache reqCache, bool isForce = false) { DefaultReqCacheDbKernal.RemoveBadIP(ref reqCache, isForce); }
/// <summary> /// /// </summary> /// <param name="request"></param> /// <param name="key"></param> /// <param name="reqCache"></param> /// <param name="isCached"></param> /// <param name="isForever"></param> /// <returns></returns> public bool Set(System.Web.HttpRequest request, string key, ReqCache reqCache, bool isCached, bool isForever) { return DefaultReqCacheDbKernal.Set(request, key, reqCache, isCached, isForever); }
/// <summary> /// /// </summary> /// <param name="reqCache"></param> /// <returns></returns> public bool IsValidIP(ReqCache reqCache) { return DefaultReqCacheDbKernal.IsValidIP(reqCache); }
/// <summary> /// 添加/减少请求挂起的次数(addNum大于0,表示添加,否则减少) /// </summary> /// <param name="reqCache">需要调整的ReqCache对象</param> /// <param name="addNum">添加/减少的次数</param> internal static void AddReq_Wait_Count(ref ReqCache reqCache, int addNum) { reqCache.Req_Wait_Count += addNum; reqCache.Req_Pre_Date = DateTime.Now; }
/// <summary> /// 校验 ReqCache 是否允许解除IsBadIP标识 /// </summary> /// <param name="reqCache">ReqCache对象</param> /// <returns></returns> internal static bool IsAllowResetIsBadIP(ReqCache reqCache) { // 当前时间比解除黑名单时间小,说明已经达到解除黑名单的时间 return (DateTime.Now.Subtract(reqCache.Req_Allow_Clear_IsBadIP_Date).TotalSeconds >= 0); }
/// <summary> /// 定义一个标识当 http_service_module 模块开始校验客户端请求的时的方法 /// 注意:如果请求验证通过,需要返回True。如果请求验证失败,返回false,程序将直接调用EndRequest()方法结束本次请求处理 /// </summary> /// <param name="arg">RunModuleEvent参数,可以通过修改Handled来改变是否需要执行系统自定义的校验</param> /// <param name="reqCache">输出参数(当前请求的reqCache对象)</param> protected virtual bool OnBeginValidConnect(RunModuleEvent arg, ref ReqCache reqCache) { // 验证IP是否可访问,会自动增加挂起次数,单位时间访问次数 if (!ReqCacheDbUtility.IsValid(CurrentHTTPApp, out reqCache)) { arg.Handled = false; // 如果请求感觉不合法,调用OnConnectFeelExistProblem函数 OnConnectFeelExistProblem(arg, reqCache); return !(arg.Handled); } return true; }
/// <summary> /// 移除ReqCache的IsBadIP标识 /// </summary> /// <param name="reqCache">ReqCache对象</param> /// <param name="isForce">是否不检验reqCache.IsBadIP标识进行强制重置IdBadIP</param> internal static void RemoveBadIP(ref ReqCache reqCache, bool isForce = false) { if (isForce) { reqCache.Req_Wait_Count = 0; reqCache.Req_Seconds_Count = 0; reqCache.IsPassBadIPValid = false; reqCache.Req_Allow_Clear_IsBadIP_Date = DateTime.Now.AddMinutes(AppUtility.Cfg.Allow_ClearIsBadIP_Wait_Minutes); } else { if (reqCache.IsBadIP) { reqCache.Req_Wait_Count = 0; reqCache.Req_Seconds_Count = 0; reqCache.IsPassBadIPValid = false; reqCache.Req_Allow_Clear_IsBadIP_Date = DateTime.Now.AddMinutes(AppUtility.Cfg.Allow_ClearIsBadIP_Wait_Minutes); } } }
/// <summary> /// 校验IP地址是否不属于黑名单IP /// </summary> /// <param name="reqCache">需要校验的ReqCache对象</param> /// <returns></returns> internal static bool IsValidIP(ReqCache reqCache) { return !(reqCache.IsBadIP); }
/// <summary> /// 添加/减少单位时间内的请求次数(addNum大于0,表示添加,否则减少) /// </summary> /// <param name="reqCache">需要调整的ReqCache对象</param> /// <param name="addNum">添加/减少的次数</param> internal static void AddReq_Seconds_Count(ref ReqCache reqCache, int addNum) { reqCache.Req_Seconds_Count += addNum; }
/// <summary> /// /// </summary> /// <param name="reqCache"></param> /// <param name="addNum"></param> public void AddReq_Wait_Count(ref ReqCache reqCache, int addNum) { DefaultReqCacheDbKernal.AddReq_Wait_Count(ref reqCache, addNum); }
/// <summary> /// 将ReqCache的Req_Allow_Clear_IsBadIP_Date添加到最大时间(此ReqCache对象将永远被禁止访问,直到解除为止) /// </summary> /// <param name="reqCache">ReqCache对象</param> internal static void SetBadIPForever(ref ReqCache reqCache) { reqCache.IsPassBadIPValid = false; reqCache.Req_Allow_Clear_IsBadIP_Date = DateTime.MaxValue; }
/// <summary> /// 定义一个标识当 http_service_module 模块成功校验客户端请求的时的方法,您可以在此方法里面订阅任何非BeginRequest事件 /// </summary> /// <param name="app">HttpApplication上下文对象</param> /// <param name="reqCache">当前请求的ReqCache对象</param> protected virtual void OnValidConnectCompleted(HttpApplication app, ReqCache reqCache) { }
/// <summary> /// 定义一个标识当 http_service_module 模块检测到某个请求客户端可能存在问题时执行的方法 /// </summary> /// <param name="arg">RunModuleEvent参数,可以通过修改Handled来改变是否需要执行系统自定义的校验</param> /// <param name="reqCache">可能存在问题的ReqCache对象,此对象保存在Memcached中</param> protected virtual void OnConnectFeelExistProblem(RunModuleEvent arg, ReqCache reqCache) { arg.Handled = true; }
/// <summary> /// 将ReqCache的IsPassBadIPValid设置为True,标识此ReqCache永远在黑名单IP外 /// </summary> /// <param name="reqCache">ReqCache对象</param> internal static void SetIsValidIPForever(ref ReqCache reqCache) { reqCache.IsPassBadIPValid = true; }