You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 6下Kestrel使用Let's Encrypt证书提示过期但Nginx正常问题问询

根因分析

Let's Encrypt在DST Root CA X3根证书2021年过期后,默认对新签发证书提供双证书链配置:

  • 兼容旧安卓系统的长链:证书 -> 跨签版R3中间证 -> 过期的DST Root CA X3
  • 现代系统兼容的短链:证书 -> 正式版R3中间证 -> 有效期到2035年的ISRG Root X1

Nginx的TLS栈默认会自动选择有效的证书链返回,而.NET 6的X509证书链构建逻辑会优先匹配本地证书存储中存在的历史证书,哪怕对应根证书已经过期,所以会优先选择到已过期的长链触发报错。

可用解决方案

方案1:重新生成仅带短链的证书

使用certbot等证书签发工具时,添加指定链参数重新签发证书:
certbot renew --preferred-chain "ISRG Root X1"
重新导出pfx格式证书后替换Kestrel使用的证书即可。

方案2:删除服务器本地的过期根证书

在部署.NET程序的服务器上打开本地计算机证书管理器(运行certlm.msc),进入「受信任的根证书颁发机构」-「证书」目录,找到DST Root CA X3证书直接删除,重启.NET程序后系统会自动匹配有效的ISRG Root X1链。

方案3:Kestrel手动指定证书链

在Program.cs中配置Kestrel时,手动加载完整的有效证书链,强制程序使用短链,示例代码如下:

using System.Security.Cryptography.X509Certificates;
using System.Security.Authentication;

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.UseKestrel(options =>
{
    options.ListenAnyIP(443, listenOpts =>
    {
        listenOpts.UseHttps("你的证书文件.pfx", "证书密码", httpsOpts =>
        {
            httpsOpts.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13;
            httpsOpts.OnAuthenticate = (ctx, sslOpts) =>
            {
                sslOpts.CertificateChainPolicy = new X509ChainPolicy
                {
                    ExtraStore = new X509Certificate2Collection
                    {
                        // 提前下载好R3中间证和ISRG Root X1根证放到程序目录
                        new X509Certificate2("r3.cer"),
                        new X509Certificate2("isrg-root-x1.cer")
                    },
                    RevocationMode = X509RevocationMode.NoCheck
                };
            };
        });
    });
});

var app = builder.Build();
app.Run();
验证方式

配置完成后可执行命令查看返回的证书链是否正确:
openssl s_client -connect 你的域名:443
确认返回的证书链路径为「你的证书 -> R3 -> ISRG Root X1」即可。

内容的提问来源于stack exchange,提问作者Joe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 23:57:03