コード例 #1
0
ファイル: AntiDdos.cs プロジェクト: vincenthfrance/ISPCore
        public JsonResult StatsDay()
        {
            var DtNumberOfRequestDay = coreDB.AntiDdos_NumberOfRequestDays.AsNoTracking().ToList();

            if (memoryCache.TryGetValue(KeyToMemoryCache.AntiDdosNumberOfRequestDay(DateTime.Now), out NumberOfRequestDay dataHour))
            {
                DtNumberOfRequestDay.Add(dataHour);
            }

            return(Json(DtNumberOfRequestDay));
        }
コード例 #2
0
        public IActionResult Index(bool ajax, bool IsJurnal, int page = 1)
        {
            // Данные для вывода статистики
            var DtNumberOfRequestDay = coreDB.AntiDdos_NumberOfRequestDays.AsNoTracking().ToList();

            if (memoryCache.TryGetValue(KeyToMemoryCache.AntiDdosNumberOfRequestDay(DateTime.Now), out NumberOfRequestDay dataHour))
            {
                DtNumberOfRequestDay.Add(dataHour);
            }

            // База и остальные параметры
            ViewData["DtNumberOfRequestDay"] = DtNumberOfRequestDay;
            ViewData["jsonDB"]   = jsonDB;
            ViewData["ajax"]     = ajax;
            ViewData["page"]     = page;
            ViewData["IsJurnal"] = IsJurnal;
            return(View("~/Views/Security/AntiDdos.cshtml", coreDB));
        }
コード例 #3
0
ファイル: AntiDdos.cs プロジェクト: vincenthfrance/ISPCore
        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;
        }
コード例 #4
0
ファイル: AntiDdos.cs プロジェクト: vincenthfrance/ISPCore
        public static void Run(CoreDB coreDB, JsonDB jsonDB, IMemoryCache memoryCache)
        {
            if (IsRun || !jsonDB.AntiDdos.IsActive || Platform.Get != PlatformOS.Unix)
            {
                return;
            }
            IsRun = true;

            #region Переносим данные TCP/UPD с кеша в базу (за прошлый час)
            var TimeAntiDdosNumberOfRequestDay = DateTime.Now.AddHours(-1);
            if (memoryCache.TryGetValue(KeyToMemoryCache.AntiDdosNumberOfRequestDay(TimeAntiDdosNumberOfRequestDay), out NumberOfRequestDay dataLastHour))
            {
                // Меняем режим доступа к SQL
                SqlToMode.SetMode(SqlMode.Read);

                // Записываем данные в базу
                coreDB.AntiDdos_NumberOfRequestDays.Add(dataLastHour);

                // Сохраняем базу
                coreDB.SaveChanges();

                // Меняем режим доступа к SQL
                SqlToMode.SetMode(SqlMode.ReadOrWrite);

                // Сносим кеш (статистика за час)
                memoryCache.Remove(KeyToMemoryCache.AntiDdosNumberOfRequestDay(TimeAntiDdosNumberOfRequestDay));
            }
            #endregion

            #region Очистка баз + перенос NumberOfRequestDay в NumberOfRequestMonth
            if (memoryCache.TryGetValue("CronAntiDdosClearDB", out DateTime CronClearDB))
            {
                // Если дата отличается от текущей
                if (CronClearDB.Day != DateTime.Now.Day)
                {
                    // Меняем режим доступа к SQL
                    SqlToMode.SetMode(SqlMode.Read);

                    // Обновляем кеш
                    memoryCache.Set("CronAntiDdosClearDB", DateTime.Now);

                    #region Очищаем NumberOfRequestMonth
                    foreach (var item in coreDB.AntiDdos_NumberOfRequestMonths.AsNoTracking())
                    {
                        // Если записи больше 90 дней
                        if ((DateTime.Now - item.Time).TotalDays > 90)
                        {
                            coreDB.Database.ExecuteSqlCommand(ComandToSQL.Delete(nameof(coreDB.AntiDdos_NumberOfRequestMonths), item.Id));
                        }
                    }
                    #endregion

                    #region Очищаем Jurnals
                    foreach (var item in coreDB.AntiDdos_Jurnals.AsNoTracking())
                    {
                        // Если записи больше 90 дней
                        if ((DateTime.Now - item.Time).TotalDays > 90)
                        {
                            coreDB.Database.ExecuteSqlCommand(ComandToSQL.Delete(nameof(coreDB.AntiDdos_Jurnals), item.Id));
                        }
                    }
                    #endregion

                    #region Очищаем NumberOfRequestDay + Переносим NumberOfRequestDay в NumberOfRequestMonth
                    // Хранимм дату и значение
                    var NumberOfRequestMonth = new Dictionary <int, (DateTime time, long value, int CountBlocked)>();

                    // Собираем статистику за прошлые дни
                    foreach (var item in coreDB.AntiDdos_NumberOfRequestDays.AsNoTracking())
                    {
                        // Пропускаем статистику за сегодня
                        if (item.Time.Day == DateTime.Now.Day && item.Time.Month == DateTime.Now.Month)
                        {
                            continue;
                        }

                        #region Переносим значения в NumberOfRequestMonth
                        if (NumberOfRequestMonth.TryGetValue(item.Time.Day, out (DateTime time, long value, int CountBlocked)it))
                        {
                            NumberOfRequestMonth[item.Time.Day] = (it.time, (item.value > it.value ? item.value : it.value), (item.CountBlocked + it.CountBlocked));
                        }
                        else
                        {
                            NumberOfRequestMonth.Add(item.Time.Day, (item.Time, item.value, item.CountBlocked));
                        }
                        #endregion

                        // Удаляем значения из базы
                        coreDB.Database.ExecuteSqlCommand(ComandToSQL.Delete(nameof(coreDB.AntiDdos_NumberOfRequestDays), item.Id));
                    }

                    // Переносим временные данные с NumberOfRequestMonth в базу
                    foreach (var item in NumberOfRequestMonth)
                    {
                        // Добовляем в базу
                        coreDB.AntiDdos_NumberOfRequestMonths.Add(new NumberOfRequestMonth()
                        {
                            Time         = item.Value.time,
                            value        = item.Value.value,
                            CountBlocked = item.Value.CountBlocked
                        });
                    }
                    #endregion

                    // Сохраняем базу
                    coreDB.SaveChanges();

                    // Меняем режим доступа к SQL
                    SqlToMode.SetMode(SqlMode.ReadOrWrite);

                    // Раз в сутки
                    GC.Collect(GC.MaxGeneration);
                }
            }
            else
            {
                // Создаем кеш задним числом
                memoryCache.Set("CronAntiDdosClearDB", DateTime.Now.AddDays(-1));
            }
            #endregion

            #region Очистка IPTables/IP6Tables
            if (jsonDB.AntiDdos.BlockToIPtables)
            {
                Bash bash = new Bash();

                foreach (var comandTables in "iptables,ip6tables".Split(','))
                {
                    // Список IP
                    foreach (var line in bash.Run(comandTables + " -L INPUT -v --line-numbers | awk '{print $1,$2,$9,$12}'").Split('\n').Reverse())
                    {
                        // Разбираем строку
                        var gr = new Regex("^([0-9]+) ([^ ]+) [^ ]+ ISPCore_([^\n\r]+)$").Match(line).Groups;
                        if (string.IsNullOrWhiteSpace(gr[1].Value) || !DateTime.TryParse(gr[3].Value, out DateTime time))
                        {
                            continue;
                        }

                        // Если время блокировки истекло
                        if (DateTime.Now > time)
                        {
                            if (jsonDB.AntiDdos.ActiveLockMode)
                            {
                                if (gr[2].Value == "0")
                                {
                                    bash.Run($"{comandTables} -D INPUT {gr[1].Value}");
                                }
                                else
                                {
                                    bash.Run($"{comandTables} -Z INPUT {gr[1].Value}");
                                }
                            }
                            else
                            {
                                bash.Run($"{comandTables} -D INPUT {gr[1].Value}");
                            }
                        }
                    }
                }
            }
            #endregion

            IsRun = false;
        }