2
0

KestrelServerOptionsExtensions.cs 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. using FastGithub.ReverseProxy;
  2. using Microsoft.AspNetCore.Hosting;
  3. using Microsoft.AspNetCore.Server.Kestrel.Core;
  4. using Microsoft.Extensions.DependencyInjection;
  5. using Microsoft.Extensions.Logging;
  6. using System;
  7. using System.Collections.Concurrent;
  8. using System.Security.Cryptography.X509Certificates;
  9. namespace FastGithub
  10. {
  11. /// <summary>
  12. /// Kestrel扩展
  13. /// </summary>
  14. public static class KestrelServerOptionsExtensions
  15. {
  16. /// <summary>
  17. /// 监听github的反向代理
  18. /// </summary>
  19. /// <param name="kestrel"></param>
  20. /// <param name="caPublicCerPath"></param>
  21. /// <param name="caPrivateKeyPath"></param>
  22. public static void ListenGithubReverseProxy(this KestrelServerOptions kestrel, string caPublicCerPath, string caPrivateKeyPath)
  23. {
  24. var loggerFactory = kestrel.ApplicationServices.GetRequiredService<ILoggerFactory>();
  25. var logger = loggerFactory.CreateLogger($"{nameof(FastGithub)}{nameof(ReverseProxy)}");
  26. TryInstallCaCert(caPublicCerPath, logger);
  27. kestrel.ListenAnyIP(443, listen => listen.UseGithubHttps(caPublicCerPath, caPrivateKeyPath));
  28. logger.LogInformation("反向代理服务启动成功");
  29. }
  30. /// <summary>
  31. /// 安装根证书
  32. /// </summary>
  33. /// <param name="caPublicCerPath"></param>
  34. /// <param name="logger"></param>
  35. private static void TryInstallCaCert(string caPublicCerPath, ILogger logger)
  36. {
  37. if (OperatingSystem.IsWindows())
  38. {
  39. try
  40. {
  41. var caCert = new X509Certificate2(caPublicCerPath);
  42. using var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
  43. store.Open(OpenFlags.ReadWrite);
  44. if (store.Certificates.Find(X509FindType.FindByThumbprint, caCert.Thumbprint, true).Count == 0)
  45. {
  46. store.Add(caCert);
  47. store.Close();
  48. }
  49. }
  50. catch (Exception ex)
  51. {
  52. logger.LogError($"安装根证书{caPublicCerPath}失败:{ex.Message}");
  53. }
  54. }
  55. }
  56. /// <summary>
  57. /// 应用fastGihub的https
  58. /// </summary>
  59. /// <param name="listenOptions"></param>
  60. /// <param name="caPublicCerPath"></param>
  61. /// <param name="caPrivateKeyPath"></param>
  62. /// <returns></returns>
  63. private static ListenOptions UseGithubHttps(this ListenOptions listenOptions, string caPublicCerPath, string caPrivateKeyPath)
  64. {
  65. return listenOptions.UseHttps(https =>
  66. {
  67. const string defaultDomain = "github.com";
  68. var certs = new ConcurrentDictionary<string, X509Certificate2>();
  69. https.ServerCertificateSelector = (ctx, domain) => certs.GetOrAdd(domain ?? defaultDomain, CreateCert);
  70. });
  71. X509Certificate2 CreateCert(string domain)
  72. {
  73. var domains = new[] { domain };
  74. var validFrom = DateTime.Today.AddYears(-1);
  75. var validTo = DateTime.Today.AddYears(10);
  76. return CertGenerator.Generate(domains, 2048, validFrom, validTo, caPublicCerPath, caPrivateKeyPath);
  77. }
  78. }
  79. }
  80. }