/// <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 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); }
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))); }
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>"))); }
/// <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 }
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); }
/// <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); } }
/// <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)); } } } } }
public static Task Check(HttpContext context) { #region Получаем параметры запроса var gRequest = new Regex(@"^(\?ip=([^&]+)&|\?)method=([^&]+)&host=([^&]+)&uri=([^\n\r]+)").Match(context.Request.QueryString.Value).Groups; string IP = gRequest[2].Value, method = gRequest[3].Value.ToUpper(), host = Regex.Replace(gRequest[4].Value, @"^www\.", "", RegexOptions.IgnoreCase), uri = WebUtility.UrlDecode(gRequest[5].Value); // Проверяем правильно ли мы спарсили данные if (string.IsNullOrWhiteSpace(host) || string.IsNullOrWhiteSpace(uri)) { context.Response.ContentType = "text/html; charset=utf-8"; return(context.Response.WriteAsync("Не сохранен порядок запроса<br />Пример: /core/check/request?ip=127.0.0.1&method=GET&host=test.com&uri=/", context.RequestAborted)); } // IP адрес пользователя if (string.IsNullOrWhiteSpace(IP)) { IP = context.Connection.RemoteIpAddress.ToString(); } #endregion #region Получаем параметры POST запроса string FormData = string.Empty; if (context.Request.Method == "POST") { StringBuilder mass = new StringBuilder(); foreach (var arg in context.Request.Form) { // Удаляем из ключа массивы [] и проверяем на пустоту string key = Regex.Replace(arg.Key, @"\[([^\]]+)?\]", "", RegexOptions.IgnoreCase); if (string.IsNullOrWhiteSpace(key)) { continue; } mass.Append($"&{key}={arg.Value[0]}"); } FormData = mass.ToString(); } #endregion #region ViewBag var viewBag = new ViewBag(); viewBag.DebugEnabled = jsonDB.Base.DebugEnabled; // Режим дебага, выводит json правил viewBag.IsErrorRule = false; // Переменная для ловли ошибок regex #endregion // Если домена нету в базе, то выдаем 303 или заглушку if (ISPCache.DomainToID(host) is int DomainID && DomainID == 0) { return(jsonDB.Base.EnableToDomainNotFound ? ViewDomainNotFound(context) : View(context, viewBag, ActionCheckLink.allow)); } // Если у IP есть полный доступ к сайтам или к сайту if (CheckLinkWhitelistToAllDomain()) { return(View(context, viewBag, ActionCheckLink.allow)); } #region Получаем User-Agent и Referer // User-Agent string userAgent = string.Empty; if (context.Request.Headers.TryGetValue("User-Agent", out var tmp_userAgent)) { userAgent = tmp_userAgent.ToString(); } // Referer string Referer = string.Empty; if (context.Request.Headers.TryGetValue("Referer", out var tmp_Referer)) { Referer = tmp_Referer.ToString(); } #endregion // Достаем данные домена var Domain = ISPCache.GetDomain(DomainID); // Достаем настройки AntiBot из кеша var antiBotToGlobalConf = AntiBot.GlobalConf(jsonDB.AntiBot); // Достаем настройки WhiteList из кеша var whiteList = Engine.Base.SqlAndCache.WhiteList.GetCache(jsonDB.WhiteList); #region Проверяем "IP/User-Agent" в блокировке IPtables // Проверяем IP в блокировке IPtables по домену if (IPtablesMiddleware.CheckIP(IP, memoryCache, out IPtables BlockedData, host)) { // Логируем пользователя AddJurnalTo200(IsIPtables: true); SetCountRequestToHour(TypeRequest._200, host, Domain.confToLog.EnableCountRequest); // Отдаем ответ context.Response.StatusCode = 401; context.Response.ContentType = "text/html; charset=utf-8"; return(context.Response.WriteAsync(IPtablesMiddleware.BlockedToHtml(IP, BlockedData.Description, BlockedData.TimeExpires), context.RequestAborted)); } // Проверяем User-Agent в блокировке IPtables if (IPtablesMiddleware.CheckUserAgent(userAgent)) { // Логируем пользователя AddJurnalTo200(IsIPtables: true); SetCountRequestToHour(TypeRequest._200, host, Domain.confToLog.EnableCountRequest); // Отдаем ответ context.Response.StatusCode = 401; context.Response.ContentType = "text/html; charset=utf-8"; return(context.Response.WriteAsync(IPtablesMiddleware.BlockedHtmlToUserAgent(userAgent), context.RequestAborted)); } #endregion // IP нету в пользовательском белом списке // IP нету в глобальном белом списке if (!Regex.IsMatch(IP, whiteList.IpRegex) && !WhitePtr.IsWhiteIP(IP)) { #region AntiBot if (!AntiBot.ValidRequest(((antiBotToGlobalConf.conf.Enabled || Domain.AntiBot.UseGlobalConf) ? antiBotToGlobalConf.conf.type : Domain.AntiBot.type), host, method, uri, context, Domain, out string outHtml)) { // Логируем пользователя AddJurnalTo200(IsAntiBot: true); SetCountRequestToHour(TypeRequest._200, host, Domain.confToLog.EnableCountRequest); // Выводим html пользователю context.Response.ContentType = "text/html; charset=utf-8"; return(context.Response.WriteAsync(outHtml, context.RequestAborted)); } #endregion #region Лимит запросов if (Domain.limitRequest.IsEnabled || antiBotToGlobalConf.conf.limitRequest.IsEnabled) { // Настройки лимита запросов var limitRequest = (antiBotToGlobalConf.conf.limitRequest.IsEnabled || Domain.limitRequest.UseGlobalConf) ? antiBotToGlobalConf.conf.limitRequest : Domain.limitRequest; // Проверяем белый список UserAgent if (!Regex.IsMatch(userAgent, whiteList.UserAgentRegex, RegexOptions.IgnoreCase)) { #region IsWhitePtr bool IsWhitePtr(out string PtrHostName) { PtrHostName = null; string KeyLimitRequestToBlockedWait = $"LimitRequestToBlockedWait-{IP}_{host}"; if (memoryCache.TryGetValue(KeyLimitRequestToBlockedWait, out _)) { return(true); } memoryCache.Set(KeyLimitRequestToBlockedWait, (byte)0, TimeSpan.FromMinutes(5)); #region DNSLookup try { // Белый список Ptr string WhitePtrRegex = whiteList.PtrRegex; if (WhitePtrRegex != "^$" && !string.IsNullOrWhiteSpace(WhitePtrRegex)) { // Получаем имя хоста по IP var DnsHost = Dns.GetHostEntryAsync(IP).Result; // Получаем IP хоста по имени DnsHost = Dns.GetHostEntryAsync(DnsHost.HostName).Result; // Проверяем имя хоста и IP на совпадение if (DnsHost.AddressList.Where(i => i.ToString() == IP).FirstOrDefault() != null) { PtrHostName = DnsHost.HostName; // Проверяем имя хоста на белый список DNSLookup if (Regex.IsMatch(DnsHost.HostName, WhitePtrRegex, RegexOptions.IgnoreCase)) { // Добовляем IP в белый список на 9 дней WhitePtr.Add(IP, DateTime.Now.AddDays(9)); memoryCache.Remove(KeyLimitRequestToBlockedWait); return(true); } } } } catch { } #endregion // Сносим временную запись memoryCache.Remove(KeyLimitRequestToBlockedWait); return(false); } #endregion #region Локальный метод - "СheckingToreCAPTCHA" bool СheckingToreCAPTCHA(out Task content, int ExpiresToMinute) { content = null; if (IsWhitePtr(out _)) { return(false); } #region Валидный пользователь if (memoryCache.TryGetValue(KeyToMemoryCache.LimitRequestToreCAPTCHA(IP), out (int countRequest, int ExpiresToMinute)item)) { // Пользователь превысил допустимый лимит if (item.countRequest >= limitRequest.MaxRequestToAgainСheckingreCAPTCHA) { // Удаляем запись memoryCache.Remove(KeyToMemoryCache.LimitRequestToreCAPTCHA(IP)); return(false); } // Считаем количество запросов item.countRequest++; memoryCache.Set(KeyToMemoryCache.LimitRequestToreCAPTCHA(IP), item, TimeSpan.FromMinutes(item.ExpiresToMinute)); return(false); } #endregion #region Кеш шаблона // Путь к шаблону string SourceFile = $"{Folders.Tpl.LimitRequest}/reCAPTCHA.tpl"; if (!File.Exists(SourceFile)) { SourceFile = $"{Folders.Tpl.LimitRequest}/default/reCAPTCHA.tpl"; } // Время модификации файла DateTime LastWriteTimeToFile = File.GetLastWriteTime(SourceFile); // default value (DateTime LastWriteTime, string Source)cacheTpl = (DateTime.Now, ""); // Обновляем кеш if (!memoryCache.TryGetValue("core.Check.Request:LimitRequest-tpl", out cacheTpl) || LastWriteTimeToFile != cacheTpl.LastWriteTime) { cacheTpl.LastWriteTime = LastWriteTimeToFile; cacheTpl.Source = File.ReadAllText(SourceFile); memoryCache.Set("core.Check.Request:LimitRequest-tpl", cacheTpl); } #endregion #region Замена полей string tpl = Regex.Replace(cacheTpl.Source, @"\{isp:([^\}]+)\}", key => { switch (key.Groups[1].Value) { case "CoreApiUrl": return(jsonDB.Base.CoreAPI); case "reCAPTCHASitekey": return(jsonDB.Base.reCAPTCHASitekey); case "IP": return(IP); case "ExpiresToMinute": return(ExpiresToMinute.ToString()); case "hash": return(md5.text($"{IP}{ExpiresToMinute}:{PasswdTo.salt}")); default: return(string.Empty); } }); #endregion // Ответ context.Response.ContentType = "text/html; charset=utf-8"; content = context.Response.WriteAsync(tpl, context.RequestAborted); return(true); } #endregion #region Локальный метод - "CheckToLimit" bool CheckToLimit(string keyName, int limit, int ExpiresToMinute, out CacheValue _cacheValue) { string key = $"LimitRequestTo{keyName}-{IP}_{host}"; if (memoryCache.TryGetValue(key, out CacheValue item)) { item.value++; _cacheValue = item; if (item.value > limit) { return(true); } } else { _cacheValue = new CacheValue() { value = 1, Expires = DateTime.Now.AddMinutes(ExpiresToMinute) }; memoryCache.Set(key, _cacheValue, TimeSpan.FromMinutes(ExpiresToMinute)); } return(false); } #endregion #region Локальный метод - "BlockedToIP" void BlockedToIP(string Msg, DateTime Expires) { if (IsWhitePtr(out string PtrHostName)) { return; } // Записываем IP в кеш IPtables и журнал SetBlockedToIPtables(Msg, Expires, PtrHostName); } #endregion // Переменная для кеша CacheValue cacheValue; #region Метод блокировки LimitToBlockType BlockType = limitRequest.BlockType; if (BlockType == LimitToBlockType.reCAPTCHA && (antiBotToGlobalConf.conf.limitRequest.IsEnabled || Domain.limitRequest.UseGlobalConf)) { // Если домена нету в глобальных настройках if (!Regex.IsMatch(host, antiBotToGlobalConf.DomainsToreCaptchaRegex, RegexOptions.IgnoreCase)) { BlockType = LimitToBlockType._403; } } #endregion #region Минутный лимит if (limitRequest.MinuteLimit != 0 && CheckToLimit("Minute", limitRequest.MinuteLimit, 1, out cacheValue)) { switch (BlockType) { case LimitToBlockType._403: BlockedToIP("Превышен минутный лимит на запросы", cacheValue.Expires); memoryCache.Remove($"LimitRequestToMinute-{IP}_{host}"); break; case LimitToBlockType.reCAPTCHA: { if (СheckingToreCAPTCHA(out Task res, 2)) { return(res); } } break; } } #endregion #region Часовой лимит if (limitRequest.HourLimit != 0 && CheckToLimit("Hour", limitRequest.HourLimit, 60, out cacheValue)) { switch (BlockType) { case LimitToBlockType._403: BlockedToIP("Превышен часовой лимит на запросы", cacheValue.Expires); memoryCache.Remove($"LimitRequestToHour-{IP}_{host}"); break; case LimitToBlockType.reCAPTCHA: { if (СheckingToreCAPTCHA(out Task res, 61)) { return(res); } } break; } } #endregion #region Дневной лимит if (limitRequest.DayLimit != 0 && CheckToLimit("Day", limitRequest.DayLimit, 1440, out cacheValue)) { switch (BlockType) { case LimitToBlockType._403: BlockedToIP("Превышен дневной лимит на запросы", cacheValue.Expires); memoryCache.Remove($"LimitRequestToHour-{IP}_{host}"); memoryCache.Remove($"LimitRequestToDay-{IP}_{host}"); break; case LimitToBlockType.reCAPTCHA: { if (СheckingToreCAPTCHA(out Task res, 1441)) { return(res); } } break; } } #endregion } } #endregion } #region Защита от Brute Force if (Domain.StopBruteForce != BruteForceType.Not) { // Настройки var BrutConf = jsonDB.BruteForceConf; // Переменная для кеша CacheValue cacheValue; #region Локальный метод - "CheckToLimit" bool CheckToLimit(string keyName, int limit, int ExpiresToMinute, out CacheValue _cacheValue) { string key = $"BruteForceTo{keyName}-{IP}_{host}"; if (memoryCache.TryGetValue(key, out CacheValue item)) { _cacheValue = item; if (item.value >= limit) { return(true); } } _cacheValue = null; return(false); } #endregion #region Локальный метод - "BlockedToIP" void BlockedToIP(string Msg, DateTime Expires) { string KeyLimitRequestToBlockedWait = $"BruteForceToBlockedWait-{IP}_{host}"; if (memoryCache.TryGetValue(KeyLimitRequestToBlockedWait, out _)) { return; } memoryCache.Set(KeyLimitRequestToBlockedWait, (byte)0, TimeSpan.FromMinutes(5)); // Записываем IP в кеш IPtables и журнал SetBlockedToIPtables(Msg, Expires, null); // Сносим временную запись memoryCache.Remove(KeyLimitRequestToBlockedWait); } #endregion // Блокировка IP if (CheckToLimit("Day", BrutConf.DayLimit, 1440, out cacheValue) || CheckToLimit("Hour", BrutConf.HourLimit, 60, out cacheValue) || CheckToLimit("Minute", BrutConf.MinuteLimit, 1, out cacheValue)) { BlockedToIP("Защита от Brute Force", cacheValue.Expires); } // Была авторизация if (BruteForce.IsLogin(Domain.StopBruteForce, method, uri, FormData)) { #region Локальный метод - "SetValue" void SetValue(string keyName, int ExpiresToMinute) { string key = $"BruteForceTo{keyName}-{IP}_{host}"; if (memoryCache.TryGetValue(key, out CacheValue item)) { item.value++; } else { memoryCache.Set(key, new CacheValue() { value = 1, Expires = DateTime.Now.AddMinutes(ExpiresToMinute) }, TimeSpan.FromMinutes(ExpiresToMinute)); } } #endregion // Обновляем счетчики SetValue("Day", 1440); SetValue("Hour", 60); SetValue("Minute", 1); } } #endregion #region ViewBag if (jsonDB.Base.DebugEnabled) { viewBag.IP = IP; viewBag.jsonDomain = JsonConvert.SerializeObject(Domain, Formatting.Indented); viewBag.antiBotToGlobalConf = JsonConvert.SerializeObject(antiBotToGlobalConf, Formatting.Indented); viewBag.FormData = FormData; } viewBag.method = method; viewBag.host = host; viewBag.uri = uri; viewBag.Referer = context.Request.Headers["Referer"]; viewBag.UserAgent = userAgent; #endregion #region Замена ответа - 302/код try { // Проверка url и GET аргументов if (Regex.IsMatch(uri, Domain.RuleReplaces.RuleGetToRegex, RegexOptions.IgnoreCase)) { // Проверка POST аргументов if (method != "POST" || (method == "POST" && Regex.IsMatch($"{(new Regex(@"^(/[^\?\&]+)").Match(uri).Groups[1].Value)}{FormData}", Domain.RuleReplaces.RulePostToRegex, RegexOptions.IgnoreCase))) { // Разделяем URL на аргументы var g = new Regex(@"^(/([^\?&]+)?((\?|&).*)?)$").Match(uri).Groups; string args = g[3].Value.Replace("?", "&"); #region Локальный метод - GetRule ModelCache.Rules.RuleReplace GetRule() { foreach (var item in Domain.RuleReplaces.Rules) { // Url не подходит if (!Regex.IsMatch($"/{g[2].Value}", $"^{item.uri}$", RegexOptions.IgnoreCase)) { continue; } if (method == "POST") { // Get или POST аргументы подходят if (Regex.IsMatch(args, item.GetArgsToRegex, RegexOptions.IgnoreCase) || Regex.IsMatch(FormData, item.PostArgsToRegex, RegexOptions.IgnoreCase)) { return(item); } } else { // Get аргументы подходят if (Regex.IsMatch(args, item.GetArgsToRegex, RegexOptions.IgnoreCase)) { return(item); } } } return(null); } #endregion // Находим правило которое подходит для нашего запроса if (GetRule() is ModelCache.Rules.RuleReplace rule) { #region Локальный метод - "ReplaceArgs" string ReplaceArgs(string _args, string regexArgs) { StringBuilder mass = new StringBuilder(); foreach (var arg in _args.Split('&')) { if (string.IsNullOrWhiteSpace(arg) || !arg.Contains('=')) { continue; } var tmpArg = arg.Split('='); // Список аргументов для замены if (Regex.IsMatch(regexArgs, tmpArg[0], RegexOptions.IgnoreCase)) { mass.Append("&" + tmpArg[0] + "=" + Regex.Replace(tmpArg[1], rule.RegexWhite, "")); } else { mass.Append("&" + arg); } } return(mass.ToString()); } #endregion #region Локальный метод - "ResponseContent" Task ResponseContent(string _argsGet) { // Записываем данные пользователя AddJurnalTo200(); SetCountRequestToHour(TypeRequest._200, host, Domain.confToLog.EnableCountRequest); // Тип ответа if (rule.TypeResponse == TypeResponseRule.kode) { // Пользовательский код context.Response.ContentType = rule.ContentType; return(context.Response.WriteAsync(rule.kode, context.RequestAborted)); } else { if (string.IsNullOrWhiteSpace(rule.ResponceUri)) { // Если url для 302 не указан return(RewriteTo.Local(context, g[2].Value + Regex.Replace(_argsGet, "^&", "?"))); } else { // Редирект на указаный URL return(RewriteTo.Local(context, rule.ResponceUri.Replace("{arg}", Regex.Replace(_argsGet, "^&", "?")))); } } } #endregion // Если аргументы для проверки не указаны if (rule.GetArgs == "" && rule.PostArgs == "") { return(ResponseContent(string.Empty)); } #region argsGet / argsPOST string argsGet = ReplaceArgs(args, rule.GetArgs); string argsPOST = string.Empty; if (method == "POST") { argsPOST = ReplaceArgs(FormData, rule.PostArgs); } #endregion // Замена ответа, если в аргументах есть лишние символы if (args != argsGet || FormData != argsPOST) { return(ResponseContent(argsGet)); } } } } } catch (Exception ex) { // Записываем данные ошибки в журнал AddJurnalTo500(ex.Message); SetCountRequestToHour(TypeRequest._500, host, Domain.confToLog.EnableCountRequest); // Выводим ошибку viewBag.IsErrorRule = true; viewBag.ErrorTitleException = "Ошибка в правиле"; viewBag.ErrorRuleException = jsonDB.Base.DebugEnabled ? ex.Message : "Данные ошибки доступны в журнале 500"; return(View(context, viewBag, ActionCheckLink.deny)); } #endregion // Переопределенные правила if (OpenPageToRule(Domain.RuleOverrideAllow, Domain.RuleOverride2FA, Domain.RuleOverrideDeny) is Task pageToRuleOverride) { return(pageToRuleOverride); } // Обычные правила if (OpenPageToRule(Domain.RuleAllow, Domain.Rule2FA, Domain.RuleDeny) is Task pageToRule) { return(pageToRule); } // Записываем данные пользователя AddJurnalTo403And303(Is303: true); SetCountRequestToHour(TypeRequest._303, host, Domain.confToLog.EnableCountRequest); // Если не одно правило не подошло return(View(context, viewBag, ActionCheckLink.allow)); #region Локальный метод - "OpenPageToRule" Task OpenPageToRule(ModelCache.Rules.Rule RuleAllow, ModelCache.Rules.Rule Rule2FA, ModelCache.Rules.Rule RuleDeny) { #region азрешенные запросы if (IsRequestTheRules(RuleAllow)) { // Записываем данные пользователя AddJurnalTo403And303(Is303: true); SetCountRequestToHour(TypeRequest._303, host, Domain.confToLog.EnableCountRequest); // Если режим дебага выключен if (!jsonDB.Base.DebugEnabled) { context.Response.StatusCode = 303; return(context.Response.WriteAsync("303", context.RequestAborted)); } // Разрешаем запрос return(View(context, viewBag, ActionCheckLink.allow)); } #endregion #region Правила 2FA else if (IsRequestTheRules(Rule2FA)) { // Записываем данные пользователя AddJurnalTo200(Is2FA: true); SetCountRequestToHour(TypeRequest._200, host, Domain.confToLog.EnableCountRequest); // Если IP для 2FA уже есть if (memoryCache.TryGetValue(KeyToMemoryCache.CheckLinkWhitelistTo2FA(host, IP), out byte _)) { // Авторизация в Telegram if (!TelegramBot.IsAuth(IP, Is2FA: true)) { context.Response.ContentType = "text/html"; return(context.Response.WriteAsync(TelegramBot.AuthToHtml(IP), context.RequestAborted)); } // Успех return(View(context, viewBag, ActionCheckLink.allow)); } // Просим пройти 2FA авторизацию viewBag.CoreAPI = jsonDB.Base.CoreAPI; return(View(context, viewBag, ActionCheckLink.Is2FA)); } #endregion #region Запрещенные запросы else if (IsRequestTheRules(RuleDeny)) { // Записываем данные пользователя AddJurnalTo403And303(Is403: true); SetCountRequestToHour(TypeRequest._403, host, Domain.confToLog.EnableCountRequest); // Отдаем страницу 403 return(View(context, viewBag, ActionCheckLink.deny)); } #endregion // Если не одно правило не подошло return(null); } #endregion #region Локальный метод - "IsRequestTheRules" bool IsRequestTheRules(ModelCache.Rules.Rule rule) { #region Быстрая проверка 'GET/POST' запроса try { switch (method) { case "GET": return(rule.RuleGetToRegex != "^$" && Regex.IsMatch(uri, rule.RuleGetToRegex, RegexOptions.IgnoreCase)); case "POST": { if (rule.RulePostToRegex != "^$" && Regex.IsMatch(uri, rule.RulePostToRegex, RegexOptions.IgnoreCase)) { return(true); } break; } default: { // Записываем данные ошибки в журнал AddJurnalTo500($"Метод '{method}' не поддерживается", IsException: true); SetCountRequestToHour(TypeRequest._500, host, Domain.confToLog.EnableCountRequest); return(true); } } // Быстрая проверка POST запроса if (rule.RuleArgsCheckPostToRegex == "^$" || !Regex.IsMatch(uri, rule.RuleArgsCheckPostToRegex, RegexOptions.IgnoreCase)) { return(false); } } catch (Exception ex) { // Записываем данные ошибки в журнал AddJurnalTo500(ex.Message); SetCountRequestToHour(TypeRequest._500, host, Domain.confToLog.EnableCountRequest); // Если есть ошибка в одном из регексов viewBag.IsErrorRule = true; viewBag.ErrorTitleException = "Ошибка в правиле"; viewBag.ErrorRuleException = jsonDB.Base.DebugEnabled ? ex.Message : "Данные ошибки доступны в журнале 500"; return(true); } #endregion #region Полная проверка POST запроса // Если POST правил нету - (ложное срабатывание в 'RuleArgsCheckPostToRegex') if (rule.postRules == null && rule.postRules.Count < 1) { return(false); } foreach (var postRules in rule.postRules) { try { if (Regex.IsMatch(uri, postRules.rule, RegexOptions.IgnoreCase)) { // Проверяем есть ли в запросе POST аргументы не указаные в списке правил if (Regex.IsMatch(FormData, postRules.RulePostToRegex, RegexOptions.IgnoreCase)) { return(true); } } } catch (Exception ex) { // Записываем данные ошибки в журнал AddJurnalTo500(ex.Message); SetCountRequestToHour(TypeRequest._500, host, Domain.confToLog.EnableCountRequest); // Если есть ошибка в одном из регексов viewBag.IsErrorRule = true; viewBag.ErrorTitleException = "Ошибка в правиле"; viewBag.ErrorRuleException = jsonDB.Base.DebugEnabled ? ex.Message : "Данные ошибки доступны в журнале 500"; return(true); } } #endregion // Если ничего не подошло return(false); } #endregion #region Локальный метод - "AddJurnalTo500" void AddJurnalTo500(string errorMsg, bool IsException = false) { if (IsException) { viewBag.IsErrorRule = true; viewBag.ErrorTitleException = "Ошибка в запросе"; viewBag.ErrorRuleException = errorMsg; } if (Domain.confToLog.Jurn500 != WriteLogMode.off) { // Игнорирование логов if (!Regex.IsMatch(uri, Domain.IgnoreLogToRegex, RegexOptions.IgnoreCase)) { var model = new Jurnal500() { IP = IP, Host = host, Method = method, Uri = uri, FormData = FormData, UserAgent = userAgent, Referer = context.Request.Headers["Referer"], Time = DateTime.Now, ErrorMsg = errorMsg }; // Записываем данные в журнал switch (Domain.confToLog.Jurn500) { 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 #region Локальный метод - "AddJurnalTo403And303" void AddJurnalTo403And303(bool Is403 = false, bool Is303 = false) { if (viewBag.IsErrorRule) { return; } // Игнорирование логов if (Domain.confToLog.IsActive && (Domain.confToLog.Jurn403 != WriteLogMode.off || Domain.confToLog.Jurn303 != WriteLogMode.off) && !Regex.IsMatch(uri, Domain.IgnoreLogToRegex, RegexOptions.IgnoreCase)) { ThreadPool.QueueUserWorkItem(ob => { var geoIP = (Country: "Disabled", City: "Disabled", Region: "Disabled"); if (Domain.confToLog.EnableGeoIP) { geoIP = GeoIP2.City(IP); } #region 403 if (Is403) { var model = new Jurnal403() { IP = IP, Host = host, Method = method, Uri = uri, FormData = FormData, UserAgent = userAgent, Referer = Referer, Country = geoIP.Country, City = geoIP.City, Region = geoIP.Region, Time = DateTime.Now }; // Записываем данные в журнал switch (Domain.confToLog.Jurn403) { 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 #region 303 if (Is303) { var model = new Jurnal303() { IP = IP, Host = host, Method = method, Uri = uri, FormData = FormData, UserAgent = userAgent, Referer = Referer, Country = geoIP.Country, City = geoIP.City, Region = geoIP.Region, Time = DateTime.Now }; // Записываем данные в журнал switch (Domain.confToLog.Jurn303) { 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 }); } } #endregion #region Локальный метод - "AddJurnalTo200" void AddJurnalTo200(bool IsAntiBot = false, bool Is2FA = false, bool IsIPtables = false) { // Игнорирование логов if (Domain.confToLog.IsActive && !Regex.IsMatch(uri, Domain.IgnoreLogToRegex, RegexOptions.IgnoreCase)) { ThreadPool.QueueUserWorkItem(ob => { var geoIP = (Country: "Disabled", City: "Disabled", Region: "Disabled"); if (Domain.confToLog.EnableGeoIP) { geoIP = GeoIP2.City(IP); } #region Тип журнала var typeJurn = TypeJurn200.Unknown; if (IsAntiBot) { typeJurn = TypeJurn200.AntiBot; } if (Is2FA) { typeJurn = TypeJurn200._2FA; } if (IsIPtables) { typeJurn = TypeJurn200.IPtables; } #endregion var model = new Jurnal200() { typeJurn = typeJurn, IP = IP, Host = host, Method = method, Uri = uri, FormData = FormData, 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; } }); } } #endregion #region Локальный метод - "SetBlockedToIPtables" void SetBlockedToIPtables(string Msg, DateTime Expires, string PtrHostName) { // Данные для статистики SetCountRequestToHour(TypeRequest._401, host, Domain.confToLog.EnableCountRequest); // Записываем IP в кеш IPtables memoryCache.Set(KeyToMemoryCache.IPtables(IP, host), new IPtables(Msg, Expires), Expires); // Дублируем информацию в SQL WriteLogTo.SQL(new BlockedIP() { IP = IP, BlockingTime = Expires, Description = Msg, typeBlockIP = TypeBlockIP.domain, 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; } } } #endregion #region Локальный метод - "CheckLinkWhitelistToAllDomain" bool CheckLinkWhitelistToAllDomain() { // Глобальный доступ для IP ко всем сайтам // Глобальный доступ для IP в этому сайту if (memoryCache.TryGetValue(KeyToMemoryCache.CheckLinkWhitelistToAllDomain(IP), out byte _) || memoryCache.TryGetValue(KeyToMemoryCache.CheckLinkWhitelistToAll(host, IP), out byte _)) { return(true); } // IP для проверки в формате /24 string ipCache = Regex.Replace(IP, @"\.[0-9]+$", "");; // Глобальный доступ для IP ко всем сайтам // Глобальный доступ для IP в этому сайту if (memoryCache.TryGetValue(KeyToMemoryCache.CheckLinkWhitelistToAllDomain(ipCache), out byte _) || memoryCache.TryGetValue(KeyToMemoryCache.CheckLinkWhitelistToAll(host, ipCache), out byte _)) { return(true); } // IP нету в белом списке return(false); } #endregion }
public static void CreateToOnCallback() { try { // Настройка tlg = Service.Get <JsonDB>().TelegramBot; Bot = new TelegramBotClient(tlg.Token); Bot.SetWebhookAsync("").Wait(); // Callback Bot.OnCallbackQuery += async(object sc, CallbackQueryEventArgs ev) => { try { var message = ev.CallbackQuery.Message; if (ev.CallbackQuery.Data.Contains("AuthCmd")) { // IP адрес string IP = new Regex("([^\n\r\t ]+)([\n\r\t ]+)?$").Match(message.Text).Groups[0].Value; #region Действие switch (ev.CallbackQuery.Data) { case "AuthCmd-Access": { memoryCache.Set(GetKey(IP, message.Text.Contains("2FA")), (byte)0, TimeSpan.FromMinutes(20)); await Bot.SendTextMessageAsync(message.Chat.Id, $"Доступ для '{IP}' разрешен"); break; } case "AuthCmd-NotAccess": { await Bot.SendTextMessageAsync(message.Chat.Id, "Рекомендуем сменить пароли"); break; } case "AuthCmd-BlockedIP": { // Записываем IP в кеш IPtables memoryCache.Set(KeyToMemoryCache.IPtables(IP), new IPtables("TelegramBot", DateTime.Now.AddHours(1)), TimeSpan.FromHours(1)); await Bot.SendTextMessageAsync(message.Chat.Id, $"IP '{IP}' заблокирован\nРекомендуем сменить пароли"); break; } } #endregion // Отсылаем пустое, чтобы убрать "часики" на кнопке await Bot.AnswerCallbackQueryAsync(ev.CallbackQuery.Id); } } catch { } }; // Запускаем прием обновлений new System.Threading.Thread(() => Bot.StartReceiving()).Start(); } catch { } }
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IApplicationLifetime applicationLifetime, IMemoryCache memoryCache) { #region Системные настройки loggerFactory.AddConsole(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); // Страница для тестов app.UseMvc(routes => routes.MapRoute("TestPage", "test", new { controller = "Test", action = "Index" })); } #endregion #region Добовляем порт в белый список if (Platform.Get == PlatformOS.Unix) { if (string.IsNullOrWhiteSpace(new Bash().Run("iptables -L INPUT -v -n 2>/dev/null | grep 8793"))) { new Bash().Run("iptables -I INPUT -p tcp --dport 8793 -j ACCEPT"); } } #endregion #region Unix Socket try { applicationLifetime.ApplicationStarted.Register(() => { if (Platform.Get == PlatformOS.Unix || Platform.Get == PlatformOS.Docker) { ThreadPool.QueueUserWorkItem((s) => { while (true) { // Ждем 3 секунды Thread.Sleep(1000 * 3); // Меняем права доступа if (File.Exists("/var/run/ispcore.sock")) { new Bash().Run("chmod 666 /var/run/ispcore.sock"); return; } } }); } }); } catch { } #endregion // Создаем сервис Service.Create(memoryCache); #region Загружаем список BlockedIP в кеш using (CoreDB coreDB = Service.Get <CoreDB>()) { // IP который нужно удалить string unlockip = string.Empty; if (File.Exists($"{Folders.Tmp}/unlockip.root")) { unlockip = File.ReadAllText($"{Folders.Tmp}/unlockip.root").Trim(); } // Загружаем IP адреса foreach (var blockedIP in coreDB.BlockedsIP.AsNoTracking()) { if (blockedIP.BlockingTime > DateTime.Now && blockedIP.typeBlockIP != TypeBlockIP.UserAgent) { // IP адрес string RemoteIpAddress = blockedIP.IP.Replace(".*", "").Replace(":*", ""); // Белый IP if (RemoteIpAddress.Contains(unlockip)) { continue; } // Где именно блокировать IP string keyIPtables = blockedIP.typeBlockIP == TypeBlockIP.domain ? KeyToMemoryCache.IPtables(RemoteIpAddress, blockedIP.BlockedHost) : KeyToMemoryCache.IPtables(RemoteIpAddress); // Записываем IP в кеш IPtables memoryCache.Set(keyIPtables, new IPtables(blockedIP.Description, blockedIP.BlockingTime), blockedIP.BlockingTime); } } } #endregion #region Загружаем список WhitePtrIP в кеш using (CoreDB coreDB = Service.Get <CoreDB>()) { // Загружаем IP адреса foreach (var item in coreDB.WhitePtrIPs.AsNoTracking()) { // Добовляем IP в кеш if (item.Expires > DateTime.Now) { memoryCache.Set(KeyToMemoryCache.WhitePtrIP(item.IPv4Or6), (byte)0, item.Expires); } } } #endregion #region Загружаем список "Разрешенные доступы" в кеш foreach (var item in AccessIP.List()) { // IP для кеша string ipCache = item.IP.Replace(".*", "").Replace(":*", ""); switch (item.accessType) { case AccessType.all: memoryCache.Set(KeyToMemoryCache.CheckLinkWhitelistToAll(item.host, ipCache), (byte)1, item.Expires); break; case AccessType.Is2FA: memoryCache.Set(KeyToMemoryCache.CheckLinkWhitelistTo2FA(item.host, ipCache), (byte)1, item.Expires); break; case AccessType.allDomain: memoryCache.Set(KeyToMemoryCache.CheckLinkWhitelistToAllDomain(ipCache), (byte)1, item.Expires); break; } } #endregion // Статичиские файлы app.UseStaticFiles(); #region IP-адрес клиента app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto, KnownProxies = { IPAddress.Parse("172.17.42.1"), IPAddress.Parse("127.0.0.1") }, }); #endregion // Страницы ошибок app.UseMvc(routes => { routes.MapRoute("ErrorPage-404", "404", new { controller = "Error", action = "_404" }); }); // Блокировка IP app.UseIPtablesMiddleware(); #region Core API // Доступ запрещен с порта панели 8793 app.UseCoreMiddleware(); // Core CheckRequest app.Map("/core/check/request", ap => ap.Run(context => { // Состояние потока bool RanToCompletion = false; // Завершаем подключение через 10 секунд var token = new CancellationTokenSource(1000 * 10).Token; token.Register(() => { if (!RanToCompletion) { context.Abort(); } }); // Проверка запроса var task = Engine.core.Check.Request.Check(context); RanToCompletion = task.Status == TaskStatus.RanToCompletion; // Успех return(task); })); // Core API app.UseMvc(routes => { routes.MapRoute(null, "core/unlock/2fa", new { controller = "CoreUnlock2FA", action = "Index" }); routes.MapRoute(null, "core/check/cookie", new { controller = "CoreCheckCookie", action = "Index" }); routes.MapRoute(null, "core/check/recaptcha", new { controller = "CoreCheckRecaptcha", action = "Base" }); routes.MapRoute(null, "core/check/recaptcha/limitrequest", new { controller = "CoreCheckRecaptcha", action = "LimitRequest" }); }); // AntiBotHub app.UseSignalR(routes => routes.MapHub <AntiBotHub>("core/AntiBotHub")); // Генерация скриптов app.UseMvc(routes => { routes.MapRoute(null, "core/gen/antibot.js", new { controller = "CoreGenToAntiBot", action = "Index" }); }); // Заглушка для "Core API" app.Map("/core", ap => ap.Run(context => context.Response.WriteAsync("404 Not Found"))); #endregion #region Открытый API { // Проверка авторизации app.UseAuthApiMiddleware(); #region API - List app.UseMvc(routes => { routes.MapRoute(null, "api/list/home/jurnal", new { controller = "ApiListHome", action = "Jurnal" }); routes.MapRoute(null, "api/list/notifications", new { controller = "ApiListNotifications", action = "Jurnal" }); routes.MapRoute(null, "api/list/jsondb", new { controller = "ApiListJsonDB", action = "Get" }); routes.MapRoute(null, "api/list/security/anti-ddos/stats/day", new { controller = "ApiListAntiDdos", action = "StatsDay" }); routes.MapRoute(null, "api/list/security/anti-ddos/stats/month", new { controller = "ApiListAntiDdos", action = "StatsMonth" }); routes.MapRoute(null, "api/list/security/anti-ddos/jurnal", new { controller = "ApiListAntiDdos", action = "Jurnal" }); routes.MapRoute(null, "api/list/security/iptables/blockedip", new { controller = "ApiListIptables", action = "BlockedsIP" }); routes.MapRoute(null, "api/list/security/av/report", new { controller = "ApiListAntiVirus", action = "Report" }); routes.MapRoute(null, "api/list/requests-filter/domain", new { controller = "ApiListDomain", action = "Domain" }); routes.MapRoute(null, "api/list/requests-filter/domains", new { controller = "ApiListDomain", action = "Domains" }); routes.MapRoute(null, "api/list/requests-filter/template", new { controller = "ApiListTemplate", action = "Template" }); routes.MapRoute(null, "api/list/requests-filter/templates", new { controller = "ApiListTemplate", action = "Templates" }); routes.MapRoute(null, "api/list/requests-filter/access", new { controller = "ApiListAccess", action = "Get" }); routes.MapRoute(null, "api/list/requests-filter/monitoring/stats/day", new { controller = "ApiListMonitoring", action = "StatsDay" }); routes.MapRoute(null, "api/list/requests-filter/monitoring/stats/month", new { controller = "ApiListMonitoring", action = "StatsMonth" }); routes.MapRoute(null, "api/list/requests-filter/monitoring/jurnal", new { controller = "ApiListMonitoring", action = "Jurnal" }); routes.MapRoute(null, "api/list/backup/task", new { controller = "ApiListBackup", action = "Task" }); routes.MapRoute(null, "api/list/backup/tasks", new { controller = "ApiListBackup", action = "Tasks" }); routes.MapRoute(null, "api/list/backup/operations", new { controller = "ApiListBackup", action = "Operation" }); }); #endregion #region API - Add app.UseMvc(routes => { routes.MapRoute(null, "api/add/whitelist", new { controller = "ApiAddWhiteList", action = "Base" }); routes.MapRoute(null, "api/add/security/iptables", new { controller = "ApiAddIptables", action = "Base" }); routes.MapRoute(null, "api/add/backup/task", new { controller = "ApiAddBackup", action = "Task" }); routes.MapRoute(null, "api/add/backup/ignore", new { controller = "ApiAddBackup", action = "Ignore" }); routes.MapRoute(null, "api/add/requests-filter/template", new { controller = "ApiAddTemplate", action = "Base" }); routes.MapRoute(null, "api/add/requests-filter/template/rule", new { controller = "ApiAddRule", action = "RuleTemplate" }); routes.MapRoute(null, "api/add/requests-filter/domain", new { controller = "ApiAddDomain", action = "Domain" }); routes.MapRoute(null, "api/add/requests-filter/aliases", new { controller = "ApiAddDomain", action = "Aliases" }); routes.MapRoute(null, "api/add/requests-filter/domain/rule", new { controller = "ApiAddRule", action = "RuleDomain" }); routes.MapRoute(null, "api/add/requests-filter/domain/template", new { controller = "ApiAddDomain", action = "TemplatesId" }); routes.MapRoute(null, "api/add/requests-filter/domain/ignore", new { controller = "ApiAddDomain", action = "IgnoreLogs" }); routes.MapRoute(null, "api/add/requests-filter/access", new { controller = "ApiAddAccess", action = "Base" }); }); #endregion #region API - Remove app.UseMvc(routes => { routes.MapRoute(null, "api/remove/whitelist", new { controller = "ApiRemoveWhiteList", action = "Base" }); routes.MapRoute(null, "api/remove/security/iptables", new { controller = "ApiRemoveIptables", action = "BlockedsIP" }); routes.MapRoute(null, "api/remove/security/antivirus", new { controller = "ApiRemoveAntivirus", action = "Base" }); routes.MapRoute(null, "api/remove/backup/task", new { controller = "ApiRemoveBackup", action = "Task" }); routes.MapRoute(null, "api/remove/backup/ignore", new { controller = "ApiRemoveBackup", action = "Ignore" }); routes.MapRoute(null, "api/remove/requests-filter/rules/base", new { controller = "ApiRemoveRules", action = "Rule" }); routes.MapRoute(null, "api/remove/requests-filter/rules/replace", new { controller = "ApiRemoveRules", action = "RuleReplace" }); routes.MapRoute(null, "api/remove/requests-filter/rules/override", new { controller = "ApiRemoveRules", action = "RuleOverride" }); routes.MapRoute(null, "api/remove/requests-filter/rules/arg", new { controller = "ApiRemoveRules", action = "RuleArg" }); routes.MapRoute(null, "api/remove/requests-filter/alias", new { controller = "ApiRemoveDomain", action = "Alias" }); routes.MapRoute(null, "api/remove/requests-filter/domain", new { controller = "ApiRemoveDomain", action = "Base" }); routes.MapRoute(null, "api/remove/requests-filter/domain/template", new { controller = "ApiRemoveDomain", action = "Template" }); routes.MapRoute(null, "api/remove/requests-filter/domain/ignore", new { controller = "ApiRemoveDomain", action = "Ignore" }); routes.MapRoute(null, "api/remove/requests-filter/template", new { controller = "ApiRemoveTemplate", action = "Base" }); routes.MapRoute(null, "api/remove/requests-filter/access", new { controller = "ApiRemoveAccess", action = "Base" }); }); #endregion #region API - Common app.UseMvc(routes => { routes.MapRoute(null, "api/common/av/start", new { controller = "ApiCommonAV", action = "Start" }); routes.MapRoute(null, "api/common/av/stop", new { controller = "ApiCommonAV", action = "Stop" }); routes.MapRoute(null, "api/common/template/export", new { controller = "ApiCommonTemplate", action = "Export" }); routes.MapRoute(null, "api/common/template/import", new { controller = "ApiCommonTemplate", action = "Import" }); routes.MapRoute(null, "api/common/backup/clearing/cache", new { controller = "ApiCommonBackup", action = "ClearingCache" }); routes.MapRoute(null, "api/common/backup/recovery", new { controller = "ApiCommonBackup", action = "Recovery" }); }); #endregion #region API - Edit app.UseMvc(routes => { routes.MapRoute(null, "api/edit/settings/base", new { controller = "ApiEditSettings", action = "Base" }); routes.MapRoute(null, "api/edit/settings/api", new { controller = "ApiEditSettings", action = "API" }); routes.MapRoute(null, "api/edit/settings/security", new { controller = "ApiEditSettings", action = "Security" }); routes.MapRoute(null, "api/edit/settings/passwd", new { controller = "ApiEditSettings", action = "Passwd" }); routes.MapRoute(null, "api/edit/settings/brute-force", new { controller = "ApiEditSettings", action = "BruteForce" }); routes.MapRoute(null, "api/edit/settings/telegrambot", new { controller = "ApiEditSettings", action = "TelegramBot" }); routes.MapRoute(null, "api/edit/settings/anti-ddos", new { controller = "ApiEditSettings", action = "AntiDdos" }); routes.MapRoute(null, "api/edit/settings/antivirus", new { controller = "ApiEditSettings", action = "AntiVirus" }); routes.MapRoute(null, "api/edit/antibot/base", new { controller = "ApiEditAntiBot", action = "Base" }); routes.MapRoute(null, "api/edit/antibot/limit", new { controller = "ApiEditAntiBot", action = "Limit" }); routes.MapRoute(null, "api/edit/domain/base", new { controller = "ApiEditDomain", action = "Base" }); routes.MapRoute(null, "api/edit/domain/log", new { controller = "ApiEditDomain", action = "LogSettings" }); routes.MapRoute(null, "api/edit/domain/av", new { controller = "ApiEditDomain", action = "AntiVirus" }); routes.MapRoute(null, "api/edit/domain/antibot", new { controller = "ApiEditDomain", action = "AntiBot" }); routes.MapRoute(null, "api/edit/domain/limit/request", new { controller = "ApiEditDomain", action = "LimitRequest" }); routes.MapRoute(null, "api/edit/template", new { controller = "ApiEditTemplate", action = "Base" }); routes.MapRoute(null, "api/edit/backup/task", new { controller = "ApiEditBackup", action = "Task" }); routes.MapRoute(null, "api/edit/backup/ftp", new { controller = "ApiEditBackup", action = "FTP" }); routes.MapRoute(null, "api/edit/backup/webdav", new { controller = "ApiEditBackup", action = "WebDav" }); routes.MapRoute(null, "api/edit/backup/onedrive", new { controller = "ApiEditBackup", action = "OneDrive" }); }); #endregion } #endregion #region Авторизация // Страница авторизации app.UseMvc(routes => { routes.MapRoute(null, "auth", new { controller = "Auth", action = "Index" }); routes.MapRoute(null, "auth/unlock", new { controller = "Auth", action = "Unlock" }); routes.MapRoute(null, "auth/signout", new { controller = "Auth", action = "SignOut" }); }); // Проверка авторизации app.UseAuthMiddleware(); #endregion // Главная страница app.UseMvc(routes => { routes.MapRoute(null, "", new { controller = "Home", action = "Index" }); }); #region API // FAQ app.UseMvc(routes => routes.MapRoute(null, "api/faq", new { controller = "ApiFaq", action = "Index" })); // Заглушка для "API" app.Map("/api", ap => ap.Run(context => context.Response.WriteAsync("404 Not Found"))); #endregion #region Настройки app.UseMvc(routes => { routes.MapRoute(null, "settings", new { controller = "Settings", action = "Index" }); routes.MapRoute(null, "settings/save/base", new { controller = "Settings", action = "Save" }); routes.MapRoute(null, "settings/remove/whiteList", new { controller = "Settings", action = "RemoveWhiteList" }); }); #endregion #region Безопастность системы // Брандмауэр app.UseMvc(routes => { routes.MapRoute(null, "security/iptables", new { controller = "SecurityToIPtables", action = "Index" }); routes.MapRoute(null, "security/iptables/remove", new { controller = "SecurityToIPtables", action = "Remove" }); routes.MapRoute(null, "security/iptables/add", new { controller = "SecurityToIPtables", action = "Add" }); }); // Антивирус app.UseMvc(routes => { routes.MapRoute(null, "security/antivirus", new { controller = "SecurityToAntiVirus", action = "Index" }); routes.MapRoute(null, "security/antivirus/save", new { controller = "SecurityToAntiVirus", action = "Save" }); routes.MapRoute(null, "security/antivirus/remove", new { controller = "SecurityToAntiVirus", action = "Remove" }); routes.MapRoute(null, "security/antivirus/start", new { controller = "SecurityToAntiVirus", action = "Start" }); routes.MapRoute(null, "security/antivirus/stop", new { controller = "SecurityToAntiVirus", action = "Stop" }); }); // Антидосс if (Platform.Get == PlatformOS.Unix) { app.UseMvc(routes => { routes.MapRoute(null, "security/anti-ddos", new { controller = "SecurityToAntiDdos", action = "Index" }); routes.MapRoute(null, "security/anti-ddos/save", new { controller = "SecurityToAntiDdos", action = "Save" }); }); } // Anti-Bot app.UseMvc(routes => { routes.MapRoute(null, "security/antibot", new { controller = "SecurityToAntiBot", action = "Index" }); routes.MapRoute(null, "security/antibot/save", new { controller = "SecurityToAntiBot", action = "Save" }); }); #endregion #region Фильтрация запросов // Views app.UseMvc(routes => { routes.MapRoute(null, "requests-filter/domains", new { controller = "RequestsFilterToDomains", action = "Index" }); routes.MapRoute(null, "requests-filter/templates", new { controller = "RequestsFilterToTemplates", action = "Index" }); routes.MapRoute(null, "requests-filter/monitoring", new { controller = "RequestsFilterToMonitoring", action = "Index" }); }); // Common app.UseMvc(routes => { routes.MapRoute(null, "requests-filter/common/remove/rule", new { controller = "RequestsFilterToCommon", action = "RemoveToRule" }); routes.MapRoute(null, "requests-filter/common/remove/rulereplace", new { controller = "RequestsFilterToCommon", action = "RemoveToRuleReplace" }); routes.MapRoute(null, "requests-filter/common/remove/ruleoverride", new { controller = "RequestsFilterToCommon", action = "RemoveToRuleOverride" }); routes.MapRoute(null, "requests-filter/common/remove/rulearg", new { controller = "RequestsFilterToCommon", action = "RemoveToRuleArg" }); routes.MapRoute(null, "requests-filter/common/remove/alias", new { controller = "RequestsFilterToCommon", action = "RemoveToAlias" }); }); // Шаблон app.UseMvc(routes => { routes.MapRoute(null, "requests-filter/template", new { controller = "RequestsFilterToTemplate", action = "Index" }); routes.MapRoute(null, "requests-filter/template/save", new { controller = "RequestsFilterToTemplate", action = "Save" }); routes.MapRoute(null, "requests-filter/template/remove", new { controller = "RequestsFilterToTemplate", action = "Remove" }); routes.MapRoute(null, "requests-filter/template/import", new { controller = "RequestsFilterToTemplate", action = "Import" }); routes.MapRoute(null, "requests-filter/template/export", new { controller = "RequestsFilterToTemplate", action = "Export" }); }); // Разрешенные доступы app.UseMvc(routes => { routes.MapRoute(null, "requests-filter/access", new { controller = "RequestsFilterToAccess", action = "Index" }); routes.MapRoute(null, "requests-filter/access/open", new { controller = "RequestsFilterToAccess", action = "Open" }); routes.MapRoute(null, "requests-filter/access/remove", new { controller = "RequestsFilterToAccess", action = "Remove" }); }); #endregion #region Фильтрация запросов - Домен // Домен - Главная/FAQ app.UseMvc(routes => { routes.MapRoute(null, "requests-filter/domain/base", new { controller = "RequestsFilterToDomainBase", action = "Index" }); routes.MapRoute(null, "requests-filter/domain/faq", new { controller = "RequestsFilterToDomainBase", action = "Faq" }); routes.MapRoute(null, "requests-filter/domain/remove", new { controller = "RequestsFilterToDomainBase", action = "Remove" }); routes.MapRoute(null, "requests-filter/domain/save/base", new { controller = "RequestsFilterToDomainBase", action = "Save" }); routes.MapRoute(null, "requests-filter/domain/import", new { controller = "RequestsFilterToDomainBase", action = "Import" }); routes.MapRoute(null, "requests-filter/domain/export", new { controller = "RequestsFilterToDomainBase", action = "Export" }); }); // Домен - Алиасы app.UseMvc(routes => { routes.MapRoute(null, "requests-filter/domain/aliases", new { controller = "RequestsFilterToDomainAliases", action = "Index" }); routes.MapRoute(null, "requests-filter/domain/save/aliases", new { controller = "RequestsFilterToDomainAliases", action = "Save" }); }); // Домен - Правила app.UseMvc(routes => { routes.MapRoute(null, "requests-filter/domain/rules", new { controller = "RequestsFilterToDomainRules", action = "Index" }); routes.MapRoute(null, "requests-filter/domain/save/rules", new { controller = "RequestsFilterToDomainRules", action = "Save" }); }); // Домен - Настройки журнала app.UseMvc(routes => { routes.MapRoute(null, "requests-filter/domain/logsettings", new { controller = "RequestsFilterToDomainLogSettings", action = "Index" }); routes.MapRoute(null, "requests-filter/domain/save/logsettings", new { controller = "RequestsFilterToDomainLogSettings", action = "Save" }); }); // Домен - Антивирус app.UseMvc(routes => { routes.MapRoute(null, "requests-filter/domain/av", new { controller = "RequestsFilterToDomainAv", action = "Index" }); routes.MapRoute(null, "requests-filter/domain/save/av", new { controller = "RequestsFilterToDomainAv", action = "Save" }); }); // Домен - AntiBot app.UseMvc(routes => { routes.MapRoute(null, "requests-filter/domain/antibot", new { controller = "RequestsFilterToDomainAntiBot", action = "Index" }); routes.MapRoute(null, "requests-filter/domain/save/antibot", new { controller = "RequestsFilterToDomainAntiBot", action = "Save" }); }); // Домен - Лимит запросов app.UseMvc(routes => { routes.MapRoute(null, "requests-filter/domain/limitrequest", new { controller = "RequestsFilterToDomainLimitRequest", action = "Index" }); routes.MapRoute(null, "requests-filter/domain/save/limitrequest", new { controller = "RequestsFilterToDomainLimitRequest", action = "Save" }); }); #endregion #region SyncBackup // Views app.UseMvc(routes => { routes.MapRoute(null, "backup/tasks", new { controller = "SyncBackupToTasks", action = "Index" }); routes.MapRoute(null, "backup/operation", new { controller = "SyncBackupToOperation", action = "Index" }); }); // Задание app.UseMvc(routes => { routes.MapRoute(null, "backup/task", new { controller = "SyncBackupToTask", action = "Index" }); routes.MapRoute(null, "backup/task/remove", new { controller = "SyncBackupToTask", action = "Remove" }); routes.MapRoute(null, "backup/task/save", new { controller = "SyncBackupToTask", action = "Save" }); routes.MapRoute(null, "backup/task/clearing-cache", new { controller = "SyncBackupToTask", action = "ClearingCache" }); }); // Улиты app.UseMvc(routes => { routes.MapRoute(null, "backup/tools", new { controller = "SyncBackupToTools", action = "Index" }); routes.MapRoute(null, "backup/tools/recover", new { controller = "SyncBackupToTools", action = "Recovery" }); }); // Получение токенов app.UseMvc(routes => { routes.MapRoute(null, "backup/authorize/onedrive", new { controller = "SyncBackupToAuthorize", action = "OneDrive" }); }); #endregion // Уведомления app.UseMvc(routes => { routes.MapRoute(null, "notifications", new { controller = "Notifications", action = "Index" }); }); // Ошибка 404 app.Run(async(context) => { await RewriteTo.Local(context, "404" + (context.Request.QueryString.Value.Contains("ajax=true") ? "?ajax=true" : "")); }); }