예제 #1
0
        public static void Update(RateLimitEntity item, ref bool ifContain)
        {
            RateLimitEntity rateLimitOld = RateLimitAccess.GetRateLimitByID(item.TableID);

            if (item.ZoneId == rateLimitOld.ZoneId)
            {
                var list = RateLimitAccess.GetRateLimits(item.ZoneId, null, null, string.Empty);
                list.RemoveAt(list.FindIndex((r) => { return(r.TableID == item.TableID); }));

                if (IfContain(list, item))
                {
                    ifContain = true;
                    return;
                }
                else
                {
                    ifContain = false;
                }

                RateLimitAccess.Edit(item);
            }
            else
            {
                RateLimitBusiness.Add(item, ref ifContain);
                if (!ifContain)
                {
                    Delete(rateLimitOld.TableID, rateLimitOld.OrderNo, rateLimitOld.ZoneId);
                }
            }
        }
        private List <AuditLogEntity> OpenRageLimit(ZoneEntity zone, CloudFlareApiService cloudflare, AnalyzeResult analyzeResult)
        {
            List <AuditLogEntity> auditLogEntities = new List <AuditLogEntity>();
            var sbDetail = new StringBuilder();

            #region Open Rate Limiting Rule

            foreach (var rst in analyzeResult.result)
            {
                // 更新 Rate Limit Trigger Time
                RateLimitBusiness.TriggerRateLimit(new RateLimitEntity()
                {
                    Url       = rst.Url,
                    Period    = rst.Period,
                    Threshold = rst.Threshold,
                    ZoneId    = zone.ZoneId
                });

                sbDetail = new StringBuilder(
                    $"[{rst.BrokenIpList.Count}] IPs exceeded rate limiting threshold(Url=[{rst.Url}],Threshold=[{rst.Threshold}],Period=[{rst.Period}],EnlargementFactor=[{rst.EnlargementFactor}],RateLimitTriggerIpCount=[{rst.RateLimitTriggerIpCount}]), time range:[{analyzeResult.timeStage}], details:<br />");

                foreach (var rule in rst.BrokenIpList)
                {
                    sbDetail.AppendFormat("IP [{0}] visited [{1}] times.<br /> ", rule.IP, rule.RequestRecords.Sum(x => x.RequestCount));
                }
                //auditLogEntities.Add(new AuditLogEntity(zone.TableID, LogLevel.App, sbDetail.ToString()));
                ////sbDetail.AppendFormat("Start opening rate limiting rule in Cloudflare [URL=[{0}],Threshold=[{1}],Period=[{2}]].<br />", rateLimit.Url, rateLimit.Threshold, rateLimit.Period);
                //sbDetail = new StringBuilder();
                if (zone != null && zone.IfTestStage)
                {
                    sbDetail.AppendFormat("Open rate limiting rule in Cloudflare [URL=[{0}],Threshold=[{1}],Period=[{2}]] successfully.<br />", rst.Url, rst.Threshold, rst.Period);
                }
                else
                {
                    if (cloudflare.OpenRateLimit(rst.Url, rst.Threshold, rst.Period, out var errorLog))
                    {
                        sbDetail.AppendFormat("Open rate limiting rule in Cloudflare [URL=[{0}],Threshold=[{1}],Period=[{2}]] successfully.<br />", rst.Url, rst.Threshold, rst.Period);
                    }
                    else
                    {
                        sbDetail.AppendFormat(errorLog.Detail);
                    }
                }

                auditLogEntities.Add(new AuditLogEntity(zone.TableID, LogLevel.Audit, sbDetail.ToString()));

                //Ban Ip
                foreach (var broken in rst.BrokenIpList)
                {
                    sbDetail = new StringBuilder();
                    if (rst.Url.EndsWith("*"))
                    {
                        var count = broken.RequestRecords.Sum(a => a.RequestCount);
                        sbDetail.Append($"IP [{broken.IP}] visited [{rst.Url}] [{count}] times, time range:[{analyzeResult.timeStage}].<br /> Exceeded rate limiting threshold(URL=[{rst.Url}],Period=[{rst.Period}],Threshold=[{rst.Threshold}],EnlargementFactor=[{rst.EnlargementFactor}]),details(only list the top 10 records):<br />");
                        var top10 = broken.RequestRecords.OrderByDescending(a => a.RequestCount).Take(10);

                        foreach (var item in top10)
                        {
                            sbDetail.AppendFormat("[{0}] {1} times.<br />", item.FullUrl, item.RequestCount);
                        }
                    }
                    else
                    {
                        var count = broken.RequestRecords.Sum(a => a.RequestCount);
                        sbDetail.Append($"IP [{broken.IP}] visited [{rst.Url}] [{count}] times, time range:[{analyzeResult.timeStage}].<br /> Exceeded rate limiting threshold(URL=[{rst.Url}],Period=[{rst.Period}],Threshold=[{rst.Threshold}],EnlargementFactor=[{rst.EnlargementFactor}]).<br />");
                    }
                    string banIpLog = BanIpByRateLimitRule(zone, zone.IfTestStage, cloudflare, analyzeResult.timeStage, broken.RequestRecords.FirstOrDefault().HostName, broken.IP, rst.Period, rst.Threshold, rst.BrokenIpList.Count);

                    if (!string.IsNullOrEmpty(banIpLog))
                    {
                        sbDetail.Append(banIpLog);
                    }

                    auditLogEntities.Add(new AuditLogEntity(zone.TableID, LogLevel.Audit, sbDetail.ToString()));
                }
            }

            #endregion
            return(auditLogEntities);
        }