[英]Reload certs without restart of server kestrel
我使用每 90 天更新一次的 Let's Encrypt 證書,我想知道是否有辦法在不重新啟動紅隼服務器的情況下重新加載證書。
我在 github 上嘗試了這個答案,但我就是不明白,或者我無法讓它工作: https://github.com/aspnet/KestrelHttpServer/issues/2967
現在我有這個代碼:
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseKestrel(options =>
{
options.Listen(IPAddress.Any, 80);
options.Listen(IPAddress.Any, 443, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
{
httpsOptions.ServerCertificateSelector = (context, dnsName) =>
{
var certificate = new X509Certificate2("C:\\Users\\jserra\\Desktop\\folder1\\Cert1.pfx", "`P@ssw0rd");
return certificate;
};
});
});
}).UseStartup<Startup>();
});
}
}
此代碼為每個請求創建一個新的 var 證書。
所以我有 2 個證書,Cert1.pfx 和 Cert2.pfx。
首先我嘗試發出請求,它加載 Cert1,然后在運行時使用文件資源管理器將 Cert1.pfx 重命名為 Cert1.pfx.old。
然后我將 Cert2.pfx 重命名為 Cert1.pfx,我提出了一個新請求,這次服務器正在使用新證書。
這有意義嗎? 每個新請求都制作一個新的 var certificate = Cert1.pfx 很好嗎?
如果您有什么想法可以解決我的問題,我想閱讀它,謝謝大家。
將證書放入 static 變量中。 將第二個 DateTime 存儲在另一個 static 變量中。 當日期時間變量早於閾值時,從文件重新加載證書。
public static class CertificateCache
{
private const string certificatePath = "C:\\Users\\jserra\\Desktop\\folder1\\Cert1.pfx";
// password should be loaded from environment variable or configuration
private const string password = "`P@ssw0rd";
// cache certificate for one day
private static readonly TimeSpan cacheTime = TimeSpan.FromDays(1.0);
private static readonly object certificateLock = new();
private static X509Certificate2 certificate;
private static DateTime lastCertificateLoad;
public static X509Certificate2 GetCertificate()
{
if (DateTime.UtcNow - lastCertificateLoad > cacheTime)
{
lock (certificateLock)
{
// in case multiple callers got through the first if statement, check again
if (DateTime.UtcNow - lastCertificateLoad > cacheTime)
{
try
{
var oldCertificate = certificate;
certificate = new X509Certificate2(certificatePath, password);
lastCertificateLoad = DateTime.UtcNow;
// dispose of old certificate after 1 minute to eliminate memory leaks, this allows any connections using it to finish up cleanly
if (oldCertificate is not null)
{
Task.Run(async () =>
{
await Task.Delay(60000);
oldCertificate.Dispose();
});
}
}
catch (Exception ex)
{
// manual intervention probably required, send an email or high priority notification
}
}
}
}
return certificate;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.