瀏覽代碼

WAF防火墙自动上报cloudflare

懒得勤快 5 年之前
父節點
當前提交
d722c0e8e0

+ 0 - 1
src/Masuit.MyBlogs.Core/Configs/AutofacModule.cs

@@ -2,7 +2,6 @@
 using Hangfire;
 using Masuit.MyBlogs.Core.Extensions;
 using Masuit.MyBlogs.Core.Extensions.Hangfire;
-using System.Diagnostics;
 using System.Reflection;
 
 namespace Masuit.MyBlogs.Core.Configs

+ 5 - 0
src/Masuit.MyBlogs.Core/Controllers/SystemController.cs

@@ -1,4 +1,5 @@
 using Masuit.MyBlogs.Core.Common;
+using Masuit.MyBlogs.Core.Extensions;
 using Masuit.MyBlogs.Core.Extensions.Hangfire;
 using Masuit.MyBlogs.Core.Hubs;
 using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
@@ -19,6 +20,7 @@ using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
+using System.Net;
 using System.Net.Sockets;
 using System.Text;
 using System.Threading.Tasks;
@@ -35,6 +37,8 @@ namespace Masuit.MyBlogs.Core.Controllers
         /// </summary>
         public ISystemSettingService SystemSettingService { get; set; }
 
+        public IFirewallRepoter FirewallRepoter { get; set; }
+
         /// <summary>
         /// 获取硬件基本信息
         /// </summary>
@@ -397,6 +401,7 @@ namespace Masuit.MyBlogs.Core.Controllers
             await System.IO.File.WriteAllTextAsync(Path.Combine(basedir, "App_Data", "denyip.txt"), CommonHelper.DenyIP, Encoding.UTF8);
             CommonHelper.IPWhiteList.Remove(ip);
             await System.IO.File.WriteAllTextAsync(Path.Combine(basedir, "App_Data", "whitelist.txt"), string.Join(",", CommonHelper.IPWhiteList.Distinct()), Encoding.UTF8);
+            await FirewallRepoter.ReportAsync(IPAddress.Parse(ip));
             return ResultData(null);
         }
 

+ 51 - 0
src/Masuit.MyBlogs.Core/Extensions/CloudflareRepoter.cs

@@ -0,0 +1,51 @@
+using Masuit.MyBlogs.Core.Common;
+using Masuit.Tools.Logging;
+using Microsoft.Extensions.Configuration;
+using System.Net;
+using System.Net.Http;
+using System.Net.Sockets;
+using System.Threading.Tasks;
+
+namespace Masuit.MyBlogs.Core.Extensions
+{
+    public class CloudflareRepoter : IFirewallRepoter
+    {
+        private readonly HttpClient _httpClient;
+        private readonly IConfiguration _configuration;
+
+        public CloudflareRepoter(HttpClient httpClient, IConfiguration configuration)
+        {
+            _httpClient = httpClient;
+            _configuration = configuration;
+        }
+
+        public void Report(IPAddress ip)
+        {
+            ReportAsync(ip).Wait();
+        }
+
+        public Task ReportAsync(IPAddress ip)
+        {
+            return _httpClient.PostAsJsonAsync($"https://api.cloudflare.com/client/v4/zones/{_configuration["FirewallService:Cloudflare:ZoneId"]}/firewall/access_rules/rules", new
+            {
+                mode = "block",
+                notes = $"恶意请求IP({ip.GetIPLocation()})",
+                configuration = new
+                {
+                    target = ip.AddressFamily switch
+                    {
+                        AddressFamily.InterNetworkV6 => "ip6",
+                        _ => "ip"
+                    },
+                    value = ip.ToString()
+                }
+            }).ContinueWith(t =>
+            {
+                if (!t.Result.IsSuccessStatusCode)
+                {
+                    LogManager.Info("cloudflare请求出错");
+                }
+            });
+        }
+    }
+}

+ 26 - 0
src/Masuit.MyBlogs.Core/Extensions/DefaultFirewallRepoter.cs

@@ -0,0 +1,26 @@
+using System.Net;
+using System.Threading.Tasks;
+
+namespace Masuit.MyBlogs.Core.Extensions
+{
+    public class DefaultFirewallRepoter : IFirewallRepoter
+    {
+        /// <summary>
+        /// 上报IP
+        /// </summary>
+        /// <param name="ip"></param>
+        public void Report(IPAddress ip)
+        {
+        }
+
+        /// <summary>
+        /// 上报IP
+        /// </summary>
+        /// <param name="ip"></param>
+        /// <returns></returns>
+        public Task ReportAsync(IPAddress ip)
+        {
+            return Task.CompletedTask;
+        }
+    }
+}

+ 3 - 0
src/Masuit.MyBlogs.Core/Extensions/FirewallAttribute.cs

@@ -12,6 +12,7 @@ using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.Filters;
 using System;
 using System.Linq;
+using System.Net;
 using System.Text;
 using System.Text.RegularExpressions;
 using System.Web;
@@ -22,6 +23,7 @@ namespace Masuit.MyBlogs.Core.Extensions
     public class FirewallAttribute : ActionFilterAttribute
     {
         public ICacheManager<int> CacheManager { get; set; }
+        public IFirewallRepoter FirewallRepoter { get; set; }
 
         /// <inheritdoc />
         public override void OnActionExecuting(ActionExecutingContext context)
@@ -84,6 +86,7 @@ namespace Masuit.MyBlogs.Core.Extensions
             if (times > limit * 1.2)
             {
                 CacheManager.Expire("Frequency:" + ip, ExpirationMode.Sliding, TimeSpan.FromMinutes(CommonHelper.SystemSettings.GetOrAdd("BanIPTimespan", "10").ToInt32()));
+                FirewallRepoter.ReportAsync(IPAddress.Parse(ip));
                 AccessDeny(ip, request, "访问频次限制");
             }
 

+ 21 - 0
src/Masuit.MyBlogs.Core/Extensions/IFirewallRepoter.cs

@@ -0,0 +1,21 @@
+using System.Net;
+using System.Threading.Tasks;
+
+namespace Masuit.MyBlogs.Core.Extensions
+{
+    public interface IFirewallRepoter
+    {
+        /// <summary>
+        /// 上报IP
+        /// </summary>
+        /// <param name="ip"></param>
+        void Report(IPAddress ip);
+
+        /// <summary>
+        /// 上报IP
+        /// </summary>
+        /// <param name="ip"></param>
+        /// <returns></returns>
+        Task ReportAsync(IPAddress ip);
+    }
+}

+ 16 - 5
src/Masuit.MyBlogs.Core/Startup.cs

@@ -38,7 +38,6 @@ using StackExchange.Profiling;
 using System;
 using System.IO;
 using System.Linq;
-using System.Net.Http;
 using System.Threading.Tasks;
 using IWebHostEnvironment = Microsoft.AspNetCore.Hosting.IWebHostEnvironment;
 using SameSiteMode = Microsoft.AspNetCore.Http.SameSiteMode;
@@ -125,10 +124,7 @@ namespace Masuit.MyBlogs.Core
                 Path = "lucene"
             }); // 配置7z和断点续传和Redis和Lucene搜索引擎
 
-            services.AddHttpClient("", c => c.Timeout = TimeSpan.FromSeconds(30)).ConfigurePrimaryHttpMessageHandler(provider => new HttpClientHandler
-            {
-                ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
-            }); //注入HttpClient
+            services.AddHttpClient("", c => c.Timeout = TimeSpan.FromSeconds(30)); //注入HttpClient
             services.AddHttpClient<ImagebedClient>();
             services.AddHttpContextAccessor(); //注入静态HttpContext
             services.AddMiniProfiler(options =>
@@ -152,6 +148,21 @@ namespace Masuit.MyBlogs.Core
                     services.AddSingleton<IMailSender, SmtpSender>();
                     break;
             }
+            switch (Configuration["FirewallService:type"])
+            {
+                case "Cloudflare":
+                case "cloudflare":
+                case "cf":
+                    services.AddHttpClient<IFirewallRepoter, CloudflareRepoter>().ConfigureHttpClient(c =>
+                    {
+                        c.DefaultRequestHeaders.Add("X-Auth-Email", Configuration["FirewallService:Cloudflare:AuthEmail"]);
+                        c.DefaultRequestHeaders.Add("X-Auth-Key", Configuration["FirewallService:Cloudflare:AuthKey"]);
+                    });
+                    break;
+                default:
+                    services.AddSingleton<IFirewallRepoter, DefaultFirewallRepoter>();
+                    break;
+            }
             services.AddMapper().AddAutofac().AddMyMvc().Configure<ForwardedHeadersOptions>(options => // X-Forwarded-For
             {
                 options.ForwardLimit = null;

+ 8 - 0
src/Masuit.MyBlogs.Core/appsettings.json

@@ -26,6 +26,14 @@
         "apikey": "mailgun的apikey",
         "from": "[email protected]"
     },
+    "FirewallService": {
+        "type": "cloudflare",
+        "Cloudflare": {
+            "ZoneId": "",
+            "AuthEmail": "",
+            "AuthKey": ""
+        }
+    },
     "Imgbed": { // 图床相关配置
         "EnableLocalStorage": false, // 允许本地硬盘存储?
         "Gitlabs": [