This is a blog with random OpenShift, Kubernetes, OpenStack and Linux related notes so I don't forget things.
If you find something inaccurate or that could be fixed, please file a bug report here.
Since the Pike release, we run most of the TripleO services on containers. As
part of trying to harden the deployment, I’m investigating what it takes to run
our containers with SELinux enabled.
Here are some of the things I learned.
Enabling SElinux for docker containers
Docker has the --selinux-enabled flag by default in CentOS 7.4.1708.
However, in case your image or your configuration management tool is disabling
it, as was the case for our puppet module verify this, you verify by running
the following command:
To enable it, you need to modify the /etc/sysconfig/docker file, which you
can use to enable SELinux for docker. In this file you’ll notice the
$OPTIONS variable defined there, where you can append the relevant option
as follows:
After restarting docker:
You’ll see SELinux is enabled as a security option:
Note that for this to actually have any effect, SELinux must be enforcing in
the host itself.
Docker containers can read /etc and /usr
SELinux blocks writes to files in /etc/ and /usr/, but it allows
reading them.
Lets say we create a file in the /etc/ directory:
Now, lets mount the file in a container and attempt to read and write it.
The same is possible if the file contains labeling more standard to the
/etc/directory:
This same behavior is not seen if we attempt it in another directory. Say, the
user’s home directory:
This might be useful if we want to mount a CA certificate for the container to
trust, as it will effectively be read-only:
Just be careful that the files from /etc/ or /usr/ that you mount into
the containers don’t contain any sensitive data that you don’t really want to
share.
Enabling access to files protected by SELinux
In order to give a container access to files protected by SELinux, you need to
use one of the following volume options: z or Z.
z(lower): relabels the content you’re mounting into the container, and
makes it shareable between containers.
Z(upper): relabels the content you’re mounting into the container, and
makes it private. So, mounting this file in another container won’t work.
Lets show how the z(lower) flag works in practice:
Note that we were now able to append to the file. As we can see, from the
host we could see the changes reflected in the file. Finally, checking the
SELinux context, we will note that docker has changed the type to be
svirt_sandbox_file_t, which makes it shareable between containers.
If we run another container and append to that file, we will be able to do so:
Now, lets try using the Z(upper) option. If we grab the same file and mount
it in a container with that option we’ll see the following:
If we open another terminal, and try to append to that file, we won’t be able
to:
We can verify the contents of the file:
Now we can see that the MCS label for the container changed and is specific to
the container that first accessed it. Assuming the container that first mounted
and accessed the file is named reverent_davinci, we can check the
container’s label with the following command:
And we can see that the container’s MCS label matches that of the file.
Disabling SELinux for a specific container
While this is not ideal, it is possible to do by using the --security-opt
label:disable option: