Impossible de configurer le point de terminaison HTTPS pour .net Core Kestral Server dans le conteneur Linux sur Azure
J'ai une application .net core 3 fonctionnant localement / développement très bien, à la fois seule et lorsqu'elle est exécutée dans un conteneur Linux. Je prends ensuite l'application et je l'ai intégrée dans une image docker à l'intérieur des pipelines Azure. L'image est chargée dans le registre de conteneurs Azure.
Enfin, j'ai une application Web Azure pour conteneurs (Linux) qui utilise l'image pour s'exécuter.
Localement, j'ai le fichier docker-compose configuré comme ceci:
environment:
- "ASPNETCORE_ENVIRONMENT=Development"
...
- "ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx"
- "ASPNETCORE_Kestrel__Certificates__Default__Password=Your_password123"
volumes:
- ~/.aspnet/https:/https:ro
Pour la production, j'ai les éléments suivants:
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
J'ai chargé "mycert" dans le portail Azure et ajouté son empreinte numérique aux paramètres de configuration de l'application sous WEBSITE_LOAD_CERTIFICATES
J'ai utilisé Open SSL pour créer le fichier mycert et je peux l'utiliser localement et kestral l'utilisera, mais avec un avertissement.
LE PROBLÈME
Lorsque j'exécute l'application avec cette image, j'obtiens l'erreur suivante dans les journaux du docker:
System.InvalidOperationException: impossible de configurer le point de terminaison HTTPS. Aucun certificat de serveur n'a été spécifié et le certificat de développeur par défaut est introuvable ou est obsolète ... sur Microsoft.AspNetCore.Hosting.ListenOptionsHttpsExtensions.UseHttps (ListenOptions listenOptions, Action`1 configureOptions)
J'ai essayé de nombreuses variantes de certificats de chargement et je ne parviens à faire fonctionner aucune d'entre elles. C'est un problème qui ne se produit qu'en production.
J'ai aussi essayé:
- J'ai acheté un certificat d'application Azure et utilisé le fichier thumbprint.p12 comme:
- ASPNETCORE_Kestrel__Certificates__Default__Path=/var/ssl/private/<thumbprint>.p12
- ASPNETCORE_Kestrel__Certificates__Default__Password=""
Je n'ai utilisé aucun mot de passe car lorsque vous achetez un certificat, il n'y a pas de mot de passe défini
Téléchargé le certificat d'application acheté et utilisé ssl ouvert pour créer un fichier .pfk lié par mot de passe et téléchargé cela comme une autre clé privée
Utilisez le montage de fichier azure et téléchargez mes fichiers de certificat de développement et référencez-les à partir du montage de fichier comme:
- ASPNETCORE_Kestrel__Certificates__Default__Path=/security/mycert.com.pfx
- ASPNETCORE_Kestrel__Certificates__Default__Password="Your_password123"
volumes:
- fsmount001: /security:/security
EDIT 1: configuration complète du fichier docker-compose et azure
- Voici comment j'ai défini mon partage de fichiers:
Il y a un dossier de sécurité avec le fichier mycert.pfx à l'intérieur
- Voici comment configurer le montage de fichier dans ma configuration de service d'application Azure:
J'ai défini le chemin de montage comme le dossier de sécurité dans mon partage de fichiers
- Voici le fichier de composition complet du docker:
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
EDIT 2: DOCKERFILE
pour plus de contexte, vous pouvez trouver mon fichier docker ci-dessous
veuillez noter que j'utilise le modèle d'application open source / framework cleanarchiecture. Vous pouvez voir que j'essaye d'utiliser la demande d'extraction de docker pour le repo comme code de base. Mon objectif est de «dockeriser» ce framework de base dans le pipeline azure ci / cd et de le déployer sur azure web app for containers (linux)
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"]
Quelqu'un peut-il m'aider à comprendre comment définir un certificat pour kestral dans un conteneur Linux?
Merci d'avance
Réponses
Est-il possible que votre docker-composefichier comporte une erreur dans la définition du service volumes?
Vous disposez du docker-composefragment suivant pour votre service:
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
Avec cette configuration, vous essayez de créer deux volumes.
D'une part, vous mappez le /var/ssl/privatechemin du système hôte vers la /httpsdestination du conteneur. Cela devrait fonctionner correctement.
Mais, d'un autre côté, je pense que vous mélangez la syntaxe des volumes nommés et des volumes basés sur le mappage de chemin.
Pour votre mise à jour, vous essayez d'utiliser un montage de stockage Azure File. Ensuite, vous devez modifier votre volumesdéfinition de service comme suit:
environment:
...
ports:
...
volumes:
- fsmount001:/security
- /var/ssl/private:/https
Comme indiqué dans la documentation , il est important de comprendre que le chemin de montage correspond au dossier à l'intérieur du conteneur que vous souhaitez monter sur Azure Storage:
Le paramètre de chemin de montage correspond au dossier à l'intérieur du conteneur que vous souhaitez monter sur Azure Storage. Le définir sur '/' monte l'ensemble du conteneur sur le stockage Azure.
Veuillez également noter que le chemin fourni fsmount001dans votre docker-composefichier est le même que le chemin de montage indiqué lors de la création du montage, /securitydans ce cas.
Avec cette configuration, vous devez configurer l'emplacement du certificat comme ceci:
- ASPNETCORE_Kestrel__Certificates__Default__Path=/security/security/mycert.pfx
Le premier /securitypour le chemin dans le conteneur, et le second pour le répertoire dans lequel votre pfx est inclus dans le partage de fichiers.
METTRE À JOUR
Après avoir examiné vos fichiers Dockerfileet docker-composeensemble, je pense que votre problème pourrait être motivé non pas pour le partage de fichiers réel, mais parce que les variables d'environnement requises pour configurer votre HTTPS ne sont pas visibles à l'intérieur du conteneur docker car elles ne sont utilisées que dans sa phase de construction. S'il vous plaît, voyez cette question liée au débordement de pile, je pense.
Vous devez fournir ces informations d'environnement directement dans votre fichier Dockerfileou en utilisant indirectement ARGs dans votre docker-composefichier.
Par exemple, modifiez votre docker-composefichier comme suit - en gros, modifiez votre environmententrée pour 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
Et ils modifient votre Dockerfilepour lire les arguments de construction fournis:
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"]
Veuillez le modifier comme vous le jugez approprié. Faites attention en particulier au moment où les différents ARGs et ENVs doivent être définis car ils sont étendus par étape de construction et ne seront pas conservés à l'étape suivante. Vous pouvez essayer tel quel, ou vous pouvez définir le ARGs in baseet le ENVs in final, car l'un s'étendant de l'autre, les ARGvariables s doivent être visibles dans les deux.