无法在Azure上的Linux容器中为.net Core Kestral服务器配置HTTPS终结点

时间:2020-10-27 21:43:26

标签: azure docker .net-core docker-compose azure-web-app-service

我有一个运行 local / development 的.net core 3应用程序,可以独立运行,也可以在linux容器中运行。 然后,我将应用程序安装到Azure管道中的docker映像中。该图像已加载到Azure容器注册表中。

最后,我有一个用于容器的 Azure Web APP (Linux)

我在本地设置了docker-compose文件,如下所示:

    environment:
      - "ASPNETCORE_ENVIRONMENT=Development"
      ...
      - "ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx"
      - "ASPNETCORE_Kestrel__Certificates__Default__Password=Your_password123"
    volumes:
      - ~/.aspnet/https:/https:ro

对于生产,我有以下内容:

    environment:
      - UseInMemoryDatabase=false
      - ASPNETCORE_ENVIRONMENT=Production
      - ASPNETCORE_Kestrel__Certificates__Default__Path=/security/mycert.pfx
      - "ASPNETCORE_Kestrel__Certificates__Default__Password=Your_password123"
    ports:
      - "5000:5000"
      - "5001:5001"
    volumes:
       - fsmount001: /security:/security
       - /var/ssl/private:/https

我将“ mycert”加载到了Azure门户中,并在 WEBSITE_LOAD_CERTIFICATES

下将其指纹添加到了应用程序的配置设置中

我使用Open SSL创建了 mycert 文件,我可以在本地使用它,而kestral会使用它,但会出现警告。

问题

当我使用该图像运行应用程序时,我在docker日志中收到以下错误:

System.InvalidOperationException:无法配置HTTPS端点。 未指定服务器证书,并且是默认开发者 找不到证书或证书过期...在 Microsoft.AspNetCore.Hosting.ListenOptionsHttpsExtensions.UseHttps(ListenOptions listenOptions,操作1个configureOptions)

我尝试了很多加载证书的变体,但无法使它们工作。 这是一个仅在生产中发生的问题。

我也尝试过:

  1. 购买了Azure应用证书,并使用了thumbprint.p12文件,例如:
      - ASPNETCORE_Kestrel__Certificates__Default__Path=/var/ssl/private/<thumbprint>.p12
      - ASPNETCORE_Kestrel__Certificates__Default__Password=""

我没有使用密码,因为当您购买证书时没有设置密码

  1. 下载了购买的App Cert,并使用open ssl创建了一个密码链接的.pfk文件,并将其作为另一个私钥上传

  2. 使用azure文件挂载并上传我的dev cert文件,并从文件挂载中引用它们,例如:

      - ASPNETCORE_Kestrel__Certificates__Default__Path=/security/mycert.com.pfx
      - ASPNETCORE_Kestrel__Certificates__Default__Password="Your_password123"
    volumes:
       - fsmount001: /security:/security

编辑1:完整的docker-compose和azure文件设置

  1. 这是我定义文件共享的方式: enter image description here

有一个带有mycert.pfx文件的安全文件夹

  1. 这是我在azure应用程序服务配置中设置文件挂载的方式:

enter image description here

我将安装路径设置为文件共享中的安全文件夹

  1. 这是完整的docker compose文件:
services:
  webui:
    image: ${DOCKER_REGISTRY-}webui
    build:
      context: .
      dockerfile: src/WebUI/Dockerfile
    environment:
      - UseInMemoryDatabase=false
      - ASPNETCORE_ENVIRONMENT=Production
      - ASPNETCORE_URLS=https://+:443;http://+:80
      - "ConnectionStrings__DefaultConnection=****"
      - ASPNETCORE_Kestrel__Certificates__Default__Path=/secure/mycert.pfx
      - ASPNETCORE_Kestrel__Certificates__Default__Password="Your_password123"
    ports:
      - "5000:5000"
      - "5001:5001"
    volumes:
       - fsmount001: /secure
       - ~/var/ssl/private:/https
    restart: always

volumes:
  fsmount001:
    driver: azure_file
    driver_opts:
      share_name: st-*****tus
      storage_account_name: st********001

编辑2:DOCKERFILE

有关更多信息,您可以在下面找到我的dockerfile

请注意,我正在使用开源应用程序模板/框架清洁体系结构。您可以看到,我正在尝试将docker pull request用于存储库作为基本代码。我的目标是在azure ci / cd管道中“ dockerize”此基础框架,并将其部署到用于容器(linux)的azure Web应用程序


FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
ENV ASPNETCORE_URLS=https://+:5001;http://+:5000

WORKDIR /app
EXPOSE 5000 5001 2222

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
RUN curl -sL https://deb.nodesource.com/setup_12.x | bash -
RUN apt install -y nodejs
WORKDIR /src
COPY ["src/WebUI/WebUI.csproj", "src/WebUI/"]
COPY ["src/Application/Application.csproj", "src/Application/"]
COPY ["src/Domain/Domain.csproj", "src/Domain/"]
COPY ["src/Infrastructure/Infrastructure.csproj", "src/Infrastructure/"]
RUN dotnet restore "src/WebUI/WebUI.csproj"
COPY . .
WORKDIR "/src/src/WebUI"
RUN dotnet build "WebUI.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "WebUI.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .

ENTRYPOINT ["dotnet", "CleanArchitecture.WebUI.dll"]

有人可以帮我弄清楚如何在Linux容器中设置kestral证书吗?

预先感谢

1 个答案:

答案 0 :(得分:2)

您的docker-compose文件是否可能在服务volumes的定义中有错误?

对于您的服务,您有以下docker-compose片段:

    environment:
      - UseInMemoryDatabase=false
      - ASPNETCORE_ENVIRONMENT=Production
      - ASPNETCORE_Kestrel__Certificates__Default__Path=/security/mycert.pfx
      - "ASPNETCORE_Kestrel__Certificates__Default__Password=Your_password123"
    ports:
      - "5000:5000"
      - "5001:5001"
    volumes:
       - fsmount001: /security:/security
       - /var/ssl/private:/https

使用此设置,您尝试创建两个卷。

一方面,您正在将主机系统中的/var/ssl/private路径映射到/https容器目的地。应该可以。

但是,另一方面,我认为您正在混合命名卷和基于路径映射的卷的语法。

对于更新,您尝试使用Azure文件存储安装。然后,您需要修改服务volumes的定义,如下所示:

    environment:
      ...
    ports:
      ...
    volumes:
       - fsmount001:/security
       - /var/ssl/private:/https

documentation中所述,重要的是要了解安装路径与要安装到Azure存储的容器内的文件夹相对应:

安装路径设置与要安装到Azure存储的容器内的文件夹相对应。将其设置为“ /”会将整个容器安装到Azure存储。

请注意,fsmount001文件中为docker-compose提供的路径与创建挂载时指示的挂载路径相同,在这种情况下为/security

使用此设置,您需要配置证书位置,如下所示:

- ASPNETCORE_Kestrel__Certificates__Default__Path=/security/security/mycert.pfx

第一个/security用于容器中的路径,第二个用于目录pfx包含在文件共享中。

更新

一起查看您的Dockerfiledocker-compose文件之后,我认为您的问题可能不是由文件共享引起的,而是因为在docker内部看不到设置HTTPS所需的环境变量容器,因为它们仅在其构建阶段使用。请参阅this我认为相关的堆栈溢出问题。

您需要直接在Dockerfile中提供此环境信息,或使用ARG文件中的docker-compose间接提供此环境信息。

例如,如下修改您的docker-compose文件-基本上,将environment的{​​{1}}条目更改为:

args

然后他们修改您的services: webui: image: ${DOCKER_REGISTRY-}webui build: context: . dockerfile: src/WebUI/Dockerfile args: - UseInMemoryDatabase=false - ASPNETCORE_ENVIRONMENT=Production - ASPNETCORE_URLS=https://+:443;http://+:80 - ConnectionStrings__DefaultConnection=**** - ASPNETCORE_Kestrel__Certificates__Default__Path=/secure/mycert.pfx - ASPNETCORE_Kestrel__Certificates__Default__Password="Your_password123" ports: - "5000:5000" - "5001:5001" volumes: - fsmount001: /secure - ~/var/ssl/private:/https restart: always volumes: fsmount001: driver: azure_file driver_opts: share_name: st-*****tus storage_account_name: st********001 来读取提供的构建参数:

Dockerfile

请在您认为适当的时候对其进行修改。特别是在应该定义不同的FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base ARG UseInMemoryDatabase ENV UseInMemoryDatabase=$UseInMemoryDatabase ARG ASPNETCORE_ENVIRONMENT ENV ASPNETCORE_ENVIRONMENT=$ASPNETCORE_ENVIRONMENT ARG ASPNETCORE_URLS=https://+:5001;http://+:5000 ENV ASPNETCORE_URLS=$ASPNETCORE_URLS ARG ConnectionStrings__DefaultConnection ENV ConnectionStrings__DefaultConnection=$ConnectionStrings__DefaultConnection ARG ASPNETCORE_Kestrel__Certificates__Default__Path ENV ASPNETCORE_Kestrel__Certificates__Default__Path=$ASPNETCORE_Kestrel__Certificates__Default__Path ARG ASPNETCORE_Kestrel__Certificates__Default__Password ENV ASPNETCORE_Kestrel__Certificates__Default__Password=$ASPNETCORE_Kestrel__Certificates__Default__Password WORKDIR /app EXPOSE 5000 5001 2222 FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build RUN curl -sL https://deb.nodesource.com/setup_12.x | bash - RUN apt install -y nodejs WORKDIR /src COPY ["src/WebUI/WebUI.csproj", "src/WebUI/"] COPY ["src/Application/Application.csproj", "src/Application/"] COPY ["src/Domain/Domain.csproj", "src/Domain/"] COPY ["src/Infrastructure/Infrastructure.csproj", "src/Infrastructure/"] RUN dotnet restore "src/WebUI/WebUI.csproj" COPY . . WORKDIR "/src/src/WebUI" RUN dotnet build "WebUI.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "WebUI.csproj" -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "CleanArchitecture.WebUI.dll"] ARG时,要特别注意,因为它们是在每个构建阶段确定范围的,不会在下一阶段保留。您可以按原样尝试,也可以在ENV中定义ARG和在base中定义ENV,因为它们是彼此final的扩展s的变量在两者中均应可见。