Пример #1
0
        /// <summary>
        /// Неудачная авторизация
        /// </summary>
        /// <param name="Settings"></param>
        /// <param name="memoryCache"></param>
        /// <param name="RemoteIpAddress">IP адрес пользователя</param>
        /// <param name="typeBlockIP">Блокировка IP в 'Брандмауэр' глобально или только для домена</param>
        /// <param name="host"></param>
        public static void FailAuthorization(string RemoteIpAddress, TypeBlockIP typeBlockIP, string host = null)
        {
            var    memoryCache = Service.Get <IMemoryCache>();
            string key         = KeyToMemoryCache.LimitLogin(RemoteIpAddress);

            if (memoryCache.TryGetValue(key, out List <DateTime> TimeArray))
            {
                // Актуальные записи
                var array = (from time in TimeArray where (DateTime.Now - time).TotalMinutes < 10 select time).ToList();

                // База JsonDB
                var jsonDB = Service.Get <JsonDB>();

                // Блокировка IP
                if ((array.Count + 1) >= jsonDB.Security.CountAccess)
                {
                    // Где именно блокировать IP
                    string keyIPtables = typeBlockIP == TypeBlockIP.domain ? KeyToMemoryCache.IPtables(RemoteIpAddress, host) : KeyToMemoryCache.IPtables(RemoteIpAddress);

                    // Записываем IP в кеш IPtables
                    memoryCache.Set(keyIPtables, new IPtables("Перебор паролей", DateTime.Now.AddMinutes(jsonDB.Security.BlockingTime)), TimeSpan.FromMinutes(jsonDB.Security.BlockingTime));

                    // Удаляем ключ LimitLogin
                    memoryCache.Remove(key);

                    // Дублируем информацию в SQL
                    WriteLogTo.SQL(new BlockedIP()
                    {
                        IP           = RemoteIpAddress,
                        BlockingTime = DateTime.Now.AddMinutes(jsonDB.Security.BlockingTime),
                        Description  = "Перебор паролей",
                        typeBlockIP  = typeBlockIP,
                        BlockedHost  = host
                    });
                    return;
                }

                // Обновление записей
                array.Add(DateTime.Now);
                memoryCache.Set(key, array, TimeSpan.FromMinutes(10));
            }
            else
            {
                memoryCache.Set(key, new List <DateTime>()
                {
                    DateTime.Now
                }, TimeSpan.FromMinutes(10));
            }
        }
Пример #2
0
        /// <summary>
        /// Разблокировать IPv4/6
        /// </summary>
        /// <param name="IP">IPv4/6</param>
        /// <param name="target">Цель</param>
        /// <param name="BlockedHost">Заблокированный домен</param>
        public static void RemoveIPv4Or6(string IP, TypeBlockIP target, string BlockedHost)
        {
            if (target == TypeBlockIP.domain)
            {
                memoryCache.Remove(KeyToMemoryCache.IPtables(IP, BlockedHost));
                Trigger.OnRemoveIPv4Or6((IP, BlockedHost));
            }
            else if (target != TypeBlockIP.UserAgent)
            {
                if (IPNetwork.CheckingSupportToIPv4Or6(IP, out var ipnetwork))
                {
                    // IPv6
                    if (IP.Contains(":"))
                    {
                        string ipRegex = IPNetwork.IPv6ToRegex(ipnetwork.FirstUsable);
                        IPv6ToRegex = Regex.Replace(IPv6ToRegex, $@"^\^\({ipRegex}\|?", "^(");
                        IPv6ToRegex = Regex.Replace(IPv6ToRegex, $@"\|{ipRegex}", "");
                        if (IPv6ToRegex == "^()")
                        {
                            IPv6ToRegex = "^$";
                        }

                        if (IPv6ToModels.TryRemove(ipRegex, out _))
                        {
                            Trigger.OnRemoveIPv4Or6((IP, BlockedHost));
                        }
                    }

                    // IPv4
                    else
                    {
                        if (IPNetwork.IPv4ToRange(ipnetwork.FirstUsable, ipnetwork.LastUsable) is var item && item.FirstUsable != 0)
                        {
                            IPv4ToRange.RemoveAll(i => i.FirstUsable == item.FirstUsable && i.LastUsable == item.LastUsable);
                            if (IPv4ToModels.TryRemove(item.FirstUsable, out _))
                            {
                                Trigger.OnRemoveIPv4Or6((IP, BlockedHost));
                            }
                        }
                    }
                }
            }
        }
Пример #3
0
        public JsonResult Add(string value, string Description, int BlockingTimeDay, TypeBlockIP typeBlockIP = TypeBlockIP.global, bool IsAPI = false)
        {
            #region Демо режим
            if (Platform.IsDemo)
            {
                return(Json(new Text("Операция недоступна в демо-режиме")));
            }
            #endregion

            // Коректировка
            if (typeBlockIP == TypeBlockIP.domain)
            {
                typeBlockIP = TypeBlockIP.global;
            }

            // Коректор времени
            if (BlockingTimeDay <= 0)
            {
                BlockingTimeDay = 1;
            }

            #region Проверка IP/UserAgent
            if (typeBlockIP == TypeBlockIP.global)
            {
                // IP-адрес
                string IP = value;

                // Проверка IP
                if (!IPNetwork.CheckingSupportToIPv4Or6(IP, out _))
                {
                    return(Json(new Text($"Not supported format: {IP}")));
                }

                // Записываем IP в кеш IPtables
                IPtables.AddIPv4Or6(IP, new ModelIPtables(Description, DateTime.Now.AddDays(BlockingTimeDay)), typeBlockIP);
            }
            else
            {
                // Проверка UserAgent
                if (string.IsNullOrWhiteSpace(value))
                {
                    return(Json(new Text("Поле 'Значение' имеет недопустимое значение")));
                }
            }
            #endregion

            // Дублируем информацию в SQL
            var blockedIP = new BlockedIP()
            {
                IP           = value,
                Description  = Description,
                BlockingTime = DateTime.Now.AddDays(BlockingTimeDay),
                typeBlockIP  = typeBlockIP
            };
            coreDB.BlockedsIP.Add(blockedIP);

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

            // Кеш IPtables
            if (typeBlockIP == TypeBlockIP.UserAgent)
            {
                IPtables.UpdateCacheToUserAgent();
            }

            if (IsAPI)
            {
                return(Json(new TrueOrFalse(true)));
            }

            // Отдаем результат
            return(Json(new Html($@"<tr class='elemDelete'>
                                        <td class='text-left table-products'>
                                            <strong>{value}</strong>
                                        </td>

                                        <td>{(typeBlockIP == TypeBlockIP.global ? "IP-адрес" : "User Agent")}</td>
                                        <td>{Description}</td>
                                        <td>{DateTime.Now.AddDays(BlockingTimeDay).ToString("dd.MM.yyyy H:mm")}</td>

                                        <td style='text-align: right;' class='table-products btn-icons'>" +
                                 "<a onclick=\"return deleteElement(this,'/security/iptables/remove',{Id:'" + blockedIP.Id + "'});\" class=\"btn nopadding-nomargin\"><i class=\"fa fa-trash-o\"></i></a>" +
                                 @"</td>
                                    </tr>")));
        }
Пример #4
0
        public JsonResult Add(string value, string Description, int BlockingTimeDay, TypeBlockIP typeBlockIP = TypeBlockIP.global, bool IsAPI = false)
        {
            #region Демо режим
            if (Platform.IsDemo)
            {
                return(Json(new Text("Операция недоступна в демо-режиме")));
            }
            #endregion

            // Коректировка
            if (typeBlockIP == TypeBlockIP.domain)
            {
                typeBlockIP = TypeBlockIP.global;
            }

            // Коректор времени
            if (BlockingTimeDay <= 0)
            {
                BlockingTimeDay = 1;
            }

            #region Проверка IP/UserAgent
            if (typeBlockIP == TypeBlockIP.global)
            {
                // IP-адрес
                string IP = value;

                // Проверка IP
                if (string.IsNullOrWhiteSpace(IP) || (!IP.Contains(".") && !IP.Contains(":")))
                {
                    return(Json(new Models.Response.Text("Поле 'Значение' имеет недопустимое значение")));
                }

                // IP для кеша и проверки
                string IPshort = IP.Replace(".*", "").Replace(":*", "");

                // Проверка IP на дубликат
                if (IPtablesMiddleware.CheckIP(IPshort, memoryCache, out _))
                {
                    return(Json(new Models.Response.Text("Данный IP-адрес уже заблокирован")));
                }

                // Записываем IP в кеш IPtables
                memoryCache.Set(KeyToMemoryCache.IPtables(IPshort), new IPtables(Description, DateTime.Now.AddDays(BlockingTimeDay)), TimeSpan.FromDays(BlockingTimeDay));
            }
            else
            {
                // Проверка UserAgent
                if (string.IsNullOrWhiteSpace(value))
                {
                    return(Json(new Models.Response.Text("Поле 'Значение' имеет недопустимое значение")));
                }
            }
            #endregion

            // Дублируем информацию в SQL
            var blockedIP = new BlockedIP()
            {
                IP           = value,
                Description  = Description,
                BlockingTime = DateTime.Now.AddDays(BlockingTimeDay),
                typeBlockIP  = typeBlockIP
            };
            coreDB.BlockedsIP.Add(blockedIP);

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

            // Очистка кеша IPtables
            if (typeBlockIP == TypeBlockIP.UserAgent)
            {
                IPtablesMiddleware.ClearCache();
            }

            if (IsAPI)
            {
                return(Json(new TrueOrFalse(true)));
            }

            // Отдаем результат
            return(Json(new Html($@"<tr class='elemDelete'>
                                        <td class='text-left table-products'>
                                            <strong>{value}</strong>
                                        </td>

                                        <td>{(typeBlockIP == TypeBlockIP.global ? "IP-адрес" : "User Agent")}</td>
                                        <td>{Description}</td>
                                        <td>{DateTime.Now.AddDays(BlockingTimeDay).ToString("dd.MM.yyyy H:mm")}</td>

                                        <td style='text-align: right;' class='table-products btn-icons'>" +
                                 "<a onclick=\"return deleteElement(this,'/security/iptables/remove',{Id:'" + blockedIP.Id + "'});\" class=\"btn nopadding-nomargin\"><i class=\"fa fa-trash-o\"></i></a>" +
                                 @"</td>
                                    </tr>")));
        }
Пример #5
0
        public JsonResult Index(string password, string host, string method, string uri, string referer, string hash)
        {
            // Декодируем uri, referer и FormData
            uri     = WebUtility.UrlDecode(uri);
            referer = WebUtility.UrlDecode(referer);

            #region Проверка переданых параметров
            if (string.IsNullOrWhiteSpace(password))
            {
                return(Json(new Models.Response.Text("Введите пароль")));
            }

            if (SHA256.Text($"{host}:{method}:{uri}:{referer}:{PasswdTo.salt}") != hash)
            {
                return(Json(new Models.Response.Text("Хеш сумма не совпадает")));
            }
            #endregion

            // User-Agent
            string userAgent = string.Empty;
            if (HttpContext.Request.Headers.TryGetValue("User-Agent", out var tmp_userAgent))
            {
                userAgent = tmp_userAgent.ToString();
            }

            // Переменные
            string      IP          = HttpContext.Connection.RemoteIpAddress.ToString();   // IP адрес пользователя
            string      HostConvert = Regex.Replace(host.ToLower().Trim(), "^www\\.", ""); // Спецальный host
            TypeBlockIP typeBlockIP = TypeBlockIP.global;                                  // Блокировка IP в 'Брандмауэр' глобально или только для домена
            var         memoryCache = Service.Get <IMemoryCache>();                        // Кеш IMemoryCache

            #region ModelCache.Domain
            ModelCache.Domain domain = new ModelCache.Domain();
            int DomainID             = ISPCache.DomainToID(HostConvert);
            if (DomainID != 0)
            {
                // Достаем данные для домена из кеша
                domain      = ISPCache.GetDomain(DomainID);
                typeBlockIP = domain.typeBlockIP;
            }
            #endregion

            #region Проверяем IP в блокировке IPtables по домену
            if (IPtables.CheckIP(IP, out ModelIPtables BlockedData, HostConvert))
            {
                // Логируем пользователя
                AddJurnalToIPtables(domain, IP, host, method, userAgent, referer, uri);
                CheckRequest.SetCountRequestToHour(TypeRequest._200, host, domain.confToLog.EnableCountRequest);

                // Отдаем ответ
                return(Json(new Models.Response.Text(BlockedData.Description)));
            }
            #endregion

            // Проверяем пароль
            if (SHA256.Text(password) == PasswdTo.FA || (!string.IsNullOrWhiteSpace(domain.Auth2faToPasswd) && SHA256.Text(password) == domain.Auth2faToPasswd))
            {
                // Добавляем информацию о разрешеном доступе, для вывода информации и отмены доступа
                AccessIP.Add(IP, host, DateTime.Now.AddHours(12), domain.Auth2faToAccess == Auth2faToAccess.FullAccess ? AccessType.all : AccessType.Is2FA);

                // Добовляем IP в белый список на 12 часа
                string keyToAccess = domain.Auth2faToAccess == Auth2faToAccess.FullAccess ? KeyToMemoryCache.CheckLinkWhitelistToAll(host, IP) : KeyToMemoryCache.CheckLinkWhitelistTo2FA(host, IP);
                memoryCache.Set(keyToAccess, (byte)1, TimeSpan.FromHours(12));

                // Записываем данные авторизации в журнал
                AddToJurnal2FA(domain, IP, host, method, uri, referer, "Успешная авторизация");

                // Считаем статистику запросов
                CheckRequest.SetCountRequestToHour(TypeRequest._2fa, host, domain.confToLog.EnableCountRequest);

                // Удаляем список неудачных попыток
                LimitLogin.SuccessAuthorization(IP);

                //
                Trigger.OnUnlock2FA((IP, userAgent, referer, DomainID, method, HostConvert, uri, password, true));

                // Отдаем результат
                return(Json(new Models.Response.TrueOrFalse(true)));
            }

            // Записываем данные авторизации в журнал
            AddToJurnal2FA(domain, IP, host, method, uri, referer, "Неудачная попытка авторизации");

            // Считаем статистику запросов
            CheckRequest.SetCountRequestToHour(TypeRequest._2fa, host, domain.confToLog.EnableCountRequest);

            // Записываем в базу IP адрес пользователя, который ввел неправильно пароль
            LimitLogin.FailAuthorization(IP, typeBlockIP, HostConvert);

            //
            Trigger.OnUnlock2FA((IP, userAgent, referer, DomainID, method, HostConvert, uri, password, false));

            // Отдаем результат
            return(Json(new Models.Response.Text("Неверный пароль")));
        }
Пример #6
0
 public JsonResult Base(string value, string Description, int BlockingTimeDay, TypeBlockIP typeBlockIP)
 {
     return(new SecurityToIPtablesController().Add(value, Description, BlockingTimeDay, IsAPI: true, typeBlockIP: typeBlockIP));
 }
Пример #7
0
 public JsonResult Domain(string host, BruteForceType bruteForceType, Protection Protect, TypeBlockIP typeBlockIP = TypeBlockIP.global, string auth2faToPasswd = null)
 {
     return(new RequestsFilterToDomainBaseController().Save(new Domain()
     {
         host = host,
         Protect = Protect,
         typeBlockIP = typeBlockIP,
         StopBruteForce = bruteForceType,
         Auth2faToPasswd = auth2faToPasswd
     }));
 }
Пример #8
0
        /// <summary>
        /// Заблокировать IPv4/6
        /// </summary>
        /// <param name="IP">IPv4/6</param>
        /// <param name="target">Цель</param>
        /// <param name="data">Время и причина блокировки</param>
        public static void AddIPv4Or6(string IP, ModelIPtables data, TypeBlockIP target, string BlockedHost = null)
        {
            if (target == TypeBlockIP.domain)
            {
                memoryCache.Set(KeyToMemoryCache.IPtables(IP, BlockedHost), data, data.TimeExpires);
                Trigger.OnAddIPv4Or6((IP, BlockedHost, data.Description, data.TimeExpires));
            }
            else if (target != TypeBlockIP.UserAgent)
            {
                if (IPNetwork.CheckingSupportToIPv4Or6(IP, out var ipnetwork))
                {
                    // Крон нужно запустить раньше
                    if (NextTimeClearDbAndCacheToIPv4Or6 > data.TimeExpires)
                    {
                        NextTimeClearDbAndCacheToIPv4Or6 = data.TimeExpires;
                    }

                    // IPv6
                    if (IP.Contains(":"))
                    {
                        string IPv6 = IPNetwork.IPv6ToRegex(ipnetwork.FirstUsable);

                        // Время и причина блокировки
                        IPv6ToModels.AddOrUpdate(IPv6, data, (s, e) => data);
                        Trigger.OnAddIPv4Or6((IP, BlockedHost, data.Description, data.TimeExpires));

                        #region Обновляем IPv6ToRegex
                        if (IPv6ToRegex == "^$")
                        {
                            IPv6ToRegex = $"^({IPv6})";
                        }
                        else
                        {
                            IPv6ToRegex = Regex.Replace(IPv6ToRegex, @"\)$", $"|{IPv6})");
                        }
                        #endregion
                    }

                    // IPv4
                    else
                    {
                        if (IPNetwork.IPv4ToRange(ipnetwork.FirstUsable, ipnetwork.LastUsable) is var item && item.FirstUsable != 0)
                        {
                            #region Находим число которое выше FirstUsable и ставим FirstUsable перед ним
                            int index = IPv4ToRange.FindIndex(0, IPv4ToRange.Count, i => i.FirstUsable > item.FirstUsable);

                            if (index == -1)
                            {
                                IPv4ToRange.Add(item);
                            }
                            else
                            {
                                IPv4ToRange.Insert(index, item);
                            }
                            #endregion

                            // Время и причина блокировки
                            IPv4ToModels.AddOrUpdate(item.FirstUsable, data, (s, e) => data);
                            Trigger.OnAddIPv4Or6((IP, BlockedHost, data.Description, data.TimeExpires));
                        }
                    }
                }
            }
        }