Kestrel代码配置证书失效问题排查与实验分析
问题描述
Kestrel需监听http://localhost:50008和https://localhost:50009,证书需在启动时从外部源加载(本次示例从文件加载)。通过appsettings.json配置可正常工作,但通过代码配置Kestrel时HTTPS连接失效。
实验验证
环境准备
证书由Letsencrypt生产环境颁发,域名匹配*.mydomain.xyz,www.mydomain.xyz的A记录指向127.0.0.1。
实验1:通过appsettings.json配置Kestrel
Program.cs
var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.MapGet("/", () => Results.Ok("hello")); app.Run();
appsettings.json
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Debug" } }, "AllowedHosts": "*", "Kestrel": { "Endpoints": { "Https": { "Url": "https://*:50009", "Certificate": { "Path": "C:\\Users\\myusername\\certs\\acme_certificate_pem.crt", "KeyPath": "C:\\Users\\myusername\\certs\\acme_certificate_private_key_pem.key" } }, "Http": { "Url": "http://*:50008" } } } }
调试输出
info: Microsoft.Hosting.Lifetime[14] Now listening on: http://[::]:50008 info: Microsoft.Hosting.Lifetime[14] Now listening on: https://[::]:50009
curl测试(浏览器也显示正确的*.mydomain.xyz证书)
$ curl http://www.mydomain.xyz:50008 "hello" $ curl https://www.mydomain.xyz:50009 "hello"
实验2:通过Program.cs配置Kestrel
Program.cs
var builder = WebApplication.CreateBuilder(args); var certPath = "C:\\Users\\myusername\\certs\\acme_certificate_pem.crt"; var keyPath = "C:\\Users\\myusername\\certs\\acme_certificate_private_key_pem.key"; var certificate = X509Certificate2.CreateFromPemFile(certPath, keyPath); builder.WebHost.ConfigureKestrel((context, serverOptions) => { serverOptions.Listen(IPAddress.Any, 50008); serverOptions.Listen(IPAddress.Any, 50009, listenOptions => { listenOptions.UseHttps(certificate); }); }); var app = builder.Build(); app.MapGet("/", () => Results.Ok("hello")); app.Run();
appsettings.json
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Debug" } } }
调试输出
info: Microsoft.Hosting.Lifetime[14] Now listening on: http://0.0.0.0:50008 info: Microsoft.Hosting.Lifetime[14] Now listening on: https://0.0.0.0:50009
curl测试
$ curl http://www.mydomain.xyz:50008 "hello" $ curl https://www.mydomain.xyz:50009 curl: (35) schannel: failed to receive handshake, SSL/TLS connection failed
实验3:通过Program.cs配置Kestrel但不指定证书
Program.cs
var builder = WebApplication.CreateBuilder(args); builder.WebHost.ConfigureKestrel((context, serverOptions) => { serverOptions.Listen(IPAddress.Any, 50008); serverOptions.Listen(IPAddress.Any, 50009, listenOptions => { listenOptions.UseHttps(); }); }); var app = builder.Build(); app.MapGet("/", () => Results.Ok("hello")); app.Run();
appsettings.json
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Debug" } } }
调试输出
info: Microsoft.Hosting.Lifetime[14] Now listening on: http://0.0.0.0:50008 info: Microsoft.Hosting.Lifetime[14] Now listening on: https://0.0.0.0:50009
curl测试(使用颁发给localhost的开发证书)
$ curl http://www.mydomain.xyz:50008 "hello" $ curl https://www.mydomain.xyz:50009 -k "hello" $ curl https://www.mydomain.xyz:50009 curl: (60) schannel: SNI or certificate check failed: SEC_E_WRONG_PRINCIPAL (0x80090322) - 目标主体名称不正确。 curl无法验证服务器的合法性,因此无法建立安全连接。
内容的提问来源于stack exchange,提问作者jkf
相关产品推荐
相关产品推荐

