2

first of all, i am not an expert in linux and certificate related topics. I try to code a webapi-service and publish it as a docker-container.

My Coding environment is a Visual Studio, running on Windows 10 in a VM. Here, everything is up and running.

My target environment is a Ubuntu 18.04.4 LTS with Docker version 19.03.6-rc1.

Since i want to have multiple services in future, i try to use 'docker-compose up' which is not working as aspected.


Steps i do:

  1. Code in Windows VS 2017
  2. Publish on Docker.hub
  3. Try to compose on Ubuntu

More detailed...

1. Code in Windows VS 2017

In Debug Mode, everything is working for me.

I have a docker-compose project and the api project. The docker-compose project includes the docker-compose.yml and an override file.

Here is my project in VS: The Project in VS2017

docker-compose.yml

version: '3.4'

    services:
      logs.api:
        env_file: .env
        image: ${DOCKER_REGISTRY-}logsapi
        build:
          context: .
          dockerfile: logs.api/Dockerfile

docker-compose.override.yml

version: '3.4'

services:
  logs.api:
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=https://+:443;http://+:80
      - ASPNETCORE_HTTPS_PORT=44374
      - ConnectionString=${CONNECTION_STRING}
    ports:
      - "50530:80"
      - "44374:443"
    volumes:
      - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro
      - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro

Dockerfile

FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY logs.api/logs.api.csproj logs.api/
RUN dotnet restore logs.api/logs.api.csproj
COPY . .
WORKDIR /src/logs.api
RUN dotnet build logs.api.csproj -c Release -o /app

FROM build AS publish
RUN dotnet publish logs.api.csproj -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "logs.api.dll"]

3. Try to compose on Ubuntu

I try to compose in ubuntu with the following command and modified .yml files. Before i login to docker hub with docker login.

Compose command: sudo docker-compose -f docker-compose.yml -f docker-compose.production.yml up

docker-compose.yml

version: '3.4'

services:
  logs.api:
    env_file: .env
    image: autoempire/logsapi

docker-compose.production.yml

version: '3.4'

services:
  logs.api:
    environment:
      - ASPNETCORE_ENVIRONMENT=Production
      - ASPNETCORE_URLS=https://+:443;http://+:80
      - ASPNETCORE_HTTPS_PORT=44374
      - ConnectionString=${CONNECTION_STRING}
      - ASPNETCORE_Kestrel__Certificates__Default__Password=""
      - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/logs.api.pfx
    volumes:
      - ${HOME}/.aspnet/https:/https/
    ports:
      - "50530:80"
      - "44374:443"
    build:
      context: "http://${GIT_USR}:${GIT_PWD}@github.com/r...s/mymicroservices.git#master"
      dockerfile: logs.api/Dockerfile

Here you see, i already changed the volumes. With the secrets i am not sure what to do, so i removed them, since i do not have any password for the cert. But this is maybe another topic.

I added the ASPNETCORE_Kestrel__Certificates__Default__Password and ASPNETCORE_Kestrel__Certificates__Default__Path regarding to some usefull descriptions on stackoverflow and created a self signed certificate on ubuntu which i moved to ~/.aspnet/https/logs.api.pfx.

This is what i get:

logs.api_1  | info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]
logs.api_1  |       User profile is available. Using '/root/.aspnet/DataProtection-Keys' as key repository; keys will not be encrypted at rest.
logs.api_1  | crit: Microsoft.AspNetCore.Server.Kestrel[0]
logs.api_1  |       Unable to start Kestrel.
logs.api_1  | Interop+Crypto+OpenSslCryptographicException: error:23076071:PKCS12 routines:PKCS12_parse:mac verify failure
logs.api_1  |    at Internal.Cryptography.Pal.OpenSslPkcs12Reader.Decrypt(SafePasswordHandle password)
logs.api_1  |    at Internal.Cryptography.Pal.PkcsFormatReader.TryReadPkcs12(OpenSslPkcs12Reader pfx, SafePasswordHandle password, Boolean single, ICertificatePal& readPal, List`1& readCerts)
logs.api_1  |    at Internal.Cryptography.Pal.PkcsFormatReader.TryReadPkcs12(SafeBioHandle bio, SafePasswordHandle password, Boolean single, ICertificatePal& readPal, List`1& readCerts, Exception& openSslException)
logs.api_1  |    at Internal.Cryptography.Pal.CertificatePal.FromBio(SafeBioHandle bio, SafePasswordHandle password)
logs.api_1  |    at Internal.Cryptography.Pal.CertificatePal.FromFile(String fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
logs.api_1  |    at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(String fileName, String password, X509KeyStorageFlags keyStorageFlags)
logs.api_1  |    at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(String fileName, String password)
logs.api_1  |    at Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.LoadCertificate(CertificateConfig certInfo, String endpointName)
logs.api_1  |    at Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.LoadDefaultCert(ConfigurationReader configReader)
logs.api_1  |    at Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.Load()
logs.api_1  |    at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.ValidateOptions()
logs.api_1  |    at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
logs.api_1  |
logs.api_1  | Unhandled Exception: Interop+Crypto+OpenSslCryptographicException: error:23076071:PKCS12 routines:PKCS12_parse:mac verify failure
logs.api_1  |    at Internal.Cryptography.Pal.OpenSslPkcs12Reader.Decrypt(SafePasswordHandle password)
logs.api_1  |    at Internal.Cryptography.Pal.PkcsFormatReader.TryReadPkcs12(OpenSslPkcs12Reader pfx, SafePasswordHandle password, Boolean single, ICertificatePal& readPal, List`1& readCerts)
logs.api_1  |    at Internal.Cryptography.Pal.PkcsFormatReader.TryReadPkcs12(SafeBioHandle bio, SafePasswordHandle password, Boolean single, ICertificatePal& readPal, List`1& readCerts, Exception& openSslException)
logs.api_1  |    at Internal.Cryptography.Pal.CertificatePal.FromBio(SafeBioHandle bio, SafePasswordHandle password)
logs.api_1  |    at Internal.Cryptography.Pal.CertificatePal.FromFile(String fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
logs.api_1  |    at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(String fileName, String password, X509KeyStorageFlags keyStorageFlags)
logs.api_1  |    at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(String fileName, String password)
logs.api_1  |    at Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.LoadCertificate(CertificateConfig certInfo, String endpointName)
logs.api_1  |    at Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.LoadDefaultCert(ConfigurationReader configReader)
logs.api_1  |    at Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.Load()
logs.api_1  |    at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.ValidateOptions()
logs.api_1  |    at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
logs.api_1  |    at Microsoft.AspNetCore.Hosting.Internal.WebHost.StartAsync(CancellationToken cancellationToken)
logs.api_1  |    at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token, String shutdownMessage)
logs.api_1  |    at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token)
logs.api_1  |    at Microsoft.AspNetCore.Hosting.WebHostExtensions.Run(IWebHost host)
logs.api_1  |    at logs.api.Program.Main(String[] args) in /src/logs.api/Program.cs:line 18
reco_logs.api_1 exited with code 139

The location of the certificate in the production.yml seems to be ok because when I change it, I get an error like "file not found". I tried a certificate with and without a password. It does not matter... maybe not really good registered?

rogras
  • 21
  • 5
  • 3
    - ASPNETCORE_Kestrel__Certificates__Default__Password="" has to be without ""like ASPNETCORE_Kestrel__Certificates__Default__Password=mypassword. And it works :/ – rogras Feb 07 '20 at 10:00

0 Answers0