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

.NET 6 Docker Web API部分端点SSL连接失败问题排查

问题:Docker部署.NET 6 Web API后SSL连接失败(移除危险证书验证依赖)

原始问题

在Windows主机上开发面向Linux的.NET 6 Web API Docker容器,本地通过dotnet run或发布生产版本运行时,所有端点均可正常访问。但部署到Docker容器后,仅/api/weatherforecast端点可访问,其余两个端点/api/users?userId=1、/api/cart?userId=1&cartId=1均出现Error: The SSL connection could not be established, see inner exception.错误,且无法找到内部异常信息。

已完成的开发证书配置步骤:

  • 执行dotnet dev-certs https --clean,通过certmgr.exe确认并删除旧证书;
  • 执行dotnet dev-certs https -ep %USERPROFILE%\.aspnet\https\aspnetapp.pfx -p {password here}生成新证书;
  • 执行dotnet dev-certs https --trust信任证书。

Dockerfile内容:

FROM myprivaterepo/dotnet/sdk:6.0.202-bullseye-slim-amd64 AS build

WORKDIR /app

COPY *.csproj .
RUN dotnet restore

COPY . .
RUN dotnet publish -c Release -o out

FROM myprivaterepo/dotnet/aspnet:6.0.4-bullseye-slim-amd64

WORKDIR /app
EXPOSE 80
EXPOSE 443
EXPOSE 5000
EXPOSE 5001

ENV ASPNETCORE_URLS=https://+:5001;http://+:5000

COPY --from=build /app/out .
ENTRYPOINT ["dotnet", "mantis-server.dll"]

构建命令:docker build -t my-app .
运行命令:

docker run --rm -it -p 5001:5001 -e ASPNETCORE_HTTPS_PORT=5001 -e ASPNETCORE_Kestrel__Certificates__Default__Password="password here" -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx -e ASPNETCORE_ENVIRONMENT=Development -v ~/.aspnet/https:/https:ro -v ~/devsecrets:/.microsoft/usersecrets my-app

Insomnia中显示* Re-using existing connection! (#10) with host localhost,不确定其含义。

更新信息

添加以下代码到API控制器后请求可正常执行,推测是证书问题:

[ApiController]
[Route("api/[controller]")]
public class MyController : ControllerBase
{
    private HttpClientHandler handler = new HttpClientHandler();

    private static HttpClient _httpClient;


    public MyController()
    {
        handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
        _httpClient = new HttpClient(handler);
    }
...
}

但希望移除对HttpClientHandler.DangerousAcceptAnyServerCertificateValidator的依赖,恢复正常的自签名证书验证流程。

原因分析

本地运行时,Windows系统已经通过dotnet dev-certs https --trust将自签名证书加入了系统信任根,所以HttpClient调用外部HTTPS服务时会信任该证书。但Docker容器内的Linux系统默认没有这个信任记录,导致容器内的HttpClient无法验证自签名证书的合法性,从而抛出SSL连接错误。

DangerousAcceptAnyServerCertificateValidator是跳过所有证书验证的危险操作,虽然能解决问题,但会带来安全风险,必须替换为合法的验证方式。

解决方案

1. 将自签名证书导入Docker容器的系统信任存储

针对Debian/Ubuntu系的Linux容器(bullseye-slim属于Debian),可以在Dockerfile中添加步骤,将自签名证书导入系统信任根:

FROM myprivaterepo/dotnet/sdk:6.0.202-bullseye-slim-amd64 AS build

WORKDIR /app

COPY *.csproj .
RUN dotnet restore

COPY . .
RUN dotnet publish -c Release -o out

FROM myprivaterepo/dotnet/aspnet:6.0.4-bullseye-slim-amd64

WORKDIR /app
EXPOSE 80
EXPOSE 443
EXPOSE 5000
EXPOSE 5001

# 安装证书工具并导入自签名证书
RUN apt-get update && apt-get install -y --no-install-recommends openssl ca-certificates \
    # 从PFX导出PEM格式证书(替换{password here}为你的证书密码)
    && openssl pkcs12 -in /https/aspnetapp.pfx -clcerts -nokeys -out /usr/local/share/ca-certificates/aspnetapp.crt -passin pass:"{password here}" \
    # 更新系统信任证书
    && update-ca-certificates \
    # 清理安装包,减小镜像体积
    && apt-get clean && rm -rf /var/lib/apt/lists/*

ENV ASPNETCORE_URLS=https://+:5001;http://+:5000

COPY --from=build /app/out .
ENTRYPOINT ["dotnet", "mantis-server.dll"]

注意:运行容器时要确保/https/aspnetapp.pfx路径已通过挂载卷正确映射。

2. 在HttpClient中仅信任指定的自签名证书

不跳过所有验证,只信任我们的自签名证书,更安全:

[ApiController]
[Route("api/[controller]")]
public class MyController : ControllerBase
{
    private static HttpClient _httpClient;

    public MyController()
    {
        var handler = new HttpClientHandler();
        // 加载自签名证书(路径对应容器内的挂载路径)
        using var trustedCert = new X509Certificate2("/https/aspnetapp.pfx", "{password here}");
        
        handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) =>
        {
            // 如果没有SSL错误,直接通过
            if (sslPolicyErrors == SslPolicyErrors.None)
                return true;
            
            // 验证服务器证书是否与我们信任的证书一致
            return cert.Thumbprint.Equals(trustedCert.Thumbprint, StringComparison.OrdinalIgnoreCase);
        };

        _httpClient = new HttpClient(handler);
    }
    // ...控制器其他代码
}

也可以预先获取证书的指纹(本地运行dotnet dev-certs https --check --trust查看,或用openssl x509 -in aspnetapp.crt -noout -fingerprint命令),直接对比指纹:

var trustedThumbprint = "ABC123..."; // 替换为你的证书指纹
handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) =>
{
    if (sslPolicyErrors == SslPolicyErrors.None)
        return true;
    return cert.Thumbprint.Equals(trustedThumbprint, StringComparison.OrdinalIgnoreCase);
};

3. 开发环境临时使用HTTP(仅测试用)

如果只是开发阶段测试,可以暂时将外部服务的调用改为HTTP,避免SSL验证问题,但生产环境必须使用HTTPS。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 00:05:22