Most enterprise companies now days have multiple layers of security protecting their network. One of those layers is SSL/TLS interception. SSL/TLS interception is performed by software on proxies located in between the client and HTTPS website at the enterprises perimeter. SSL/TLS interception relies on the client having previously installed a root certificate onto their operating system. Any outgoing SSL/TLS connections from the client are terminated and re-established by the proxy to the server, which acts as an in-the-middle attacker. In an ideal deployment, the proxy’s ClientHello mirrors the TLS parameters expressed in the client’s ClientHello, to provide the same expected parameters to the client. The proxy can then inspect plaintext and establish a TLS connection back to the client using the installed certificate to circumvent browser warnings and silently intercept the connection between client and server.
Even with an enterprise root certificate installed on the clients operating system individual applications can still experience issues. This is common with development tools such as NPM, Nuget, and GitHub because their client applications are validating the certificate themselves rather than relying on the host operating system. Another area this can cause issues is with containers. Unless the image you are using has the root certificate installed all HTTPS traffic will fail. So let’s see how to import the certificate.
To import the certificate during the build process follow these steps:
Export the root certificate.
- Open a Command Prompt window.
- Type
mmc
and press the ENTER key. Note that to view certificates in the local machine store, you must be in the Administrator role. - On the File menu, click Add/Remove Snap In.
- Click Add.
- In the Add Standalone Snap-in dialog box, select Certificates.
- Click Add.
- In the Certificates snap-in dialog box, select Computer account and click Next. Optionally, you can select My User account or Service account. If you are not an administrator of the computer, you can manage certificates only for your user account.
- In the Select Computer dialog box, click Finish.
- In the Add Standalone Snap-in dialog box, click Close.
- On the Add/Remove Snap-in dialog box, click OK.
- In the Console Root window, click Certificates (Local Computer) to view the certificate stores for the computer.
- Locate the certificate that is used by your SSL interception appliance under Trusted Root Certification Authorities.
- Right click on the item, and under All Tasks select Export.
- In your options for the export, select DER encoded binary X.509 (.CER).
- Click Next
- Export the certificate to the folder containing your Dockerfile
Modify your Dockerfile
Add the following to your Dockerfile. I prefer to add it right after defining the FROM and WORKDIR.
COPY ./corporaterootssl.cer ./ COPY ./certoc.exe ./ USER ContainerAdministrator RUN certoc.exe -addstore root corporaterootssl.cer
Here is an example Dockerfile from a Microsoft Quick Start with the certificate modifications.
FROM microsoft/aspnetcore-build:2.0 AS build-env WORKDIR /app COPY ./corporaterootssl.cer ./ COPY ./certoc.exe ./ USER ContainerAdministrator RUN certoc.exe -addstore root corporaterootssl.cer COPY *.csproj ./ RUN dotnet restore COPY . ./ RUN dotnet publish -c Release -o out FROM microsoft/aspnetcore:2.0 WORKDIR /app COPY --from=build-env /app/out . ENTRYPOINT ["dotnet", "ContainerApp1.dll"]
Here is a break down of what is happening. First we copy the certificate and certoc.exe tool into the container.
COPY ./corporaterootssl.cer ./ COPY ./certoc.exe ./
Then we elevate to the ContainerAdministrator user. Nano Server runs as ContainerUser, so commands that require administrator privileges will fail.
USER ContainerAdministrator
Finally we import the certificate into the Trusted Root store.
RUN certoc.exe -addstore root corporaterootssl.cer
There are a number of different tools that can be used to manage certificates on Windows including certutil.exe, certmgr.exe, and PowerShell with the Import-Certificate cmdlet just to name a few. Windows Nano Server is a different beast though. It has been stripped down to the bare metal only containing those libraries required to have a functioning operating system. It is amazing that they have been able to take a 5GB Windows Server Core image and strip it down to 80MB currently. With that size reduction came the loss of certain things we have taken for granted such as the .NET Framework, PowerShell, and a host of system tools. Nano Server is built on top of the .NET Core Framework and thus many tools that relied on the Full .NET Framework will not run. With the loss of .NET Framework Microsoft had to rewrite PowerShell to run against .NET Core which PowerShell 6.0 does. But to make the image as small as possible Microsoft decided not to include PowerShell in the base image. You can get an image with PowerShell installed just use microsoft/powershell:nanoserver. PowerShell 6.0 is a subset of PowerShell 5.1 and is currently lacking the Import-Certificate cmdlet.
I will mention that the Sysinternals Suite of tools has a version available for Nano Server so go download it.
Summary
Discovering this solution took many hours spread across multiple days and I hope to save others from having to go through that discovery process.
5 responses to “How to Import an Enterprise Certificate into a Windows Container”
Where does certoc.exe come from?
LikeLike
certoc.exe can be found in a Windows Nano server container image. The path is C:\Windows\System32\certoc.exe. Since Microsoft pulled PowerShell out of the base image of Nano Server it appears certoc.exe was created to serve the certificate management role. I couldn’t find it anywhere else.
LikeLike
Hi
I see an error
COPY failed: CreateFile \\?\C:\ProgramData\Docker\tmp\docker-builder294890712\certoc.exe: The system cannot find the file specified.
Has something changed to copy cert tool?
LikeLike
Hello. I’ve followed your example and got the root ca being added within the docker image, however I also need to a certificate to TrustedPeople store which isn’t working, any help will be appreciated.
Here is the snippet
#ADD Certificates to store
COPY –from=tool /Windows/System32/certoc.exe .
USER ContainerAdministrator
RUN certoc.exe -addstore root SigmaCA.cer #This line works
RUN certoc.exe -addstore TrustedPeople identity.cer #This line doesn’t work
Regards,
Dhruv
LikeLike
Hi Joshua,
Thank you for posting this. A lot of people have posted the code for adding the certificate to a store. But all of them have missed the fact that if doing this in a windows container (asp net core maybe) then we have to use “USER ContainerAdministrator”. Your post helped me. Thank you.
LikeLike