/// <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)); } }
/// <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)); } } } } } }
public JsonResult Add(string value, string Description, int BlockingTimeDay, TypeBlockIP typeBlockIP = TypeBlockIP.global, bool IsAPI = false) { #region Демо режим if (Platform.IsDemo) { return(Json(new Text("Операция недоступна в демо-режиме"))); } #endregion // Коректировка if (typeBlockIP == TypeBlockIP.domain) { typeBlockIP = TypeBlockIP.global; } // Коректор времени if (BlockingTimeDay <= 0) { BlockingTimeDay = 1; } #region Проверка IP/UserAgent if (typeBlockIP == TypeBlockIP.global) { // IP-адрес string IP = value; // Проверка IP if (!IPNetwork.CheckingSupportToIPv4Or6(IP, out _)) { return(Json(new Text($"Not supported format: {IP}"))); } // Записываем IP в кеш IPtables IPtables.AddIPv4Or6(IP, new ModelIPtables(Description, DateTime.Now.AddDays(BlockingTimeDay)), typeBlockIP); } else { // Проверка UserAgent if (string.IsNullOrWhiteSpace(value)) { return(Json(new Text("Поле 'Значение' имеет недопустимое значение"))); } } #endregion // Дублируем информацию в SQL var blockedIP = new BlockedIP() { IP = value, Description = Description, BlockingTime = DateTime.Now.AddDays(BlockingTimeDay), typeBlockIP = typeBlockIP }; coreDB.BlockedsIP.Add(blockedIP); // Сохраняем SQL coreDB.SaveChanges(); // Кеш IPtables if (typeBlockIP == TypeBlockIP.UserAgent) { IPtables.UpdateCacheToUserAgent(); } if (IsAPI) { return(Json(new TrueOrFalse(true))); } // Отдаем результат return(Json(new Html($@"<tr class='elemDelete'> <td class='text-left table-products'> <strong>{value}</strong> </td> <td>{(typeBlockIP == TypeBlockIP.global ? "IP-адрес" : "User Agent")}</td> <td>{Description}</td> <td>{DateTime.Now.AddDays(BlockingTimeDay).ToString("dd.MM.yyyy H:mm")}</td> <td style='text-align: right;' class='table-products btn-icons'>" + "<a onclick=\"return deleteElement(this,'/security/iptables/remove',{Id:'" + blockedIP.Id + "'});\" class=\"btn nopadding-nomargin\"><i class=\"fa fa-trash-o\"></i></a>" + @"</td> </tr>"))); }
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>"))); }
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 JsonResult Base(string value, string Description, int BlockingTimeDay, TypeBlockIP typeBlockIP) { return(new SecurityToIPtablesController().Add(value, Description, BlockingTimeDay, IsAPI: true, typeBlockIP: typeBlockIP)); }
public JsonResult Domain(string host, BruteForceType bruteForceType, Protection Protect, TypeBlockIP typeBlockIP = TypeBlockIP.global, string auth2faToPasswd = null) { return(new RequestsFilterToDomainBaseController().Save(new Domain() { host = host, Protect = Protect, typeBlockIP = typeBlockIP, StopBruteForce = bruteForceType, Auth2faToPasswd = auth2faToPasswd })); }
/// <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)); } } } } }