Py学习  »  docker

在Ubuntu Linux的Docker中使用SSL在Kestrel上获取ASP.NET Core应用程序时遇到问题

Andrew • 1 年前 • 941 次点击  

我在使用SSL在Ubuntu 20.04上的Docker中获得一个简单的ASP.NET Core Hello World应用程序时遇到了问题。以下是设置详细信息:

  • 开发环境是Windows 10上的Visual Studio 2022。
  • Framework是在.NET 6上运行的ASP.NET核心。
  • 我使用的是在创建新ASP.NET时创建的香草helloworld应用程序 VS中的核心项目。除了在应用程序中添加一个Dockerfile之外,我什么都没做。
  • 目标运行环境是运行在Linux Docker容器内的Kestrel服务器,该容器本身运行在Ubuntu 20.04上。
  • 我正在尝试在Ubuntu机器上使用Firefox访问该应用程序。

(这种奇怪的设置背后的原因是,我们有一位客户想在他们的Ubuntu盒子上的Docker容器中托管我们的应用程序。然而,我们的传统代码库和团队的技能集决定了我们在Windows上的.NET中开发。因此,我只是想让POC研究如何在Ubuntu上的Docker中运行ASP.NET Core应用程序。)

我使用的Dockerfile只是Visual Studio在我告诉它添加Docker支持时为我创建的未修改版本:

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();
        }
    }
}

这是我构建、部署和运行Docker镜像/容器的过程:

在我的Windows开发机器上:

  1. 打开Powershell,导航到解决方案文件夹(Dockerfile所在的位置)并运行以下命令:
docker build -t aspnetssl .
  1. 仍然在Powershell中,使用以下命令将图像从docker导出到tar文件:
docker save -o aspnetssl.tar aspnetssl
  1. 将.tar文件复制到与我的Ubuntu虚拟机(名为VMShared)共享的文件夹中。

在我的Ubuntu 20.04虚拟机上

首先,我需要创建一个自签名证书,以便应用程序可以使用SSL。我引用了 this blog post 对于这些步骤:

  1. 创建 https.config 文件,其中包含以下内容:
[ req ]
default_bits       = 2048
default_md         = sha256
default_keyfile    = key.pem
prompt             = no
encrypt_key        = no

distinguished_name = req_distinguished_name
req_extensions     = v3_req
x509_extensions    = v3_req

[ req_distinguished_name ]
commonName             = "localhost"

[ v3_req ]
subjectAltName      = DNS:localhost
basicConstraints    = critical, CA:false
keyUsage            = critical, keyEncipherment
extendedKeyUsage    = critical, 1.3.6.1.5.5.7.3.1
  1. 运行以下命令以生成私钥和证书签名请求:
openssl req -config https.config -new -out csr.pem
  1. 运行以下命令以创建自签名证书:
openssl x509 -req -days 365 -extfile https.config -extensions v3_req -in csr.pem -signkey key.pem -out https.crt
  1. 运行以下命令生成可与Kestrel一起使用的pfx文件:
openssl pkcs12 -export -out https.pfx -inkey key.pem -in https.crt -password pass:password
  1. 复制 https.pfx 到我的共享文件夹 /mnt/hgfs/VMShared/https 使其可访问Kestrel服务器(它可以去任何地方,只要它可以通过卷装载传递给Docker)

现在我需要信任证书:

  1. 复制 https.crt /usr/local/share/ca-certificates/ 并运行 sudo update-ca-certificates 命令,该命令提供一个输出,指示已添加1个证书。

  2. 将证书添加到Firefox的可信证书存储中:

  • 查找Firefox默认配置文件

Firefox profiles

  • 将该配置文件的证书添加到Firefox的证书存储中:
sudo certutil -A -n "https" -t "TC,," -i ~/https.crt -d sql:/home/u/.mozilla/firefox/ayi0vczl.default-release
  • 验证它是否已放入该存储:
sudo certutil -d sql:/home/u/.mozilla/firefox/ayi0vczl.default-release -L

其示出了该输出:

Firefox certs

最后,我准备运行docker镜像:

  1. 将docker图像加载到docker中:
sudo docker load -i /mnt/hgfs/VMShared/aspnetssl.tar
  1. 通过运行以下命令(打包在脚本文件中)运行docker映像:
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

当集装箱启动时,我在码头窗口中看到:

warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]
      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.
warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
      No XML encryptor configured. Key {3ad53391-8a83-486b-9c15-f783ffe52d87} may be persisted to storage in unencrypted form.
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: https://[::]:443
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://[::]:80
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Docker
info: Microsoft.Hosting.Lifetime[0]
      Content root path: /app/

没有明显的错误,警告在我看来还可以,所以它似乎运行得很好。然而,当我尝试在Firefox中导航到它时 http://localhost:5000 https://localhost:5001 ,它只是挂起,我最终得到了一个超时错误。

Firefox timeout

我目前的工作理论是我的SSL设置有问题,比如Firefox无法访问证书之类的。这很难诊断,因为我对SSL和web技术没有太多经验,也不确定应该查看哪些错误或日志。然而,我可以想到一些可能的故障点:

  • 未正确生成自签名证书。
  • 该证书在Ubuntu虚拟机上不受信任。
    • 我还尝试添加 https.crt 文件到 /etc/ssl/certs /etc/ca-certificates 文件夹,但这似乎不起作用。
  • Firefox无法访问该证书,或者由于某种原因无法信任它。
  • Kestrel服务器没有正确地向Firefox提供证书。

我不确定这些是否有意义,但我的直觉是,破坏与SSL有关,因为我 通过从中删除一些行,可以让这个Hello World应用程序的一个版本只在http上运行 Program.cs 以及设置 "useSSL":false 在我的 launchsettings.json 文件

有人知道为什么Firefox在尝试ping ASP.NET应用程序时超时了吗?我感谢大家给予我的帮助。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/158178
 
941 次点击  
文章 [ 1 ]  |  最新文章 1 年前