社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  docker

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

Andrew • 1 年前 • 947 次点击  

我在使用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
 
947 次点击  
文章 [ 1 ]  |  最新文章 1 年前