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; } }
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; } }
/// <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 }
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("Неверный пароль"))); }
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); }