Avoid Using Lazy, Privileged Docker Containers


It’s probably a little unfair to call everyone who uses privileged containers “lazy” but, from what I’ve seen, some (even security) vendors deserve to be labeled as such.

Running your container using privileged mode opens up a world of pain if your container is abused. Not only are your host’s resources directly accessed with impunity by code within your container (a little like enabling the omnipotent CAP_SYS_ADMIN capability) but you’re also relinquishing the cgroups resource limitations which were added to the kernel as a level of protection, too.

By enabling this dangerous mode, you might consider it like leaving a window open in your house and going away on holiday. It’s simply an unnecessary risk that you shouldn’t be taking.

Don’t get me wrong, certain system “control” containers need full host access, but you’re much better off spending some time figuring out every single capability that your powerful container requires and then opening each one up. You should always strictly work with a “default deny” approach.

In other words, lock everything down and then only open up precisely what you need. This is the only way that security can truly work.

Opening up a specific system component for access should only happen when a requirement has been identified. Then the access must be carefully considered, analyzed, and tested. Otherwise, it remains closed without exception.

You’ll be glad to know that such tasks needn’t be too onerous. Think of an IPtables rule. You might have a ephemeral, temporary End Point which will be destroyed programatically in seven days time. You could create a new rule, make sure it works and set a scheduled job — e.g., using a cron job or an at job, to remove that rule in seven days. The process is logical; test the access works and then delete the rule.  Hopefully, it’s relatively easy.

Back to being lax with your container security. Let’s now look at a quick example which, admittedly, is designed to scare you against using privileged mode on your servers unless you really have to.

Directly on our host we’ll check the setting of a kernel parameter, as so:

$ sysctl -a | grep hostname

kernel.hostname = chrisbinnie

Our host is definitely called “chrisbinnie” in this case.

Next, we’ll create a container and prove that the container’s hostname isn’t the same as the host’s name, as seen in Figure 1.

Figure 1: How I created a simple Debian container.

We can see above that we’ve fired up a vanilla Debian container, entered the container and been offered its hashed hostname as we’d expect (6b898d49131e in this case).

Now from within our container we can try and alter the container’s hostname. Note how directly connected to our host’s kernel that an arbitrary container is by default.

Thankfully, however, our host is rejecting the kernel parameter change as shown below.

root@6b898d49131e /# sysctl kernel.hostname=Jurgen
sysctl: setting key "kernel.hostname": Read-only file system

Next (please ignore the container name-change), I’ll simply fire up another container in exactly the same way.

This time I’m going to use this “ps” command below inside our container as shown in Figure 2.

$ ps -eo uid,gid,args

Figure 2: Inside the container, I’m definitely the superuser, the “root” user with UID 0, but I’m not affecting the container’s hostname or thankfully the host’s.

Still with me? Now we’re going to try the same approach but the lazy way. Yes, correct, by opening up the aforementioned and daunting “–privileged” mode.

$ docker run –privileged -it debian bash

In Figure 3, we can see below that the container and host didn’t complain but instead, frighteningly, we had access to the host’s kernel directly and made a parameter change.

Figure 3: We can affect the host’s kernel from within a container.

As you can imagine, altering hostnames is just the beginning. There’s all kinds of permuations from having access to both the kernel and the pseudo filesystems on the host from within a container.

I’d encourage you to experiment using this simple example and other kernel parameters.

In the meantime, make sure that you avoid elevating privileges within your containers at all costs. It’s simply not worth the risk.

Chris Binnie is a Technical Consultant with 20 years of Linux experience and a writer for Linux Magazine and Admin Magazine. His new book Linux Server Security: Hack and Defend teaches you how to launch sophisticated attacks, make your servers invisible and crack complex passwords.

Advance your career in Linux System Administration! Check out the Essentials of System Administration course from The Linux Foundation.

This article originally appeared on DevSecOps.