Container Security 101: A Guide to Safe and Efficient Operations
Over the past few years, container adoption has revolutionized everything. Containers became the de facto standard of software deployments, providing a wide range of advantages such as:
- Fast deployment
- Resource isolation
- Workload portability
- High scalability
- Better observability
Before we dive into the technical details, let’s ensure we’re on the same page by giving a brief recap of what containers are in the context of software development.
Containers are system processes (from the host machine perspective) that run with dedicated resources. Now, the next logical question that may arise could be: How are these containers created?
Answering this question leads us forward in understanding the heart of this article’s topics.
Containers are generated from OCI Images that include the elements needed to run an application in a containerized way, such as code, config files, environment variables, libraries, as well as metadata describing its needs and capabilities.
The most common scenario in container generation is developers relying on base images taken from public registries, to which is add the developed software.
There are different types of base images that developers can use; they could be “simple,” like a base OS image, or “complex,” and already contain information like specific system libraries or tools.
Since “the devil is in the details,” so is DevSecOps.
- Can you really trust and rely on a base image made by someone else?
- Is it safe to consider “production ready” software based on public images?
It can be challenging to ensure that selected base images will not have any security impact while executed, especially if you rely on “complex” ones.
Security? Yes, Please!
Let’s start from the basics: being aware of the risks is a good starting point to take countermeasures.
There are different sources where developers can pull base images to build their containers, mostly from public registries like:
- Docker HUB
- Cloud provider registries (Amazon ECR, Azure Container Registry, etc.)
Other common sources are git repositories, where developers can easily find Docker files with the instructions needed for the build.
This is a great example of open source strength, as it enables everyone to build their own images starting from someone else’s work.
The downside is that risks need to be considered when deploying them in production:
- Malicious code
- Image misconfiguration
Let’s take a deeper look at these and at the easiest best practices developers can implement to avoid them.
A good way to limit the risk of having an image with malicious code is to pull base images only from an official source or a verified developer.
The well-known public registries have many verified and official developers/companies that push and maintain updated images.
All registries taken as example have regular vulnerability scans that provide reports about the current ones being detected.
There is no official repository that can completely solve this issue if the images are not proactively updated with regular scan and patching processes.
Bugs and Image Misconfiguration
Bugs and images misconfiguration could be mitigated using only recent and regularly updated images. For example, from a security perspective on Kubernetes, a good mitigation practice could be an admission webhook that denies the deployment of containers based on images older than a given date.
At this stage, it should be clear that working with containers and images is a blast, but it needs to be done the right way or at least with awareness.
Over the last few years, unfortunately, many security breaches have been leveraged on a compromised CI/CD supply chain, sometimes driven by malicious code injected into images, sometimes making use of known CVEs.
In the year 2023, DevOps should definitely be aware of these risks and work accordingly with the internal security team to mitigate them.
How to Keep Risks Away? (Container Security Golden Rules)
The picture is now clear. How can we live securely, or at least reduce the risks?
The answer can be long and complicated, and will depend on the level of security required for the production workloads.
Some basic level one rules:
- Retrieve images only from trusted registries.
- Use only official images.
- Check the number of vulnerabilities before considering the use.
- Fix (at least) the critical vulnerabilities of the images.
- Use recent images when available.
Another great piece of advice about container images is the minimal, the better.
Using a complete OS as a base container image could be useful for troubleshooting purposes, but more libraries and executables inside the images also means a larger attack surface.
As risk mitigation, DevOps should consider the use of a minimal Linux base image (like Alpine) or a distro-less container image.
Consider, though, that this strategy makes it harder to troubleshoot. Using minimal base images only in a production environment could be a good compromise between security (where it matters most) and troubleshooting during development.
Taking into account the security aspect of base images, keeping them updated and secured over time could be challenging. Usually, relying on trusted sources, verified registries and using updated images can be enough, but this is not always the case.
If a high-security level for the containerized workloads is mandatory, for example finance, insurance or any other high-risk environment, a good idea might be to rely on dedicated services that offer secured, verified and regularly updated images.