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:
- Code in Windows VS 2017
- Publish on Docker.hub
- 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?