public JsonResult StatsDay(string SearchHost = null) { // Данные для вывода статистики var DtNumberOfRequestDay = new Dictionary <string, List <NumberOfRequestDay> >(); #region Локальный метод "AddOrUpdateToNumberOfRequestDay" void AddOrUpdateToNumberOfRequestDay(string _host, NumberOfRequestBase dt, DateTime time) { if (SearchHost != null && SearchHost != _host) { return; } var item = new NumberOfRequestDay() { Host = _host, Time = time, Count200 = dt.Count200, Count303 = dt.Count303, Count401 = dt.Count401, Count403 = dt.Count403, Count500 = dt.Count500, Count2FA = dt.Count2FA, }; if (DtNumberOfRequestDay.TryGetValue(_host, out List <NumberOfRequestDay> mass)) { // Добовляем данные mass.Add(item); // Перезаписываем данные DtNumberOfRequestDay[_host] = mass; } else { // Записываем новые данные DtNumberOfRequestDay.Add(_host, new List <NumberOfRequestDay>() { item }); } } #endregion #region Статистика из базы за сутки foreach (var RequestToHour in coreDB.RequestsFilter_NumberOfRequestDay.AsNoTracking()) { AddOrUpdateToNumberOfRequestDay(RequestToHour.Host, RequestToHour, RequestToHour.Time); } #endregion #region Статистика из кеша за текущий час if (memoryCache.TryGetValue(KeyToMemoryCache.IspNumberOfRequestToHour(DateTime.Now), out IDictionary <string, NumberOfRequestHour> DataNumberOfRequestToHour)) { foreach (var item in DataNumberOfRequestToHour) { AddOrUpdateToNumberOfRequestDay(item.Key, item.Value, DateTime.Now); } } #endregion // Ответ return(Json(DtNumberOfRequestDay)); }
public static void RunSecond(JsonDB jsonDB, IMemoryCache memoryCache) { if (IsRunSecond) { return; } IsRunSecond = true; try { Bash bash = new Bash(); byte second = (byte)DateTime.Now.Second; #region Максимальное значение TCP/UPD за текущий час int MaxTcpOrUpd = int.Parse(bash.Run("ss -ntu | wc -l")); // Записываем данные в кеш if (memoryCache.TryGetValue(KeyToMemoryCache.AntiDdosNumberOfRequestDay(DateTime.Now), out dataHour)) { Trigger.OnCountTcpOrUpd((MaxTcpOrUpd, dataHour.value)); if (MaxTcpOrUpd > dataHour.value) { dataHour.value = MaxTcpOrUpd; memoryCache.Set(KeyToMemoryCache.AntiDdosNumberOfRequestDay(DateTime.Now), dataHour); } } else { dataHour = new NumberOfRequestDay() { value = MaxTcpOrUpd, Time = DateTime.Now }; memoryCache.Set(KeyToMemoryCache.AntiDdosNumberOfRequestDay(DateTime.Now), dataHour); Trigger.OnCountTcpOrUpd((MaxTcpOrUpd, dataHour.value)); } #endregion #region Получаем список IP которые нужно заблокировать List <string> MassIP = new List <string>(); // Количиство активных соеденений MassIP.AddRange(bash.Run(@"ss -ntu | awk '{print $6}' | sed 's%\:[0-9]*$%%g' | sed 's%\:\:ffff\:\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\)%\1%g' | sort | uniq -ic | awk '{if ($1 >= " + jsonDB.AntiDdos.MaximumBurstSize + ") {print $2}}'").Split('\n')); // Максимальное количество запросов за 120 секунд if (!memoryCache.TryGetValue("Cron_AntiDdos-tcpdump", out _)) { // Создаем кеш на 120 секунд memoryCache.Set("Cron_AntiDdos-tcpdump", (byte)0, TimeSpan.FromSeconds(120)); // Убиваем tcpdump bash.Run("pkill tcpdump"); // Считываем файл MassIP.AddRange(bash.Run(@"awk '{if ($6 > 0) {print $2}}' " + Folders.Log + @"/tcpdump.log | sed 's%\.[0-9]*$%%g' | sed 's%\:\:ffff\:\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\)%\1%g' | sort | uniq -ic | awk '{if ($1 >= " + jsonDB.AntiDdos.NumberOfRequestsIn120Second + ") {print $2}}'").Split('\n')); // Запускаем tcpdump bash.Run($"tcpdump -i {jsonDB.AntiDdos.Interface} -nnpqSt dst port {string.Join(" or dst port ", jsonDB.AntiDdos.CheckPorts.Split(','))} > {Folders.Log}/tcpdump.log 2> /dev/null &"); } #endregion #region Блокируем IP foreach (var IP in MassIP) { // IP в белом списке if (string.IsNullOrWhiteSpace(IP) || IsWhiteIP(jsonDB, memoryCache, IP)) { continue; } // Блокируем IP Blocked(memoryCache, Regex.Replace(IP, "[\n\r\t ]+", "")); } #endregion } catch { } IsRunSecond = false; }