That –privileged Flag Looks Pretty Practical
Quite some time ago Docker in September 2013/Docker 0.6 announced proudly, that it is now possible to run Docker from within Docker. This was made possible by the new –privileged flag feature. An explanation, I posted as a Stackoverflow answer, on how you can do this you can find here. This feature allowed bypassing a prior constraint of using containers, they were unable to access the host system’s devices. A possible use case for this, aside from running Docker inside Docker, was allowing you to trivially use things like your web-cam and such from within Docker.
Devices and Standard Containers (Safe and Secure)
You can get a quick idea of the degree of containerization for a standard container by just running a standard Debian container bash and checking the visible hard disks and devices.
Just open a standard bash shell:
Then check what devices are hard drives to you in there. On my trusty old Linux laptop I see something like this:
So even the standard container is able to see my hard drive on /dev/sda1 apparently. If I check the contents of /dev though, this is what I get:
The hard-drive at /dev/sda1 is not there, which in almost all conceivable use cases for Docker, is a very good and important thing, you’ll see!
Devices and Privileged Containers ( You’re running something as root, you better know what you’re doing! )
So let’s move on to the privileged case. In all of this please remember, the Docker daemon always runs as root! As pointed out in this Github ticket for the Docker project, there is no way around that! Even if you can run Docker commands as non-root, the daemon is always running as root and that’s what matters here! You simply cannot set the daemon to run as a non-root process for technological reasons. So lets see what we allow the privileged container, running from a process owned by root, to see and do on our host system.
Again open a standard bash shell, but this time run it in a privileged container:
So far so good, so lets see what we get for our hard drives this time around:
No changes here, but lets look at what devices we have available now:
Bam, that looks a little different from before doesn’t it ? Now our hard drive isn’t only there in name. We can actually access the device! This means, we should be able to mount it inside the container. Lets try it:
we got the host file system mounted inside the “container”, making it not a container at all!
Depending on your Docker host configuration you might even be able to see the contents of proc/1/ns/pid and simply nsenter into a shell in the host. And well … if things aren’t configured as the container likes … the container should have an easy time making the config a little more pleasing to it’s nefarious plans.
Don’t use privileged containers unless you treat them the same way you treat any other process running as root. Newer Docker versions allow you more fine grained control over the containers device access anyhow, check this out for more documentation on container capabilities and rights management.
If you want to try this out on EC or a VM additional steps might be needed to make the device descriptor appear. On EC2 all you need to do is run:
and you got a descriptor of the host’s hd that you can mount.
On Virtualbox/Boot2Docker you need to make the logical volumes appear as proper devices:
is your friend here. If this doesn’t work you might need to activate the needed kernel module for handling logical volumes the way we want it here:
The fact that this actually works should scare you straight enough to not use privileged containers unless you have to btw ;)