SELinux is not hard. SELinux is hard to understand
I spent the last couple of days learning about AppArmor. The time spent is definitely not sufficient, but I want to share some thoughts about SELinux. The reason for this is, because while researching AppArmor, one inevitably comes to comparisons between SELinux and AppArmor. And if I have to summarize such discussions, this would sound like this: “SELinux is very hard to maintain and this makes it more error-prone. AppArmor is very easy and you can achieve the same results as SELinux with it.”
It is unnecessary to say, I don’t agree with both statements. SELinux is not hard to maintain. The problem is, that few people understand how SELinux works and therefore the ones who don’t, find SELinux hard to maintain. The “complexity” of SELinux gives it a lot of flexibility. The situations, which AppArmor can handle good is just a subset of the situations, which SELinux can handle at all. The question, of course, is if you experience the additional situations. For me quite often the answer is “yes”, that is why I use SELinux. And there are few Linux distributions, which come pre-installed with a good set of SELinux rules — the RedHat derivatives are some of them.
Let me try to explain how SELinux works — on a high level. And I will try not to use Linux commands.
Look at the following picture:
Two things need to be noted on it:
- SELinux needs every object to be labeled;
- SELinux looks at two objects, which want to interact with each other, and based on their labels decides, if the interaction should be denied or allowed.
That’s it. That is how SELinux works.
But we can detail this a bit. What are objects? An object can be anything in Linux, but the most common case is, where one object is a process and the other object is a file. But the objects can be sockets (which are also files by the way), or a pipe, or even a network interface.
Can the label be in free form? The label in SELinux is actually called “context” and it has the form:
user:role:type:level{:category}
These four (five) parts are described perfectly in RedHat’s article “Chapter 2. SELinux Contexts”. The most important one of them is the TYPE. Let us add some details to the image above:
On the new image we have a process, whose label is “ssh_t”, and a file on the disk, whose label is “ssh_home_t”. Now, if this process tries to read, or write, or execute this file, it is SELinux’ job to either allow or deny this interaction. SELinux does this by a set of rules. The rules are compiled and loaded at boot or by special SELinux commands. I will devote another post on the “complex” SELinux language.
On the image above, we’ve omitted the full context of the process and the file and we’ve used only their types as labels. Their full contexts could look like:
- for the process: “staff_u:staff_r:ssh_t:s0”
- for the file: “unconfined_u:object_r:ssh_home_t:s0”
Let’s see another, more exact image:
On the image above, we see the same process, whose interaction with the file labeled “ssh_home_t” was granted, but another interaction — with the file labeled “top_secret_t” — was denied.
Small summary of this part: the type in two objects’ contexts are used by SELinux to decide if an interaction between these two objects should take place, or not.
What about the users and the roles? Each type in a SELinux system is assigned to a role.
On my system there are 4987 types divided throughout 14 roles.
Users are an independent entity in the SELinux world. They can be linked to roles. On my system there are 8 SELinux users.
Please note, there is a difference between the SELinux users and the Linux users. On my machine, I have 3 normal Linux users. Normal Linux users are assigned to SELinux users. So, essentially SELinux users could be said to be “user types”, as several normal Linux users may be linked to one and the same SELinux user. On my system: I am in the “unconfined_u” SELinux user type and two other users are in the “user_u” SELinux user type.
Here is the final image for the SELinux context:
“Real” users are connected to SELinux users, which are assigned to roles, and the roles have a set of types. That is why a context looks like: “user_u:object_r:ssh_home_t:s0". It depicts in textual form the exact image above.
Why does SELinux use RBAC? It is for the same reason any other system uses RBAC — flexibility and maintainability. Imagine a small startup company, where 5 co-workers take care of everything — financials, marketing, SW development, HW development, production, etc. This would mean everyone needs to have access to every system in this company. With time, the company grows, if the system administrators keep the status quo, then they need to grant and deny rights to every new person coming, or every person going from the company. With RBAC, the different roles are assigned the proper rights and are never changed again. Then for each new person, it has to be added to the proper role, or if a person goes — first its role binding deleted and then of course the whole user. It makes sys admin’s job much easier.
And why are the types linked to the role? Imagine the “types” as document types. Each role is responsible for a document type. The financials department is NOT responsible for a PCB layout document, but for the cash flow statement at the end of the year. The SW development department is NOT responsible for the latest commercial on TV, but for the source code of the latest product. This is the reason, why SELinux allows access from specific object (e.g. process) types only to specific other object (e.g. file) types. And these types have to be under the same role (or there should be a “transition” definition, but this will be explained in a follow-up). There is normally no need for the financials role to touch PCB layouts.
What are s0 and c0.c1023? The fourth (and fifth) part of the context are the so called “severity level” and “category”. These allow a more fine-grained control inside the role. I will devote an additional post about them. For now just use “s0:c0.c1023” if you need them ;)
Disclaimer
While I am not a representative of Red Hat and my views about Red Hat are my own, I am a member of Red Hat Accelerators community which gives me a connection to Red Hat and through which I engage with other Red Hat Accelerators.
Learn more about the Red Hat Accelerators