2013年5月15日 星期三

SELinux Notes -- Part I, Overview

SELinux by Example: Using Security Enhanced Linux
By Frank Mayer,, Karl MacMillan,, David Caplan

=======================================================

  • SELinux access control is based on a security context associated with all system resources including processes. The security context contains three elements: user, role, and type identifiers. The type identifier is the primary basis for access control.
    In SELinux, type enforcement is the primary access control feature. Access is granted between subjects (that is, processes) and objects by specifying allow rules that have the subject's type (also called a domain type) as the source and the object's type as the target. Access is granted for specified object classes using a fine-grained set of permissions defined for each object class.
    One of the key benefits of type enforcement is the ability to control which programs may run with a given domain type, thereby allowing access control down to individual programs (rather than the less-secure level of a user). The capability for a program to enter into a domain (that is, run with a given process type) is called domain transition and is tightly controlled by SELinux allow rules. SELinux also allows domain transitions to occur automatically through the type_transition rule.

  • SELinux does not directly use the role identifiers in a security context for access control. Instead, all access is controlled based on types. Roles are used to associate the allowed domain types into which a process running on behalf of a user may transition. This allows sets of type enforcement allowed capabilities to be grouped together and authorized for a user as a role.

Type Enforcement Access Control


In SELinux, all access must be explicitly granted. SELinux allows no access by default, regardless of the Linux user/group IDs. Yes, this means that there is no default superuser in SELinux, unlike root in standard Linux.

An allow rule has four elements:
  • Source type(s) Usually the domain type of a process attempting access
  • Target type(s) The type of an object being accessed by the process
  • Object class(es) The class of object that the specified access is permitted
  • Permission(s) The kind of access that the source type is allowed to the target type for the indicated object classes
As an example, take the following rule:
allow user_t bin_t : file {read execute getattr};


The translation of this rule would be as follows:

A process with a domain type of user_t can read, execute, or get attributes for a file object with a type of bin_t.




Example: passwd program
allow passwd_t shadow_t : file {ioctl read write create getattr setattr lock relabelfrom relabelto append unlink link rename};




In this example, we defined two types. The passwd_t type is a domain type intended for use by the password program. The shadow_t type is the type for the shadow password file. If we examine such a file on disk, we would see something like this:
# ls -Z /etc/shadow
-r----  root   root  system_u:object_r:shadow_t  shadow

Likewise, examining a process running the password program under this policy would yield this:
# ps -aZ
joe:user_r:passwd_t   16532 pts/0    00:00:00 passwd

The purpose of this rule is to give the passwd process' domain type (passwd_t) the access to the shadow's file type (shadow_t) needed to allow the process to move and create a new shadow password file.





Above figure shows an example of passwd program security in SELinux. The first rule is as follows:
allow user_t passwd_exec_t : file {getattr execute};

What this rule does is allow Joe's shell (user_t) to initiate an execve() system call on the passwd executable file (passwd_exec_t). The SELinux execute file permission is essentially the same permission as x access for files in standard Linux.


The next allow rules is
allow passwd_t passwd_exec_t : file entrypoint;

This rule provides entrypoint access to the passwd_t domain. The entrypoint permission is a rather valuable permission in SELinux. What this permission does is define which executable files (and therefore which programs) may "enter" a domain.



Let's now look at the final rule:
allow user_t passwd_t : process transition;

This is the first allow rule we have seen that did not provide access to file objects. In this case, the object class is process, meaning the object class representing processes. Recall that all system resources are encapsulated in an object class.




These three rules together provide the necessary access for a domain transition to occur. For a domain transition to succeed, all three rules are necessary; alone, none is sufficient. Therefore, a domain transition is allowed only when the following three conditions are true:

  1. The process' new domain type has enTRypoint access to an executable file type.
  2. The process' current (or old) domain type has execute access to the entry point file type.
  3. The process' current domain type has transition access to the new domain type.

When all three of these permissions are permitted in a TE policy, a domain transition may occur. Further, with the use of the entrypoint permission on executable files, we have the power to strictly control which programs can run with a given domain type. The execve() system call is the only way to change a domain type, giving the policy writer great control over an individual program's access to privilege, regardless of the user who may be invoking the program.


Default Domain Transitions: type_transition Statement



To support domain transitions occurring by default (as we want in the case of the password program), we need to introduce a new rule, the type transition rule (type_transition). This rule provides a means for the SELinux policy to specify default transitions that should be attempted if an explicit transition was not requested.

type_transition user_t passwd_exec_t : process passwd_t;

The syntax of this rule differs from the allow rule. There are still source and target types (user_t and passwd_exec_t, respectively) and an object class (process). However, instead of permissions, we have a third type, the default type (passwd_t).
Type_transition rules are used for multiple different purposes relating to default type changes.

The type_transition rule indicates that, by default on an execve() system call, if the calling process' domain type is user_t and the executable file's type is passwd_exec_t , a domain transition to a new domain type (passwd_t) will be attempted.


The type_transition rule allows the policy writer to cause default domain transitions to be initiated without explicit user input. This makes type enforcement less obtrusive to the user.


Role-Based Access Control (RBAC)


The RBAC feature of SELinux is built upon type enforcement; access control in SELinux is primarily via type enforcement. Roles limit the types to which a process may transition based on the role identifier in the process' security context.

We have added the role portion (user_r) of the security contexts for the processes depicted. We also added a new rule, specifically the role statement:
role user_r type passwd_t;

The role statement declares role identifiers and associates types with the declared role. The previous statement declares the role user_r (if it has not already been declared in the policy) and associates the type passwd_t with the role. What this association means is that the passwd_t type is allowed to coexist in a security context with the role user_r. Without this role statement, the new context joe:user_r:passwd_t could not be created, and the execve() system call would fail, even though the TE policy allows Joe's type (user_t) all the necessary access.

Role-based access control (RBAC) is a general security model that simplifies administration by assigning roles to users and then assigning permissions to those roles. RBAC in Security-Enhanced Linux (SELinux) acts as a layer of abstraction between the user and the underlying type-enforcement (TE) model, which provides highly granular access control but is not geared for ease of management.



Multilevel Security in SELinux (MLS)

The security level used by MLS systems is a combination of a hierarchical sensitivity and a set (including the null set) of nonhierarchical categories. These sensitivities and categories are used to reflect real information confidentiality or user clearances. In most SELinux policies, the sensitivities (s0, s1, ...) and categories (c0, c1, ...) are given generic names, leaving it to userspace programs and libraries to assign user-meaningful names. (For example, s0 might be associated with UNCLASSIFIED and s1 with SECRET.)
To support MLS, the security context is extended to include security levels as such these:
user:role:type:sensitivity[:category,...][-sensitivity[:category,...]]

Notice that the MLS security context must have at least one security level (which is composed of a single sensitivity and zero or more categories), but can include two security levels. These two security levels are called low (or current for processes) and high (or clearance for processes), respectively. If the high security level is missing, it is considered to be the same value as the low (the most common situation).

There are four dominance operators that can relate two MLS security levels are as follows:
dom:
(dominates) SL1 dom SL2 if the sensitivity of SL1 is higher or equal to the sensitivity of SL2, and the categories of SL1 are a superset of the categories of SL2.
domby:
(dominated by) SL1 domby SL2 if the sensitivity of SL1 is lower than or equal to the sensitivity of SL2, and the categories of SL1 are a subset of the categories of SL2.
eq:
(equals) SL1 eq SL2 if the sensitivity of SL1 and SL2 are equal, and the categories of SL1 and SL2 are the same set.
incomp:
(incomparable or noncomparable) SL1 incomp SL2 if the categories of SL1 and SL2 cannot be compared (that is, neither is a subset of the other).

SELinux Policy Server Architecture



In the policy server architecture, all manipulation and management of the overall system policy is controlled through the policy management server (PMS). The PMS is itself a userspace object manager in that it creates object classes representing policy resources and enforces a fine-grained access control policy over those resources.

With the PMS, you can now allow access to portions of the policy and limit access to others. For example, the SELinux policy can allow user management tools to add users and make role assignments, but not change type enforcement allow rules. Better yet, you can authorize a database server to change type enforcement (TE) rules relating to its object classes and types, but not those of the kernel. Internally, the PMS is designed to use another recent new feature of SELinux, loadable policy modules.


The second major function of the PMS is to split the system policy into kernel and user portions and load them respectively into the kernel security server and userspace security server (USSS). In this way, the kernel is not made aware of rules and object classes of concern only to userspace object managers. Userspace object managers query the USSS and not the kernel. AVCs in various userspace object managers register with the USSS (and not the kernel) for policy update and cache coherency functions.



SELinux Policy Language


The first section of a policy source file defines the object classes to the security server. This section also defines the permissions for each object class. For the kernel, these classes are directly related to kernel source files. In general, as an SELinux policy writer you would never change or modify the object class and permission definitions. 

The next section contains the type enforcement statements, which is by far the largest portion of an SELinux policy. This is the section that policy writers spend most of their time writing. It contains all the type declarations and all the TE rules (including all allow, type_transition, and other TE rules).

The next section of a policy source file contains the constraints. Constraints provide a means of further limiting the TE policy beyond what the TE rules permit. The multilevel security (MLS) policy, for example, is implemented as a set of constraints.

The last section of a policy file contains labeling specifications. All objects must be labeled with a security context for SELinux to enforce access control. This section tells SELinux how to treat filesystems for the purpose of labeling and contains the rules for labeling transient objects that are created at runtime. A separate related mechanism, called a file contexts file, is used to initialize the security context labeling of files, directories, and other objects on permanent filesystems.

Building and Installing Monolithic Policies


Above figure shows  a typical way that a policy is constructed.

Starting from the left side of this figure, you have the source files for the policy broken down into many tens of individual source modules. Compile the source policy using checkpolicy into a binary policy file, load_policy program is then used to load the binary policy file into the kernel, which then enforces access control based on the policy rules.
policy
Make policy.conf and policy.[ver] locally to test the compilation and check for error.
install
Do everything that make policy does plus install the binary policy file such that it will be loaded into the kernel at boot time and the policy configuration files.
load
Do everything that make policy does plus immediately load the binary policy file into the kernel as the active access control policy and install the file_contexts file.


  • SELinux is implemented as an LSM module in the kernel. SELinux uses LSM hooks throughout the kernel to control access to kernel resources. Access decisions are made by the SELinux security server, which is part of the SELinux LSM module. The security policy enforced by the security server is loaded into the kernel via a privileged userspace interface. The AVC provides performance improvement for access validation.
    The SELinux framework also supports userspace object managers through the libselinux library. In its basic form, the kernel security server directly provides access validation, whereas the library contains a per-process AVC. This approach requires the kernel to hold the policy for all userspace managers and to be aware of all userspace object classes.
  • The emerging policy server architecture enhances support for userspace object managers by providing a userspace security server that will enforce all portions of the policy relating to userspace objects, thereby relieving the kernel of its need to know of userspace object classes and policy rules. The policy server will also provide fine-grained access control to the policy itself, allowing greater distribution of policy management authority.

沒有留言:

張貼留言