If you would like to read the other parts in this article series please go to:
- Containerization Proliferation: The Docker Effect (Part 1)
- Containerization Proliferation: The Docker Effect (Part 2)
- Containerization Proliferation: The Docker Effect (Part 3)
- Containerization Proliferation: The Docker Effect (Part 5)
- Containerization Proliferation: The Docker Effect (Part 6)
In Part 1 of this multi-part article series, I briefly explained what containers are, some benefits of using containers and the scenarios in which they aren’t the best choice, and some generalities about how they work. In Part 2, we discussed popular container solutions, beginning with Docker. In Part 3, we started talking about container security in general and Docker security in particular.
Now, in Part 4, we will continue where we left off in part 3.
To briefly recap some Docker security benefits and challenges: Docker segregates applications from one another, which makes it easier to get insight into how packets are flowing and to identify suspicious patterns, and the ability to use namespaces to limit resources assigned to containers, which can help provide isolation. Capabilities can be assigned to individual processes and containers are assigned a limited set of capabilities so this provides some protection to the host system if a container is breached.
However, because containers don’t run separate instances of the operating system as virtual machines do, but share the same host, the segregation and isolation are not as complete, and the running of the Docker daemon with root permissions opens up a security hole. Thus, in order to implement enterprise-level security in a Dockerized environment, you need to be aware of and put into operation security best practices and utilize security tools and mechanisms beyond the default configurations.
SELinux is the short name for Security-Enhanced Linux. One way to protect your Docker environment is with the SELinux security module. For those who aren’t familiar with Linux Security Modules (LSM), this is a GNU-licensed framework or interface for loading code that extends the functionality of the operating system kernel. For those of us who grew up in a Windows-centric world, these loadable kernel modules (LKMs) are similar to kernel-mode drivers in Windows.
The function of SELinux is to allow you to apply security policies for implementing access controls. Its architecture was actually developed by the NSA (National Security Agency), specifically their Trusted Systems Research Group, based on a mandatory access control (MAC) architecture called Flask. It was then mainstreamed into Linux and ported to FreeBSD and Solaris. SELinux is also a part of the Android security model
The security mechanisms are designed to allow data to be separated according to confidentiality and integrity needs and helps to limit (but doesn’t completely prevent) damage from malicious applications and tampering. Access controls can operate under one of two principles: Allow all by default and specifically select what to deny (blacklisting) or deny all by default and specifically select what to allow (whitelisting).
Policies are sets of rules that allow or deny operations. You can have more than one policy installed, but only one of the policies at a time can be active and in use. The NSA developed SELinux to operate on the principle of “Deny all.” If something isn’t explicitly allowed, then it’s denied. However, that doesn’t work well for all scenarios, so in addition to two principles and two modes, there are also two default policies:
- Strict policy
- Targeted policy
A strict policy is one where everything is denied by default. Policy rules define what is allowed. Although this is the most secure, and is the policy provided by the NSA, as you can imagine it can cause problems with users being unable to access what they need in order to get their work done. This is based on the “principle of least privilege.” Targeted policy is the opposite. Everything is allowed by default, then you create deny rules to control access. This is obviously less secure.
It’s important to note, too, that SELinux can be set to operate in one of two different modes. In “permissive” mode, it does not actually deny the operations that aren’t allowed; instead it merely logs when those operations are performed. In other words, it’s used to audit the accesses that would be denied. The other mode is enforcing mode, and as its name implies, in this mode the policies are enforced and access requests are actually denied, as well as being logged.
SELinux uses the concept of security domains to define which processes are affected by a particular policy. A virtual machine is a process. A domain is what defines which actions a process can perform. User roles determine what domains can be used by a user. Windows admins can think of this as similar to the way security groups are used to grant access rights in Windows. Linux security domains, though, apply to processes – not to objects such as files, directories and devices. These are assigned to a type rather than domain.
Docker supports SELinux in two ways, one of which based rules on process type and the other, called MCS or Multi-Category Security separation (or svirt) where the level field of each container’s SELinux label is assigned a unique value. The first is for the protection of the host and the second is to protect the containers from each other. SVirt (Secure Virtualization) integrates Mandatory Access Control security with Linux virtualization to isolate virtual machines that run on the same host kernel.
The Application Armor security module (AppArmor) is similar in function and purpose to SELinux but is implemented differently. AppArmor is included in the Linux kernel (versions 2.6.36 and later) but it appeared first in SUSE Linux. In the beginning, it was called SubDomain, then Novell renamed it to AppArmor in 2005. It is designed to be easier for admins to work with than SELinux, and it can work with any file system, whereas SELinux doesn’t work with NFS-mounted files because there is no support for security labels.
AppArmor works by allowing you to use profiles on a per-application basis that control the particular capabilities that will be allowed. Linux capabilities (based on POSIX capabilities) are subsets of root privileges. Capabilities are referred to as “privileges” in some other UNIX operating systems. Whenever a process attempts to perform an operation that requires root privileges, the operating system checks to see whether or not the process is assigned that capability. If not, the operation won’t be allowed.
AppArmor can be used to protect applications that are frequently targeted by attackers, such as web browsers. AppArmor comes with some profiles and you can install others. Some software comes with its own AppArmor profile that is installed when you install the software package. You can also build your own AppArmor profiles.
AppArmor profiles are text files that contain rules consisting of path entries that define which files the application can access and capability entries that define which privileges the confined process can use. You can create custom profiles by editing the included profiles with a text editor. When AppArmor is running on the Linux host, Docker will automatically apply the default profile to each container that is launched.
AppArmor has two modes that work like those of SELinux but in addition to “enforce mode,” AppArmor has “complain mode” that logs when applications engage in actions that are restricted by the profile, as SELinux’s “permissive” mode does.
Grsec and PaX
Yet another Linux security mechanism that can benefit your Docker containers is Grsecurity (Grsec), which is a set of patches that are designed to enhance the security of the Linux kernel. It has been around for fifteen years and it can be used to implement role based access control but it goes further than the Linux security modules we’ve discussed thus far and provides for more than access controls.
Grsec also protects against memory corruption vulnerabilities, which are one of the most common (and commonly exploited) vulnerabilities types and helps to thwart zero-day attacks – those that leverage vulnerabilities that have not yet been patched by the software vendor. It can be used with any Linux distro.
PaX comes with Grsec but was developed by different developers. Running the Linux kernel with Grsec and PaX will harden your Docker host machine against attack and exploit. This will provide such security features as address space layout randomization (ASLR), which is an important means of protecting against buffer overflow attacks and others that depend on predictable addressing. In fact, the PaX project originated the term “ASLR,” which is now a security feature in other operating systems such as Windows and iOS.
In this, Part 4 of our article series dedicated to Docker and the containerization phenomenon, we took a look at some of the security mechanisms built into or included with Linux that can be used to add more security to a host/container environment. Next time, in Part 5, we’ll examine some of the third party solutions that are available for securing Docker and other containers.
If you would like to read the other parts in this article series please go to: