In this post, I will address the case where certificate validation within a container in an isolated environment is required, without binding it to the host’s certificates.
Meaning when the certificate can not be a part of the host’s CA bundle, the file with all the root and intermediate certificates.
The concept is pretty simple.
Considering we want our container to be deployed on different hosts with different operating systems, the isolated solution is basically to install the certificate inside the container when it starts.
All we need to do is to pass the certificate to the container and run a script to update the container’s CA bundle with the new certificate.
The guidelines are:
1. Create an entry point script helper to take the certificate’s folder as input and update the CA bundle
2. Modify the dockerfile ENTRYPOINT to point to the script helper
3. Volume the required certificate anywhere inside the container
*See examples below
This approach is both robust and user-friendly since the user does not need to care about where to put his certificate to update the container’s CA bundle.
For demonstrating a certificate installation using an entry point script helper, we’ll take a basic scenario of a “client” container that requires the server’s certificate public key to successfully establish secure communication.
Keep in mind that installing a certificate in any store is pending on the base image for the following reasons:
- The location of where the OS uses to update the CA bundle is different between the various operating systems.
- Certificate type — might need a conversion to a type supported by the base image.
- Update command
Once you have the base image details, path, and the “update” command, you are good to go.
In this example the entry point script helper consists of two operations:
1. Copy the certificate from the volume folder to the OS certificates update folder.
2. Run the “certificates update” command to update the CA bundle.
*Advanced scenarios might require more complex scripts or even an external tool, but the concept stays the same.
Check out the following working code samples of a dockerfile, entrypoint script helper, and a docker-compose file you can play with.
- Based on Debian/Ubuntu OS
docker-entrypoint.sh
#!/usr/bin/env bash
usage()
{
echo “Please insert certificates folder path \
to update CA-bundle.”
}
certificatesFolder=$1if [ ${#certificatesFolder} -gt 1 ]
then
cp ${certificatesFolder}/*.* /usr/local/share/ca-certificates/
update-ca-certificates
finode --version
dockerfile
FROM node:lts-busterWORKDIR /app
COPY ./docker-entrypoint.sh .
EXPOSE 8088ENTRYPOINT ["sh", "/app/docker-entrypoint.sh"]
docker-compose.yml
version: '3'
services:
my-server:
image: my-test-image:latest
container_name: my-test-container
user: root
restart: always
volumes:
- /var/myCerts/:/var/myCerts/
command:
- "/var/myCerts"
Build and test
1. Create the above files and place them under the same folder
2. Convert the certificate to crt format
3. Move the certificate to the volume folder
4. Build the image
docker build -t my-test-image .
5. Run the container
docker-compose up
6. View container’s logs for certificate installation
docker logs -f <containerID>
Look for “Updating certificates… 1 added” in the console output
[root@template7–6 _aviad]# docker-compose up
Creating my-test-container … done
Attaching to my-test-container
my-test-container | Updating certificates in /etc/ssl/certs…
my-test-container | 1 added, 0 removed; done.
my-test-container | Running hooks in /etc/ca-certificates/update.d…my-test-container | done.
my-test-container | v14.16.1
To summarize
This post’s target is to give you a general idea about certificate installation in containers, I pointed out the guidelines, and how to use an entry point script with some basic code samples.
Take into consideration that there are other ways to achieve this and even more ways to go around it.