예제 #1
0
        private void AddToJurnal2FA(ModelCache.Domain domain, string ip, string host, string method, string uri, string referer, string msg)
        {
            // Игнорирование логов
            if (domain.confToLog.Jurn2FA == WriteLogMode.off || Regex.IsMatch(uri, domain.IgnoreLogToRegex, RegexOptions.IgnoreCase))
            {
                return;
            }

            // GeoIP пользователя
            var geoIP = (Country : "Disabled", City : "Disabled", Region : "Disabled");

            if (domain.confToLog.EnableGeoIP)
            {
                geoIP = GeoIP2.City(ip);
            }

            // Данные для записи в журнал
            var model = new Jurnal2FA()
            {
                IP        = ip,
                Host      = host,
                Uri       = uri,
                Method    = method,
                Msg       = msg,
                UserAgent = Request.Headers["User-Agent"],
                Referer   = referer,
                Country   = geoIP.Country,
                City      = geoIP.City,
                Region    = geoIP.Region,
                Time      = DateTime.Now,
            };

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

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

            case WriteLogMode.all:
                WriteLogTo.SQL(model);
                WriteLogTo.FileStreamTo2faAuth(model);
                break;
            }
        }
예제 #2
0
        private void AddJurnalToIPtables(ModelCache.Domain domain, string IP, string host, string method, string userAgent, string Referer, string uri)
        {
            // Игнорирование логов
            if (domain.confToLog.Jurn200 == WriteLogMode.off || Regex.IsMatch(uri, domain.IgnoreLogToRegex, RegexOptions.IgnoreCase))
            {
                return;
            }

            var geoIP = (Country : "Disabled", City : "Disabled", Region : "Disabled");

            if (domain.confToLog.EnableGeoIP)
            {
                geoIP = GeoIP2.City(IP);
            }

            var model = new Jurnal200()
            {
                typeJurn  = TypeJurn200.IPtables,
                IP        = IP,
                Host      = host,
                Method    = method,
                Uri       = uri,
                FormData  = null,
                UserAgent = userAgent,
                Referer   = Referer,
                Country   = geoIP.Country,
                City      = geoIP.City,
                Region    = geoIP.Region,
                Time      = DateTime.Now
            };

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

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

            case WriteLogMode.all:
                WriteLogTo.FileStream(model);
                break;
            }
        }
예제 #3
0
        /// <summary>
        /// Получить домен
        /// </summary>
        /// <param name="Id">Id домена</param>
        /// <returns>DomainCacheModel</returns>
        public static ModelCache.Domain GetDomain(int Id)
        {
            #region Достаем данные из кеша
            if (MassGetDomain.TryGetValue(Id, out var cache))
            {
                cache.IsCache = true;
                return(cache);
            }
            #endregion

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

            #region Список правил
            List <Models.RequestsFilter.Base.Rules.RuleReplace> RulesReplace = new List <Models.RequestsFilter.Base.Rules.RuleReplace>();
            List <Rule>    RulesAllow         = new List <Rule>();
            List <Rule>    RulesDeny          = new List <Rule>();
            List <Rule>    Rules2FA           = new List <Rule>();
            List <Rule>    RulesOverrideAllow = new List <Rule>();
            List <Rule>    RulesOverrideDeny  = new List <Rule>();
            List <Rule>    RulesOverride2FA   = new List <Rule>();
            List <RuleArg> RuleArgs           = new List <RuleArg>();
            #endregion

            // База CoreDB
            using (var coreDB = Service.Get <CoreDB>())
            {
                #region Если домена нету в базе
                cache = new ModelCache.Domain();
                var domain = coreDB.RequestsFilter_Domains.FindAndInclude(Id, AsNoTracking: true);
                if (domain == null)
                {
                    // Отдаем пустой кеш без  правил
                    SqlToMode.SetMode(SqlMode.ReadOrWrite);
                    return(cache);
                }
                #endregion

                // Блокировка IP в 'Брандмауэр' глобально или только для домена
                cache.typeBlockIP = domain.typeBlockIP;

                // Настройки логирования запросов
                cache.confToLog = domain.confToLog;

                // 2FA и защита сайта от BruteForce
                cache.StopBruteForce  = domain.StopBruteForce;
                cache.Auth2faToAccess = domain.Auth2faToAccess;
                cache.Auth2faToPasswd = domain.Auth2faToPasswd;

                #region Найтройки AntiBot
                // Клонируем обьект
                cache.AntiBot = domain.AntiBot.Clone();

                // Переопределяем правило
                cache.AntiBot.BackgroundCheckToAddExtensions = string.IsNullOrWhiteSpace(cache.AntiBot.BackgroundCheckToAddExtensions) ? "^$" : $"(\\.{cache.AntiBot.BackgroundCheckToAddExtensions.Replace(",", "|\\.")})";
                #endregion

                // Достаем список правил для игнорирования логов
                var IgnoreToLogs = domain.IgnoreToLogs.Select(i => i.rule).ToList();
                if (IgnoreToLogs.Count > 0)
                {
                    cache.IgnoreLogToRegex = "^(" + string.Join('|', domain.IgnoreToLogs.Select(i => i.rule)) + ")$";
                }

                #region Настройки лимитирования запросов
                if (domain.limitRequest.UseGlobalConf || domain.limitRequest.MinuteLimit > 0 || domain.limitRequest.HourLimit > 0 || domain.limitRequest.DayLimit > 0)
                {
                    cache.limitRequest.IsEnabled     = true;                                                                          // Режим лимитирования запросов включен
                    cache.limitRequest.UseGlobalConf = domain.limitRequest.UseGlobalConf;                                             // Использовать глобальные или локальные настройки
                    cache.limitRequest.MinuteLimit   = domain.limitRequest.MinuteLimit;                                               // Минутный лимит запросов
                    cache.limitRequest.HourLimit     = domain.limitRequest.HourLimit;                                                 // Часовой лимит запросов
                    cache.limitRequest.DayLimit      = domain.limitRequest.DayLimit;                                                  // Метод блокировки при достижении лимита запросов
                    cache.limitRequest.BlockType     = domain.limitRequest.BlockType;                                                 // Суточный лимит запросов
                    cache.limitRequest.MaxRequestToAgainСheckingreCAPTCHA = domain.limitRequest.MaxRequestToAgainСheckingreCAPTCHA;   // Количество запросов перед повторной проверкой reCAPTCHA
                }
                #endregion

                #region Собираем правила c шаблонов
                foreach (var TemplateId in domain.Templates.Select(t => t.Template))
                {
                    // Поиск шаблона
                    if (coreDB.RequestsFilter_Templates.FindAndInclude(TemplateId, AsNoTracking: true) is Models.RequestsFilter.Templates.Template tpl)
                    {
                        // Позволяет удалить кеш домена если изменится шаблон
                        cache.TemplateIds.Add(TemplateId);

                        // Собираем правила c шаблона
                        SortToRule(tpl.Rules, IsOverrides: false);
                        SortToRule(tpl.RuleOverrides, IsOverrides: true);

                        // Cписок аргументов шаблона
                        RuleArgs.AddRange(tpl.RuleArgs);

                        // Правила шаблона - "Замена ответа"
                        RulesReplace.AddRange(tpl.RuleReplaces);
                    }
                }
                #endregion

                // Основные правила домена
                SortToRule(domain.Rules, IsOverrides: false);
                SortToRule(domain.RuleOverrides, IsOverrides: true);

                // Cписок аргументов домена
                RuleArgs.AddRange(domain.RuleArgs);

                // Правила домена - "Замена ответа"
                RulesReplace.AddRange(domain.RuleReplaces);

                // Конвертируем Rule в ModelCache.Rule
                ConvertToModelCache(RuleArgs, RulesAllow, cache.RuleAllow);
                ConvertToModelCache(RuleArgs, RulesDeny, cache.RuleDeny);
                ConvertToModelCache(RuleArgs, Rules2FA, cache.Rule2FA);
                ConvertToModelCache(RuleArgs, RulesOverrideAllow, cache.RuleOverrideAllow);
                ConvertToModelCache(RuleArgs, RulesOverrideDeny, cache.RuleOverrideDeny);
                ConvertToModelCache(RuleArgs, RulesOverride2FA, cache.RuleOverride2FA);

                // Конвертируем RuleReplace в ModelCache.RuleReplaces
                ConvertRuleReplaceToModelCache(RulesReplace, cache.RuleReplaces);

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

                // Отдаем данные
                MassGetDomain.AddOrUpdate(Id, cache, (i, d) => cache);
                return(cache);
            }

            #region Локальный метод SortToRule
            void SortToRule(IEnumerable <Rule> inRules, bool IsOverrides)
            {
                foreach (var rile in inRules)
                {
                    if (IsOverrides)
                    {
                        switch (rile.order)
                        {
                        case ActionCheckLink.allow:
                            RulesOverrideAllow.Add(rile);
                            break;

                        case ActionCheckLink.deny:
                            RulesOverrideDeny.Add(rile);
                            break;

                        case ActionCheckLink.Is2FA:
                            RulesOverride2FA.Add(rile);
                            break;
                        }
                    }
                    else
                    {
                        switch (rile.order)
                        {
                        case ActionCheckLink.allow:
                            RulesAllow.Add(rile);
                            break;

                        case ActionCheckLink.deny:
                            RulesDeny.Add(rile);
                            break;

                        case ActionCheckLink.Is2FA:
                            Rules2FA.Add(rile);
                            break;
                        }
                    }
                }
            }

            #endregion
        }
예제 #4
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("Неверный пароль")));
        }
예제 #5
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);
        }