let’s start by saying that Docker is great, for many reasons. To mention one, the possibility of using a simple and lightweight tool to manage and deploy apps during all phases of their lifecycle.
For the sake of clarity, it is worth pointing out that Docker leverages a number of tools and mechanisms that were available in Linux long before Docker came up. Indeed, Docker is heavily based on Linux containers and a bunch of other tools.
That being said, let’s now focus on what we care about the most, that is security! Besides flexibility, containers also provide a way to enhance security thanks to isolation. For instance, if an application such as a REST API backend runs within a container, it will be (in theory) isolated from the host environment, resulting in a reduction of the attack surface. That’s great!
Lack of isolation!
However, this is only partially true. In the past many vulnerabilities have been found, which could allow an attacker to break out of the container and attack the host. In addition to this, some misconceptions have promoted the idea that everything that runs within a container is safe, no matter how the container, and more generally the system, is configured. That is why in many cases, users run their own containers as root and give containers access to the host file system.In practice, this means that any vulnerability in one of the apps running within the container can easily allow the attacker to gain access to the host.
So how can we harden our Docker environment and make sure that a vulnerability in one of our apps does not compromise the host?
Well, a first and costly (in terms of maintenance) option consists of leveraging virtualization, meaning that we can run our containers in a VM. Even though an attacker manages to break out of a container, in the worst case he will compromise the VM instead of the host (assuming that the hypervisor is not vulnerable). However, in the worst case scenario, even your hypervisor may be vulnerable: therefore, you also need to make sure that your hypervisor is always up-to-date and securely configured. If it’s not the case, be aware that a vulnerable container may allow an attacker to escape from the VM boundaries and gain access to your host!
Best Security Practices for Docker
Fortunately, we can enhance security without introducing much complexity or losing the advantages of containers. In order to do so, we need to put in place a number of best practices which can greatly simplify this task:
- First of all, don’t forget to apply all well known best practices to secure and harden your Linux server (regular and trusted updates, limit traffic with iptables, etc.). In this regard, a recurring and planned vulnerability scan would be of great help (at SecludIT we do vulnerability scanning, and we do it well);
- Security folks at Docker released a CIS Benchmark to address some security issues (download it here). Also, they kindly provided a script which automatically performs some of the most critical checks (Check it out);
- Don’t run apps with root privileges, not even within a container. In addition to this, take advantage of namespaces, thanks to which you can map a user within a container to a user (with no privileges) on the host;
- Don’t pull images from untrusted repositories. A malicious image may compromise your host. In this regard, the Docker community is working on a project aimed at providing a tool to assess the authenticity and the integrity of an image;
- Use seccomp to disable unused but potentially harmful system calls (by default seccomp already disables privileged system calls);
- Use tools such as AppArmor and SELinux to properly track the activity of your containers and stop any unusual and potentially malicious activity;
- Carefully analyze Docker capabilities (you can find the full list here) to minimize the privileges given to your containers. Be aware that Docker enables by default some capabilities (e.g. CHOWN which allows the container to arbitrarily change file owners bypassing all security controls) which are (mistakenly?) not considered harmful. However, it is always a good practice to drop all capabilities that are not necessary for your container. This will reduce the attack surface in case your container is compromised.
This being said, we acknowledge that, especially in large infrastructures, manually monitoring hundreds or thousands of containers can easily become a headache. This is one of the reasons why modern security solutions are based on automated security checks aimed at simplifying the security enforcement in your infrastructure. This is also the approach that we at SecludIT developed in our flagship product Elastic Detector. Speaking of Docker, Elastic Detector helps you secure your Docker environment by putting in place a mechanism that we call Continuous Docker Security Analysis, which consists of performing recurring and automated checks on the configuration of your Docker environment, including single containers.
Wouldn’t it be great if you could get notified as soon as an issue arises in your Docker environment?