【问题标题】:Kestrel Fails TLS Handshake after Attempt to Download Intermediate Certificate Fails尝试下载中间证书失败后,Kestrel 无法进行 TLS 握手
【发布时间】: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


    【解决方案1】:

    不是一个很好的解决方案,但升级到 .NET 5.0 解决了这个问题。似乎在 .NET 5.0 中,Kestrel 仅在初始应用程序启动期间尝试获取证书链(并且失败)。后续传入的 HTTP 请求不会触发 fetch 过程,并且会按预期处理请求。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-16
      • 2015-01-04
      相关资源
      最近更新 更多