public JsonResult Save(IDictionary <string, WhiteListModel> whiteList) { #region Демо режим if (Platform.IsDemo) { return(Json(new Text("Операция недоступна в демо-режиме"))); } #endregion #region Проверка IP-адресов foreach (var item in whiteList) { if (!IPNetwork.CheckingSupportToIPv4Or6(item.Value.Value, out _)) { return(Json(new Text($"Not supported format: {item.Value.Value}"))); } } #endregion // Список Id WhiteList IDictionary <string, IId> NewWhiteList = null; // Записываем даннные из whiteList jsonDB.WhiteList.UpdateOrAddRange(whiteList, out NewWhiteList); // Создаем новые Id foreach (var item in whiteList) { if (item.Value != null && item.Value.Id == 0) { item.Value.Id = int.Parse(Generate.Passwd(6, true)); } } // Сохраняем значения jsonDB.Save(); // Кеш настроек WhiteList WhiteUserList.UpdateCache(); // Trigger.OnChange((0, 0)); // Отдаем сообщение и Id новых настроек WhiteList return(Json(new UpdateToIds("Настройки успешно сохранены", 0, NewWhiteList))); }
/// <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>"))); }
/// <summary> /// Кеш настроек WhiteList /// </summary> public static void UpdateCache() { // Оригинальные настройки WhiteList var conf = Service.Get <JsonDB>().WhiteList; #region Локальный метод - "JoinMass" string JoinMass(List <string> mass, bool IsUserAgent = false, bool IsIPv6 = false) { if (mass == null || mass.Count == 0) { return("^$"); } if (IsUserAgent || IsIPv6) { return($"({string.Join("|", mass)})"); } return($"^({string.Join("|", mass)})$"); } #endregion #region Обновляем список IPv4/6 // Базовый список IPv6 var IPv6ToMass = new List <string>() { "::1" }; // Базовый список IPv4 var IPv4ToMass = new List <CidrToIPv4>(); IPv4ToMass.Add(IPNetwork.IPv4ToRange("127.0.0.1")); IPv4ToMass.Add(IPNetwork.IPv4ToRange("8.8.4.4")); IPv4ToMass.Add(IPNetwork.IPv4ToRange("8.8.8.8")); IPv4ToMass.Add(IPNetwork.IPv4ToRange("192.168.0.1", "192.168.0.254")); // Пользовательский список IPv4/6 foreach (string IP in conf.Where(i => i.Type == WhiteListType.IPv4Or6).Select(i => i.Value)) { if (IP.Contains(":")) { // IPv6 if (IPNetwork.CheckingSupportToIPv4Or6(IP, out var ipnetwork)) { IPv6ToMass.Add(IPNetwork.IPv6ToRegex(ipnetwork.FirstUsable)); } } else { // IPv4 if (IPNetwork.CheckingSupportToIPv4Or6(IP, out var ipnetwork)) { if (IPNetwork.IPv4ToRange(ipnetwork.FirstUsable, ipnetwork.LastUsable) is var item && item.FirstUsable != 0) { IPv4ToMass.Add(item); } } } } // Обновляем базу IPv4ToRange = IPv4ToMass.OrderBy(i => i.FirstUsable).ToList(); IPv6ToRegex = JoinMass(IPv6ToMass, IsIPv6: true); #endregion // Базовый список PTR List <string> PTRs = new List <string>(conf.Where(i => i.Type == WhiteListType.PTR).Select(i => i.Value).ToArray()); PTRs.Add(@".*\.(yandex.(ru|net|com)|googlebot.com|google.com|mail.ru|search.msn.com)"); // Создаем кеш PtrRegex = JoinMass(PTRs); UserAgentRegex = JoinMass(conf.Where(i => i.Type == WhiteListType.UserAgent).Select(i => i.Value).ToList(), IsUserAgent: true); LastUpdateCache = DateTime.Now; }
/// <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)); } } } } }