Ubuntu Docker环境下Kestrel运行ASP.NET Core SSL应用超时求助
ASP.NET Core SSL Docker容器访问超时问题排查
问题背景
开发环境:Windows 10 + Visual Studio 2022 + .NET 6
目标环境:Ubuntu 20.04 Docker容器(Kestrel服务器),本地Firefox访问
仅使用VS生成的默认Dockerfile,未修改其他项目内容。移除SSL配置的纯HTTP版本可正常运行,但配置SSL后,容器启动日志无报错,但访问http://localhost:5000或https://localhost:5001均超时。
操作流程
- Windows端:通过PowerShell构建Docker镜像,导出为tar包后复制到Ubuntu共享目录
- Ubuntu端:
- 生成自签名证书并添加到系统及Firefox信任库
- 加载镜像并运行容器,命令如下:
docker run --rm \ -p 5000:80 \ -p 5001:443 \ -v /mnt/hgfs/VMShared/https:/https/ \ -e ASPNETCORE_Kestrel__Certificates__Default__Password="password" \ -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/https.pfx \ -e ASPNETCORE_URLS="https://+:443;http://+:80" \ -e ASPNETCORE_ENVIRONMENT=Docker \ aspnetssl:latest
怀疑方向
- 自签名证书生成不规范
- 证书未被正确信任
- Kestrel SSL配置异常
相关配置文件
Dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base WORKDIR /app EXPOSE 80 EXPOSE 443 FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build WORKDIR /src COPY ["AspNetSsl/AspNetSsl.csproj", "AspNetSsl/"] RUN dotnet restore "AspNetSsl/AspNetSsl.csproj" COPY . . WORKDIR "/src/AspNetSsl" RUN dotnet build "AspNetSsl.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "AspNetSsl.csproj" -c Release -o /app/publish /p:UseAppHost=false FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "AspNetSsl.dll"]
launchsettings.json
{ "profiles": { "AspNetSsl": { "commandName": "Project", "launchBrowser": true, "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" }, "dotnetRunMessages": true, "applicationUrl": "https://localhost:7033;http://localhost:5041" }, "IIS Express": { "commandName": "IISExpress", "launchBrowser": true, "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } }, "Docker": { "commandName": "Docker", "launchBrowser": true, "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}", "publishAllPorts": true, "useSSL": true } }, "iisSettings": { "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { "applicationUrl": "http://localhost:34953", "sslPort": 44378 } } }
appsettings.json
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*" }
Program.cs
namespace AspNetSsl { public class Program { public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddRazorPages(); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapRazorPages(); app.Run(); } } }
排查步骤
1. 验证端口映射与容器网络
- 在Ubuntu本地执行
netstat -tulpn | grep -E ":5000|:5001",确认端口是否被Docker正确监听 - 进入容器内部,执行
curl http://localhost:80和curl https://localhost:443,验证应用在容器内是否可访问:- 若容器内访问正常,说明问题出在宿主机到容器的网络/端口映射
- 若容器内也超时,说明Kestrel未正常启动服务
2. 检查证书有效性与权限
- 验证宿主机上的
https.pfx文件路径与权限:执行ls -l /mnt/hgfs/VMShared/https/https.pfx,确保容器挂载目录有读权限(Docker默认以非root用户运行,需确认文件权限允许读取) - 在容器内执行
dotnet dev-certs https --check --trust,检查证书是否可被Kestrel识别 - 尝试重新生成符合要求的自签名证书:使用
openssl生成包含localhostSAN(Subject Alternative Name)的证书,再导出为PFX格式,命令示例:openssl req -x509 -newkey rsa:4096 -sha256 -days 365 -nodes \ -keyout localhost.key -out localhost.crt -subj "/CN=localhost" \ -addext "subjectAltName=DNS:localhost" openssl pkcs12 -export -out https.pfx -inkey localhost.key -in localhost.crt -passout pass:password
3. 调整Kestrel配置与环境变量
- 移除
ASPNETCORE_ENVIRONMENT=Docker,改用ASPNETCORE_ENVIRONMENT=Production或Development,避免环境变量未被正确识别导致配置加载异常 - 在
Program.cs中显式配置Kestrel SSL,替代环境变量配置,测试是否生效:builder.WebHost.ConfigureKestrel(options => { options.ListenAnyIP(80); options.ListenAnyIP(443, listenOptions => { listenOptions.UseHttps("/https/https.pfx", "password"); }); }); - 临时注释
app.UseHttpsRedirection(),测试HTTP访问是否正常,排除重定向导致的异常
4. 检查防火墙与SELinux
- Ubuntu本地执行
ufw status,确认5000、5001端口已开放 - 检查SELinux状态(
sestatus),如果处于Enforcing模式,尝试临时关闭(setenforce 0)测试是否可访问
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

