9

I have the following Container Setup.

On a bare metal server two Docker Daemons are installed and running.

  1. Main Docker Daemon Runs my application containers exposing 80/443 to the outside world.
  2. Plugin Docker Daemon Runs some containers provided by the customer that communicate with my application via 80/443.

I would like give the customer access to the API (2376) of the Plugin Docker Daemon so that the customer can deploy/start/stop his own containers. The customer will only have access to the API not to the Host (SSH).

The problem I currently face is, what if the customers runs a container that does something insecure like docker run -v /:/host/root Ubuntu rm -rf /host/root.

My question is what can I do to prevent the Plugin Docker Daemon from mounting root / or any other directory outside /home/user/,

  • Is it an option to start the Docker Daemon in /home/user/?
  • Can I use some LSM (Linux Security Modules SELinux/Apparmor) magic to prevent the docker daemon to mount some or all host paths except users home or var/docker/libs?
  • Can --userns-remap help me to achieve my goal?
  • Are they any other options available except VMs?

The server belongs entirely to a single customer. So security or data leakage is not my primary concern. What I really want to prevent is that someone in Plugin Daemon is doing something stupid, that influences my containers that run in Main Docker Daemon. I would like to keep lean and stick to docker only workflow and don't won't to set up an extra workflow for VM creation.

Vad1mo
  • 268
  • 2
  • 14
  • 1
    Yes, SELinux prevents this attack. Showing that it doesn't work makes for a nice demo. Use Docker on a Red Hat-based distro to gain access to SELinux protection. On Debian-based distros, SELinux has historically been not well maintained. – Michael Hampton Oct 03 '16 at 19:11
  • What about Apparmor is it possible there as well? – Vad1mo Oct 03 '16 at 20:46
  • I don't believe so. I've never heard of AppArmor being able to do anything like this. It's a rather different and much less secure technology, you know. – Michael Hampton Oct 03 '16 at 20:52

1 Answers1

8

SELinux will prevent anything not correctly labelled to be mounted as a volume inside a docker container, as proof, here using a single file, same policy applies to directories:

$ sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Max kernel policy version:      30

Using the sample file:

$ cat sample_script.sh 
echo 'Hello, world'

Its default security context is:

$ ls -lrtZ sample_script.sh 
-rw-------. 1 david david unconfined_u:object_r:user_home_t:s0 20 Oct  3 17:18 sample_script.sh

Trying to use this file inside a container fails as expected:

$ docker run -v /home/david/sample_script.sh:/sample_script.sh --rm ubuntu bash sample_script.sh
bash: sample_script.sh: Permission denied

And an AVC denial will be logged:

$ sudo ausearch -m avc -ts recent
time->Mon Oct  3 17:39:28 2016
type=AVC msg=audit(1475512768.444:784): avc:  denied  { read } for  pid=28720 comm="bash" name="sample_script.sh" dev="dm-13" ino=101062112 scontext=system_u:system_r:svirt_lxc_net_t:s0:c457,c992 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=file permissive=0

After changing the security context to one Docker can use:

$ sudo chcon -Rt svirt_sandbox_file_t sample_script.sh
$ ls -lrtZ sample_script.sh 
-rw-------. 1 david david unconfined_u:object_r:svirt_sandbox_file_t:s0 20 Oct  3 17:18 sample_script.sh 

The container now has access to the file:

$ docker run -v /home/david/sample_script.sh:/sample_script.sh --rm ubuntu bash sample_script.sh
Hello, world

More information about Docker and SELinux in the official Red Hat documentation and this article by Dan Walsh.

dawud
  • 14,918
  • 3
  • 41
  • 61