selinux概述

学习 selinux 时看到的一篇文章,觉得讲得很不错,就转载翻译一下。
原文 selinux-policy-guide

We are celebrating the SELinux 10th year anversary this year. Hard to believe it. SELinux was first introduced in Fedora Core 3 and later in Red Hat Enterprise Linux 4. For those who have never used SELinux, or would like an explanation…

真令人难以置信, 我们已经在庆祝 SELinux 10 周年纪念日了(译注:原文是在 2013年写的了,到现在2019年了,已经是16周年了)。SELinux 最初是在 Fedora Core 3 和随后的 Red Hat Enterprise Linux 4 上引入的。 本文将为那些从来没有使用过 SELinux 的同学作一个概述。

SElinux is a labeling system. Every process has a label. Every file/directory object in the operating system has a label. Even network ports, devices, and potentially hostnames have labels assigned to them. We write rules to control the access of a process label to an a object label like a file. We call this policy. The kernel enforces the rules. Sometimes this enforcement is called Mandatory Access Control (MAC).

SELinux 是一个标签系统, 系统中的每一个进程都有一个标签, 每一个文件/目录对象也都有一个标签,甚至网络端口,设备文件,和主机名都会给它们设置标签。 我们通过编写规则来控制一个进程标签对一个对象(比如文件)标签的访问。我们称之为策略。内核会强制执行这些规则,有时候我们把这种强制性称为:强制访问控制 Mandatory Access Control (MAC).

The owner of an object does not have discretion over the security attributes of a object. Standard Linux access control, owner/group + permission flags like rwx, is often called Discretionary Access Control (DAC). SELinux has no concept of UID or ownership of files. Everything is controlled by the labels. Meaning an SELinux system can be setup without an all powerful root process.

标准 Linux 的访问控制系统中的用户/组权限位(比如 rwx)通常被称作自由访问控制 Discretionary Access Control (DAC)(译注:可以理解为文件属主可以对文件作任意操作)。但在 SELinux 中, 一个对象的所有者并不能越过文件的安全属性对文件进行任意操作, SELinux 并没有 UID 或者文件属主的概念,所有的东西都是由标签控制的。这也就意味着一个 SELinux 系统可以由一个不具有 root 权限的进程来设置。

Note: SELinux does not let you side step DAC Controls. SELinux is a parallel enforcement model. An application has to be allowed by BOTH SELinux and DAC to do certain activities. This can lead to confusion for administrators because the process gets Permission Denied. Administrators see Permission Denied means something is wrong with DAC, not SELinux labels.

注意:SELinux 并不能让你摆脱 DAC 的控制。SELinux 与 DAC 是同时起作用的。一个应用必须同时通过 SELinux 和 DAC 的允许,才能对对象进程操作。有时候,进程遇到Permission Denied时,会让系统管理员感到困惑,因为系统管理员看到 Permission Denied, 就会以为是DAC 出错了,并没有想到是 SELinux 的权限控制。

Type enforcement
Lets look a little further into the labels. The SELinux primary model or enforcement is called type enforcement. Basically this means we define the label on a process based on its type, and the label on a file system object based on its type.Analogy, Imagine a system where we define types on objects like cats and dogs. A cat and dog are process types.

类型强制执行
让我们更深入的探讨一下标签。SELinux 的基本模型和执行被称为类型强制执行。基本上这意味着,我们基于一个进程或者文件的类型来定义它的标签。作个比喻:

type-enforcement_01_catdog

We have a class of objects that they want to interact with which we call food. And I want to add types to the food, cat_food and dog_food.

type-enforcement_03_foods

As a policy writer, I would say that a dog has permission to eat dog_chow food and a cat has permission to eat cat_chow food. In SELinux we would write this rule in policy.

type-enforcement_04_policy

1
2
3
allow cat cat_chow:food eat;

allow dog dog_chow:food eat;

With these rules the kernel would allow the cat process to eat food labeled cat_chow and the dog to eat food labeled dog_chow.

type-enforcement_02_eat

But in an SELinux system everything is denied by default. This means that if the dog process tried to eat the cat_chow, the kernel would prevent it.

type-enforcement_06_tux-dog-leash

Likewise cats would not be allowed to touch dog food.

mcs-enforcement_07_tux-cat-no

Real world, We label Apache processes as httpd_t and we label Apache content as httpd_sys_content_t and httpd_sys_content_rw_t. Imagine we have credit card data stored in a mySQL database which is labeled msyqld_data_t. If an Apache process is hacked, the hacker could get control of the httpd_t process and would be allowed to read httpd_sys_content_t files and write to httpd_sys_content_rw_t. But the hacker would not be allowed to read the credit card data (mysqld_data_t) even if the process was running as root. In this case SELinux has mitigated the break in.

MCS enforcement
Analogy, Above, we typed the dog process and cat process, but what happens if you have multiple dogs processes: Fido and Spot. You want to stop Fido from eating Spot’s dog_chow.

mcs-enforcement_02_fido-eat-spot-food

One solution would be to create lots of new types, like Fido_dog and Fido_dog_chow. But, this will quickly become unruly because all dogs have pretty much the same permissions.

To handle this we developed a new form of enforcement, which we call Multi Category Security (MCS). In MCS, we add another section of the label which we can apply to the dog process and to the dog_chow food. Now we label the dog process as dog:random1 (Fido) and dog:random2 (Spot).

mcs-enforcement_01_fido-spot

We label the dog chow as dog_chow:random1 (Fido) and dog_chow:random2 (Spot).

mcs-enforcement_03_foods

MCS rules say that if the type enforcement rules are OK and the random MCS labels match exactly, then the access is allowed, if not it is denied.

Fido (dog:random1) trying to eat cat_chow:food is denied by type enforcement.

mcs-enforcement_04-bad-fido-cat-chow

Fido (dog:random1) is allowed to eat dog_chow:random1.

mcs-enforcement_05_fido-eat-fido-food

Fido (dog:random1) denied to eat spot’s (dog_chow:random2) food.

mcs-enforcement_06_fido-no-spot-food

Real world, In computer systems we often have lots of processes all with the same access, but we want them separated from each other. We sometimes call this a multi-tenant environment. The best example of this is virtual machines. If I have a server running lots of virtual machines, and one of them gets hacked, I want to prevent it from attacking the other virtual machines and virtual machine images. But in a type enforcement system the KVM virtual machine is labeled svirt_t and the image is labeled svirt_image_t. We have rules that say svirt_t can read/write/delete content labeled svirt_image_t. With libvirt we implemented not only type enforcement separation, but also MCS separation. When libvirt is about to launch a virtual machine it picks out a random MCS label like s0:c1,c2, it then assigns the svirt_image_t:s0:c1,c2 label to all of the content that the virtual machine is going to need to manage. Finally, it launches the virtual machine as svirt_t:s0:c1,c2. Then, the SELinux kernel controls that svirt_t:s0:c1,c2 can not write to svirt_image_t:s0:c3,c4, even if the virtual machine is controled by a hacker and takes it over. Even if it is running as root.

We use similar separation in OpenShift. Each gear (user/app process)runs with the same SELinux type (openshift_t). Policy defines the rules controlling the access of the gear type and a unique MCS label to make sure one gear can not interact with other gears.

Watch this short video on what would happen if an Openshift gear became root.

MLS enforcement
Another form of SELinux enforcement, used much less frequently, is called Multi Level Security (MLS); it was developed back in the 60s and is used mainly in trusted operating systems like Trusted Solaris.

The main idea is to control processes based on the level of the data they will be using. A secret process can not read top secret data.

MLS is very similar to MCS, except it adds a concept of dominance to enforcement. Where MCS labels have to match exactly, one MLS label can dominate another MLS label and get access.

Analogy, Instead of talking about different dogs, we now look at different breeds. We might have a Greyhound and a Chihuahua.

mls-enforcement_01_chigrey

We might want to allow the Greyhound to eat any dog food, but a Chihuahua could choke if it tried to eat Greyhound dog food.

We want to label the Greyhound as dog:Greyhound and his dog food as dog_chow:Greyhound, and label the Chihuahua as dog:Chihuahua and his food as dog_chow:Chihuahua.

mls-enforcement_04_mlstypes

With the MLS policy, we would have the MLS Greyhound label dominate the Chihuahua label. This means dog:Greyhound is allowed to eat dog_chow:Greyhound and dog_chow:Chihuahua.

mls-enforcement_05_chigreyeating

But dog:Chihuahua is not allowed to eat dog_chow:Greyhound.

mls-enforcement_03_chichoke

Of course, dog:Greyhound and dog:Chihuahua are still prevented from eating cat_chow:Siamese by type enforcement, even if the MLS type Greyhound dominates Siamese.

mls-enforcement_06_nocatchow

Real world, I could have two Apache servers: one running as httpd_t:TopSecret and another running as httpd_t:Secret. If the Apache process httpd_t:Secret were hacked, the hacker could read httpd_sys_content_t:Secret but would be prevented from reading httpd_sys_content_t:TopSecret.

However, if the Apache server running httpd_t:TopSecret was hacked, it could read httpd_sys_content_t:Secret data as well as httpd_sys_content_t:TopSecret.

We use the MLS in military environments where a user might only be allowed to see secret data, but another user on the same system could read top secret data.

Conclusion
SELinux is a powerful labeling system, controlling access granted to individual processes by the kernel. The primary feature of this is type enforcement where rules define the access allowed to a process is allowed based on the labeled type of the process and the labeled type of the object. Two additional controls have been added to separate processes with the same type from each other called MCS, total separtion from each other, and MLS, allowing for process domination.

For more information on SELinux read my blog at danwalsh.livejournal.com

About the author
Daniel J Walsh - Daniel Walsh has worked in the computer security field for almost 30 years. Dan joined Red Hat in August 2001. Dan leads the RHEL Docker enablement team since August 2013, but has been working on container technology for several years. He has led the SELinux project, concentrating on the application space and policy development. Dan helped developed sVirt, Secure Virtualization. He also created the SELinux Sandbox, the Xguest user and the Secure Kiosk. Previously, Dan worked Netect/Bindview…