【发布时间】:2021-05-01 16:55:04
【问题描述】:
Kestrel 的网络服务器在加载公开签名的 SSL 证书后超时,显示连接已关闭。
背景 - 我们有一个托管 dotnet 3.1 webapi/react 应用程序的 docker 容器,用户可以在其中上传自定义 SSL 证书。 PKCS#12 证书存储在我们的数据库中,并在启动时使用 .ConfigureKestrel((context,options)) 和 options.ConfigureHttpsDefaults(listenOptions=>{listenOptions.ServerCertificate = certFromDatabase; }) 绑定。这一直完美无缺。
但是,现在的问题是用户试图在限制性防火墙环境中运行此应用,并且在加载新证书并重新启动应用后立即尝试访问 Kestrel 时收到 HTTP 连接关闭错误。
每当 Kestrel 收到传入请求时,它就会开始尝试通过端口 80 上的 http 从证书的 CA 的公共 CDN 存储库下载中间证书。它似乎正在使用证书的授权信息访问部分的 URL。由于防火墙阻止了这一点,它会重复重试大约 20 秒,在此期间客户端的 TLS 握手等待服务器响应。当服务器最终无法获取中间证书时,它会取消 TLS 握手并关闭连接。
考虑到绑定到 Kestrel 的 PKCS#12 PFX 捆绑包中嵌入了相同的证书,我无法弄清楚它为何尝试下载此证书。我应该将根 CA 或中间节点加载到文件系统中的 CA 信任文件夹中吗? (例如 /usr/local/share/ca-certificates/ - 我不能在那里加载中间体,只能加载 CA?)
public static IWebHost BuildFullWebHost(string[] args)
{
var webHostBuilder = GetBaseWebHostBuilder(args);
return webHostBuilder
.ConfigureAppConfiguration((context, builder) => { [...] })
.ConfigureLogging((hostingContext, logging) => { [...] })
.UseStartup<Startup>()
.ConfigureKestrel((context, options) =>
{
var sp = options.ApplicationServices;
using (var scope = sp.CreateScope())
{
var dbContext = scope.ServiceProvider.GetService<DbContext>();
var cert = Example.Services.HttpsCertificateService.GetHttpsCert(dbContext);
//this returns a new X509Certificate2(certificate.HttpsCertificate, certificate.Password);
options.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.ServerCertificate = cert;
listenOptions.CheckCertificateRevocation = false;
});
}
})
.Build();
}
【问题讨论】:
标签: asp.net-core .net-core ssl-certificate kestrel-http-server