Best Security Practices for Docker
For the sake of clarity, it is worth pointing out that Docker leverages some 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 (regarding 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. To do so, we need to put in place some best practices which can significantly 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 Outpost24 we do cloud and container solution, 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.