Ejemplo n.º 1
0
        async public Task <JsonResult> LimitRequest(string recaptchaKey, string IP, int ExpiresToMinute, string hash)
        {
            if (string.IsNullOrWhiteSpace(recaptchaKey))
            {
                return(Json(new Text("recaptchaKey == null")));
            }

            if (hash != md5.text($"{IP}{ExpiresToMinute}:{PasswdTo.salt}"))
            {
                return(Json(new Text("hash error")));
            }

            // Проверяем reCAPTCHA
            if (await Recaptcha.Verify(recaptchaKey, jsonDB.Base.reCAPTCHASecret))
            {
                // Создаем кеш
                memoryCache.Set(KeyToMemoryCache.LimitRequestToreCAPTCHA(IP), (0, ExpiresToMinute), TimeSpan.FromMinutes(ExpiresToMinute));

                // Отдаем ответ
                return(Json(new TrueOrFalse(true)));
            }

            // Ошибка
            return(Json(new Text("Verify == false")));
        }
Ejemplo n.º 2
0
        public JsonResult Remove(int Id)
        {
            #region Демо режим
            if (Platform.IsDemo)
            {
                return(Json(new Text("Операция недоступна в демо-режиме")));
            }
            #endregion

            // Удаляем домен
            if (coreDB.WhitePtrIPs.FindItem(i => i.Id == Id) is WhitePtrIP item)
            {
                // Удаляем IP в кеше
                memoryCache.Remove(KeyToMemoryCache.WhitePtrIP(item.IPv4Or6));

                //
                ISPCore.Models.Triggers.Events.Base.SqlAndCache.WhitePtrIP.OnRemove((item.IPv4Or6, item.PTR));

                // Удаляем запись в SQL
                coreDB.WhitePtrIPs.Remove(item);
                coreDB.SaveChanges();

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

            // Ошибка
            return(Json(new Text("Ошибка ;(")));
        }
Ejemplo n.º 3
0
        public JsonResult Open(string host, string IP, int AccessTimeToMinutes, AccessType accessType)
        {
            #region Демо режим
            if (Platform.IsDemo)
            {
                return(Json(new Modal("Операция недоступна в демо-режиме")));
            }
            #endregion

            // Проверка IP
            if (string.IsNullOrWhiteSpace(IP) || (!IP.Contains(".") && !IP.Contains(":")) || (IP.Contains(".") && !Regex.IsMatch(IP, @"^[0-9]+\.[0-9]+\.[0-9]+\.([0-9]+|\*)$")))
            {
                return(Json(new Modal("Поле 'IP-адрес' имеет недопустимое значение")));
            }

            // ППроверка домена
            if (accessType != AccessType.allDomain && string.IsNullOrWhiteSpace(host))
            {
                return(Json(new Modal("Поле 'Домен' не может быть пустым")));
            }

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

            // Достаем IMemoryCache
            var memoryCache = Service.Get <IMemoryCache>();

            // Добавляем данные в список разрешенных IP, для вывода информации и отмены доступа
            AccessIP.Add(IP, accessType == AccessType.allDomain ? "все домены" : host, DateTime.Now.AddMinutes(AccessTimeToMinutes), accessType);

            // IP для кеша
            string ipCache = IP.Replace(".*", "").Replace(":*", "");

            // Добовляем IP в белый список
            switch (accessType)
            {
            case AccessType.all:
                memoryCache.Set(KeyToMemoryCache.CheckLinkWhitelistToAll(host, ipCache), (byte)1, TimeSpan.FromMinutes(AccessTimeToMinutes));
                break;

            case AccessType.Is2FA:
                memoryCache.Set(KeyToMemoryCache.CheckLinkWhitelistTo2FA(host, ipCache), (byte)1, TimeSpan.FromMinutes(AccessTimeToMinutes));
                break;

            case AccessType.allDomain:
                memoryCache.Set(KeyToMemoryCache.CheckLinkWhitelistToAllDomain(ipCache), (byte)1, TimeSpan.FromMinutes(AccessTimeToMinutes));
                break;
            }

            // Отдаем ответ
            return(Json(new Modal($"Разрешен доступ для '{IP}' на {AccessTimeToMinutes} {EndOfText.get("минуту", "минуты", "минут", AccessTimeToMinutes)}", true)));
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Получить html для AntiBot
        /// </summary>
        /// <param name="tplName">Имя шаблона</param>
        /// <param name="conf">Настройки AntiBot</param>
        /// <param name="CoreApiUrl">Ссылка на /core/</param>
        /// <param name="IP">IPv4/6</param>
        /// <param name="HostConvert">Домен</param>
        /// <param name="reCAPTCHASitekey">Секретный ключ reCAPTCHA</param>
        /// <param name="CacheAntiBot">Кеширование ответа</param>
        /// <param name="AntiBotHashKey">Дополнительный хеш для проверки "SignalR/JS"</param>
        static string Html(AntiBotType tplName, AntiBotBase conf, string CoreApiUrl, string IP, string HostConvert, string reCAPTCHASitekey, int CacheAntiBot, string AntiBotHashKey)
        {
            #region Базовые параметры
            string tplToUrl = string.Empty;
            var    mass     = new Dictionary <string, string>();
            mass.Add("IP", IP);
            mass.Add("CoreApiUrl", CoreApiUrl);
            mass.Add("HourCacheToUser", conf.HourCacheToUser.ToString());
            mass.Add("WaitUser", conf.WaitUser.ToString());
            mass.Add("AddCodeToHtml", conf.AddCodeToHtml != null ? conf.AddCodeToHtml : string.Empty);
            mass.Add("JsToRewriteUser", JsToRewriteUser(conf.RewriteToOriginalDomain, HostConvert));
            #endregion

            #region Хеш и куки
            switch (tplName)
            {
            case AntiBotType.SignalR:
                mass.Add("host", HostConvert);
                mass.Add("AntiBotHashKey", AntiBotHashKey);
                mass.Add("HashToSignalR", md5.text($"{IP}:{HostConvert}:{conf.HourCacheToUser}:{AntiBotHashKey}:{PasswdTo.salt}"));
                tplToUrl = File.Exists($"{Folders.Tpl.AntiBot}/{tplName}.html") ? "/statics/tpl/AntiBot/SignalR.html" : "/statics/tpl/AntiBot/default/SignalR.html";
                break;

            case AntiBotType.reCAPTCHA:
                mass.Add("reCAPTCHASitekey", reCAPTCHASitekey);
                mass.Add("HashToreCAPTCHA", md5.text($"{IP}:{conf.HourCacheToUser}:{PasswdTo.salt}"));
                tplToUrl = File.Exists($"{Folders.Tpl.AntiBot}/{tplName}.html") ? "/statics/tpl/AntiBot/reCAPTCHA.html" : "/statics/tpl/AntiBot/default/reCAPTCHA.html";
                break;

            case AntiBotType.CookieAndJS:
                string cookie = GetValidCookie(conf.HourCacheToUser, IP, "js", AntiBotHashKey);
                mass.Add("ValidCookie", cookie);
                mass.Add("AntiBotHashKey", AntiBotHashKey);
                Trigger.OnSetValidCookie((IP, HostConvert, cookie, "js", conf.HourCacheToUser));
                tplToUrl = File.Exists($"{Folders.Tpl.AntiBot}/{tplName}.html") ? "/statics/tpl/AntiBot/CookieAndJS.html" : "/statics/tpl/AntiBot/default/CookieAndJS.html";
                break;
            }
            #endregion

            // Сериализуем данные
            string json = JsonConvert.SerializeObject(mass);

            #region Создаем кеш
            if (CacheAntiBot != 0)
            {
                //IMemoryCache
                var memoryCache = Service.Get <IMemoryCache>();
                memoryCache.Set(KeyToMemoryCache.AntiBotToCache(IP), (tplToUrl, json, tplName), TimeSpan.FromMilliseconds(CacheAntiBot));
            }
            #endregion

            // Успех
            return(Html(tplToUrl, json));
        }
Ejemplo n.º 5
0
        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));
        }
Ejemplo n.º 6
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));
            }
        }
Ejemplo n.º 7
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));
        }
Ejemplo n.º 8
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));
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 9
0
        public IActionResult Index(int Id, bool ajax)
        {
            ViewData["Id"]   = Id;
            ViewData["ajax"] = ajax;

            // Статистика запросов за прошлую минуту
            if (!memoryCache.TryGetValue(KeyToMemoryCache.IspNumberOfRequestToMinutes(DateTime.Now.AddMinutes(-1)), out IDictionary <string, NumberOfRequestMinute> NumberOfRequestsPerMinute))
            {
                NumberOfRequestsPerMinute = new Dictionary <string, NumberOfRequestMinute>();
            }

            // Настройки домена
            var domain = FindAndInclude(coreDB.RequestsFilter_Domains.AsNoTracking(), Id);

            ViewBag.host = domain.host;

            // Список алиасов
            List <AliasView> Aliases = new List <AliasView>();

            // Alias To AliasView
            foreach (var alias in domain.Aliases)
            {
                // Base Alias
                var model = new AliasView()
                {
                    DomainId = alias.DomainId,
                    Folder   = alias.Folder,
                    host     = alias.host,
                    Id       = alias.Id
                };

                // Количество запросов для алиаса
                if (NumberOfRequestsPerMinute.TryGetValue(alias.host, out NumberOfRequestMinute dt))
                {
                    model.ReqToMinute = dt.NumberOfRequest;
                }

                Aliases.Add(model);
            }

            // Выводим результат
            return(View("~/Views/RequestsFilter/Domain/Aliases.cshtml", Aliases.OrderByDescending(i => i.ReqToMinute)));
        }
Ejemplo n.º 10
0
        public static bool CheckIP(string RemoteIpAddress, IMemoryCache memoryCache, out IPtables data, string BlockedHost = null)
        {
            string[] mass;
            string   patch, tmp = "";

            // IPv6
            if (RemoteIpAddress.Contains(":"))
            {
                mass  = RemoteIpAddress.Split(':');
                patch = ":";
            }

            // IPv4
            else
            {
                mass  = RemoteIpAddress.Split('.');
                patch = ".";
            }

            // Проверяем IP в кеше
            foreach (var ip in mass)
            {
                tmp += patch + ip;
                if (BlockedHost == null)
                {
                    if (memoryCache.TryGetValue(KeyToMemoryCache.IPtables(tmp.Remove(0, 1)), out data))
                    {
                        return(true);
                    }
                }
                else
                {
                    if (memoryCache.TryGetValue(KeyToMemoryCache.IPtables(tmp.Remove(0, 1), BlockedHost), out data))
                    {
                        return(true);
                    }
                }
            }

            data = new IPtables();
            return(false);
        }
Ejemplo n.º 11
0
        async public Task <JsonResult> LimitRequest(string recaptchaKey, string IP, int ExpiresToMinute, string hash)
        {
            var res = await Verify(recaptchaKey, IP, ExpiresToMinute, hash);

            if (res.res)
            {
                // Создаем кеш
                memoryCache.Set(KeyToMemoryCache.LimitRequestToreCAPTCHA(IP), (0, ExpiresToMinute), TimeSpan.FromMinutes(ExpiresToMinute));

                //
                Trigger.LimitRequest.OnRecaptchaVerify((true, IP, HttpContext.Request.Host.Host, ExpiresToMinute));

                // Отдаем ответ
                return(Json(new TrueOrFalse(true)));
            }

            // Ошибка
            Trigger.LimitRequest.OnRecaptchaVerify((false, IP, HttpContext.Request.Host.Host, ExpiresToMinute));
            return(Json(res.ob));
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Выполнить запрос в API
        /// </summary>
        /// <param name="uriPath">/add/requests-filter/aliases</param>
        /// <param name="args">"DomainId=1", "aliases[1].host=test.com"</param>
        public string API(string uriPath, params string[] args)
        {
            try
            {
                using (HttpClient client = new HttpClient())
                {
                    // Уникальный ключ
                    string apiKey = Generate.Passwd(24);

                    // Добавляем ключ в память
                    var memoryCache = Service.Get <IMemoryCache>();
                    memoryCache.Set(KeyToMemoryCache.ApiToLocalKey(apiKey), (byte)0, TimeSpan.FromSeconds(90));

                    // Отправляем запрос в API
                    client.DefaultRequestHeaders.Add("ApiKey", apiKey);
                    string arg = args.Length > 0 ? $"?{String.Join('&', args)}" : string.Empty;
                    return(client.GetStringAsync($"http://127.0.0.1:4538/api{uriPath}{arg}").Result);
                }
            }
            catch (Exception ex) { return(ex.ToString()); }
        }
Ejemplo n.º 13
0
        public JsonResult Remove(string IP, string host, AccessType accessType)
        {
            #region Демо режим
            if (Platform.IsDemo)
            {
                return(Json(new Text("Операция недоступна в демо-режиме")));
            }
            #endregion

            // Удаляем IP из списка
            AccessIP.Remove(IP, host, accessType);

            // Достаем IMemoryCache
            var memoryCache = Service.Get <IMemoryCache>();

            // IP для кеша
            string ipCache = IP.Replace(".*", "").Replace(":*", "");

            // Удаляем запись с кеша
            switch (accessType)
            {
            case AccessType.all:
                memoryCache.Remove(KeyToMemoryCache.CheckLinkWhitelistToAll(host, ipCache));
                break;

            case AccessType.Is2FA:
                memoryCache.Remove(KeyToMemoryCache.CheckLinkWhitelistTo2FA(host, ipCache));
                break;

            case AccessType.allDomain:
                memoryCache.Remove(KeyToMemoryCache.CheckLinkWhitelistToAllDomain(ipCache));
                break;
            }

            // Отдаем результат
            return(Json(new TrueOrFalse(true)));
        }
Ejemplo n.º 14
0
        public JsonResult Remove(int Id)
        {
            #region Демо режим
            if (Platform.IsDemo)
            {
                return(Json(new Text("Операция недоступна в демо-режиме")));
            }
            #endregion

            // Поиск ip
            var item = coreDB.BlockedsIP.Find(Id);
            if (item == null)
            {
                return(Json(new Text("Запись не найдена")));
            }

            string IP = item.IP.Replace(".*", "").Replace(":*", "");

            // Удаляем IP с кеша
            memoryCache.Remove(KeyToMemoryCache.IPtables(IP));
            memoryCache.Remove(KeyToMemoryCache.IPtables(IP, item.BlockedHost));

            // Удаляем IP
            coreDB.BlockedsIP.Remove(item);

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

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

            // Отдаем результат
            return(Json(new TrueOrFalse(true)));
        }
Ejemplo n.º 15
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>")));
        }
Ejemplo n.º 16
0
        public static Task View(HttpContext context, ViewBag viewBag, ActionCheckLink Model, TypeRequest typeResponse, bool NotCache = false)
        {
            #region Код ответа
            if (viewBag.IsErrorRule)
            {
                context.Response.StatusCode = 500;
            }
            else
            {
                switch (Model)
                {
                case ActionCheckLink.allow:
                {
                    context.Response.StatusCode = 303;
                    break;
                }

                case ActionCheckLink.Is2FA:
                {
                    context.Response.StatusCode = 200;
                    break;
                }

                case ActionCheckLink.deny:
                {
                    context.Response.StatusCode = 403;
                    break;
                }

                default:
                {
                    context.Response.StatusCode = 500;
                    break;
                }
                }
            }
            #endregion

            // Данные ответа
            Trigger.OnResponseView((viewBag.IP, viewBag.UserAgent, viewBag.Referer, viewBag.DomainID, viewBag.method, viewBag.host, viewBag.uri, viewBag.FormData, context.Response.StatusCode, viewBag.IsCacheView));

            #region Локальный метод - "RenderTitle"
            string RenderTitle()
            {
                if (viewBag.IsErrorRule)
                {
                    return("Ошибка");
                }
                else
                {
                    switch (Model)
                    {
                    case ActionCheckLink.allow:
                        return("303");

                    case ActionCheckLink.deny:
                        return("Доступ запрещен");

                    case ActionCheckLink.Is2FA:
                        return("Aвторизация 2FA");

                    default:
                        return("Неизвестная ошибка");
                    }
                }
            }

            #endregion

            #region Локальный метод - "RenderScript"
            string RenderScript()
            {
                if (Model == ActionCheckLink.Is2FA)
                {
                    string hash = SHA256.Text($"{viewBag.host}:{viewBag.method}:{viewBag.uri}:{viewBag.Referer}:{PasswdTo.salt}");
                    return(@"
<script>
    function unlock(e)
    {
        e.preventDefault();
        document.getElementById('unlockError').style.display = 'none';

        var password = document.getElementById('unlockPassword').value;

        $.post('" + viewBag.CoreAPI + "/unlock/2fa', { password: password, host: '" + viewBag.host + "', method: '" + viewBag.method + "', uri: '" + WebUtility.UrlEncode(viewBag.uri) + "', referer: '" + WebUtility.UrlEncode(viewBag.Referer) + "', hash: '" + hash + @"' }, function (data)
        {
            var json = JSON.parse(JSON.stringify(data));

            if (json.msg) {
                document.getElementById('unlockError').style.display = 'block';
                document.getElementById('unlockError').innerText = json.msg;
            }
            else if (json.result) {
                window.location.reload();
            }
            else {
                document.getElementById('unlockError').style.display = 'block';
                document.getElementById('unlockError').innerText = 'Неизвестная ошибка';
            }
        })
    }
</script>");
                }

                return(string.Empty);
            }

            #endregion

            #region Локальный метод - "RenderBody"
            string RenderBody()
            {
                if (viewBag.IsErrorRule)
                {
                    return(@"<div class='code'>500</div>
                    <div class='title'>" + viewBag.ErrorTitleException + @"</div>
                    <pre>" + viewBag.ErrorRuleException + @"</pre>");
                }
                else if (Model == ActionCheckLink.Is2FA)
                {
                    return(@"<div class='code'>2FA</div>
                    <div class='title'>Aвторизация</div>
                    <pre>Введите пароль безопасности для 2FA</pre>

                    <form method='post' action='/' onsubmit='unlock(event)'>
                        <div class='form-group'>
                            <div class='input-group form'>
                                <span class='input-group-addon'><i class='fa fa-lock'></i></span>
                                <input class='form-control' id='unlockPassword' type='password' name='password'>
                            </div>

                            <button type='submit' class='btn-unlock'>Unlock</button>

                            <div id='unlockError' class='errorMsg'>eroror</div>
                        </div>
                    </form>");
                }
                else if (Model == ActionCheckLink.allow)
                {
                    return(@"<div class='code'>303</div>
                    <div class='title'>Отправить в backend</div>");
                }

                else if (Model == ActionCheckLink.deny)
                {
                    return(@"<div class='code'>403</div>
                    <div class='title'>Доступ запрещен</div>");
                }

                else
                {
                    return(@"<div class='code'>500</div>
                    <div class='title'>Неизвестная ошибка</div>");
                }
            }

            #endregion

            #region Локальный метод - "RenderDebug"
            string RenderDebug()
            {
                if (viewBag.DebugEnabled)
                {
                    #region jsonDomain
                    string jsonDomain()
                    {
                        if (viewBag.jsonDomain == null)
                        {
                            return(string.Empty);
                        }

                        return(Regex.Replace(viewBag.jsonDomain.Replace("\\\\", "\\"), "(<!--|-->|\"Auth2faToPasswd\": \"[^\"]+\")", r =>
                        {
                            switch (r.Groups[1].Value)
                            {
                            case "<!--":
                                return "&lt;!--";

                            case "-->":
                                return "--&gt;";

                            default:
                                {
                                    if (r.Groups[1].Value.StartsWith("\"Auth2faToPasswd\":"))
                                    {
                                        return "\"Auth2faToPasswd\": \"Используется\"";
                                    }
                                }
                                break;
                            }

                            return r.Groups[1].Value;
                        }));
                    }

                    #endregion

                    return(@"
<!--
IP:          " + viewBag?.IP + @"
UserAgent:   " + viewBag?.UserAgent + @"
method:      " + viewBag?.method + @"
host:        " + viewBag?.host + @"
uri:         " + viewBag?.uri + @"
FormData:    " + viewBag?.FormData + @"
Referer:     " + viewBag?.Referer + @"
IsCacheView: " + viewBag.IsCacheView + @"

" + viewBag.antiBotToGlobalConf?.Replace("\\\\", "\\")?.Replace("<!--", "&lt;!--")?.Replace("-->", "--&gt;") + @"


" + jsonDomain() + @"
-->
");
                }

                return(string.Empty);
            }

            #endregion

            #region Кешируем ответ
            if (jsonDB.Cache.Checklink != 0 && !NotCache && !viewBag.IsCacheView && context.Response.StatusCode != 200)
            {
                memoryCache.Set(KeyToMemoryCache.CheckLinkToCache(viewBag.method, viewBag.host, viewBag.uri), new ResponseView()
                {
                    ActionCheckLink = Model,
                    TypeResponse    = typeResponse,
                    IsErrorRule     = viewBag.IsErrorRule,
                    CacheTime       = viewBag.CreateCacheView
                }, TimeSpan.FromMilliseconds(jsonDB.Cache.Checklink));
            }
            #endregion

            #region Ответ без html
            if (!jsonDB.Base.DebugEnabled)
            {
                // Отдавать html ненужно
                if (context.Response.StatusCode == 303 || (Startup.cmd.StatusCode.Checklink && context.Response.StatusCode != 200))
                {
                    return(Task.FromResult(true));
                }
            }
            #endregion

            // Html ответ
            return(context.Response.WriteAsync(@"<!DOCTYPE html>
<html lang='ru-RU'>
<head>
    <title>" + RenderTitle() + @"</title>
    <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
    <meta http-equiv='X-UA-Compatible' content='IE=edge'>
    <meta name='viewport' content='width=device-width, initial-scale=1, user-scalable=no'>
    <link rel='stylesheet' href='/statics/style.css'>
    " + (Model == ActionCheckLink.Is2FA ? "<script type='text/javascript' src='/statics/jquery.min.js'></script>" : string.Empty) + @"
</head>
<body>

" + RenderScript() + @"

    <div class='error'>
        <div class='error-block'>

            " + RenderBody() + @"

            <div class='copyright'>
                <div>
                    &copy; 2018 <strong>ISPCore</strong>. All rights reserved.
                </div>
                <div>
                    <a href='/'>Главная сайта</a> / <a href='http://core-system.org/' target='_blank'>Core System</a>
                </div>
            </div>
        </div>
    </div>
</body>
</html>

" + RenderDebug() + @"
", context.RequestAborted));
        }
Ejemplo n.º 17
0
        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;
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Успешнная авторизация
        /// </summary>
        /// <param name="memoryCache"></param>
        /// <param name="RemoteIpAddress">IP адрес пользователя</param>
        public static void SuccessAuthorization(string RemoteIpAddress)
        {
            var memoryCache = Service.Get <IMemoryCache>();

            memoryCache.Remove(KeyToMemoryCache.LimitLogin(RemoteIpAddress));
        }
Ejemplo n.º 19
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));
                        }
                    }
                }
            }
        }
Ejemplo n.º 20
0
        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));
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Проверка запроса
        /// </summary>
        /// <param name="IP">IPv4/6</param>
        /// <param name="antiBotType">Cпособ проверки</param>
        /// <param name="HostConvert">Домен</param>
        /// <param name="method">Метод запроса</param>
        /// <param name="uri">Url запроса</param>
        /// <param name="HttpContext">Используется для проверки cookie</param>
        /// <param name="domain">Кеш настроек домена</param>
        /// <param name="DomainID">Id домена</param>
        /// <param name="outHtml">html для вывода пользователю</param>
        public static bool ValidRequest(string IP, AntiBotType antiBotType, string HostConvert, string method, string uri, HttpContext HttpContext, Models.core.Cache.CheckLink.Domain domain, int DomainID, out string outHtml)
        {
            // По умолчанию null
            outHtml = null;

            // Не выбран способ проверки
            if (antiBotType == AntiBotType.Off)
            {
                return(true);
            }

            #region Проверка Cookie
            if (IsValidCookie(HttpContext, IP, domain.AntiBot.HashKey, out string _verification))
            {
                Trigger.OnValidCookie((IP, HostConvert, DomainID, true, _verification));
                return(true);
            }
            else
            {
                Trigger.OnValidCookie((IP, HostConvert, DomainID, false, _verification));
            }
            #endregion

            // IMemoryCache
            var memoryCache = Service.Get <IMemoryCache>();

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

            #region Отдаем данные с кеша
            if (jsonDB.Cache.AntiBot != 0 && memoryCache.TryGetValue(KeyToMemoryCache.AntiBotToCache(IP), out (string tplToUrl, string json, AntiBotType type)_cache))
            {
                outHtml = Html(_cache.tplToUrl, _cache.json);
                Trigger.OnResponseView((IP, HostConvert, DomainID, _cache.type));
                return(false);
            }
            #endregion

            // Достаем настройки AntiBot из кеша
            var antiBotToGlobalConf = GlobalConf(jsonDB.AntiBot);

            #region Проверка User-Agent
            if (HttpContext.Request.Headers.TryGetValue("User-Agent", out var userAgent))
            {
                // Проверка пользовательского User-Agent
                if (WhiteUserList.IsWhiteUserAgent(userAgent))
                {
                    return(true);
                }

                string SearchBot = "(" +
                                   // https://yandex.ru/support/webmaster/robot-workings/check-yandex-robots.html
                                   "YandexBot|YandexAccessibilityBot|YandexMobileBot|YandexDirectDyn|YandexScreenshotBot|YandexImages|YandexVideo|YandexVideoParser|YandexMedia|YandexBlogs|YandexFavicons|YandexWebmaster|YandexPagechecker|YandexImageResizer|YandexAdNet|YandexDirect|YaDirectFetcher|YandexCalendar|YandexSitelinks|YandexMetrika|YandexNews|YandexCatalog|YandexMarket|YandexVertis|YandexForDomain|YandexSpravBot|YandexSearchShop|YandexMedianaBot|YandexOntoDB|YandexVerticals" +
                                   "|" +
                                   // https://support.google.com/webmasters/answer/1061943
                                   "APIs-Google|Mediapartners-Google|AdsBot-Google|Googlebot" +
                                   "|" +
                                   // https://help.mail.ru/webmaster/indexing/robots/robot_log
                                   // https://www.bing.com/webmaster/help/how-to-verify-bingbot-3905dc26
                                   "Mail.RU_Bot|Bingbot|msnbot" +
                                   ")";

                // Проверка User-Agent на поискового бота
                if (Regex.IsMatch(userAgent, SearchBot, RegexOptions.IgnoreCase))
                {
                    #region Локальный метод - "DNSLookup"
                    bool DNSLookup()
                    {
                        string ptr    = null;
                        string memKey = $"local-fb23a52e:DNSLookup-{IP}";

                        if (memoryCache.TryGetValue(memKey, out bool _cacheToDNSLookup))
                        {
                            return(_cacheToDNSLookup);
                        }

                        // Создаем временный кеш на время проверки
                        memoryCache.Set(memKey, true, TimeSpan.FromMinutes(5));

                        try
                        {
                            // Получаем имя хоста по IP
                            var host = Dns.GetHostEntryAsync(IP).Result;

                            // Получаем IP хоста по имени
                            host = Dns.GetHostEntryAsync(host.HostName).Result;

                            // Сохраняем PTR
                            ptr = host.HostName;

                            // Проверяем имя хоста и IP на совпадение
                            if (host.AddressList.Where(i => i.ToString() == IP).FirstOrDefault() != null)
                            {
                                // Проверяем имя хоста на белый список DNSLookup
                                if (Regex.IsMatch(host.HostName, @".*\.(yandex.(ru|net|com)|googlebot.com|google.com|mail.ru|search.msn.com)$", RegexOptions.IgnoreCase))
                                {
                                    // Добовляем IP в белый
                                    int HourCacheToBot = IsGlobalConf() ? antiBotToGlobalConf.conf.HourCacheToBot : domain.AntiBot.HourCacheToBot;
                                    WhitePtr.Add(IP, host.HostName, DateTime.Now.AddHours(HourCacheToBot));
                                    Trigger.OnAddToWhitePtr((IP, HostConvert, DomainID, ptr, HourCacheToBot));
                                    return(true);
                                }
                            }
                        }
                        catch { }

                        // Записываем IP в кеш IPtables и журнал
                        if (Check.Request.SetBlockedToIPtables(domain, IP, HostConvert, "AntiBot", DateTime.Now.AddMinutes(40), uri, userAgent, ptr))
                        {
                            Trigger.OnBlockedIP((IP, ptr, HostConvert, DomainID, "AntiBot", 40));
                        }

                        // Не удалось проверить PTR-запись
                        memoryCache.Remove(memKey);
                        return(false);
                    }

                    #endregion

                    #region  ежим проверки поискового бота
                    if (IsGlobalConf() ? antiBotToGlobalConf.conf.FirstSkipToBot : domain.AntiBot.FirstSkipToBot)
                    {
                        // Проверяем DNSLookup в потоке
                        ThreadPool.QueueUserWorkItem(i => DNSLookup());
                    }
                    else
                    {
                        // Плохой бот
                        if (!DNSLookup())
                        {
                            outHtml = "Не удалось проверить PTR-запись";
                            return(false);
                        }
                    }
                    #endregion

                    // Бот может зайти на сайт
                    return(true);
                }
            }
            #endregion

            // Нужна капча или нет
            bool IsRecaptcha = antiBotType == AntiBotType.reCAPTCHA;

            // Если капча установлена глобально, то нужно проверить домен в списке
            if (IsRecaptcha && IsGlobalConf() && antiBotToGlobalConf.conf.type == AntiBotType.reCAPTCHA)
            {
                IsRecaptcha = Regex.IsMatch(HostConvert, antiBotToGlobalConf.DomainsToreCaptchaRegex, RegexOptions.IgnoreCase);
            }

            // Выбираем настройки какого конфига использовать
            AntiBotBase antiBotConf = IsGlobalConf() ? (AntiBotBase)antiBotToGlobalConf.conf : (AntiBotBase)domain.AntiBot;

            #region Проверка пользователя в фоновом режиме
            if (antiBotConf.BackgroundCheck)
            {
                // Ключ для проверки запросов
                string memKey = $"Core:AntiBot/CountBackgroundRequest-{IP}";

                if (method != "GET" && method != "HEAD")
                {
                    // Если до этого был GET/HEAD запрос
                    if (memoryCache.TryGetValue(memKey, out _))
                    {
                        return(true);
                    }
                }
                else
                {
                    int CountBackgroundRequest;
                    if (!memoryCache.TryGetValue(memKey, out CountBackgroundRequest))
                    {
                        CountBackgroundRequest = 0;
                    }

                    // Пользователь не привысил значение
                    if (antiBotConf.CountBackgroundRequest > CountBackgroundRequest)
                    {
                        // Увеличиваем количиство запросов
                        if (!uri.Contains(".") || Regex.IsMatch(uri, antiBotConf.BackgroundCheckToAddExtensions, RegexOptions.IgnoreCase))
                        {
                            // Записываем/Перезаписываем количиство запросов
                            memoryCache.Set(memKey, ++CountBackgroundRequest, TimeSpan.FromHours(antiBotConf.BackgroundHourCacheToIP));
                        }

                        // Без заглушки AntiBot
                        return(true);
                    }
                }
            }
            #endregion


            // reCAPTCHA, SignalR или JavaScript
            var tplName = (!IsRecaptcha && antiBotType == AntiBotType.reCAPTCHA) ? AntiBotType.SignalR : antiBotType;
            outHtml = Html(tplName, antiBotConf, jsonDB.Base.CoreAPI, IP, HostConvert, jsonDB.Security.reCAPTCHASitekey, jsonDB.Cache.AntiBot, domain.AntiBot.HashKey);
            Trigger.OnResponseView((IP, HostConvert, DomainID, tplName));
            return(false);

            #region Локальный метод - "IsGlobalConf"
            bool IsGlobalConf()
            {
                return(antiBotToGlobalConf.conf.Enabled || domain.AntiBot.UseGlobalConf);
            }

            #endregion
        }
Ejemplo n.º 22
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("Неверный пароль")));
        }
Ejemplo n.º 23
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="antiBotType"></param>
        /// <param name="HostConvert"></param>
        /// <param name="method"></param>
        /// <param name="HttpContext"></param>
        /// <param name="domain"></param>
        /// <param name="outHtml"></param>
        public static bool ValidRequest(AntiBotType antiBotType, string HostConvert, string method, string uri, HttpContext HttpContext, Models.core.Cache.CheckLink.Domain domain, out string outHtml)
        {
            // По умолчанию null
            outHtml = null;

            // Не выбран способ проверки
            if (antiBotType == AntiBotType.Off)
            {
                return(true);
            }

            //IMemoryCache
            var memoryCache = Service.Get <IMemoryCache>();

            // IP адрес
            string IP = HttpContext.Connection.RemoteIpAddress.ToString();

            // Проверка Cookie
            if (IsValidCookie(HttpContext, IP))
            {
                return(true);
            }

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

            // Достаем настройки AntiBot из кеша
            var antiBotToGlobalConf = GlobalConf(jsonDB.AntiBot);

            #region Проверка User-Agent
            string SearchBot = "(" +
                               // https://yandex.ru/support/webmaster/robot-workings/check-yandex-robots.html
                               "YandexBot|YandexAccessibilityBot|YandexMobileBot|YandexDirectDyn|YandexScreenshotBot|YandexImages|YandexVideo|YandexVideoParser|YandexMedia|YandexBlogs|YandexFavicons|YandexWebmaster|YandexPagechecker|YandexImageResizer|YandexAdNet|YandexDirect|YaDirectFetcher|YandexCalendar|YandexSitelinks|YandexMetrika|YandexNews|YandexCatalog|YandexMarket|YandexVertis|YandexForDomain|YandexSpravBot|YandexSearchShop|YandexMedianaBot|YandexOntoDB|YandexVerticals" +
                               "|" +
                               // https://support.google.com/webmasters/answer/1061943
                               "APIs-Google|Mediapartners-Google|AdsBot-Google|Googlebot" +
                               "|" +
                               // https://help.mail.ru/webmaster/indexing/robots/robot_log
                               // https://www.bing.com/webmaster/help/how-to-verify-bingbot-3905dc26
                               "Mail.RU_Bot|Bingbot|msnbot" +
                               ")";

            // Достаем User-Agent
            if (HttpContext.Request.Headers.TryGetValue("User-Agent", out var userAgent))
            {
                // Проверка User-Agent на поискового бота
                if (Regex.IsMatch(userAgent, SearchBot, RegexOptions.IgnoreCase))
                {
                    #region Локальный метод - "DNSLookup"
                    bool DNSLookup()
                    {
                        try
                        {
                            // Получаем имя хоста по IP
                            var host = Dns.GetHostEntryAsync(IP).Result;

                            // Получаем IP хоста по имени
                            host = Dns.GetHostEntryAsync(host.HostName).Result;

                            // Проверяем имя хоста и IP на совпадение
                            if (host.AddressList.Where(i => i.ToString() == IP).FirstOrDefault() != null)
                            {
                                // Проверяем имя хоста на белый список DNSLookup
                                if (Regex.IsMatch(host.HostName, @".*\.(yandex.(ru|net|com)|googlebot.com|google.com|mail.ru|search.msn.com)$", RegexOptions.IgnoreCase))
                                {
                                    // Добовляем IP в белый
                                    WhitePtr.Add(IP, DateTime.Now.AddHours(IsGlobalConf() ? antiBotToGlobalConf.conf.HourCacheToBot : domain.AntiBot.HourCacheToBot));
                                    return(true);
                                }
                            }
                        }
                        catch { }

                        #region  Блокируем IP и записываем в журнал
                        // Данные для статистики
                        Check.Request.SetCountRequestToHour(TypeRequest._401, HostConvert, domain.confToLog.EnableCountRequest);

                        // Информация по блокировке
                        DateTime Expires = DateTime.Now.AddMinutes(40);
                        string   Msg     = "AntiBot";

                        // Записываем IP в кеш IPtables
                        memoryCache.Set(KeyToMemoryCache.IPtables(IP, HostConvert), new IPtables(Msg, Expires), Expires);

                        // Дублируем информацию в SQL
                        WriteLogTo.SQL(new BlockedIP()
                        {
                            IP           = IP,
                            BlockingTime = Expires,
                            Description  = Msg,
                            typeBlockIP  = TypeBlockIP.domain,
                            BlockedHost  = HostConvert
                        });

                        // Лог запроса
                        if (domain.confToLog.IsActive)
                        {
                            var geoIP = (Country : "Disabled", City : "Disabled", Region : "Disabled");
                            if (domain.confToLog.EnableGeoIP)
                            {
                                geoIP = GeoIP2.City(IP);
                            }

                            // Модель
                            Jurnal401 model = new Jurnal401()
                            {
                                Host      = HostConvert,
                                IP        = IP,
                                Msg       = Msg,
                                Ptr       = null,
                                UserAgent = userAgent,
                                Country   = geoIP.Country,
                                City      = geoIP.City,
                                Region    = geoIP.Region,
                                Time      = DateTime.Now
                            };

                            // Записываем данные в журнал
                            switch (domain.confToLog.Jurn401)
                            {
                            case WriteLogMode.File:
                                WriteLogTo.FileStream(model);
                                break;

                            case WriteLogMode.SQL:
                                WriteLogTo.SQL(model);
                                break;

                            case WriteLogMode.all:
                                WriteLogTo.SQL(model);
                                WriteLogTo.FileStream(model);
                                break;
                            }
                        }
                        #endregion

                        // Не удалось проверить PTR-запись
                        return(false);
                    }

                    #endregion

                    #region  ежим проверки поискового бота
                    if (IsGlobalConf() ? antiBotToGlobalConf.conf.FirstSkipToBot : domain.AntiBot.FirstSkipToBot)
                    {
                        // Проверяем DNSLookup в потоке
                        ThreadPool.QueueUserWorkItem(i => DNSLookup());
                    }
                    else
                    {
                        // Плохой бот
                        if (!DNSLookup())
                        {
                            outHtml = "Не удалось проверить PTR-запись";
                            return(false);
                        }
                    }
                    #endregion

                    // Бот может зайти на сайт
                    return(true);
                }

                // Достаем настройки WhiteList из кеша
                var whiteList = Engine.Base.SqlAndCache.WhiteList.GetCache(jsonDB.WhiteList);

                // Проверка пользовательского User-Agent
                if (Regex.IsMatch(userAgent, whiteList.UserAgentRegex, RegexOptions.IgnoreCase))
                {
                    return(true);
                }
            }
            #endregion

            // Нужна капча или нет
            bool IsRecaptcha = antiBotType == AntiBotType.reCAPTCHA;

            // Если капча установлена глобально, то нужно проверить домен в списке
            if (IsRecaptcha && IsGlobalConf() && antiBotToGlobalConf.conf.type == AntiBotType.reCAPTCHA)
            {
                IsRecaptcha = Regex.IsMatch(HostConvert, antiBotToGlobalConf.DomainsToreCaptchaRegex, RegexOptions.IgnoreCase);
            }

            // Выбираем настройки какого конфига использовать
            AntiBotBase antiBotConf = IsGlobalConf() ? (AntiBotBase)antiBotToGlobalConf.conf : (AntiBotBase)domain.AntiBot;

            #region Проверка пользователя в фоновом режиме
            if (antiBotConf.BackgroundCheck)
            {
                // Ключ для проверки запросов
                string memKey = $"Core:AntiBot/CountBackgroundRequest-{IP}";

                if (method != "GET")
                {
                    // Если до этого был GET запрос
                    if (memoryCache.TryGetValue(memKey, out _))
                    {
                        return(true);
                    }
                }
                else
                {
                    int CountBackgroundRequest;
                    if (!memoryCache.TryGetValue(memKey, out CountBackgroundRequest))
                    {
                        CountBackgroundRequest = 0;
                    }

                    // Пользователь не привысил значение
                    if (antiBotConf.CountBackgroundRequest > CountBackgroundRequest)
                    {
                        // Увеличиваем количиство запросов
                        if (!uri.Contains(".") || Regex.IsMatch(uri, antiBotConf.BackgroundCheckToAddExtensions, RegexOptions.IgnoreCase))
                        {
                            // Записываем/Перезаписываем количиство запросов
                            memoryCache.Set(memKey, ++CountBackgroundRequest, TimeSpan.FromHours(antiBotConf.BackgroundHourCacheToIP));
                        }

                        // Без заглушки AntiBot
                        return(true);
                    }
                }
            }
            #endregion


            // reCAPTCHA, SignalR или JavaScript
            var tplName = (!IsRecaptcha && antiBotType == AntiBotType.reCAPTCHA) ? AntiBotType.SignalR : antiBotType;
            outHtml = Html(tplName.ToString(), antiBotConf, jsonDB.Base.CoreAPI, IP, HostConvert, jsonDB.Base.reCAPTCHASitekey);
            return(false);

            #region Локальный метод - "IsGlobalConf"
            bool IsGlobalConf()
            {
                return(antiBotToGlobalConf.conf.Enabled || domain.AntiBot.UseGlobalConf);
            }

            #endregion
        }
Ejemplo n.º 24
0
        private string StatReguestToHours(string ShowHost = null)
        {
            // Данные для вывода статистики
            var DtNumberOfRequestDay = new Dictionary <int, NumberOfRequestBase>();

            #region Локальный метод - "AddToNumberOfRequestDay"
            void AddOrUdpateNumberOfRequestDay(string host, NumberOfRequestBase dt)
            {
                // Статистика не для текущего дня
                // Поиск по домену
                if (dt.Time.Day != DateTime.Now.Day || (ShowHost != null && ShowHost != host))
                {
                    return;
                }

                if (DtNumberOfRequestDay.TryGetValue(dt.Time.Hour, out NumberOfRequestBase item))
                {
                    // Добовляем данные к статистике
                    item.Count200      += dt.Count200;
                    item.Count303      += dt.Count303;
                    item.Count403      += dt.Count403;
                    item.Count401      += dt.Count401;
                    item.Count500      += dt.Count500;
                    item.Count2FA      += dt.Count2FA;
                    item.CountIPtables += dt.CountIPtables;
                }
                else
                {
                    // Записываем данные
                    DtNumberOfRequestDay.TryAdd(dt.Time.Hour, new NumberOfRequestBase()
                    {
                        Time          = dt.Time,
                        Count200      = dt.Count200,
                        Count303      = dt.Count303,
                        Count403      = dt.Count403,
                        Count401      = dt.Count401,
                        Count500      = dt.Count500,
                        Count2FA      = dt.Count2FA,
                        CountIPtables = dt.CountIPtables
                    });
                }
            }

            #endregion

            #region Статистика из базы за сутки
            foreach (var RequestToHour in coreDB.RequestsFilter_NumberOfRequestDay.AsNoTracking())
            {
                AddOrUdpateNumberOfRequestDay(RequestToHour.Host, RequestToHour);
            }
            #endregion

            #region Статистика из кеша за текущий час
            if (memoryCache.TryGetValue(KeyToMemoryCache.IspNumberOfRequestToHour(DateTime.Now), out IDictionary <string, NumberOfRequestHour> DataNumberOfRequestToHour))
            {
                foreach (var item in DataNumberOfRequestToHour)
                {
                    AddOrUdpateNumberOfRequestDay(item.Key, item.Value);
                }
            }
            #endregion

            #region Переменные для статистики
            string tmpBase     = "{x:'0:00',y:0},{x:'1:00',y:0},{x:'2:00',y:0},{x:'3:00',y:0},{x:'4:00',y:0},{x:'5:00',y:0},{x:'6:00',y:0},{x:'7:00',y:0},{x:'8:00',y:0},{x:'9:00',y:0},{x:'10:00',y:0},{x:'11:00',y:0},{x:'12:00',y:0},{x:'13:00',y:0},{x:'14:00',y:0},{x:'15:00',y:0},{x:'16:00',y:0},{x:'17:00',y:0},{x:'18:00',y:0},{x:'19:00',y:0},{x:'20:00',y:0},{x:'21:00',y:0},{x:'22:00',y:0},{x:'23:00',y:0}";
            string tmp200      = tmpBase;
            string tmp303      = tmpBase;
            string tmp403      = tmpBase;
            string tmp401      = tmpBase;
            string tmp500      = tmpBase;
            string tmp2FA      = tmpBase;
            string tmpIPtables = tmpBase;
            #endregion

            #region Обновляем переменные
            foreach (var dt in DtNumberOfRequestDay)
            {
                #region Локальный метод - "GeReplacet"
                string GeReplace(string s, long value)
                {
                    return(s.Replace("{x:'" + dt.Value.Time.Hour + ":00',y:0}", "{x:'" + dt.Value.Time.Hour + ":00',y:" + value + "}"));
                }

                #endregion

                tmp200      = GeReplace(tmp200, dt.Value.Count200);
                tmp303      = GeReplace(tmp303, dt.Value.Count303);
                tmp403      = GeReplace(tmp403, dt.Value.Count403);
                tmp401      = GeReplace(tmp401, dt.Value.Count401);
                tmpIPtables = GeReplace(tmpIPtables, dt.Value.CountIPtables);
                tmp500      = GeReplace(tmp500, dt.Value.Count500);
                tmp2FA      = GeReplace(tmp2FA, dt.Value.Count2FA);
            }
            #endregion

            #region Собираем json
            StringBuilder json = new StringBuilder();
            json.Append("{key: '200', nonStackable: false, shifting: false, values: [ " + tmp200 + " ] },");
            json.Append("{key: '303', nonStackable: false, shifting: false, values: [ " + tmp303 + " ] },");
            json.Append("{key: '403', nonStackable: false, shifting: false, values: [ " + tmp403 + " ] },");
            json.Append("{key: '401', nonStackable: false, shifting: false, values: [ " + tmp401 + " ] },");
            json.Append("{key: 'IPtables', nonStackable: false, shifting: false, values: [ " + tmpIPtables + " ] },");
            json.Append("{key: '500', nonStackable: false, shifting: false, values: [ " + tmp500 + " ] },");
            json.Append("{key: '2FA', nonStackable: false, shifting: false, values: [ " + tmp2FA + " ] }");
            #endregion

            // Успех
            return(json.ToString());
        }
Ejemplo n.º 25
0
        public static void SetCountRequestToHour(TypeRequest type, string host, bool EnableCountRequest)
        {
            #region Локальный метод - "SetCount"
            void SetCount(NumberOfRequestHour dt)
            {
                switch (type)
                {
                case TypeRequest._200:
                    dt.Count200++;
                    break;

                case TypeRequest._303:
                    dt.Count303++;
                    break;

                case TypeRequest._403:
                    dt.Count403++;
                    break;

                case TypeRequest._401:
                    dt.Count401++;
                    break;

                case TypeRequest._500:
                    dt.Count500++;
                    break;

                case TypeRequest._2fa:
                    dt.Count2FA++;
                    break;
                }
            }

            #endregion

            if (EnableCountRequest)
            {
                string keyNumberOfRequestToHour = KeyToMemoryCache.IspNumberOfRequestToHour(DateTime.Now);
                if (memoryCache.TryGetValue(keyNumberOfRequestToHour, out IDictionary <string, NumberOfRequestHour> DataNumberOfRequestDay))
                {
                    // Если хост есть в кеше
                    if (DataNumberOfRequestDay.TryGetValue(host, out NumberOfRequestHour dtValue))
                    {
                        SetCount(dtValue);
                    }

                    // Если хоста нету в кеше
                    else
                    {
                        var dt = new NumberOfRequestHour();
                        dt.Time = DateTime.Now;
                        SetCount(dt);
                        DataNumberOfRequestDay.Add(host, dt);
                    }
                }
                else
                {
                    // Считаем запрос
                    var dt = new NumberOfRequestHour();
                    dt.Time = DateTime.Now;
                    SetCount(dt);

                    // Создаем кеш
                    memoryCache.Set(keyNumberOfRequestToHour, new Dictionary <string, NumberOfRequestHour>()
                    {
                        [host] = dt
                    }, TimeSpan.FromHours(2));
                }
            }
        }
Ejemplo n.º 26
0
        public static void SetCountRequestToMinute(string IP, TypeRequest type, string host, int DomainID, bool EnableCountRequest)
        {
            if (type != TypeRequest.All && type != TypeRequest._303)
            {
                return;
            }

            #region Локальный метод - "SetCount"
            void SetCount(NumberOfRequestMinute dt)
            {
                switch (type)
                {
                case TypeRequest._303:
                    dt.Count303++;
                    Trigger.OnRequestToMinute((IP, type, dt.Count303, host, DomainID));
                    break;

                case TypeRequest.All:
                    dt.NumberOfRequest++;
                    Trigger.OnRequestToMinute((IP, type, dt.NumberOfRequest, host, DomainID));
                    break;
                }
            }

            #endregion

            if (EnableCountRequest)
            {
                string keyNumberOfRequestToMinutes = KeyToMemoryCache.IspNumberOfRequestToMinutes(DateTime.Now);
                if (memoryCache.TryGetValue(keyNumberOfRequestToMinutes, out IDictionary <string, NumberOfRequestMinute> NumberOfRequestsPerMinute))
                {
                    // Если хост есть в кеше
                    if (NumberOfRequestsPerMinute.TryGetValue(host, out NumberOfRequestMinute dtValue))
                    {
                        SetCount(dtValue);
                    }

                    // Если хоста нету в кеше
                    else
                    {
                        var dt = new NumberOfRequestMinute();
                        dt.DomainID = DomainID;
                        SetCount(dt);
                        NumberOfRequestsPerMinute.Add(host, dt);
                    }
                }
                else
                {
                    // Считаем запрос
                    var dt = new NumberOfRequestMinute();
                    dt.DomainID = DomainID;
                    SetCount(dt);

                    // Создаем кеш
                    memoryCache.Set(keyNumberOfRequestToMinutes, new Dictionary <string, NumberOfRequestMinute>()
                    {
                        [host] = dt
                    }, TimeSpan.FromMinutes(3));
                }
            }
        }
Ejemplo n.º 27
0
        public IActionResult Index(bool ajax, int page = 1, string search = null, string sort = null)
        {
            int pageSize = 12;

            #region Локальный метод - NavPageSize
            int NavPageSize()
            {
                int x = (page % 5);

                if (x == 0)
                {
                    return(pageSize + 1);
                }

                return((pageSize * (5 - x)) + 1);
            }

            #endregion

            #region Статистика запросов за прошлую минуту
            Dictionary <int, ulong> numberOfRequestsPerMinute = new Dictionary <int, ulong>();
            {
                if (memoryCache.TryGetValue(KeyToMemoryCache.IspNumberOfRequestToMinutes(DateTime.Now.AddMinutes(-1)), out IDictionary <string, NumberOfRequestMinute> data))
                {
                    foreach (var dt in data)
                    {
                        if (numberOfRequestsPerMinute.TryGetValue(dt.Value.DomainID, out ulong item))
                        {
                            numberOfRequestsPerMinute[dt.Value.DomainID] = item + dt.Value.NumberOfRequest;
                        }
                        else
                        {
                            numberOfRequestsPerMinute.Add(dt.Value.DomainID, dt.Value.NumberOfRequest);
                        }
                    }

                    #region Сортируем массив
                    if (sort == "req")
                    {
                        numberOfRequestsPerMinute = numberOfRequestsPerMinute.OrderByDescending(i => i.Value).Skip((page * pageSize) - pageSize).Take(NavPageSize()).ToDictionary(i => i.Key, i => i.Value);
                    }
                    else
                    {
                        numberOfRequestsPerMinute = numberOfRequestsPerMinute.OrderByDescending(i => i.Value).ToDictionary(i => i.Key, i => i.Value);
                    }
                    #endregion
                }
            }
            #endregion

            // Поиск / Сортировка
            Func <Domain, bool> predicat = i => search == null || i.host.Contains(search);
            if (sort == "req")
            {
                predicat = i => numberOfRequestsPerMinute.ContainsKey(i.Id);
            }

            // Список доменов
            List <DomainView> domains = new List <DomainView>();

            // Domain To DomainView
            foreach (var domain in coreDB.RequestsFilter_Domains.AsNoTracking().Include(t => t.Templates).AsEnumerable().Where(predicat).Reverse().Skip((page * pageSize) - pageSize).Take(NavPageSize()))
            {
                var model = new DomainView()
                {
                    Id      = domain.Id,
                    host    = domain.host,
                    Protect = domain.Protect
                };

                /// Количество запросов за прошлую минуту
                if (numberOfRequestsPerMinute.TryGetValue(domain.Id, out ulong ReqToMinute))
                {
                    model.ReqToMinute = ReqToMinute;
                }

                #region Имена шаблонов
                StringBuilder TemplateName = new StringBuilder();
                foreach (var tpl in domain.Templates)
                {
                    TemplateName.Append(coreDB.RequestsFilter_Templates.GetTemplateName(tpl.Template, "") + ", ");
                }
                model.Templates = Regex.Replace(TemplateName.ToString(), ",([ ]+)?$", "");
                #endregion

                // Модель
                domains.Add(model);
            }

            // Дополнительная информация
            ViewBag.Info = page == 1 && search == null && sort == null ? "У вас еще нет добавленных доменов" : "Нет данных для вывода";

            // Сортировка по "req/s"
            if (sort == "req")
            {
                return(View("~/Views/RequestsFilter/Domains.cshtml", new NavPage <DomainView>(domains.OrderByDescending(i => i.ReqToMinute).ToList(), HttpContext, pageSize, page, overrideMass: true), ajax));
            }

            // Базовая сортировка
            return(View("~/Views/RequestsFilter/Domains.cshtml", new NavPage <DomainView>(domains, HttpContext, pageSize, page, overrideMass: true), ajax));
        }
Ejemplo n.º 28
0
        /// <summary>
        /// Проверить IPv4/6
        /// </summary>
        /// <param name="RemoteIpAddress">IPv4/6</param>
        /// <param name="data">Время и причина блокировки</param>
        /// <param name="BlockedHost">Домен для которого делать проверку</param>
        public static bool CheckIP(string RemoteIpAddress, out ModelIPtables data, string BlockedHost = null)
        {
            data = null;

            // Блокировка по домену
            if (BlockedHost != null)
            {
                if (memoryCache.TryGetValue(KeyToMemoryCache.IPtables(RemoteIpAddress, BlockedHost), out data))
                {
                    Trigger.OnReturn401((RemoteIpAddress, BlockedHost, "IP"));
                    return(true);
                }
            }

            // IPv6
            if (RemoteIpAddress.Contains(":"))
            {
                #region Локальный метод - "IsMatch"
                bool IsMatch(out string matchIP)
                {
                    var match = Regex.Match(RemoteIpAddress, IPv6ToRegex);

                    if (match.Length > 0 && RemoteIpAddress.Contains(match.Groups[1].Value))
                    {
                        matchIP = match.Groups[1].Value;
                        return(true);
                    }

                    matchIP = null;
                    return(false);
                }

                #endregion

                if (IPv6ToRegex != "^$" && IsMatch(out string matchIPv6))
                {
                    if (!IPv6ToModels.TryGetValue(matchIPv6, out data))
                    {
                        data = new ModelIPtables();
                    }
                    Trigger.OnReturn401((RemoteIpAddress, BlockedHost, "IP"));
                    return(true);
                }

                return(false);
            }

            // IPv4
            else
            {
                if (IPNetwork.CheckToIPv4(RemoteIpAddress, IPv4ToRange, out ulong FirstUsable))
                {
                    if (!IPv4ToModels.TryGetValue(FirstUsable, out data))
                    {
                        data = new ModelIPtables();
                    }
                    Trigger.OnReturn401((RemoteIpAddress, BlockedHost, "IP"));
                    return(true);
                }

                return(false);
            }
        }
Ejemplo n.º 29
0
        public static void Run(CoreDB coreDB, IMemoryCache memoryCache)
        {
            if (IsRun)
            {
                return;
            }
            IsRun = true;

            #region IspNumberOfRequestToHour
            // Если есть кеш за прошлый час
            var TimeIspNumberOfRequestDay = DateTime.Now.AddHours(-1);
            if (memoryCache.TryGetValue(KeyToMemoryCache.IspNumberOfRequestToHour(TimeIspNumberOfRequestDay), out IDictionary <string, NumberOfRequestHour> DataNumberOfRequestToHour))
            {
                SqlToMode.SetMode(SqlMode.Read);
                coreDB.ChangeTracker.AutoDetectChangesEnabled = false;

                // Записываем данные в базу
                foreach (var item in DataNumberOfRequestToHour)
                {
                    coreDB.RequestsFilter_NumberOfRequestDay.Add(new NumberOfRequestDay()
                    {
                        Host     = item.Key,
                        Time     = TimeIspNumberOfRequestDay,
                        Count200 = item.Value.Count200,
                        Count303 = item.Value.Count303,
                        Count401 = item.Value.Count401,
                        Count403 = item.Value.Count403,
                        Count500 = item.Value.Count500,
                        Count2FA = item.Value.Count2FA,
                    });
                }

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

                // Разрешаем записывать данные в SQL
                SqlToMode.SetMode(SqlMode.ReadOrWrite);
                coreDB.ChangeTracker.AutoDetectChangesEnabled = true;

                // Сносим кеш (статистика за час)
                memoryCache.Remove(KeyToMemoryCache.IspNumberOfRequestToHour(TimeIspNumberOfRequestDay));

                // Раз в час
                GC.Collect(GC.MaxGeneration);
            }
            #endregion

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

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

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

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

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

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

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

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

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

                    #region Переносим NumberOfRequestDay в NumberOfRequestMonth
                    // Хранимм дату и значение
                    Dictionary <int, NumberOfRequestBase> NumberOfRequestMonth = new Dictionary <int, NumberOfRequestBase>();

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

                        #region Переносим значения в NumberOfRequestMonth
                        if (NumberOfRequestMonth.TryGetValue(item.Time.Day, out NumberOfRequestBase it))
                        {
                            it.Count200 += item.Count200;
                            it.Count303 += item.Count303;
                            it.Count403 += item.Count403;
                            it.Count401 += item.Count401;
                            it.Count500 += item.Count500;
                            it.Count2FA += item.Count2FA;
                        }
                        else
                        {
                            NumberOfRequestMonth.Add(item.Time.Day, item);
                        }
                        #endregion

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

                    // Переносим временные данные с NumberOfRequestMonth в базу
                    foreach (var item in NumberOfRequestMonth)
                    {
                        // Добовляем в базу
                        coreDB.RequestsFilter_NumberOfRequestMonth.Add(new NumberOfRequestMonth()
                        {
                            Time        = item.Value.Time,
                            allRequests = item.Value.Count200 + item.Value.Count303 + item.Value.Count403 + item.Value.Count500 + item.Value.Count401 + item.Value.Count2FA,
                            Count200    = item.Value.Count200,
                            Count303    = item.Value.Count303,
                            Count401    = item.Value.Count401,
                            Count403    = item.Value.Count403,
                            Count500    = item.Value.Count500,
                            Count2FA    = item.Value.Count2FA,
                        });
                    }
                    #endregion

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

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

            IsRun = false;
        }
Ejemplo n.º 30
0
        public static bool SetBlockedToIPtables(ModelCache.Domain Domain, string IP, string host, string Msg, DateTime Expires, string uri, string userAgent, string PtrHostName)
        {
            if (Domain.typeBlockIP == TypeBlockIP.Triggers)
            {
                // Что-бы в статистике не считать лишний раз +1 к блокировке
                string memKey = $"local-fb482608:SetBlockedToIPtables-{IP}";
                if (memoryCache.TryGetValue(memKey, out _))
                {
                    return(false); // Уже заблокирован
                }
                // Данные для статистики
                SetCountRequestToHour(TypeRequest._401, host, Domain.confToLog.EnableCountRequest);
                memoryCache.Set(memKey, (byte)0, Expires);
            }
            else
            {
                // Если IP уже заблокирован
                if ((Domain.typeBlockIP == TypeBlockIP.domain && memoryCache.TryGetValue(KeyToMemoryCache.IPtables(IP, host), out _)) ||
                    (Domain.typeBlockIP == TypeBlockIP.global && Engine.Security.IPtables.CheckIP(IP, out _)))
                {
                    return(false);
                }

                // Записываем IP в кеш IPtables
                IPtables.AddIPv4Or6(IP, new ModelIPtables(Msg, Expires), Domain.typeBlockIP, host);

                // Данные для статистики
                SetCountRequestToHour(TypeRequest._401, host, Domain.confToLog.EnableCountRequest);

                // Дублируем информацию в SQL
                WriteLogTo.SQL(new BlockedIP()
                {
                    IP           = IP,
                    BlockingTime = Expires,
                    Description  = Msg,
                    typeBlockIP  = Domain.typeBlockIP,
                    BlockedHost  = host
                });
            }

            // Игнорирование логов
            if (Domain.confToLog.IsActive && !Regex.IsMatch(uri, Domain.IgnoreLogToRegex, RegexOptions.IgnoreCase))
            {
                var geoIP = (Country : "Disabled", City : "Disabled", Region : "Disabled");
                if (Domain.confToLog.EnableGeoIP)
                {
                    geoIP = GeoIP2.City(IP);
                }

                // Модель
                Jurnal401 model = new Jurnal401()
                {
                    Host      = host,
                    IP        = IP,
                    Msg       = Msg,
                    Ptr       = PtrHostName,
                    UserAgent = userAgent,
                    Country   = geoIP.Country,
                    City      = geoIP.City,
                    Region    = geoIP.Region,
                    Time      = DateTime.Now
                };

                // Записываем данные в журнал
                switch (Domain.confToLog.Jurn401)
                {
                case WriteLogMode.File:
                    WriteLogTo.FileStream(model);
                    break;

                case WriteLogMode.SQL:
                    WriteLogTo.SQL(model);
                    break;

                case WriteLogMode.all:
                    WriteLogTo.SQL(model);
                    WriteLogTo.FileStream(model);
                    break;
                }
            }

            //
            return(true);
        }