SELinux functionality inside a LXC container


I am currently trying to investigate how SELinux is used from a container perspective. I have a basic setup, in which I have a SELinux enabled kernel, and I am running a CentOS(which also uses SELinux) LXD container.

What i have noticed so far is that, all processes running inside the container have the same kind of SELinux domains set. When i tried writing to the /dev/console device from the LXD container, I got a SELinux denial. Through this what I understood was SELinux policies were applied for processes inside the container namespace.

The main question I had was, is the functionality of SELinux from a container’s viewpoint just to protect the host from container, or can we have more granular SELinux control for processes/files inside the container? If the SELinux domains are similar for all processes inside container, then one policy will apply to all processes. Can we also have multiple domains for different processes that run in the container’s namespace?

Our SELinux knowledge is very limited so we have close to no support for it at present.
liblxc supports some amount of configuration around SELinux, mostly setting up a particular context for the container.

The ability to then further constraint processes inside the container may depend on SELinux namespacing, I have no idea where that work is at the moment though.

We have kernel engineers involved in upstream LSM namespacing and stacking which should effectively allow for AppArmor protected containers on SELinux host as well as eventually, the reverse, running SELinux protected containers on AppArmor hosts.
Some of the work done in that regard may allow for SELinux protected containers on SELinux systems to also get their own namespace and be able to further load and apply policy, but as I said, I don’t know exactly where things stand there.

Hi Stephane.

Thanks a lot for your response. What does it means when we say liblxc has support for setting a particular context for a container? Does it mean that all processes in the containers namespace would run under the same context?

If we omit security namespace from the picture for once, and let all host policies apply to all processes/files in the container. Then, can we influence the SELinux contexts of the processes inside the container namespace, and write corresponding policies on the host ? By influencing the contexts, I meant, is it possible to set the SELinux contexts for all processes in the Container namespace such that they are different from the host SELinux contexts, and they also have differing contexts for different processes. Through this, if we can load policies we could potentially gain more granular access control.

Yeah, what liblxc does with that setting is override the current context of the init process as it gets spawned, all children processes will then inherit that.

You should be able to do the container wide context with the liblxc option, as for then having different contexts on different processes, I’m not sure how that works exactly. Last time we tried making this work properly (with our extremely limited SELinux knowledge) we got stuck in a bit of filesystem labeling rabbit hole, especially around shared filesystems like proc and sysfs.

Hello everyone,
(Newbie alert: I am new to LXC and SELinux, just trying to get my hands dirty and playing around with the code)

I see that this thread is quite relatable with what I am trying to do. I am very well aware that there is no SELinux implementation for namespaces yet in any of the stable kernel releases, but there is some patch work going on (quite old now, but something is there) and I have cloned and compiled a working-selinuxns kernel branch and am running it on my VM.

I can see that the kernel can now atleast run another instance of SELinux. I just want to run the instance of SELinux in permissive mode. There is very quick demo of how this can be acheived in the patch commit and can be found here. There are series of commit with good comments to help understand the flow also, and can be seen here.

Now the prototype test script shows that the new process unshares it network and mount namespace and the unmounts-remounts the SELinux fs. I am using LXC3.0, and I want to enable SELinux inside it (in permissive mode so that things do not stop working, just get logged) and centos.yaml has 2-3 lines when I search for selinux (which of course I changed but SELinux is still disabled). Unlike the previous templates we used to have as shell scripts, changing stuff there is a bit different.

Is there a way I can change the centos.yaml so that it mounts another /sys/fs/selinux and the container should unshare mount and network namespaces before this happens (but after writing into /…/unshare as is done in the test script)?

My goal here is to understand where to make the changes (I am okay with changing the distrobuilder source on my machine also; would also appreciate a documentation link and/or code flow)

I would really appreciate any help here.
(My work is POC and is intended for learning purposes.)

unshare changes would need to happen in liblxc (C codebase) but we’re not going to accept changes there for kernel features that are not in the mainline kernel.

So you’ll likely need to custom patch liblxc and run a modified version locally.

With that done, you should be able to then just mount your new copy of the selinux filesystem in there or the container may even just do that for you on boot out of the box.

Thank you very much for your response! :slight_smile:
Correct, I will do it locally. I’ll follow up here again in case I have question.