How to run an Https ASP.NET Core App using test certificates in Nanoserver 1709/1803 with Docker
Run Https ASP.NET Core Applications in Nanoserver 1709/1803 Containers with Docker
I struggled with this a little bit, so I decided to make the smallest example possible and write the details in here.
First, we need a root certificate that both the server and client are going to trust:
$rootCert = New-SelfSignedCertificate ` -Subject "CN=Root CA,OU=Me,O=MyCompany,L=Brussels,ST=Belgium,C=BE" ` -CertStoreLocation cert:\CurrentUser\My ` -Provider "Microsoft Strong Cryptographic Provider" ` -DnsName "MyCompany Root CA" ` -KeyLength 2048 ` -KeyAlgorithm "RSA" ` -HashAlgorithm "SHA256" ` -KeyExportPolicy "Exportable" ` -KeyUsage "CertSign", "CRLSign"
The we need to create a
.cer file that will be copied in containers and imported in their trust store:
Export-Certificate -Type CERT -Cert $rootCert -FilePath root-ca.cer
The second certificate we need is the one that will be used by the server for TLS and that must be signed by the root certificate:
$serverCert = New-SelfSignedCertificate ` -Subject "CN=server,OU=ESF,O=Ingenico,L=Brussels,ST=Belgium,C=BE" ` -CertStoreLocation cert:\CurrentUser\My ` -Provider "Microsoft Strong Cryptographic Provider" ` -Signer $rootCert ` -KeyLength 2048 ` -KeyAlgorithm "RSA" ` -HashAlgorithm "SHA256" ` -KeyExportPolicy "Exportable"
Notice that in this case the certificate is signed by the root certificate. The client will use “server” as the hostname and the certificate has to contain it in order for the client to not reject it because of a miss-match (I’m going on a limb here since I’m no TLS/certificates expert, but after fiddling this is what has been working for me).
This certificate needs to be exported as
Export-PfxCertificate -Cert $serverCert -Password $password -FilePath server.pfx
Creating the Server
A tricky bit when using
1803 nanoserver containers is that they don’t include PowerShell. You can get it is by getting it from the internet and then copying it in the image (some Microsoft images, such as the powershell one, do that) but it’s a hassle, and actually useless because the PKI module is not part of PowerShell code (pwsh.exe) which means Import-Certificate will not be available anyway.
I found that nanoserver’s image contains a tool called
certoc.exe (which is completely undocumented, by the way) that allows you to do that. But surprise, it is not present in the
1803 images, only in
certoc.exe is a standalone tool which can be copied over, so we can solve all this by copying the file from the
sac2016 image onto the
1803 image in the
FROM microsoft/nanoserver:sac2016 as tool FROM microsoft/dotnet:2.1-aspnetcore-runtime-nanoserver-1803 WORKDIR /app COPY /bin/publish . COPY --from=tool /Windows/System32/certoc.exe . USER ContainerAdministrator RUN certoc.exe -addstore root root-ca.cer USER ContainerUser ENTRYPOINT ["dotnet", "MyApp.dll"]
Two important things here:
- copy the
certoc.exefile from the tool image into the target image
- import the root certificate (as ContainerAdministrator user)
Creating the Client
FROM microsoft/nanoserver:sac2016 as tool FROM microsoft/dotnet:2.1-runtime-nanoserver-1803 WORKDIR /app COPY /bin/publish . COPY --from=tool /Windows/System32/certoc.exe . USER ContainerAdministrator RUN certoc.exe -addstore root root-ca.cer USER ContainerUser ENTRYPOINT ["dotnet", "Client.dll"]
Again, we copy the tool from the
sac2016 image then import the root certificate in the root store of the machine so that it is trusted.
You can find a full example for this, including a client and a server, here: https://github.com/Pvlerick/AspNetCoreTlsInNanoserverDocker
Written with StackEdit.
blog comments powered by Disqus