Browse Source

完善防火墙上报cloudflare

懒得勤快 5 years ago
parent
commit
669b655803

+ 10 - 25
src/Masuit.MyBlogs.Core/Common/ImagebedClient.cs

@@ -6,6 +6,7 @@ using Masuit.Tools.Html;
 using Masuit.Tools.Logging;
 using Masuit.Tools.Systems;
 using Microsoft.Extensions.Configuration;
+using Polly;
 using System;
 using System.Collections.Generic;
 using System.IO;
@@ -55,19 +56,9 @@ namespace Masuit.MyBlogs.Core.Common
             }
 
             file = SnowFlake.NewId + Path.GetExtension(file);
-            for (var i = 0; i < 3; i++)
-            {
-                try
-                {
-                    return await UploadGitlab(stream, file);
-                }
-                catch (Exception e)
-                {
-                    LogManager.Error(e);
-                }
-            }
-
-            return UploadOss(stream, file);
+            var fallbackPolicy = Policy<(string url, bool success)>.Handle<Exception>().FallbackAsync(async _ => UploadOss(stream, file));
+            var retryPolicy = Policy<(string url, bool success)>.Handle<Exception>().RetryAsync(3);
+            return await fallbackPolicy.WrapAsync(retryPolicy).ExecuteAsync(() => UploadGitlab(stream, file));
         }
 
         private readonly List<string> _failedList = new List<string>();
@@ -168,19 +159,13 @@ namespace Masuit.MyBlogs.Core.Common
             }
 
             var objectName = DateTime.Now.ToString("yyyy/MM/dd/") + file;
-            for (int i = 0; i < 3; i++)
+            var fallbackPolicy = Policy<(string url, bool success)>.Handle<Exception>().Fallback(_ => (null, false));
+            var retryPolicy = Policy<(string url, bool success)>.Handle<Exception>().Retry(3);
+            return fallbackPolicy.Wrap(retryPolicy).Execute(() =>
             {
-                try
-                {
-                    return OssClient.PutObject(AppConfig.AliOssConfig.BucketName, objectName, stream).HttpStatusCode == HttpStatusCode.OK ? (AppConfig.AliOssConfig.BucketDomain + "/" + objectName, true) : (null, false);
-                }
-                catch (Exception e)
-                {
-                    LogManager.Info($"图片上传到oss失败,重试{i}:" + e.Message);
-                }
-            }
-
-            return (null, false);
+                var result = OssClient.PutObject(AppConfig.AliOssConfig.BucketName, objectName, stream);
+                return result.HttpStatusCode == HttpStatusCode.OK ? (AppConfig.AliOssConfig.BucketDomain + "/" + objectName, true) : throw new Exception("上传oss失败");
+            });
         }
 
         /// <summary>

+ 8 - 14
src/Masuit.MyBlogs.Core/Controllers/BaseController.cs

@@ -2,6 +2,7 @@
 using Masuit.MyBlogs.Core.Common;
 using Masuit.MyBlogs.Core.Configs;
 using Masuit.MyBlogs.Core.Extensions;
+using Masuit.MyBlogs.Core.Extensions.Firewall;
 using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
 using Masuit.MyBlogs.Core.Models.DTO;
 using Masuit.MyBlogs.Core.Models.Enum;
@@ -15,7 +16,6 @@ using Microsoft.EntityFrameworkCore.Internal;
 using System;
 using System.Linq;
 using System.Net;
-using Masuit.MyBlogs.Core.Extensions.Firewall;
 
 namespace Masuit.MyBlogs.Core.Controllers
 {
@@ -149,22 +149,16 @@ namespace Masuit.MyBlogs.Core.Controllers
         /// <param name="filterContext">有关当前请求和操作的信息。</param>
         public override void OnActionExecuted(ActionExecutedContext filterContext)
         {
-            base.OnActionExecuted(filterContext);
-            if (filterContext.HttpContext.Request.Method.Equals("POST", StringComparison.InvariantCultureIgnoreCase))
+            if (filterContext.Result is ViewResult)
             {
-                if (filterContext.Result is ViewResult)
+                ViewBag.menus = MenuService.GetQueryFromCache<MenuDto>(m => m.Status == Status.Available).OrderBy(m => m.Sort).ToList(); //菜单
+                var model = new PageFootViewModel //页脚
                 {
-                    filterContext.Result = ResultData(null, false, "该URL仅支持Get请求方式", false, HttpStatusCode.MethodNotAllowed);
-                }
-                return;
+                    Links = LinksService.GetQueryFromCache<LinksDto>(l => l.Status == Status.Available).OrderByDescending(l => l.Recommend).ThenByDescending(l => l.Weight).ThenByDescending(l => new Random().Next()).Take(30).ToList()
+                };
+                ViewBag.Footer = model;
             }
-
-            ViewBag.menus = MenuService.GetQueryFromCache<MenuDto>(m => m.Status == Status.Available).OrderBy(m => m.Sort).ToList(); //菜单
-            var model = new PageFootViewModel //页脚
-            {
-                Links = LinksService.GetQueryFromCache<LinksDto>(l => l.Status == Status.Available).OrderByDescending(l => l.Recommend).ThenByDescending(l => l.Weight).ThenByDescending(l => new Random().Next()).Take(30).ToList()
-            };
-            ViewBag.Footer = model;
+            base.OnActionExecuted(filterContext);
         }
     }
 }

+ 2 - 1
src/Masuit.MyBlogs.Core/Controllers/PassportController.cs

@@ -1,5 +1,6 @@
 using Masuit.MyBlogs.Core.Common;
 using Masuit.MyBlogs.Core.Configs;
+using Masuit.MyBlogs.Core.Extensions.Firewall;
 using Masuit.MyBlogs.Core.Extensions.Hangfire;
 using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
 using Masuit.MyBlogs.Core.Models.DTO;
@@ -20,7 +21,7 @@ namespace Masuit.MyBlogs.Core.Controllers
     /// <summary>
     /// 登录授权
     /// </summary>
-    [ApiExplorerSettings(IgnoreApi = true)]
+    [ApiExplorerSettings(IgnoreApi = true), ServiceFilter(typeof(FirewallAttribute))]
     public class PassportController : Controller
     {
         /// <summary>

+ 2 - 0
src/Masuit.MyBlogs.Core/Controllers/SubscribeController.cs

@@ -1,5 +1,6 @@
 using Masuit.MyBlogs.Core.Common;
 using Masuit.MyBlogs.Core.Extensions;
+using Masuit.MyBlogs.Core.Extensions.Firewall;
 using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
 using Masuit.MyBlogs.Core.Models.Enum;
 using Masuit.MyBlogs.Core.Models.ViewModel;
@@ -20,6 +21,7 @@ namespace Masuit.MyBlogs.Core.Controllers
     /// <summary>
     /// 订阅服务
     /// </summary>
+    [ServiceFilter(typeof(FirewallAttribute))]
     public class SubscribeController : Controller
     {
         /// <summary>

+ 17 - 9
src/Masuit.MyBlogs.Core/Extensions/Firewall/CloudflareRepoter.cs

@@ -1,6 +1,7 @@
 using Masuit.MyBlogs.Core.Common;
 using Masuit.Tools.Logging;
 using Microsoft.Extensions.Configuration;
+using Polly;
 using System.Net;
 using System.Net.Http;
 using System.Net.Sockets;
@@ -13,14 +14,15 @@ namespace Masuit.MyBlogs.Core.Extensions.Firewall
         private readonly HttpClient _httpClient;
         private readonly IConfiguration _configuration;
 
+        public string ReporterName { get; set; } = "cloudflare";
+
+
         public CloudflareRepoter(HttpClient httpClient, IConfiguration configuration)
         {
             _httpClient = httpClient;
             _configuration = configuration;
         }
 
-        public string ReporterName { get; set; } = "cloudflare";
-
         public void Report(IPAddress ip)
         {
             ReportAsync(ip).Wait();
@@ -28,10 +30,18 @@ namespace Masuit.MyBlogs.Core.Extensions.Firewall
 
         public Task ReportAsync(IPAddress ip)
         {
-            return _httpClient.PostAsJsonAsync($"https://api.cloudflare.com/client/v4/zones/{_configuration["FirewallService:Cloudflare:ZoneId"]}/firewall/access_rules/rules", new
+            var scope = _configuration["FirewallService:Cloudflare:Scope"];
+            var zoneid = _configuration["FirewallService:Cloudflare:ZoneId"];
+            var fallbackPolicy = Policy.HandleInner<HttpRequestException>().FallbackAsync(_ =>
+            {
+                LogManager.Info($"cloudflare请求出错,{ip}上报失败!");
+                return Task.CompletedTask;
+            });
+            var retryPolicy = Policy.HandleInner<HttpRequestException>().RetryAsync(3);
+            return fallbackPolicy.WrapAsync(retryPolicy).ExecuteAsync(() => _httpClient.PostAsJsonAsync($"https://api.cloudflare.com/client/v4/{scope}/{zoneid}/firewall/access_rules/rules", new
             {
                 mode = "block",
-                notes = $"恶意请求IP({ip.GetIPLocation()})",
+                notes = $"恶意请求IP{ip.GetIPLocation()}",
                 configuration = new
                 {
                     target = ip.AddressFamily switch
@@ -43,13 +53,11 @@ namespace Masuit.MyBlogs.Core.Extensions.Firewall
                 }
             }).ContinueWith(t =>
             {
-                if (t.IsFaulted || t.IsCanceled || !t.Result.IsSuccessStatusCode)
+                if (!t.Result.IsSuccessStatusCode)
                 {
-                    LogManager.Info("cloudflare请求出错");
+                    throw new HttpRequestException("请求失败");
                 }
-
-                return Task.CompletedTask;
-            });
+            }));
         }
     }
 }

+ 1 - 0
src/Masuit.MyBlogs.Core/Masuit.MyBlogs.Core.csproj

@@ -51,6 +51,7 @@
         <PackageReference Include="OpenXmlPowerTools-NetStandard" Version="4.4.21" />
         <PackageReference Include="MiniProfiler.EntityFrameworkCore" Version="4.2.1" />
         <PackageReference Include="PanGu.HighLight" Version="1.0.0" />
+        <PackageReference Include="Polly" Version="7.2.1" />
         <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.2.1" />
         <PackageReference Include="Svg" Version="3.1.1" />
         <PackageReference Include="System.Linq.Dynamic.Core" Version="1.2.2" />

+ 7 - 6
src/Masuit.MyBlogs.Core/appsettings.json

@@ -26,12 +26,13 @@
         "apikey": "mailgun的apikey",
         "from": "[email protected]"
     },
-    "FirewallService": {
-        "type": "cloudflare",
-        "Cloudflare": {
-            "ZoneId": "",
-            "AuthEmail": "",
-            "AuthKey": ""
+    "FirewallService": { // 防火墙服务上报模块配置
+        "type": "cloudflare", // cloudflare或none
+        "Cloudflare": { // type为cloudflare时生效
+            "Scope": "accounts", // 范围:accounts、zones
+            "ZoneId": "区域或账户id", // 区域或账户id,scope为accounts则填账户id,scope为zones则填zoneid
+            "AuthEmail": "授权邮箱账号", // 授权邮箱账号
+            "AuthKey": "AuthKey" // apikey
         }
     },
     "Imgbed": { // 图床相关配置