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

ASP.NET Docker容器无法读取外部SSL证书问题求助

问题

在Ubuntu服务器上运行承载ASP.NET网站的Docker容器,此前HTTP运行正常,切换为HTTPS后启动容器出现如下错误:

app_1  | warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]
app_1  |       Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed.
app_1  | Unhandled exception. Interop+Crypto+OpenSslCryptographicException: error:2006D080:BIO routines:BIO_new_file:no such file
   at Interop.Crypto.CheckValidOpenSslHandle(SafeHandle handle)
   at Internal.Cryptography.Pal.OpenSslX509CertificateReader.FromFile(String fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
   at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(String fileName, String password, X509KeyStorageFlags keyStorageFlags)
   at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(String fileName, String password)
   at Microsoft.AspNetCore.Hosting.ListenOptionsHttpsExtensions.UseHttps(ListenOptions listenOptions, String fileName, String password)

已确认证书文件存在:

:~# ls /etc/letsencrypt/live/example.com/privkey.pem
/etc/letsencrypt/live/example.com/privkey.pem

docker-compose卷配置:

volumes:
      - /etc/letsencrypt/live/example.com/fullchain.pem:/etc/ssl/certs/fullchain.pem:ro
      - /etc/letsencrypt/live/example.com/privkey.pem:/etc/ssl/private/privkey.pem:ro

Program类中的CreateHostBuilder配置:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>()
                .UseKestrel(options =>
                {
                    options.ListenAnyIP(80); // HTTP
                    options.ListenAnyIP(443, listenOptions =>
                    {
                        listenOptions.UseHttps("/etc/ssl/certs/fullchain.pem", "/etc/ssl/private/privkey.pem");
                    });
                });
        });

已尝试将证书文件权限改为644,但问题依旧,请问可能是什么原因?

可能的原因及解决办法
  • Let's Encrypt证书软链接无法被容器解析
    Let's Encrypt live目录下的证书文件是软链接,实际指向/etc/letsencrypt/archive目录中的真实文件。直接挂载软链接到容器内,容器无法识别链接对应的真实路径,导致找不到文件。
    解决方法:

    1. 挂载archive目录下的真实证书文件:
      volumes:
        - /etc/letsencrypt/archive/example.com/fullchain1.pem:/etc/ssl/certs/fullchain.pem:ro
        - /etc/letsencrypt/archive/example.com/privkey1.pem:/etc/ssl/private/privkey.pem:ro
      
      注意:fullchain1.pem和privkey1.pem的数字会随证书更新变化,后续更新需同步修改路径。
    2. 或直接挂载整个/etc/letsencrypt目录,同时修改Program中的路径:
      volumes:
        - /etc/letsencrypt:/etc/letsencrypt:ro
      
      listenOptions.UseHttps("/etc/letsencrypt/live/example.com/fullchain.pem", "/etc/letsencrypt/live/example.com/privkey.pem");
      
  • 容器内用户无证书目录访问权限
    即使证书文件权限设为644,容器内运行ASP.NET的非root用户可能无法访问/etc/ssl/private目录(默认权限700,仅root可访问)。
    解决方法:

    1. 临时测试可在docker-compose中指定root用户运行(不推荐生产环境):
      user: "root"
      
    2. 修改宿主机证书目录权限,让容器用户可读:
      chmod -R 755 /etc/letsencrypt/archive/example.com
      chmod -R 644 /etc/letsencrypt/archive/example.com/*.pem
      
    3. 生产环境推荐在Dockerfile中创建专用用户组,赋予证书目录访问权限后用该用户运行应用。
  • 路径拼写或挂载一致性问题
    检查Program中的路径与docker-compose挂载路径是否完全一致(Linux路径区分大小写),可进入容器验证文件是否存在:

    docker exec -it <容器名> bash
    ls -l /etc/ssl/certs/fullchain.pem
    ls -l /etc/ssl/private/privkey.pem
    
  • 证书与私钥不匹配
    确认fullchain.pem和privkey.pem是配对的,可在宿主机验证:

    openssl x509 -noout -modulus -in /etc/letsencrypt/live/example.com/fullchain.pem | openssl md5
    openssl rsa -noout -modulus -in /etc/letsencrypt/live/example.com/privkey.pem | openssl md5
    

    两个命令输出的MD5值需一致,否则证书与私钥不匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 02:23:10