letsencrypt / boulder

An ACME-based certificate authority, written in Go.
Mozilla Public License 2.0
5.17k stars 604 forks source link

Docker volumes inaccessible if selinux is enforcing #4165

Closed danjeffery closed 5 years ago

danjeffery commented 5 years ago

The current docker-compose.yml attempts to mount volumes without selinux labelling. If selinux is set to enforcing, the containers will report permission denied attempting to execute the entrypoint scripts at test/entrypoint-netaccess.sh and test/entrypoint.sh.

The solution is just to add :z at the end of the volume paths and Docker will perform the labeling automatically. Adding this is a simple change that didn't appear to cause other issues in my testing. PR incoming.

jsha commented 5 years ago

Thanks for the patch! Can you link to some documentation on what adding the :z suffix does?

danjeffery commented 5 years ago

Yep: https://docs.docker.com/storage/bind-mounts/#configure-the-selinux-label

Basically, z and Z were added so that Docker can automatically add appropriate selinux labels to the files in the designated volume when the container is started. We want z rather than Z since Z will label the files to only be accessible to a single container, which won't work.

jsha commented 5 years ago

I appreciate the extra details. According to that documentation:

This affects the file or directory on the host machine itself and can have consequences outside of the scope of Docker.

Use extreme caution with these options. Bind-mounting a system directory such as /home or /usr with the Z option renders your host machine inoperable and you may need to relabel the host machine files by hand.

Based on that, I'd prefer not to the patch. I'm curious, what is it that SELinux is enforcing that prohibits executing those files on the mount? Also, have you tried using docker-compose's -v flag to override the default volume mounts work around this locally?

danjeffery commented 5 years ago

Setting Z is definitely not what we want here and won't even work for the boulder tests.

Setting z or Z also won't do anything on a system that does not have SELinux set to enforcing. That's apparently most people using this boulder test harness, since this hasn't come up before. So, the impact should be minimal, but docker-compose would work out of the box for people who do have SELinux set to enforcing and that is something I personally support. :)

I'm on Fedora 29 here and when I pull down from GitHub the context is: unconfined_u:object_r:user_home_t:s0 Once Docker has run and relabeled the context is: system_u:object_r:container_file_t:s0 From Project Atomic's page on Docker SELinux issues: By default, Docker container processes run with the system_u:system_r:svirt_lxc_net_t:s0 label. The svirt_lxc_net_t type is allowed to read/execute most content under /usr, but it is not allowed to use most other types on the system. Docker container processes are not allowed to access user_home_t.

If the context is not changed, running docker-compose up will generate the following output:

Creating network "boulder_bluenet" with driver "bridge"
Creating network "boulder_rednet" with driver "bridge"
Creating boulder_bmysql_1 ... done
Creating boulder_bhsm_1   ... done
Creating boulder_boulder_1   ... done
Creating boulder_netaccess_1 ... done
Attaching to boulder_bmysql_1, boulder_bhsm_1, boulder_netaccess_1, boulder_boulder_1
bmysql_1     | WARNING: no logs are available with the 'none' log driver
boulder_1    | /bin/bash: test/entrypoint.sh: Permission denied
netaccess_1  | /bin/bash: test/entrypoint-netaccess.sh: Permission denied
boulder_netaccess_1 exited with code 126
boulder_boulder_1 exited with code 126

The -v flag of docker-compose just outputs the version. I think you may have been thinking of the -v flag of docker itself, but I am not aware of a way to get it to just set :z by defaulf for all volumes in a Dockerfile. I think you have to specify the volume explicitly followed by the :z.

I really do think there is very little risk of disruption by this change, but the benefit may also be seen as unnecessary and not warrant any risk. If you choose not to accept the patch, at least this will be recorded here for anyone else enforcing SELinux to know how to fix it. ¯_(ツ)_/¯

jsha commented 5 years ago

Thanks, that helps. I understand some more of the problem now, but I'm still not confident that I understand the SELinux rules well enough to judge whether this is the right fix, and as you mentioned, this isn't something we're running into most of the time, so I'm going to defer this until we have more immediate need. When that happens, this issue will serve as useful documentation. :-)