HomeAboutContact

7 Best Practices for Creating Secure and Maintainable Docker Containers

By Yannik Korzikowski
11. October 2024
3 min read
🇬🇧
7 Best Practices for Creating Secure and Maintainable Docker Containers

Inhalt

01
Use a Minimal Base Image
02
Keep Images Up-to-Date
03
Principle of Least Privilege
04
Additional Principle of Least Privilege: Read-Only Filesystem
05
Use Environment Variables for Secrets
06
Use Docker Content Trust
07
Use Multi-Stage Builds
08
Conclusion

In this article, I would like to present seven ways to build secure and easy-to-maintain Docker containers. Of course, there are more optimization possibilities than the seven I describe here. However, using the ones listed here is already a good approach.

Use a Minimal Base Image

Using a minimal base image automatically reduces the attack surface. Fewer functions mean a reduced number of possibilities that an attacker can exploit in case of a breach.

For example, if curl or nc is not installed, an attacker cannot use these tools to download additional malicious code.

A good option for a base image is Alpine Linux. Compared to Debian, it is very small. In a direct size comparison, a current Debian 12 image is 49 MB, while the Alpine image is only 3.4 MB.

In the linked animation, I compare the sizes of the two images. If possible, Alpine should always be used.

Keep Images Up-to-Date

When building images in a Dockerfile, always update the already pre-installed packages. This is especially important when using custom base images to speed up the build process.

In this example, I update an Alpine image.

Principle of Least Privilege

In IT, the principle of least privilege is a standard. After installing the necessary components, switch from the root user to a regular user. Only the minimal necessary permissions should be granted, which are required for the container’s operation.

This ensures that, in the event of a successful attack on the application itself, there is another hurdle that the attacker must overcome. To minimize the attack surface, this should be implemented by default for all Docker containers.

This approach is demonstrated using a minimal Python3 application:

FROM python:3.11-slim
RUN useradd -m app_user # Create a new user
USER app_user # Change context to the newly created user
COPY . /app
WORKDIR /app
ENTRYPOINT ["python3", "/app/my_app.py"]

Additional Principle of Least Privilege: Read-Only Filesystem

Besides switching the user, it is also possible to set the root filesystem to read-only mode. This ensures that existing binaries in the container cannot be modified by the user.

This creates a double layer of protection to the already reduced permissions from the previous section. For more information, you can find further details here: https://docs.datadoghq.com/security/default_rules/cis-docker-1.2.0-5.12/

By explicitly setting the --read-only flag, the root filesystem is set to read-only mode. Writing is no longer possible, even with root permissions.

If an attacker gains shell access through a vulnerability in the application, they will not be able to modify existing binaries in the container, even if they break out of the user context and gain root privileges.

Use Environment Variables for Secrets

Environment variables should not be used for sensitive information such as passwords or API keys, as they are visible in many contexts. For example, they can be easily viewed via docker inspect on the host system or in log files.

Ideally, secrets management tools such as Docker Secrets, HashiCorp Vault, or similar solutions should be used to increase security. In practice, however, full integration of these tools can be challenging, especially when dealing with legacy code or a rapidly changing system landscape. To consistently implement this approach, the appropriate client component of the secrets management tool would have to be integrated into the application.

Therefore, I still use environment variables for now. My preferred way when using plain Docker is to store secrets in a separate environment file, which I then populate using a secrets management tool.

Secrets should always be externalized and not delivered directly with the source code or Docker image.

Use Docker Content Trust

By using digital signatures, it is possible to verify the integrity and origin of Docker images. This secures the software supply chain and prevents the execution of tampered images.

This technique is used consistently by Apple in its operating system. The execution of applications that are not signed with an Apple Developer Certificate is blocked by default and must be explicitly allowed by the user.

An example of a successful attack on the software supply chain can be read here: https://www.heise.de/news/VoIP-Anbieter-3CX-Die-doppelte-Supply-Chain-Attacke-8974948.html

With Docker Content Trust, there is a similar system where images can be digitally signed. The host system is then configured to only run signed images.

Use Multi-Stage Builds

Multi-Stage Builds are a good way to reduce the size of the image and avoid unnecessary files and dependencies in the images where the application runs. The build process of a Docker image is divided into several stages.

In the example shown here, an application needs to be built with a very specific dependency. In this case, it is the ldap-client for python3.9.

Since the dependency itself needs to be built, an additional layer is added where the ldap-client is built. This layer is discarded at the end, and only the compiled application is copied into the application image.

Conclusion

By using the methods outlined here, a high level of security can already be achieved by simply applying rules and principles. Of course, these principles do not replace adherence to rules for creating secure software. However, they can make it significantly more difficult for an attacker to compromise a system.

Photo by https://pixabay.com/de/photos/spornschildkr%C3%B6te-schildkr%C3%B6te-natur-8994997/


Affiliate

Netcup bietet virtuelle Root-Server für einen fairen Preis an.
Mit dem Gutschein 36nc17009374344 erhälst du 5€ auf deine erste Bestellung.
Hier bestellen und einen Rabatt erhalten.
Falls der Gutschein nicht mehr funktioniert, bitte in die Kommentare schreiben.


Tags

dockersecurity

Share


Previous Article
7 Wege zu sicheren Docker Containern
Yannik Korzikowski

Yannik Korzikowski

Cloud Architect

Also interesting

7 Wege zu sicheren Docker Containern
7 Wege zu sicheren Docker Containern
October 09, 2024
3 min
🇩🇪

Quick Links

AboutContact me

Social Media