From ec7515dfda5664df88c327429242805bc596b378 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=80=81=E4=B9=9D?= <366193849@qq.com>
Date: Thu, 11 Nov 2021 22:32:10 +0800
Subject: [PATCH] =?UTF-8?q?=E9=83=A8=E5=88=86linux=E4=B8=8Broot=E7=94=A8?=
=?UTF-8?q?=E6=88=B7=E8=87=AA=E5=8A=A8=E5=AE=89=E8=A3=85ca=E8=AF=81?=
=?UTF-8?q?=E4=B9=A6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../CaCertInstallerOfLinux.cs | 77 +++++++++++++++++++
.../CaCertInstallerOfLinuxCentOS.cs | 20 +++++
.../CaCertInstallerOfLinuxDebain.cs | 20 +++++
.../CaCertInstallerOfLinuxUbuntu.cs | 16 ++++
.../CaCertInstallerOfMacOS.cs | 27 +++++++
.../CaCertInstallerOfWindows.cs | 51 ++++++++++++
FastGithub.HttpServer/CertService.cs | 50 ++----------
FastGithub.HttpServer/ICaCertInstaller.cs | 23 ++++++
.../ServiceCollectionExtensions.cs | 10 ++-
publish.cmd | 7 +-
10 files changed, 251 insertions(+), 50 deletions(-)
create mode 100644 FastGithub.HttpServer/CaCertInstallerOfLinux.cs
create mode 100644 FastGithub.HttpServer/CaCertInstallerOfLinuxCentOS.cs
create mode 100644 FastGithub.HttpServer/CaCertInstallerOfLinuxDebain.cs
create mode 100644 FastGithub.HttpServer/CaCertInstallerOfLinuxUbuntu.cs
create mode 100644 FastGithub.HttpServer/CaCertInstallerOfMacOS.cs
create mode 100644 FastGithub.HttpServer/CaCertInstallerOfWindows.cs
create mode 100644 FastGithub.HttpServer/ICaCertInstaller.cs
diff --git a/FastGithub.HttpServer/CaCertInstallerOfLinux.cs b/FastGithub.HttpServer/CaCertInstallerOfLinux.cs
new file mode 100644
index 0000000..676c519
--- /dev/null
+++ b/FastGithub.HttpServer/CaCertInstallerOfLinux.cs
@@ -0,0 +1,77 @@
+using Microsoft.Extensions.Logging;
+using System;
+using System.Diagnostics;
+using System.IO;
+
+namespace FastGithub.HttpServer
+{
+ abstract class CaCertInstallerOfLinux : ICaCertInstaller
+ {
+ const string OS_RELEASE_FILE = "/etc/os-release";
+
+ ///
+ /// 更新工具文件名
+ ///
+ public abstract string CertUpdateFileName { get; }
+
+ ///
+ /// 证书根目录
+ ///
+ public abstract string RootCertPath { get; }
+
+ ///
+ /// 是否支持
+ ///
+ ///
+ public abstract bool IsSupported();
+
+ ///
+ /// 安装ca证书
+ ///
+ /// 证书文件路径
+ ///
+ public void Install(string caCertFilePath, ILogger logger)
+ {
+ if (Environment.UserName != "root")
+ {
+ logger.LogWarning($"无法自动安装CA证书{caCertFilePath},因为没有root权限");
+ return;
+ }
+
+ try
+ {
+ Directory.CreateDirectory(this.RootCertPath);
+ var destCertFilePath = Path.Combine(this.RootCertPath, "fastgithub.crt");
+ File.Copy(caCertFilePath, destCertFilePath, overwrite: true);
+ Process.Start(this.CertUpdateFileName).WaitForExit();
+ }
+ catch (Exception ex)
+ {
+ logger.LogWarning(ex.Message, "自动安装证书异常");
+ }
+ }
+
+
+ ///
+ /// 是否为某个发行版
+ ///
+ ///
+ ///
+ protected bool IsReleasName(string name)
+ {
+ if (File.Exists(OS_RELEASE_FILE) == false)
+ {
+ return false;
+ }
+
+ var releaseLines = File.ReadAllLines(OS_RELEASE_FILE);
+ if (releaseLines.Length == 0)
+ {
+ return false;
+ }
+
+ var nameLine = releaseLines[0];
+ return nameLine.Contains(name);
+ }
+ }
+}
\ No newline at end of file
diff --git a/FastGithub.HttpServer/CaCertInstallerOfLinuxCentOS.cs b/FastGithub.HttpServer/CaCertInstallerOfLinuxCentOS.cs
new file mode 100644
index 0000000..69f5333
--- /dev/null
+++ b/FastGithub.HttpServer/CaCertInstallerOfLinuxCentOS.cs
@@ -0,0 +1,20 @@
+using System;
+
+namespace FastGithub.HttpServer
+{
+ class CaCertInstallerOfLinuxCentOS : CaCertInstallerOfLinux
+ {
+ public override string RootCertPath => "/etc/pki/ca-trust/source/anchors";
+
+ public override string CertUpdateFileName => "update-ca-trust";
+
+ ///
+ /// 是否支持
+ ///
+ ///
+ public override bool IsSupported()
+ {
+ return OperatingSystem.IsLinux() && base.IsReleasName("CentOS");
+ }
+ }
+}
\ No newline at end of file
diff --git a/FastGithub.HttpServer/CaCertInstallerOfLinuxDebain.cs b/FastGithub.HttpServer/CaCertInstallerOfLinuxDebain.cs
new file mode 100644
index 0000000..eb016d4
--- /dev/null
+++ b/FastGithub.HttpServer/CaCertInstallerOfLinuxDebain.cs
@@ -0,0 +1,20 @@
+using System;
+
+namespace FastGithub.HttpServer
+{
+ class CaCertInstallerOfLinuxDebain : CaCertInstallerOfLinux
+ {
+ public override string RootCertPath => "/usr/local/share/ca-certificates";
+
+ public override string CertUpdateFileName => "update-ca-certificates";
+
+ ///
+ /// 是否支持
+ ///
+ ///
+ public override bool IsSupported()
+ {
+ return OperatingSystem.IsLinux() && base.IsReleasName("Debain");
+ }
+ }
+}
\ No newline at end of file
diff --git a/FastGithub.HttpServer/CaCertInstallerOfLinuxUbuntu.cs b/FastGithub.HttpServer/CaCertInstallerOfLinuxUbuntu.cs
new file mode 100644
index 0000000..c94bd4b
--- /dev/null
+++ b/FastGithub.HttpServer/CaCertInstallerOfLinuxUbuntu.cs
@@ -0,0 +1,16 @@
+using System;
+
+namespace FastGithub.HttpServer
+{
+ sealed class CaCertInstallerOfLinuxUbuntu : CaCertInstallerOfLinuxDebain
+ {
+ ///
+ /// 是否支持
+ ///
+ ///
+ public override bool IsSupported()
+ {
+ return OperatingSystem.IsLinux() && base.IsReleasName("Ubuntu");
+ }
+ }
+}
\ No newline at end of file
diff --git a/FastGithub.HttpServer/CaCertInstallerOfMacOS.cs b/FastGithub.HttpServer/CaCertInstallerOfMacOS.cs
new file mode 100644
index 0000000..580d3b5
--- /dev/null
+++ b/FastGithub.HttpServer/CaCertInstallerOfMacOS.cs
@@ -0,0 +1,27 @@
+using Microsoft.Extensions.Logging;
+using System;
+
+namespace FastGithub.HttpServer
+{
+ sealed class CaCertInstallerOfMacOS : ICaCertInstaller
+ {
+ ///
+ /// 是否支持
+ ///
+ ///
+ public bool IsSupported()
+ {
+ return OperatingSystem.IsMacOS();
+ }
+
+ ///
+ /// 安装ca证书
+ ///
+ /// 证书文件路径
+ ///
+ public void Install(string caCertFilePath, ILogger logger)
+ {
+ logger.LogWarning($"请手动安装CA证书然后设置信任CA证书{caCertFilePath}");
+ }
+ }
+}
diff --git a/FastGithub.HttpServer/CaCertInstallerOfWindows.cs b/FastGithub.HttpServer/CaCertInstallerOfWindows.cs
new file mode 100644
index 0000000..b4299e2
--- /dev/null
+++ b/FastGithub.HttpServer/CaCertInstallerOfWindows.cs
@@ -0,0 +1,51 @@
+using Microsoft.Extensions.Logging;
+using System;
+using System.Security.Cryptography.X509Certificates;
+
+namespace FastGithub.HttpServer
+{
+ sealed class CaCertInstallerOfWindows : ICaCertInstaller
+ {
+ ///
+ /// 是否支持
+ ///
+ ///
+ public bool IsSupported()
+ {
+ return OperatingSystem.IsWindows();
+ }
+
+ ///
+ /// 安装ca证书
+ ///
+ /// 证书文件路径
+ ///
+ public void Install(string caCertFilePath, ILogger logger)
+ {
+ try
+ {
+ using var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
+ store.Open(OpenFlags.ReadWrite);
+
+ var caCert = new X509Certificate2(caCertFilePath);
+ var subjectName = caCert.Subject[3..];
+ foreach (var item in store.Certificates.Find(X509FindType.FindBySubjectName, subjectName, false))
+ {
+ if (item.Thumbprint != caCert.Thumbprint)
+ {
+ store.Remove(item);
+ }
+ }
+ if (store.Certificates.Find(X509FindType.FindByThumbprint, caCert.Thumbprint, true).Count == 0)
+ {
+ store.Add(caCert);
+ }
+ store.Close();
+ }
+ catch (Exception)
+ {
+ logger.LogWarning($"请手动安装CA证书{caCertFilePath}到“将所有的证书都放入下列存储”\\“受信任的根证书颁发机构”");
+ }
+ }
+ }
+}
diff --git a/FastGithub.HttpServer/CertService.cs b/FastGithub.HttpServer/CertService.cs
index 98e7852..6b66f32 100644
--- a/FastGithub.HttpServer/CertService.cs
+++ b/FastGithub.HttpServer/CertService.cs
@@ -18,6 +18,7 @@ namespace FastGithub.HttpServer
private const string CACERT_PATH = "cacert";
private const int KEY_SIZE_BITS = 2048;
private readonly IMemoryCache serverCertCache;
+ private readonly IEnumerable certInstallers;
private readonly ILogger logger;
@@ -34,12 +35,16 @@ namespace FastGithub.HttpServer
///
/// 证书服务
///
+ ///
+ ///
///
public CertService(
IMemoryCache serverCertCache,
+ IEnumerable certInstallers,
ILogger logger)
{
this.serverCertCache = serverCertCache;
+ this.certInstallers = certInstallers;
this.logger = logger;
Directory.CreateDirectory(CACERT_PATH);
}
@@ -68,17 +73,10 @@ namespace FastGithub.HttpServer
///
public void InstallAndTrustCaCert()
{
- if (OperatingSystem.IsWindows())
+ var installer = this.certInstallers.FirstOrDefault(item => item.IsSupported());
+ if (installer != null)
{
- this.InstallAndTrustCaCertAtWindows();
- }
- else if (OperatingSystem.IsLinux())
- {
- this.logger.LogWarning($"请根据具体linux发行版手动安装CA证书{this.CaCerFilePath}");
- }
- else if (OperatingSystem.IsMacOS())
- {
- this.logger.LogWarning($"请手动安装CA证书然后设置信任CA证书{this.CaCerFilePath}");
+ installer.Install(this.CaCerFilePath, this.logger);
}
else
{
@@ -113,38 +111,6 @@ namespace FastGithub.HttpServer
}
}
- ///
- /// 安装CA证书
- ///
- private void InstallAndTrustCaCertAtWindows()
- {
- try
- {
- using var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
- store.Open(OpenFlags.ReadWrite);
-
- var caCert = new X509Certificate2(this.CaCerFilePath);
- var subjectName = caCert.Subject[3..];
- foreach (var item in store.Certificates.Find(X509FindType.FindBySubjectName, subjectName, false))
- {
- if (item.Thumbprint != caCert.Thumbprint)
- {
- store.Remove(item);
- }
- }
- if (store.Certificates.Find(X509FindType.FindByThumbprint, caCert.Thumbprint, true).Count == 0)
- {
- store.Add(caCert);
- }
- store.Close();
- }
- catch (Exception)
- {
- this.logger.LogWarning($"请手动安装CA证书{this.CaCerFilePath}到“将所有的证书都放入下列存储”\\“受信任的根证书颁发机构”");
- }
- }
-
-
///
/// 获取颁发给指定域名的证书
///
diff --git a/FastGithub.HttpServer/ICaCertInstaller.cs b/FastGithub.HttpServer/ICaCertInstaller.cs
new file mode 100644
index 0000000..9fe3fe9
--- /dev/null
+++ b/FastGithub.HttpServer/ICaCertInstaller.cs
@@ -0,0 +1,23 @@
+using Microsoft.Extensions.Logging;
+
+namespace FastGithub.HttpServer
+{
+ ///
+ /// CA证书安装器
+ ///
+ interface ICaCertInstaller
+ {
+ ///
+ /// 是否支持
+ ///
+ ///
+ bool IsSupported();
+
+ ///
+ /// 安装ca证书
+ ///
+ /// 证书文件路径
+ ///
+ void Install(string caCertFilePath,ILogger logger);
+ }
+}
diff --git a/FastGithub.HttpServer/ServiceCollectionExtensions.cs b/FastGithub.HttpServer/ServiceCollectionExtensions.cs
index 4151824..1224460 100644
--- a/FastGithub.HttpServer/ServiceCollectionExtensions.cs
+++ b/FastGithub.HttpServer/ServiceCollectionExtensions.cs
@@ -1,6 +1,5 @@
using FastGithub.HttpServer;
using Microsoft.Extensions.DependencyInjection;
-
namespace FastGithub
{
///
@@ -18,9 +17,14 @@ namespace FastGithub
return services
.AddMemoryCache()
.AddHttpForwarder()
- .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
.AddSingleton()
- .AddSingleton()
+ .AddSingleton()
.AddSingleton();
}
}
diff --git a/publish.cmd b/publish.cmd
index b906076..958ab82 100644
--- a/publish.cmd
+++ b/publish.cmd
@@ -1,7 +1,4 @@
set output=./publish
if exist "%output%" rd /S /Q "%output%"
-dotnet publish -c Release -o "%output%/fastgithub_win-x64" ./FastGithub.UI/FastGithub.UI.csproj
-dotnet publish -c Release /p:PublishSingleFile=true /p:PublishTrimmed=true --self-contained -r win-x64 -o "%output%/fastgithub_win-x64" ./FastGithub/FastGithub.csproj
-dotnet publish -c Release /p:PublishSingleFile=true /p:PublishTrimmed=true --self-contained -r linux-x64 -o "%output%/fastgithub_linux-x64" ./FastGithub/FastGithub.csproj
-dotnet publish -c Release /p:PublishSingleFile=true /p:PublishTrimmed=true --self-contained -r linux-arm64 -o "%output%/fastgithub_linux-arm64" ./FastGithub/FastGithub.csproj
-dotnet publish -c Release /p:PublishSingleFile=true /p:PublishTrimmed=true --self-contained -r osx-x64 -o "%output%/fastgithub_osx-x64" ./FastGithub/FastGithub.csproj
\ No newline at end of file
+
+dotnet publish -c Release /p:PublishSingleFile=true /p:PublishTrimmed=false --self-contained -r linux-x64 -o "%output%/fastgithub_linux-x64" ./FastGithub/FastGithub.csproj
\ No newline at end of file