When writing Dockerfiles and Kubernetes manifests, there are some important issues to consider that will help us create a secure product and environment.In this blog post, we embark on a journey to dissect these fundamental components, exploring best practices, common pitfalls, and advanced techniques.
Dockerfile Analysis
The first step to containerize a product is to create a Dockerfile. When creating a Dockerfile, paying attention to the following items will help you create a secure container image.
1-) User root
There may be a need to use the root user to install packages or make changes to the root filesystem in some cases when building a product into a container. However, the final user should not be left as the root user. If the final user is left as the root user in the Dockerfile, when the container process runs in the cluster environment, it will have root privileges. Thus, running the container image with the root user in a cluster environment will jeopardize the cluster’s security. If a malicious software hijacks the container, it can cause damage by accessing files that the container should not access.
2-) Latest tag
When using a base image in the Dockerfile, we specify the version of the image with a tag. The tag can be defined as a specific version or latest. If we use the latest tag, every time we create an image using the Dockerfile, it will pull the latest image from the container registry where the base image is located. The content of the latest image may have changed, and this change may include a malicious software package. Using the latest tag in the Dockerfile is not a good security practice. In cases where the latest tag is used, a container image must be created in a sandbox environment, and then a security scan must be performed.
3-) Unnecessary software
When creating a Dockerfile, we should only install the necessary software packages for our application to run. The more software packages there are in the container image, the higher the risk of security vulnerabilities. In some cases, we should not include packages used for debugging in the container image to solve the problem. For example, software packages such as curl, wget for network debugging, or ssh clients to test ssh connections can be used by attackers if they are included in the container. When debugging is necessary, a separate container image should be created, and it should be used under the control of the cluster admin.
4-) Sensitive data
The application we develop may use sensitive data such as API keys or database passwords. However, these values should not be explicitly stated in the Dockerfile. It is a good practice to keep critically important confidential account information in resources such as kubernetes secrets that the application can access at runtime.
You can see the areas that can create security vulnerabilities in the following Dockerfile.
To create a secure container image, especially in production environments, container images should not be created using a Dockerfile that contains vulnerabilities like the one in the example.
K8S Manifests Analysis
One of the important topics of static file analysis is that we need to pay attention to critical issues before creating resource manifests that we will create in the cluster.
1-) Privileged containers
Privileged containers can modify the root filesystem and change the behavior of the container. The behavior of the container images we create should not change in the environments where we deploy them.
Containers should be in immutable structure to prevent security vulnerabilities, and the container image should continue its life in that structure once created. If it is necessary for the behavior of the container image to change, such as root filesystem access, a container image should be created in compliance with SDLC standards and security tests with a different version.
2-) Latest tag
f we need to use a certain version when creating the same Dockerfile, we should not use the latest tag in the image reference when creating the deployment. In the case of using the latest tag, the deployment can automatically pull the new version from the image registry and lead to unwanted situations, and the latest version, which has not been tested, approved for quality and security, may have been updated in the production environment without realizing it.
In best practices, versioning container images and specifying the image reference in resource manifests such as deployment as a specific tag is a good solution.