2
0
xljiulang 4 жил өмнө
parent
commit
b8ac5864cc

+ 27 - 2
FastGithub.ReverseProxy/CertGenerator.cs

@@ -29,6 +29,31 @@ namespace FastGithub.ReverseProxy
     {
         private static readonly SecureRandom secureRandom = new();
 
+        /// <summary>
+        /// 生成自签名证书
+        /// </summary>
+        /// <param name="domains"></param>
+        /// <param name="keySizeBits"></param>
+        /// <param name="validFrom"></param>
+        /// <param name="validTo"></param>
+        /// <param name="caPublicCerPath"></param>
+        /// <param name="caPrivateKeyPath"></param>
+        public static void GenerateBySelf(IEnumerable<string> domains, int keySizeBits, DateTime validFrom, DateTime validTo, string caPublicCerPath, string caPrivateKeyPath)
+        {
+            var keys = GenerateRsaKeyPair(keySizeBits);
+            var cert = GenerateCertificate(domains, keys.Public, validFrom, validTo, domains.First(), null, keys.Private, null);
+
+            using var priWriter = new StreamWriter(caPrivateKeyPath);
+            var priPemWriter = new PemWriter(priWriter);
+            priPemWriter.WriteObject(keys.Private);
+            priPemWriter.Writer.Flush();
+
+            using var pubWriter = new StreamWriter(caPublicCerPath);
+            var pubPemWriter = new PemWriter(pubWriter);
+            pubPemWriter.WriteObject(cert);
+            pubPemWriter.Writer.Flush();
+        }
+
         /// <summary>
         /// 生成CA签名证书
         /// </summary>
@@ -39,7 +64,7 @@ namespace FastGithub.ReverseProxy
         /// <param name="caPublicCerPath"></param>
         /// <param name="caPrivateKeyPath"></param>
         /// <returns></returns>
-        public static X509Certificate2 Generate(IEnumerable<string> domains, int keySizeBits, DateTime validFrom, DateTime validTo, string caPublicCerPath, string caPrivateKeyPath, string? password = default)
+        public static X509Certificate2 GenerateByCa(IEnumerable<string> domains, int keySizeBits, DateTime validFrom, DateTime validTo, string caPublicCerPath, string caPrivateKeyPath, string? password = default)
         {
             if (File.Exists(caPublicCerPath) == false)
             {
@@ -90,7 +115,7 @@ namespace FastGithub.ReverseProxy
         /// <param name="issuerPrivate"></param>
         /// <param name="CA_PathLengthConstraint"></param>
         /// <returns></returns>
-        private static X509Certificate GenerateCertificate(IEnumerable<string> domains, AsymmetricKeyParameter subjectPublic, DateTime validFrom, DateTime validTo, string issuerName, AsymmetricKeyParameter issuerPublic, AsymmetricKeyParameter issuerPrivate, int? CA_PathLengthConstraint)
+        private static X509Certificate GenerateCertificate(IEnumerable<string> domains, AsymmetricKeyParameter subjectPublic, DateTime validFrom, DateTime validTo, string issuerName, AsymmetricKeyParameter? issuerPublic, AsymmetricKeyParameter issuerPrivate, int? CA_PathLengthConstraint)
         {
             var signatureFactory = issuerPrivate is ECPrivateKeyParameters
                 ? new Asn1SignatureFactory(X9ObjectIdentifiers.ECDsaWithSha256.ToString(), issuerPrivate)

+ 50 - 26
FastGithub.ReverseProxy/KestrelServerOptionsExtensions.cs

@@ -6,6 +6,7 @@ using Microsoft.Extensions.Logging;
 using System;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
+using System.IO;
 using System.Linq;
 using System.Net;
 using System.Net.NetworkInformation;
@@ -35,7 +36,9 @@ namespace FastGithub
         {
             var loggerFactory = kestrel.ApplicationServices.GetRequiredService<ILoggerFactory>();
             var logger = loggerFactory.CreateLogger($"{nameof(FastGithub)}.{nameof(ReverseProxy)}");
-            TryInstallCaCert(caPublicCerPath, logger);
+
+            GeneratorCaCert(caPublicCerPath, caPrivateKeyPath);
+            InstallCaCert(caPublicCerPath, logger);
 
             kestrel.ListenAnyIP(443, listen =>
                 listen.UseHttps(https =>
@@ -45,6 +48,51 @@ namespace FastGithub
             logger.LogInformation("https反向代理服务启动成功");
         }
 
+        /// <summary>
+        /// 生成根证书
+        /// </summary>
+        /// <param name="caPublicCerPath"></param>
+        /// <param name="caPrivateKeyPath"></param>
+        private static void GeneratorCaCert(string caPublicCerPath, string caPrivateKeyPath)
+        {
+            if (File.Exists(caPublicCerPath) && File.Exists(caPublicCerPath))
+            {
+                return;
+            }
+
+            File.Delete(caPublicCerPath);
+            File.Delete(caPrivateKeyPath);
+
+            var validFrom = DateTime.Today.AddYears(-10);
+            var validTo = DateTime.Today.AddYears(50);
+            CertGenerator.GenerateBySelf(new[] { nameof(FastGithub) }, 2048, validFrom, validTo, caPublicCerPath, caPrivateKeyPath);
+        }
+
+
+        /// <summary>
+        /// 安装根证书
+        /// </summary>
+        /// <param name="caPublicCerPath"></param>
+        /// <param name="logger"></param>
+        private static void InstallCaCert(string caPublicCerPath, ILogger logger)
+        {
+            try
+            {
+                var caCert = new X509Certificate2(caPublicCerPath);
+                using var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
+                store.Open(OpenFlags.ReadWrite);
+                if (store.Certificates.Find(X509FindType.FindByThumbprint, caCert.Thumbprint, true).Count == 0)
+                {
+                    store.Add(caCert);
+                    store.Close();
+                }
+            }
+            catch (Exception)
+            {
+                logger.LogWarning($"安装根证书{caPublicCerPath}失败:请手动安装到“将所有的证书都放入下载存储”\\“受信任的根证书颁发机构”");
+            }
+        }
+
         /// <summary>
         /// 获取颁发给指定域名的证书
         /// </summary>
@@ -63,7 +111,7 @@ namespace FastGithub
                     var domains = GetDomains(host).Distinct();
                     var validFrom = DateTime.Today.AddYears(-1);
                     var validTo = DateTime.Today.AddYears(10);
-                    return CertGenerator.Generate(domains, 2048, validFrom, validTo, caPublicCerPath, caPrivateKeyPath);
+                    return CertGenerator.GenerateByCa(domains, 2048, validFrom, validTo, caPublicCerPath, caPrivateKeyPath);
                 }, LazyThreadSafetyMode.ExecutionAndPublication);
             }
         }
@@ -94,29 +142,5 @@ namespace FastGithub
                 }
             }
         }
-
-        /// <summary>
-        /// 安装根证书
-        /// </summary>
-        /// <param name="caPublicCerPath"></param>
-        /// <param name="logger"></param>
-        private static void TryInstallCaCert(string caPublicCerPath, ILogger logger)
-        {
-            try
-            {
-                var caCert = new X509Certificate2(caPublicCerPath);
-                using var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
-                store.Open(OpenFlags.ReadWrite);
-                if (store.Certificates.Find(X509FindType.FindByThumbprint, caCert.Thumbprint, true).Count == 0)
-                {
-                    store.Add(caCert);
-                    store.Close();
-                }
-            }
-            catch (Exception)
-            {
-                logger.LogWarning($"安装根证书{caPublicCerPath}失败:请手动安装到“将所有的证书都放入下载存储”\\“受信任的根证书颁发机构”");
-            }
-        }
     }
 }

+ 0 - 18
FastGithub/FastGithub.cer

@@ -1,18 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIC2DCCAcCgAwIBAgIQAKaUqwPmF9dDFtqNp34mRTANBgkqhkiG9w0BAQsFADAY
-MRYwFAYDVQQDDA1GYXN0R2l0aHViX0NBMCAXDTExMDcxMzAwMDAwMFoYDzI1MjEw
-NzEzMDAwMDAwWjAYMRYwFAYDVQQDDA1GYXN0R2l0aHViX0NBMIIBIjANBgkqhkiG
-9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1vNFkTGacoKdOY+H8Va7BN/z+nXyUHI1aZGC
-11uzRVggi7EDxL2ThufzrQNEMqmh7aI6UbmnFMee+UtzexBSl2x8sH0uOPL31Pbh
-fsrrgjMW0p8doApaTlEVyrXI5SVEapf+B13y/Nu6e2PQ4gRT4WZaBfLgqQdcaT9/
-RdaexznlRYzet6HAKf/Hvs5tkbWkLY9mvctcMWm998wjVVD2vTyZ7Pe7s7L2w/fG
-mcz0svonr18zI+kHK/hK/2u/jvnmC8HpvhnDbNp7brOvR0TF6oYjKB20Zicy32UK
-0/PekVN9T8dzOwjkZXJ0xI7RRVLOLG1qkO8z8BhyznjQLLZSLwIDAQABoxwwGjAY
-BgNVHREEETAPgg1GYXN0R2l0aHViX0NBMA0GCSqGSIb3DQEBCwUAA4IBAQCYR68q
-oKqBiNKlWgaaY8o2w7PGL0NZ2QVGlZp4Yl8Jj60qx587TSN9YTjMgNpZnkCYJZbQ
-AhJAcwVspFsAq90SG/md0A6o3TRHSEV2HJIvAoMTiT/LLG+ZU61/NxMl0WxoQPKz
-OcleOo+fCklove9jYIhHsls30eQv/NGn+pKhnCI9VEC+sUxbxQd4LJQbBYouNV6I
-Sd8axEazqWsQrfX+CvNb2UjH3aaARaPWcacTcVlO5XJz2eDnUzVQOWwgv57sLUmY
-xn0HbGp4lATgNeUSBcn7pEHv/yjqraJn2cVl0l/ZaFcYcccYZFrA3qAi14aiGRtu
-SSC6OWHrtXwXZnkn
------END CERTIFICATE-----

+ 0 - 3
FastGithub/FastGithub.csproj

@@ -35,9 +35,6 @@
 		<None Update="FastGithub.cer">
 			<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 		</None>
-		<None Update="FastGithub.key">
-			<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-		</None>
 		<None Update="README.html">
 		  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 		</None>

+ 0 - 27
FastGithub/FastGithub.key

@@ -1,27 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEpAIBAAKCAQEA1vNFkTGacoKdOY+H8Va7BN/z+nXyUHI1aZGC11uzRVggi7ED
-xL2ThufzrQNEMqmh7aI6UbmnFMee+UtzexBSl2x8sH0uOPL31PbhfsrrgjMW0p8d
-oApaTlEVyrXI5SVEapf+B13y/Nu6e2PQ4gRT4WZaBfLgqQdcaT9/RdaexznlRYze
-t6HAKf/Hvs5tkbWkLY9mvctcMWm998wjVVD2vTyZ7Pe7s7L2w/fGmcz0svonr18z
-I+kHK/hK/2u/jvnmC8HpvhnDbNp7brOvR0TF6oYjKB20Zicy32UK0/PekVN9T8dz
-OwjkZXJ0xI7RRVLOLG1qkO8z8BhyznjQLLZSLwIDAQABAoIBABamHILviJgfRiTO
-CGN4IY2icWlHK0ipuBIPGIvLqEiawBcoCD8fQJ+66hSlXva9pAfPi7iXyNCqNgiL
-mDfz4Nf+wOax0gCDLXT9rIX5KLaX3oRD6tG1tY1CAvtQi0IF2r8mk8g/8H4PQweE
-XXqrPRFngP3WeTCmS2j1nVoFAsb4E7ZOKVVD3z6wILWHUfXuAeV/R1/pqbDvc4Yn
-i2+PZvHZVjftkOqy7FyNE18y2Q198TKWATV1WzrB/Tv0mVoQN/izM9HflERUvvMo
-v+I9ZTKrLgnHo5bHprVLRQnHfBJo/SDHJTCtP57sGElUaYl9nFM6k47k0Jp71zID
-2UrlY/kCgYEA+ZFD2L+q6y4nDXOngDUiRiLbRJDb2u5pOY6scRHa73KCvq+t+Bih
-fxtE9h4EDa1zei/tR6gkQnoIe9Nviikz2YyTrZkqHzAK55who9H6GT9pErNUvXF2
-dnje2KlRcjniMp8vcm1sbYMDEt+NFS2sL8rby97bZQ+V5WjLoYAhAacCgYEA3H2X
-IPDudA6cFPczn+19qw76nKdrc3LkxToYdscb/8tH6dX+yrt02t1Ezm81kcMcqeHd
-BzbxNeiN2NmBozLQ0SERMDkNJUUFlK3ALdx9USdwTTMywRMnkgLDuRaA6m1QDi24
-RoFDjhEQREbjRD4WxJuzgvLKhF60bQnsAf5R7DkCgYBDpWBii/FkNepX9xVb5wsX
-P7N3blxph132P/n13AUgCkXuMehR6zs7HMUggRpQKse2Qu9qEOVjL3jFN5ZwOKLZ
-QQV2dKG6Omd6SBPGN9A2r71nWDyL7QlTK4gb6iktcQsi9YsC1S4isPRQVVAEgZC+
-k5noNMv7JLJYsIMhj31i2QKBgQDbg9HVgujz9KOiH+Zuv4PQrQ4GrovEmct3K/q1
-LlAK33iOLnYHoo+ZYpehKojbwLOl0m86QpHtCMVH8mwlbW8F9fTl3LbgtxHyTvW4
-8v50sF4XDfTm0kogDM6NVAEu43vDUfNXhlQaeZSHVUfoZiRGw3j50vyawqrAsBMe
-fPNUyQKBgQCMLr1WLgnDiMx7CLXlmKdw45z0UeP+ngZOuPICX9d5DOfznuP8VgS9
-ZiwXHF8PbSdlMFPq9LkPbQTjfTLHXZx0mKl78PcFqwtryXTpUlP1qcfjE6Hl+POD
-2OkWyGz7vA80+7ilQscm0L/gLIgwiGQOdBv6akLF8qDwncOX4yWOVQ==
------END RSA PRIVATE KEY-----

+ 2 - 1
FastGithub/Program.cs

@@ -2,6 +2,7 @@
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.Hosting;
+using System;
 using System.IO;
 
 namespace FastGithub
@@ -51,7 +52,7 @@ namespace FastGithub
                 .ConfigureWebHostDefaults(web =>
                 {
                     web.Configure(app => app.UseHttpsReverseProxy("README.html"));
-                    web.UseKestrel(kestrel => kestrel.ListenHttpsReverseProxy("FastGithub.cer", "FastGithub.key"));
+                    web.UseKestrel(kestrel => kestrel.ListenHttpsReverseProxy($"FastGithub_{Environment.MachineName}.cer", $"FastGithub_{Environment.MachineName}.key"));
                 });
         }
     }