Windows主机+Linux容器下ASP.NET Core 8 HTTPS证书问题求助
问题:Windows Docker Linux容器中ASP.NET Core 8 HTTPS认证失败
环境
- 宿主系统:Windows
- Docker Desktop运行Linux容器
- ASP.NET Core 8
- 证书生成命令:
dotnet dev-certs https -ep %USERPROFILE%\.aspnet\https\aspnetapp.pfx -p VerySecurePassword123@! dotnet dev-certs https --trust
错误日志
dbug: Microsoft.AspNetCore.Server.Kestrel.Connections[39] 2024-11-14T02:09:35.774407159Z Connection id "0HN84A5GB7LGC" accepted. 2024-11-14T02:09:35.774414059Z dbug: Microsoft.AspNetCore.Server.Kestrel.Connections[1] 2024-11-14T02:09:35.774430660Z Connection id "0HN84A5GB7LGC" started. 2024-11-14T02:09:35.776304532Z dbug: Microsoft.AspNetCore.Server.Kestrel.Https.Internal.HttpsConnectionMiddleware[1] 2024-11-14T02:09:35.776340833Z Failed to authenticate HTTPS connection. 2024-11-14T02:09:35.776346834Z System.Security.Authentication.AuthenticationException: Cannot determine the frame size or a corrupted frame was received. 2024-11-14T02:09:35.776350934Z at System.Net.Security.SslStream.GetFrameSize(ReadOnlySpan`1 buffer) 2024-11-14T02:09:35.776354134Z at System.Net.Security.SslStream.EnsureFullTlsFrameAsync[TIOAdapter](CancellationToken cancellationToken, Int32 estimatedSize) 2024-11-14T02:09:35.776357734Z at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token) 2024-11-14T02:09:35.776362534Z at System.Net.Security.SslStream.ReceiveHandshakeFrameAsync[TIOAdapter](CancellationToken cancellationToken) 2024-11-14T02:09:35.776365734Z at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](Boolean receiveFirst, Byte[] reAuthenticationData, CancellationToken cancellationToken) 2024-11-14T02:09:35.776369135Z at System.Net.Security.SslStream.ProcessAuthenticationWithTelemetryAsync(Boolean isAsync, CancellationToken cancellationToken) 2024-11-14T02:09:35.776373135Z at Microsoft.AspNetCore.Server.Kestrel.Https.Internal.HttpsConnectionMiddleware.OnConnectionAsync(ConnectionContext context) 2024-11-14T02:09:35.776377135Z dbug: Microsoft.AspNetCore.Server.Kestrel.Connections[2] 2024-11-14T02:09:35.776381235Z Connection id "0HN84A5GB7LGC" stopped. 2024-11-14T02:09:35.776534441Z dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[7] 2024-11-14T02:09:35.776547141Z Connection id "0HN84A5GB7LGC" sending FIN because: "The Socket transport's send loop completed gracefully."
当前配置
docker-compose.yml
services: pr.orderservice.webapi: image: pr.orderservice.webapi build: context: . dockerfile: OrderService/PR.OrderService.WebApi/Dockerfile environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=https://+:443;http://+:80 - ASPNETCORE_Kestrel__Certificates__Default__Password=VerySecurePassword123@! - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx ports: - "5000:80" - "44362:443" volumes: - ${USERPROFILE}\.aspnet\https:/https/:ro
Dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base USER $APP_UID WORKDIR /app EXPOSE 8080 EXPOSE 8081 FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build ARG BUILD_CONFIGURATION=Release WORKDIR /src COPY ["OrderService/PR.OrderService.WebApi/PR.OrderService.WebApi.csproj", "OrderService/PR.OrderService.WebApi/"] COPY ["BuildingBlocks/PR.BuildingBlocks.EventBus/PR.BuildingBlocks.EventBus.csproj", "BuildingBlocks/PR.BuildingBlocks.EventBus/"] COPY ["BuildingBlocks/PR.BuildingBlocks.Common/PR.BuildingBlocks.Common.csproj", "BuildingBlocks/PR.BuildingBlocks.Common/"] COPY ["BuildingBlocks/PR.BuildingBlocks.Testing/PR.BuildingBlocks.Testing.csproj", "BuildingBlocks/PR.BuildingBlocks.Testing/"] COPY ["BuildingBlocks/PR.BuildingBlocks.WebCommon/PR.BuildingBlocks.WebCommon.csproj", "BuildingBlocks/PR.BuildingBlocks.WebCommon/"] COPY ["BuildingBlocks/PR.BuildingBlocks.CustomExceptions/PR.BuildingBlocks.CustomExceptions.csproj", "BuildingBlocks/PR.BuildingBlocks.CustomExceptions/"] COPY ["BuildingBlocks/PR.MultiTenancyServer.AspNetCore/PR.MultiTenancyServer.AspNetCore.csproj", "BuildingBlocks/PR.MultiTenancyServer.AspNetCore/"] COPY ["BuildingBlocks/PR.MultiTenancyServer.Core/PR.MultiTenancyServer.Core.csproj", "BuildingBlocks/PR.MultiTenancyServer.Core/"] COPY ["OrderService/PR.OrderService.Persistence.Database/PR.OrderService.Persistence.Database.csproj", "OrderService/PR.OrderService.Persistence.Database/"] COPY ["BuildingBlocks/PR.MultiTenancyServer.EFCore/PR.MultiTenancyServer.EFCore.csproj", "BuildingBlocks/PR.MultiTenancyServer.EFCore/"] COPY ["BuildingBlocks/PR.MultiTenancyServer.Stores/PR.MultiTenancyServer.Stores.csproj", "BuildingBlocks/PR.MultiTenancyServer.Stores/"] COPY ["OrderService/PR.OrderService.Domain/PR.OrderService.Domain.csproj", "OrderService/PR.OrderService.Domain/"] COPY ["OrderService/PR.OrderService.Common/PR.OrderService.Common.csproj", "OrderService/PR.OrderService.Common/"] COPY ["OrderService/PR.OrderService.Persistence/PR.OrderService.Persistence.csproj", "OrderService/PR.OrderService.Persistence/"] COPY ["OrderService/PR.OrderService.Services.Resilience/PR.OrderService.Services.Resilience.csproj", "OrderService/PR.OrderService.Services.Resilience/"] COPY ["OrderService/PR.OrderService.Services/PR.OrderService.Services.csproj", "OrderService/PR.OrderService.Services/"] COPY ["BuildingBlocks/PR.IntegrationEvents.Commons/PR.IntegrationEvents.Commons.csproj", "BuildingBlocks/PR.IntegrationEvents.Commons/"] RUN dotnet restore "OrderService/PR.OrderService.WebApi/PR.OrderService.WebApi.csproj" COPY . . WORKDIR "/src/OrderService/PR.OrderService.WebApi" RUN dotnet build "PR.OrderService.WebApi.csproj" -c $BUILD_CONFIGURATION -o /app/build FROM build AS publish ARG BUILD_CONFIGURATION=Release RUN dotnet publish "PR.OrderService.WebApi.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "PR.OrderService.WebApi.dll"]
需求:仅需在开发环境启用HTTPS,测试NuGet包在Linux下的兼容性,对证书类型、是否带密码无要求。
解决方案
1. 统一容器暴露端口与应用监听端口
Dockerfile中EXPOSE 8080 8081与应用通过ASPNETCORE_URLS监听的80/443端口不匹配,会导致流量转发异常。修改Dockerfile的EXPOSE指令:
# 替换原EXPOSE行 EXPOSE 80 EXPOSE 443
2. 修复Linux容器内证书文件权限
Windows挂载到Linux的文件默认权限可能导致容器内非root用户($APP_UID)无法读取证书,两种解决方式:
方式一:临时切换到root用户测试(开发环境可用)
修改Dockerfile的base阶段:
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base USER root # 替换原USER $APP_UID WORKDIR /app EXPOSE 80 EXPOSE 443
方式二:调整挂载目录权限
在docker-compose中添加启动命令修改权限:
services: pr.orderservice.webapi: # ... 其他配置 command: > sh -c "chmod -R 644 /https && dotnet PR.OrderService.WebApi.dll"
3. 验证证书挂载正确性
进入容器检查证书是否存在且完整:
# 替换<容器名>为你的容器名称或ID docker exec -it <容器名> ls -l /https
确认aspnetapp.pfx存在,且文件大小与Windows本地文件一致。
4. 简化HTTPS配置(开发环境推荐)
若对证书无特殊要求,可让ASP.NET Core在容器内自动生成开发证书,避免跨系统挂载问题。修改docker-compose的环境变量:
environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=https://+:443;http://+:80 # 移除原证书路径和密码配置,添加以下自动生成配置 - ASPNETCORE_DEV_CERTIFICATE_PASSWORD=VerySecurePassword123@!
5. 检查端口映射冲突
确保宿主机器44362端口未被占用:
netstat -ano | findstr :44362
若被占用,修改docker-compose的ports映射为未使用端口,比如44363:443。
内容的提问来源于stack exchange,提问作者nop
相关产品推荐
相关产品推荐

