This section describes how to customize the policy. It discusses how to perform various common changes to the policy, from adding users and permissions to defining entirely new domains, types, and roles.
When a user is added to the system, the policy may need to be updated
to recognize the user. As discussed in the Section called User Identity Model
and the Section called User Declarations, it may be appropriate to simply map the
new user to the generic user_u
user identity
if the new user only requires unprivileged access and does not need
to be separated from other such users by the policy. In that case,
no updates to the policy are required.
If the user must be recognized by the policy, then the administrator must add the user to the policy/users file, specifying the set of authorized roles for the user, and reload the policy via make load in the policy directory.
As an example, suppose that the administrator has added a user
steve
to the system who should be authorized for
both the staff_r
and sysadm_r
roles. To update the policy, the administrator would add an entry to
the policy/users file as shown below, and
run make load to reload the policy:
user steve roles { staff_r sysadm_r }; |
After installing SELinux, the administrator may discover that
additional permissions must be allowed in order for the system to
function properly. It is advisable to run SELinux in permissive mode
initially and to exercise the standard operations of the system in
order to generate audit messages for all operations that would have
been denied by the example policy. These messages can typically be
found in the dmesg output or
/var/log/messages with the prefix avc:
denied
. A couple of example audit messages that
might be generated during the execution of system cron jobs are shown below:
avc: denied { rename } for pid=26878 exe=/usr/sbin/logrotate path=/var/log/messages.4 dev=03:02 ino=1345261 scontext=system_u:system_r:system_crond_t tcontext=system_u:object_r:var_log_t tclass=file avc: denied { create } for pid=26878 exe=/usr/sbin/logrotate path=/var/log/messages dev=03:02 ino=1345261 scontext=system_u:system_r:system_crond_t tcontext=system_u:object_r:var_log_t tclass=file |
The critical fields of each avc denied message are the list of
permissions, the source security context (scontext), the target
security context (tcontext), and the target security class (tclass).
These example audit messages show that the
system_crond_t
domain is being denied permissions
to rename and create files with the var_log_t
type. The other fields in each audit message provide any information
about the specific processes and objects that can be determined when
the audit message is generated. These messages show that the
process was running the logrotate program and was
attempting to access files in the /var/log directory.
The audit messages should be carefully reviewed to determine whether the denied permission should be allowed via a TE allow rule (described in the Section called TE Access Vector Rules). The audit2allow script provides an example of how to automatically convert the audit messages to TE allow rules that grant the denied permissions, but these rules should be reviewed to ensure that they do not violate the desired security goals. Other options include placing the process into a different domain or placing the object into a different type, possibly requiring the definition of new domains and/or types. It is also sometimes desirable to continue denying the permission, but to disable auditing of the permission via a TE dontaudit rule.
In the case of the example audit messages, the denied permissions could be allowed by adding the following rule to the policy/domains/program/crond.te file:
allow system_crond_t var_log_t:file { rename create setattr unlink }; |
system_crond_t
domain allows all system cron jobs
to access these files. A better approach would be to define a
separate domain for the logrotate program that
has these permissions. This approach is discussed further in the Section called Creating a New Domain.Not all permission denials can be solved simply through modifying the TE configuration. It may be necessary to modify the RBAC configuration (described in the Section called RBAC Statements) or the constraints configuration (described in the Section called Constraint Definitions) as well. In the example policy, these configurations are relevant for the process transition permission when the role or user identity changes and for the file create or relabel permissions when the user identity of the file differs from the process.
After updating the policy configuration to allow the denied permissions, the administrator must then build and load the new policy by running make load in the policy directory. The permissions should then be granted on subsequent operations. If the same denials persist, then it is likely that the permission is being denied by the RBAC or constraints configuration and that these configurations were not updated by the administrator.
An administrator may wish to add a program to an existing domain
that is already being used for related programs that require similar
permissions. First, the administrator should locate an appropriate
domain by examining the existing program domains under
policy/domains/program and by examining how existing
programs are associated with the executable types for those domains in
policy/file_contexts/program. After selecting an
appropriate domain, the administrator should verify that a domain
transition is defined from the desired starting domain to the new
domain. If not, then an appropriate
domain_auto_trans
rule should be added to the
domain's .te file and the policy should be
reloaded via make load.
The administrator must then relabel the program with the executable type for the domain. This relabeling can be performed either using chcon or by updating the file contexts configuration and using restorecon, as discussed in the Section called Applying the File Contexts Configuration. If a process is already running the program, the administrator must then restart the process in order to place it into the domain, typically using run_init for system processes.
As an example, suppose that an administrator wants to add a new
filesystem administration utility to the system that requires similar
permissions to the fsck program. Looking at the
file contexts configuration, the administrator would see that
fsck is labeled with the
fsadm_exec_t
type. Looking under the
policy/domains/program directory, the
administrator would find the fsadm.te file with
the definitions for the corresponding fsadm_t
domain. After verifying that this domain is appropriate for the new
utility, the administrator can add an entry to
policy/file_contexts/program/fsadm.fc for the new
utility and run restorecon on the program or use
chcon to manually set the context on the program.
After installing SELinux or after installing a new software package,
the administrator may discover that some system processes are left in
the initrc_t
domain in the output of ps
-eZ. These system processes should either be
disabled or placed into an appropriate domain. This may simply
involve adding the program to an existing domain, as discussed in
the Section called Adding Programs to an Existing
Domain, or it may require creating a new domain.
The administrator may also discover that new domains are needed
to address denied permissions, as discussed in the Section called Adding Permissions,
for system processes or user programs. New domains are also needed
when new roles are defined.
To create a new domain, the administrator should first create a new .te file under the policy/domains directory and populate it with appropriate TE declarations and rules. As an example, the creation of the policy/domains/program/logrotate.te file for the logrotate program will be discussed. The need for a separate domain for the logrotate program was introduced in the Section called Adding Permissions. The domain definition begins by declaring the domain and its executable type using type declaration rules (described in the Section called Type Declarations), as shown below:
type logrotate_t, domain, privowner; type logrotate_exec_t, file_type, sysadmfile, exec_type; |
general_domain_access
macro (described in Table 6 in the Section called TE Access Vector Rules) can be used as shown below:
general_domain_access(logrotate_t) |
If the program is known to create files in shared directories, e.g. /tmp files, then the administrator can declare types for these files and file type transition rules (described in the Section called TE Transition Rules). An example type declaration and file type transition rule for temporary files created by logrotate is shown below:
type logrotate_tmp_t, file_type, sysadmfile, tmpfile; file_type_auto_trans(logrotate_t, tmp_t, logrotate_tmp_t) |
tmp_domain
macro.
Likewise, if the program is known to require certain permissions, then
these permissions can be allowed by the administrator. Since the
administrator knows that the program requires permissions to the
/var/log files, the following rules might be
initially specified:
allow logrotate_t var_log_t:dir rw_dir_perms; allow logrotate_t var_log_t:file create_file_perms; |
domain_auto_trans(system_crond_t, logrotate_exec_t, logrotate_t) domain_auto_trans(sysadm_t, logrotate_exec_t, logrotate_t) |
system_crond_entry
macro.After providing a minimal definition of the domain and transitions
into the domain, the administrator should authorize roles for the
domain. Role declarations (described in the Section called Role Declarations and Dominance)
can be placed either in the domain's .te file or
in the policy/rbac file. The former approach is
preferable in order to encapsulate the domain's definition. Role
declarations for the logrotate_t
domain are shown
below:
role system_r types logrotate_t; role sysadm_r types logrotate_t; |
The updated policy configuration can then be compiled and loaded by running make load in the policy directory. The administrator should then add the program to the file contexts configuration and run restorecon on the program or run chcon to manually set the context. A policy/file_contexts/program/logrotate.fc configuration file for logrotate is shown below:
/usr/sbin/logrotate system_u:object_r:logrotate_exec_t |
The administrator can then try running the program in its new domain to discover whether additional permissions are required. If the program is to be run as a system process, the administrator should use run_init to start it. If additional permissions are required, then the steps in the Section called Adding Permissions can be followed to complete the domain.
New types can be created to provide distinct protection for specific objects. An administrator may also discover that new types are needed to address denied permissions, as discussed in the Section called Adding Permissions. To create a new type, the administrator should first add a type declaration (described in the Section called Type Declarations) to the TE configuration. If the type is associated with a particular domain, then the declaration should be placed in the domain's .te file. If the type is a general type, then the declaration can be placed in one of the files under policy/types.
If automatic transitions to this type are desired, then the administrator should define type transition (described in the Section called TE Transition Rules) rules for the appropriate domains. The administrator should add appropriate TE allow rules to the TE configuration to permit authorized domains to access the type. The administrator can then build and reload the policy via make load. After updating the policy, the administrator can then apply the type to a file by updating the file contexts configuration and running restorecon on the file or by using chcon.
As an example, consider the /dev/initctl named
pipe, which is used to interact with the init
process. The initctl_t
type was defined for this
file in the policy/domains/program/init.te file,
as shown below:
type initctl_t, file_type, sysadmfile; |
file_type_auto_trans(init_t, device_t, initctl_t) |
allow initrc_t initctl_t:fifo_file rw_file_perms; allow sysadm_t initctl_t:fifo_file rw_file_perms; |
/dev/initctl system_u:object_r:initctl_t |
New roles can be created to provide separation among users beyond the
simple division between ordinary users and administrators. To add a
new role, the administrator should use the
full_user_role
macro to instantiate a role and a
set of domain definitions for the initial login domain for the role
and for programs run from the role. To allow transitions between the
new role and other roles, the
role_tty_type_change
macro in
domains/user.te may be used. Appropriate users
should be authorized for the new role in
policy/users. The policy can then be reloaded
via make load.
After updating the policy, the administrator should add an entry for the role to the /etc/selinux/(strict|targeted)/contexts/default_type application configuration file.