Docker container security best practices unlocked!
Let’s take a closer look at Docker container security best practices and see what you need to look at to secure your Docker environment.
Table of contents
- Security Risks in Docker
- Role-Based Access Control
- User Namespace Support
- Secure Computing Mode
- Securing the images themselves for Docker
- Make sure your registry you use is trusted
- Scanning for Vulnerabilities
- Host Kernel Protection
- Privileged Containers
- Securing Docker API and Sockets
- Logging Docker Containers
- Auditing Docker Environments
- Wrapping up
Security Risks in Docker
Docker containers are great technologies, but they can introduce risks into the environment. They use shared resources and also there can be vulnerabilities in the container images available to the public. Also, security issues can come from the level of access that is granted to your users.
Docker containers share the host kernel. This is unlike virtual machines, so this opens up the possibility of security issues that we don’t really see with virtual machines, since they don’t share the host kernel.
Attackers also realize that businesses are now moving to containers more than ever in running their applications since these are the modern way forward for cloud-native type technologies.
Some of the most common risks include:
unauthorized access to the Docker daemon,
container breakout attacks
running containers with excessive privileges.
Role-Based Access Control
While Docker itself does not have native support for role-based access control (RBAC), you can still have a way to do this by running your containers inside of container orchestration platforms like Kubernetes or using a tool like Portainer.
Kubernetes: Being what it is, a container orchestration platform, K8s allows you to use its built-in RBAC capabilities. So, you can use these to apply permissions to who can do what in the environment.
Portainer: It also has a user friendly UI that can be used to apply RBAC to your Docker containers. You can assign roles and have these applied to users or teams of users.
You can also use Portainer to configure security best practices, even in the community edition.
User Namespace Support
Namespaces map container UIDs and GIDs to different UIDs and GIDs on the host. By doing this even if an attacker compromises a running container as root, they still won’t be able to have root privileges on the Docker container host.
To enable user namespace support in Docker, follow these steps:
Create or edit the Docker daemon configuration file, which is usually located at
/etc/docker/daemon.json
. Add the following configuration to the file:
{ "userns-remap": "default" }
This configuration tells Docker to create a default user and group mapping for user namespaces
Restart the Docker daemon: After updating the configuration file, you need to restart the Docker daemon to apply the changes. Depending on your system, use one of the following commands:
For systemd-based systems: sudo systemctl restart docker
For non-systemd systems: sudo service docker restart
Verify user namespace support: Once the Docker daemon is restarted, run a new container and verify that the user namespace support is enabled. To do this, execute the following command:
docker run --rm -it alpine id
The command runs an Alpine Linux container and then prints the user and group information.
Secure Computing Mode
There is a Linux kernel security mode feature that allows you to limit system calls for better security. You can create and use a seccomp profile for your Docker daemon, that drastically reduces the attack surface by blocking certain types of system calls.
Follow these steps to enable this type of mode in Linux
The default seccomp profile can be found in the Docker GitHub repository – download it from here: https://github.com/moby/moby/blob/master/profiles/seccomp/default.json
Save the profile for example to a location like: /etc/docker/seccomp/my_custom_seccomp.json.
Run a container with the custom seccomp profile by using the flag that is –security-opt when starting the container.
docker run --rm -it --security-opt seccomp=/etc/docker/seccomp/my_custom_seccomp.json alpine sh
Securing the images themselves for Docker
Note the following best practices when working with Docker container images
Choose the minimal lightweight images that only include the necessary components you need. This reduces the attack surface
Like an OS, keep your container images updated
If you don’t need a package, remove them
separate the build and runtime environment as this will reduce the image size and cut out anything unnecessary
Make sure your registry you use is trusted
Get your images from a trusted source like Docker Hub or other trusted image registries.
Use official from trusted sources, as they are maintained by the respective software vendors or the Docker team as these are the most secure
Check the signature of the image
Use private registries to have more control over the source of the images
Scanning for Vulnerabilities
You can use tools that provide built-in security scanning feature or third-party scanners such as Clair, Anchore, and Snyk can that can scan images and make sure these don’t contain security issues
You can read more about Docker Hub vulnerability scanning here:
Host Kernel Protection
Note the following with protecting the host kernel from attack
Enable user namespaces: As mentioned earlier, enabling user namespaces can help prevent a compromised container from gaining root privileges on the host system.
Use cgroups: Cgroups (control groups) help you isolate and limit the resources containers use
Keep the host kernel up-to-date: Regularly update your host kernel to make sure it has the latest security patches
Enabling cgroups
The cgroups are a good way to limit running Docker containers from a security perspective to apply resource limits:
The flag –cpus can set the number of CPUs the container can use
docker run --rm -it --cpus=1.5 alpine sh
Use the flag –memory to set the maximum amount of memory the container can use
docker run --rm -it --memory=512m alpine sh
Use the flag –device-read-bps and –device-write-bps flags to set the maximum read and write speed for a specific device.
docker run --rm -it --device-read-bps=/dev/sda:1mb --device-write-bps=/dev/sda:512kb alpine sh
Docker doesn’t have a built-in way to limit network I/O. But, you can use third-party tools like tc (traffic control) to apply network bandwidth limits to Docker containers.
Privileged Containers
To reduce the attack surface, you should avoid running privileged containers. These are not needed most of the time unless absolutely necessary. Grant only specific privileges to containers on an as-needed basis.
Securing Docker API and Sockets
The Docker API and sockets provide access to Docker daemon functionalities. To prevent security problems with access to these features, you should:
Configure the Docker daemon to listen only on a Unix socket or a local network interface, and use TLS authentication and encryption to secure API communications.
Use access control for Docker sockets: Limit access to the Docker daemon socket by using a group with restricted membership or implementing access control mechanisms like SELinux or AppArmor.
Logging Docker Containers
Docker logging is built into the solution, so you can use this to collect and store logs from your containers, while tools like the ELK Stack (Elasticsearch, Logstash, and Kibana) or Fluentd can help you gather and then analyze which can shed light on security issues.
Auditing Docker Environments
Audit your environment using something like Docker Bench for Security or OpenSCAP. These are tools that can take a look at your Docker deployments against established security best practices. Then these provide recommendations for improvement. Doing this regularly will make sure you are doing things the right way from a security standpoint.
Wrapping up
Docker security is a really important part of the overall security strategy for businesses today. Especially since more are running their critical business apps inside of containers, this is true. Modern apps are using these types of architecture, so organizations need a strategy for security moving forward. Keeping these Docker container security best practices in mind is most important.