* [gentoo-commits] gentoo commit in xml/htdocs/proj/en/hardened/selinux: hb-intro-resources.xml hb-using-configuring.xml hb-using-policies.xml hb-using-states.xml hb-using-troubleshoot.xml
@ 2011-10-23 13:00 Sven Vermeulen (swift)
0 siblings, 0 replies; only message in thread
From: Sven Vermeulen (swift) @ 2011-10-23 13:00 UTC (permalink / raw
To: gentoo-commits
swift 11/10/23 13:00:14
Added: hb-intro-resources.xml hb-using-configuring.xml
hb-using-policies.xml hb-using-states.xml
hb-using-troubleshoot.xml
Log:
Update SELinux Handbook (cfr thread on gentoo-hardened and stabilization of policies)
Revision Changes Path
1.1 xml/htdocs/proj/en/hardened/selinux/hb-intro-resources.xml
file : http://sources.gentoo.org/viewvc.cgi/gentoo/xml/htdocs/proj/en/hardened/selinux/hb-intro-resources.xml?rev=1.1&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo/xml/htdocs/proj/en/hardened/selinux/hb-intro-resources.xml?rev=1.1&content-type=text/plain
Index: hb-intro-resources.xml
===================================================================
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE sections SYSTEM "/dtd/book.dtd">
<!-- The content of this document is licensed under the CC-BY-SA license -->
<!-- See http://creativecommons.org/licenses/by-sa/1.0 -->
<!-- $Header: /var/cvsroot/gentoo/xml/htdocs/proj/en/hardened/selinux/hb-intro-resources.xml,v 1.1 2011/10/23 13:00:13 swift Exp $ -->
<sections>
<version>2</version>
<date>2011-05-31</date>
<section>
<title>Background</title>
<subsection>
<title>Introduction to SELinux</title>
<body>
<ul>
<li>
<uri link="http://www.nsa.gov/research/_files/selinux/papers/inevit-abs.shtml">The Inevitability of Failure:
The Flawed Assumption of Security in Modern Computing Environments</uri>
explains the need for mandatory access controls.
</li>
<li>
<uri link="http://www.nsa.gov/research/_files/selinux/papers/flask-abs.shtml">The Flask Security Architecture:
System Support for Diverse Security Policies</uri>
explains the security architecture of Flask, the architecture used by SELinux.
</li>
<li>
<uri link="http://www.nsa.gov/research/_files/selinux/papers/module-abs.shtml">Implementing SELinux as a Linux Security Module</uri>
has specifics about SELinux access checks in the kernel.
</li>
</ul>
</body>
</subsection>
</section>
<section>
<title>SELinux Policy</title>
<subsection>
<title>Policy Related References</title>
<body>
<ul>
<li>
<uri link="http://www.nsa.gov/research/_files/selinux/papers/policy2-abs.shtml">Configuring the SELinux Policy</uri>
</li>
<li>
<uri link="http://oss.tresys.com/projects/refpolicy">SELinux Reference Policy</uri>
</li>
<li>
SELinux <uri link="http://www.selinuxproject.org/page/ObjectClassesPerms">Object Classes and Permissions</uri> Overview
</li>
</ul>
</body>
</subsection>
</section>
<section>
<title>Books</title>
<subsection>
<title>Paper Books</title>
<body>
<ul>
<li>
<c>SELinux by Example: Using Security Enhanced Linux</c>, Frank Mayer,
Karl MacMillan, and David Caplan, Prentice Hall, 2006; ISBN 0131963694
</li>
<li>
<c>SELinux: NSA's Open Source Security Enhanced Linux</c>, Bill McCarty,
O'Reilly Media, 2004; ISBN 0596007167
</li>
</ul>
</body>
</subsection>
</section>
<section>
<title>Gentoo Specific Resources</title>
<subsection>
<title>Gentoo Hardened</title>
<body>
<p>
The following resources are specific towards Gentoo Hardened's SELinux
implementation.
</p>
<ul>
<li>
<uri link="/proj/en/hardened/selinux-faq.xml">SELinux Frequently Asked
Questions</uri>
</li>
<!--
<li>
<uri link="/proj/en/hardened/selinux-development.xml">SELinux Development
Guidelines</uri>
</li>
<li>
<uri link="/proj/en/hardened/selinux-policy.xml">SELinux Policy</uri>
</li>
-->
</ul>
</body>
</subsection>
</section>
</sections>
1.1 xml/htdocs/proj/en/hardened/selinux/hb-using-configuring.xml
file : http://sources.gentoo.org/viewvc.cgi/gentoo/xml/htdocs/proj/en/hardened/selinux/hb-using-configuring.xml?rev=1.1&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo/xml/htdocs/proj/en/hardened/selinux/hb-using-configuring.xml?rev=1.1&content-type=text/plain
Index: hb-using-configuring.xml
===================================================================
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE sections SYSTEM "/dtd/book.dtd">
<!-- The content of this document is licensed under the CC-BY-SA license -->
<!-- See http://creativecommons.org/licenses/by-sa/1.0 -->
<!-- $Header: /var/cvsroot/gentoo/xml/htdocs/proj/en/hardened/selinux/hb-using-configuring.xml,v 1.1 2011/10/23 13:00:13 swift Exp $ -->
<sections>
<version>1</version>
<date>2011-09-30</date>
<section>
<title>Administering Users</title>
<subsection>
<title>Introduction</title>
<body>
<p>
During the installation, we already covered how to map a Linux user to a SELinux
user. In the example, we used a hypothetical user "john" and mapped him to the
SELinux user "staff_u". If you are running a multi-user system, managing the
right mappings is important. A user that is mapped to the SELinux user "user_u"
will not get any additional rights. Even if you would give that user additional
rights through commands such as <c>sudo</c>, the SELinux policy will not allow
this user to do anything that is administration related.
</p>
<p>
For this reason, it is important to go over the SELinux user mappings and the
Linux users on your system.
</p>
</body>
</subsection>
<subsection>
<title>User Mappings</title>
<body>
<p>
Run <c>semanage login -l</c> to show the current mappings between Linux logins
and SELinux users.
</p>
<pre caption="Running semanage login -l">
# <i>semanage login -l</i>
Login Name SELinux User
__default__ user_u
root root
john staff_u
system_u system_u
</pre>
<p>
The "user_u" SELinux user is for regular accounts. As such, the special
<e>__default__</e> mapping is defined by SELinux to denote every login that is
not defined otherwise. This makes sure that a newly defined account does not get
elevated privileges by default.
</p>
<p>
The next table gives an overview of the standard SELinux users available after
an installation.
</p>
<table>
<tr>
<th>SELinux User</th>
<th>Description</th>
</tr>
<tr>
<ti>user_u</ti>
<ti>
Default regular SELinux user, which should be used by end-user accounts that
are not going to administer any service(s) on the system
</ti>
</tr>
<tr>
<ti>staff_u</ti>
<ti>
SELinux user for administrators. This user has the right to switch roles and
as such gain elevated privileges
</ti>
</tr>
<tr>
<ti>root</ti>
<ti>
SELinux user for the root account. It differs little from the staff_u
account beyond being a different ID. This ensures that files protected by
the user based access control for root cannot be handled by the staff_u
(and other) users
</ti>
</tr>
<tr>
<ti>sysadm_u</ti>
<ti>
SELinux user for system administration. By default, this account is not
immediately used as this user immediately gets the administrative role
(whereas staff_u and root still need to switch roles).
</ti>
</tr>
<tr>
<ti>system_u</ti>
<ti>
SELinux user for system services. It should never be used for end users or
administrators as it provides direct access to the system role (and
privileges)
</ti>
</tr>
<tr>
<ti>unconfined_u</ti>
<ti>
Used when the policy is <e>targeted</e>, this SELinux user has many
privileges (it is essentially not limited in its actions, although it is
still handled through SELinux - just through a "wide open" policy).
</ti>
</tr>
</table>
<p>
To map a user to a specific SELinux user, use <c>semanage login -a</c>:
</p>
<pre caption="Mapping a user 'sophie' to the staff_u user">
# <i>semanage login -a -s staff_u sophie</i>
</pre>
<p>
However, when you update such mapping, the files in that users' home directory
will be owned by a wrong SELinux user. It is therefor important to relabel the
files of that user:
</p>
<pre caption="Relabeling sophie's files">
# <i>restorecon -R -F /home/sophie</i>
</pre>
</body>
</subsection>
<subsection>
<title>Additional SELinux Accounts</title>
<body>
<p>
It is perfectly possible to create additional SELinux accounts, and then map the
Linux logins to these new accounts. This can be necessary when you want a more
thorough auditing (on end user level) or when you will be enhancing the policy
with additional roles. Also, if you want to use the User Based Access Control
feature, using different SELinux users is important to enforce the control on
different users (if they all use the same SELinux user, then UBAC has little to
no effect).
</p>
<p>
Managing the SELinux accounts is done through <c>semanage user</c>:
</p>
<pre caption="Creating a SELinux user">
# <i>semanage user -a -R "staff_r sysadm_r" sophie</i>
</pre>
<p>
Let's verify how the SELinux users are currently configured:
</p>
<pre caption="Checking the SELinux user identities">
# <i>semanage user -l</i>
SELinux User SELinux Roles
root staff_r sysadm_r
sophie staff_r sysadm_r
staff_u staff_r sysadm_r
sysadm_u sysadm_r
system_u system_r
unconfined_u unconfined_r
user_u user_r
# <i>semanage login -l</i>
Login Name SELinux User
__default__ user_u
root root
sophie staff_u
swift staff_u
system_u system_u
</pre>
<p>
Now that a new SELinux user called "sophie" exists, we can now update the Linux
user mapping for "sophie" towards the new SELinux user "sophie":
</p>
<pre caption="Updating the Linux user mapping">
# <i>semanage login -m -s sophie sophie</i>
# <i>semanage login -l</i>
Login Name SELinux User
__default__ user_u
root root
sophie sophie
swift staff_u
system_u system_u
</pre>
<p>
Again, do not forget to relabel this users' files.
</p>
<p>
As you can see, managing SELinux users means defining the roles to which the
user has access to. We already gave a high-level introduction to the default
roles in <uri link="?part=1&chap=2">SELinux Concepts</uri>, but as roles are
important when using a Mandatory Access Control system, let's refresh our memory
again:
</p>
<table>
<tr>
<th>SELinux Role</th>
<th>Description</th>
</tr>
<tr>
<ti>user_r</ti>
<ti>
Default end-user role. This role provides access to regular applications and
activities, but does not allow any system or service administration beyond
what is expected for a regular user.
</ti>
</tr>
<tr>
<ti>staff_r</ti>
<ti>
Default administration role for day-to-day activities. This role has some
additional privileges beyond what is offered through user_r, but is not a
full system administrative role. It is meant for the non-administrative
activities done by operators and administrators
</ti>
</tr>
<tr>
<ti>sysadm_r</ti>
<ti>
System administration role. This role is highly privileged (since it also
contains the privileges to update the policy) and should only be given to
fully trusted administrators. It is almost never immediately granted to
users (they first need to switch roles) except for direct root access (for
instance through the console)
</ti>
</tr>
<tr>
<ti>system_r</ti>
<ti>
System service role, which is used for the runtime services (processes). It
is never granted to users directly.
</ti>
</tr>
<tr>
<ti>unconfined_r</ti>
<ti>
The unconfined role is used when the <e>targeted</e> policy is supported.
This role is given to unconfined users (such as the SELinux unconfined_u
user) which have very wide privileges (they almost run without constraints).
</ti>
</tr>
</table>
<p>
It should be noted that these roles are the default ones, but the security
administrator - yes, that means you - can create additional roles and add
particular privileges to it. We will discuss this later in this book as it means
you'll need to update the Gentoo Hardened SELinux policy.
</p>
</body>
</subsection>
</section>
<section>
<title>Reading Audit Logs</title>
<subsection>
<title>Introduction</title>
<body>
<p>
When working with a SELinux-enabled system, you will eventually notice that
things behave differently, but without giving any meaningful error message.
Usually, when SELinux "denies" a particular access, it logs it into the audit
log of the system, but for the application itself, it is perfectly possible that
it just silently dies. If not, you're most likely to get a <e>permission
denied</e> error message.
</p>
<p>
Initially, SELinux is running in <c>permissive</c> mode, which means that
SELinux will log what it <e>would</e> deny, but still let it through.
This mode is perfect for getting the system in shape without having too
much problems keeping it running. Once you think your security settings are
in order, then this mode can be switched from <c>permissive</c> to
<c>enforcing</c>. We'll talk about these modes later.
</p>
<p>
First, let's take a look at the audit log and see what it is saying...
</p>
</body>
</subsection>
<subsection>
<title>Audit Log Location(s)</title>
<body>
<p>
The SELinux kernel code writes its denials (and sometimes even allowed but
audited activities) into the audit log. If you are running on a Gentoo Hardened
installation with the <c>syslog-ng</c> system logger, then the logger is already
configured to place these audit lines in <path>/var/log/avc.log</path>. However,
different system loggers or system logger configurations might put the entries
in a different log location (such as <path>/var/log/audit.log</path>).
</p>
<p>
Below, you'll find the appropriate lines for the syslog-ng system logger
configuration for writing the events in <path>/var/log/avc.log</path>.
</p>
<pre caption="syslog-ng.conf excerpt for SELinux AVC entries">
<comment># The following lines are only /part/ of the configuration file!</comment>
source kernsrc { file("/proc/kmsg"); };
destination avc { file("/var/log/avc.log"); };
filter f_avc { message(".*avc: .*"); };
log {
source(kernsrc);
filter(f_avc);
destination(avc);
};
</pre>
</body>
</subsection>
<subsection>
<title>What is AVC?</title>
<body>
<p>
As we mentioned, SELinux writes its entries in the audit log. These entries are
called <e>avc messages</e> or <e>avc log entries</e>. The abbreviation AVC
stands for <e>Access Vector Cache</e> and, like the name sais, is a caching
system.
</p>
<p>
Using an access vector cache improves performance on dealing with (and
enforcing) activities and privileges. Since SELinux offers a very detailed
approach on privileges and permissions, it would become quite painful
(performance-wise) if each call means that the SELinux code needs to look up the
domain, the target resource label, the privilege and if it is allowed or not
over and over again. Instead, SELinux uses the Access Vector Cache to store past
requests/responses. It is the AVC subsystem that is responsible for checking
accesses and (if necessary) logging it.
</p>
</body>
</subsection>
<subsection>
<title>Reading an AVC Denial Message</title>
<body>
<p>
Below you'll find a typical AVC denial message.
</p>
<pre caption="Example AVC denial message">
Oct 15 13:04:54 hpl kernel: [963185.177043] type=1400 audit(1318676694.660:2472):
avc: denied { module_request } for pid=14561 comm="firefox" kmod="net-pf-10"
scontext=staff_u:staff_r:mozilla_t tcontext=system_u:system_r:kernel_t tclass=system
</pre>
<p>
Let's analyze each part of this message one by one.
</p>
<pre caption="AVC denial: Timestamp and location information">
<i>Oct 15 13:04:54 hpl kernel: [963185.177043]</i> type=1400 audit(1318676694.660:2472):
avc: denied { module_request } for pid=14561 comm="firefox" kmod="net-pf-10"
scontext=staff_u:staff_r:mozilla_t tcontext=system_u:system_r:kernel_t tclass=system
</pre>
<p>
This first part of the message informs you when the message was written (Oct 15
13:04:54), on which host (hpl) and how many seconds since the system was booted
(963185.177043).
</p>
<pre caption="AVC denial: source information">
Oct 15 13:04:54 hpl kernel: [963185.177043] type=1400 audit(1318676694.660:2472):
avc: denied { module_request } for <i>pid=14561 comm="firefox"</i> kmod="net-pf-10"
<i>scontext=staff_u:staff_r:mozilla_t</i> tcontext=system_u:system_r:kernel_t tclass=system
</pre>
<p>
Next is the source of the denial, i.e. what process is trying to do something.
In this case, the process is firefox, with PID 14561, which is running in the
source domain staff_u:staff_r:mozilla_t.
</p>
<pre caption="AVC denial: target resource">
Oct 15 13:04:54 hpl kernel: [963185.177043] type=1400 audit(1318676694.660:2472):
avc: denied { module_request } for pid=14561 comm="firefox" <i>kmod="net-pf-10"</i>
scontext=staff_u:staff_r:mozilla_t <i>tcontext=system_u:system_r:kernel_t</i> tclass=system
</pre>
<p>
The target of the activity is a kernel module (net-pf-10, which is the internal
name given for IPv6), labeled system_u:system_r:kernel_t
</p>
<pre caption="AVC denial: denied action">
Oct 15 13:04:54 hpl kernel: [963185.177043] type=1400 audit(1318676694.660:2472):
avc: denied { <i>module_request</i> } for pid=14561 comm="firefox" kmod="net-pf-10"
scontext=staff_u:staff_r:mozilla_t tcontext=system_u:system_r:kernel_t <i>tclass=system</i>
</pre>
<p>
Finally, the action that is denied (module_request) and its class (system).
These classes help you to identify what is denied, because a read on a file is
different from a read on a directory.
</p>
<p>
For instance, in the following case, a process <c>gorg</c> with PID 13935 is
trying to read a file called <path>localtime</path> with inode 130867 which
resides on the device <path>/dev/md3</path>:
</p>
<pre caption="AVC denial example">
Oct 15 14:40:30 hpl kernel: [968909.807802] type=1400 audit(1318682430.323:2614):
avc: denied { read } for pid=13935 comm="gorg" name="localtime" dev=md3 ino=130867
scontext=staff_u:sysadm_r:gorg_t tcontext=system_u:object_r:locale_t tclass=file
</pre>
<p>
In this case, it might be obvious that the file is <path>/etc/localtime</path>,
but when that isn't the case, then you can find the following two commands
useful:
</p>
<pre caption="Finding out the target resource based on inode and device">
<comment>(Find out which device /dev/md3 is)</comment>
# <i>mount | grep /dev/md3</i>
/dev/md3 on / type ext4 (rw,seclabel,noatime,barrier=1,nodelalloc,data=journal)
<comment>(Find out what file has inode 130867)</comment>
# <i>find / -xdev -inum 130867</i>
/etc/localtime
</pre>
</body>
</subsection>
<subsection>
<title>Handling AVC denials</title>
<body>
<p>
The major part of configuring SELinux is reading the denials, finding out what
needs to be fixed (or ignored), fix it, and repeat the steps. Hopefully, the
rest of this handbook will help you figure out what is causing a denial.
</p>
<p>
Denials can be cosmetic (an activity that is denied, but has no effect on the
application's functional behaviour). If that is the case, the denial can be
marked as <e>dontaudit</e>, meaning that the denial is not logged by default
anymore. If you think that a denial is occurring but you do not see it in the
logs, try disabling the <e>dontaudit</e> rules:
</p>
<pre caption="Disabling dontaudit">
<comment>(The command can also be abbreviated to "semodule -DB")</comment>
# <i>semodule --build --disable_dontaudit</i>
</pre>
<p>
In most cases though, denials need to be acted upon. Actions that might need to
happen are:
</p>
<ul>
<li>
relabeling the target resource (wrong labels might cause legitimate actions
to be denied)
</li>
<li>
relabeling the source (process' binary file) as a wrong label might cause
the application to run in the wrong domain
</li>
<li>
loading a necessary SELinux module, since the modules contain the rules to
allow (and label) resources. Without the appropriate module loaded, you will
notice denials since no other module gives the necessary grants (allow
statements)
</li>
<li>
granting the right role to the user executing the application. We have
covered users and their roles initially but we will go deeper into this
subject later in the handbook.
</li>
<li>
adding your own SELinux policy statements, most likely because no SELinux
policy module exists for the application you are trying to run
</li>
</ul>
</body>
</subsection>
</section>
<section>
<title>Using (File) Labels</title>
<subsection>
<title>Introduction</title>
<body>
<p>
Within SELinux, access privileges are based on the label given on the
originating part (called the <e>domain</e>) and its target resource. For
instance, a process running in the passwd_t domain wants to read (= privilege)
the file <path>/etc/shadow</path> which is labeled shadow_t (= the target
resource). It comes to no surprise then that the majority of SELinux
administration is (re)labeling the resources correctly (and ensuring their label
stays correct).
</p>
</body>
</subsection>
<subsection>
<title>Getting File Label(s)</title>
<body>
<p>
There are many ways to relabel commands, and none of them are equal to another.
But before we explain this in more detail, let's first take a look at a few file
labels (and how you can query them).
</p>
<p>
In SELinux, labels are given on a file level through the file systems' ability
to keep <e>extended attributes</e>. For SELinux, the attribute is called
<c>security.selinux</c> and can be obtained through <c>getfattr</c>:
</p>
<pre caption="Getting a file's extended attribute for SELinux">
$ <i>getfattr -n security.selinux /etc/hosts</i>
# file: etc/hosts
security.selinux="system_u:object_r:net_conf_t"
</pre>
<p>
Of course, getting the file attribute this way is time consuming and not that
flexible. For this purpose, most important applications (including
<c>coreutils</c>) are made SELinux-aware. These applications mostly use the
<c>-Z</c> option to display the SELinux context information. In case of files,
this means the extended attribute content:
</p>
<pre caption="Getting the context of a file">
$ <i>ls -Z /etc/hosts</i>
system_u:object_r:net_conf_t /etc/hosts
</pre>
<p>
Other commands exist that display the context as it should be, like
<c>matchpathcon</c>. However, their purpose is to query the SELinux policy on
your system to find out what the policy ought to be, not what it is:
</p>
<pre caption="Difference between context and matchpathcon result">
$ <i>ls -Z /etc/make.conf</i>
staff_u:object_r:etc_t /etc/make.conf
$ <i>matchpathcon /etc/make.conf</i>
/etc/make.conf system_u:object_r:portage_conf_t
</pre>
</body>
</subsection>
<subsection>
<title>Setting File Label(s)</title>
<body>
<p>
Now how can you manipulate file labels? Well, first of all: you will not be
allowed to change the file labels of any possible file (not even if you are the
owner of that file) unless the SELinux policy allows you to. These allow rules
are made on two privilege types: which labels are you allowed to change
(<c>relabelfrom</c>) and to which labels are you allowed to change
(<c>relabelto</c>). You can query these rules through <c>sesearch</c>:
</p>
<pre caption="Querying the relabelto/relabelfrom types">
<comment># From which label on files (-c) is user_t (-s) allowed (-A) to relabel from (-p)?</comment>
$ <i>sesearch -s user_t -c file -p relabelfrom -A</i>
<comment>[...]</comment>
allow user_t mozilla_home_t : file { <comment>...</comment> relabelfrom relabelto } ;
</pre>
<p>
If you have the permission, then you can use <c>chcon</c> to <e>ch</e>ange the
<e>con</e>text of a file:
</p>
<pre caption="Changing a file context">
$ <i>ls -Z strace.log</i>
staff_u:object_r:user_home_t strace.log
$ <i>chcon -t mutt_home_t strace.log</i>
$ <i>ls -Z strace.log</i>
staff_u:object_r:mutt_home_t strace.log
</pre>
<p>
If you do not hold the right privileges, you will get a descriptive error
message:
</p>
<pre caption="Trying to change file context">
$ <i>chcon -t shadow_t strace.log</i>
chcon: failed to change context of `strace.log' to `staff_u:object_r:shadow_t': Permission denied
</pre>
<p>
Now, if you now think that <c>chcon</c> is all you need, you're wrong. The
<c>chcon</c> command does nothing more than what it sais - change context. But
when the system relabels files, these changes are gone. Relabeling files is
often done to ensure that the file labels are correct (as in: the labels match
what the SELinux policy sais they ought to be). The SELinux policy contains, for
each policy module, the list of files, directories, sockets, ... and their
appropriate file context (label).
</p>
<p>
We will look at SELinux policy modules later, but below you'll find an excerpt
from such a definition, for the <c>mozilla</c> module:
</p>
<pre caption="Excerpt of the mozilla module file contexts">
/usr/bin/firefox-bin -- gen_context(system_u:object_r:mozilla_exec_t,s0)
/usr/bin/mozilla-[0-9].* -- gen_context(system_u:object_r:mozilla_exec_t,s0)
/usr/bin/mozilla-bin-[0-9].* -- gen_context(system_u:object_r:mozilla_exec_t,s0)
/usr/lib(64)?/galeon/galeon -- gen_context(system_u:object_r:mozilla_exec_t,s0)
/usr/lib(64)?/netscape/.+/communicator/communicator-smotif\.real -- gen_context(system_u:object_r:mozilla_exec_t,s0)
/usr/lib(64)?/netscape/base-4/wrapper -- gen_context(system_u:object_r:mozilla_exec_t,s0)
/usr/lib/[^/]*firefox[^/]*/plugin-container -- gen_context(system_u:object_r:mozilla_plugin_exec_t,s0)
/usr/lib64/[^/]*firefox[^/]*/plugin-container -- gen_context(system_u:object_r:mozilla_plugin_exec_t,s0)
</pre>
<p>
To put the right label on a file, you can use the <c>setfiles</c> or
<c>restorecon</c> commands. Since they are both the same command (but with a
slightly different way of using) we'll only talk about <c>restorecon</c> for now
- more information on the <c>setfiles</c> command can be found in its man page.
</p>
<p>
When you use <c>restorecon</c>, the application will query the SELinux policy to
find out what the right label of the file should be. If it differs, it will
change the label to the right setting. That means that you do not need to
provide the label for a file in order for the command to work. Also,
<c>restorecon</c> supports recursivity, so you do not need to relabel files one
by one.
</p>
<pre caption="Using restorecon">
$ <i>ls -Z /etc/make.conf</i>
staff_u:object_r:etc_t /etc/make.conf
$ <i>restorecon /etc/make.conf</i>
$ <i>ls -Z /etc/make.conf</i>
system_u:object_r:portage_conf_t /etc/make.conf
</pre>
<p>
Finally, Gentoo also provides a useful application: <c>rlpkg</c>. This script
relabels the files of a Gentoo package (<c>rlpkg <packagename></c>) or,
given the right arguments, all files on the file system:
</p>
<pre caption="Using rlpkg">
<comment># Relabel the files of the firefox-bin package:</comment>
# <i>rlpkg firefox</i>
<comment># Relabel all files on the file system:</comment>
# <i>rlpkg -a -r</i>
</pre>
</body>
</subsection>
<subsection>
<title>Overriding the SELinux Policy File Labels</title>
<body>
<p>
You might not always agree with the label that the SELinux policy enforces on
the files: you might have your files located elsewhere (a different location for
your Portage tree is a nice example) or you need to label them differently in
order for other applications to work. To not have to <c>chcon</c> these files
over and over again, you can enhance the SELinux policy on your system with
additional file context rules. These rules are used when you call
<c>restorecon</c> as well and override the rules provided by the SELinux policy.
</p>
<p>
To add additional file context rules, you need to use the <c>semanage</c>
command. This command is used to manage, manipulate and update the local SELinux
policy on your system. In this particular case, we will use the <c>semanage
fcontext</c> command:
</p>
<pre caption="Using semanage to add a file context rule">
<comment># Mark /mnt/gentoo/etc/make.conf as a portage_conf_t type</comment>
# <i>semanage fcontext -a -t portage_conf_t /mnt/gentoo/etc/make.conf</i>
<comment># Mark /mnt/gentoo/usr/portage as portage_ebuild_t</comment>
# <i>semanage fcontext -a -t portage_ebuild_t "/mnt/gentoo/usr/portage(/.*)?"</i>
</pre>
<p>
As you can see from the example, you can use wildcards. But beware about using
wildcards: when a rule holds a wildcard, it has a lower priority than a rule
without a wildcard. And the priority on rules with a wildcard is based on how
"down" the string the first occurance of a wildcard is. For more information,
please check out our <uri link="../selinux-faq.xml#matchcontext">FAQ on "How do
I know which file context rule is used for a particular file?."</uri>
</p>
<p>
If you want to delete a file context definition, you use <c>semanage fcontext
-d</c>:
</p>
<pre caption="Deleting a file context definition">
# <i>semanage fcontext -d -t portage_ebuild_t /mnt/gentoo/etc/make.conf</i>
</pre>
<p>
Finally, to view all file context definitions (both user-set and SELinux policy
provided), you can use <c>semanage fcontext -l</c>. To only see the locally set,
add <c>-C</c>:
</p>
<pre caption="Viewing user-set file context enhancements">
# <i>semanage fcontext -C -l</i>
SELinux fcontext type Context
/opt/xxe/bin/.*\.jar all files system_u:object_r:lib_t
/srv/virt/gentoo(/.*)? all files system_u:object_r:qemu_image_t
</pre>
</body>
</subsection>
<subsection>
<title>Customizable types</title>
<body>
<p>
Labels on files are not that hard to understand, but you might come into some
surprises if you do not know that there are also customizable types.
</p>
<p>
A <e>customizable type</e> is a specific type which is not touched by the
SELinux administration tools by default. If you want to relabel a file that
currently holds a customizable type, you will need to force this through the
commands (such as <c>restorecon -F</c>).
</p>
<p>
There are not that many customizable types by default. The list of types that
SELinux considers as customizable are mentioned in the
<path>customizable_types</path> file within the
<path>/etc/selinux/*/contexts</path> location:
</p>
<pre caption="Listing the customizable types">
# <i>cat /etc/selinux/strict/contexts/customizable_types</i>
mount_loopback_t
public_content_rw_t
public_content_t
swapfile_t
textrel_shlib_t
</pre>
<p>
Such types exist because these types are used for files whose location is known
not to be fixed (and as such, the SELinux policy cannot without a doubt know if
the label on the files is correct or not). The <c>public_content_t</c> one,
which is used for files that are readable by several services (like FTP, web
server, ...), might give you a nice example for such a case.
</p>
<p>
If you look at the <c>restorecon</c> man page, it mentions both customizable
types as well as the user section. The latter is for rules that are identified
in the SELinux policy as being files for an end user, like the following
definitions in the <c>mozilla</c> policy module:
</p>
<pre caption="User section definition within mozilla module">
HOME_DIR/\.mozilla(/.*)? gen_context(system_u:object_r:mozilla_home_t,s0)
HOME_DIR/\.netscape(/.*)? gen_context(system_u:object_r:mozilla_home_t,s0)
HOME_DIR/\.phoenix(/.*)? gen_context(system_u:object_r:mozilla_home_t,s0)
</pre>
<p>
Although in the above example, forcing <c>restorecon</c> on the files is
probably correct, there are examples where you do not want this. For instance,
the firefox policy by default only allows the application to write to
directories labeled <c>mozilla_home_t</c>. If you want to download something,
this isn't possible (unless you download it into <path>~/.mozilla</path>). The
solution there is to label a directory (say <path>~/Downloads</path>) as
<c>mozilla_home_t</c>.
</p>
</body>
</subsection>
</section>
<section>
<title>SELinux Policy and Booleans</title>
<subsection>
<title>Introduction</title>
<body>
<p>
We have dealt with users and labels now, but there is still a third aspect that
we haven't touched: the SELinux policy itself.
</p>
<p>
The SELinux policy as offered by Gentoo Hardened is a carefully tuned SELinux
policy, based on the reference policy (a distribution-agnostic SELinux policy)
with minor changes. Hopefully, you will not need to rewrite the policy to suit
it for your needs, but changes are very likely to occur here and there.
</p>
</body>
</subsection>
<subsection>
<title>Changing the SELinux Policy Behavior: Booleans</title>
<body>
<p>
A common and user friendly way of tweaking the SELinux policy is through
booleans. A <e>SELinux boolean</e>, also known as a conditional, changes how the
SELinux policy behaves based on the setting that the user provides. To make this
a bit more clear, let's look at a few booleans available:
</p>
<pre caption="Getting SELinux booleans">
# <i>getsebool -a | grep ^user</i>
user_direct_mouse --> off
user_dmesg --> off
user_ping --> on
user_rw_noexattrfile --> off
user_tcp_server --> off
user_ttyfile_stat --> off
</pre>
<p>
Although they might not say much on first sight, these booleans alter how the
SELinux policy enforces user activity (hence the booleans starting with
<path>user_</path>). For instance, <c>user_ping</c> is set to <c>on</c>, so a
user is allowed to use <c>ping</c>. If it was set to <c>off</c>, the SELinux
policy would not allow a user to execute <c>ping</c>.
</p>
<p>
Booleans can be toggled on or off using <c>setsebool</c> or <c>togglesebool</c>.
With <c>setsebool</c> you need to give the value (on or off) whereas
<c>togglesebool</c> switches the value.
</p>
<pre caption="Disallowing the use of ping by users">
# <i>setsebool user_ping off</i>
</pre>
<p>
By default, <c>setsebool</c> does not store the boolean values - after a reboot,
the old values are used again. To persist such changes, you need to add the
<c>-P</c> option:
</p>
<pre caption="Persistedly allow users to run dmesg">
# <i>setsebool -P user_dmesg on</i>
</pre>
<p>
Booleans allow administrators to tune the policy, and allow security
administrators to write policies that are flexible enough for a more widespread
use. In terms of Gentoo flexibility, these booleans might not be used enough (it
would be nice to couple these booleans on USE flags, so that a server build with
USE="ldap" gets the SELinux policy to use ldap, whereas USE="-ldap" disallows
it). But still, the use of booleans is a popular method for making a more
flexible SELinux policy.
</p>
</body>
</subsection>
<subsection>
<title>Managing SELinux Policy Modules</title>
<body>
<p>
In this last part, we'll cover SELinux policy modules. We mentioned before that
the SELinux policy used by Gentoo Hardened is based on the reference policy,
which offers a modular approach to SELinux policies. There is one base policy,
which is mandatory on every system and is kept as small as possible. The rest
are SELinux policy modules, usually providing the declarations, rules and file
contexts for a single application (or type of applications).
</p>
<p>
With <c>semodule -l</c> you can see the list of SELinux policy modules loaded:
</p>
<pre caption="Listing the loaded SELinux modules">
# <i>semodule -l</i>
alsa 1.11.0
apache 2.3.0
entropyd 1.6.0
dbus 1.15.0
dnsmasq 1.9.0
<comment>(...)</comment>
</pre>
<p>
Within Gentoo Hardened, each module is provided by the package
<path>sec-policy/selinux-<modulename></path>. For instance, the first
module encountered in the above example is provided by
<path>selinux-alsa</path>:
</p>
<pre caption="The SELinux policy module package in Gentoo">
$ <i>emerge --search selinux-alsa</i>
Searching...
[ Results for search key : selinux-alsa ]
[ Applications found : 1]
* sec-policy/selinux-alsa
Latest version available: 2.20110726
Latest version installed: 2.20110726
Size of files: 574 kB
Homepage: http://www.gentoo.org/proj/en/hardened/selinux/
Description: SELinux policy for alsa
License: GPL-2
</pre>
<p>
If you need a module that isn't installed on your system, this is considered a
bug (packages that need it should depend on the SELinux policy package if the
selinux USE flag is set). But once you install the package yourself, the module
will be loaded automatically:
</p>
<pre caption="Installing a SELinux policy package">
# <i>emerge selinux-screen</i>
</pre>
<p>
If you want to remove a module from your system though, uninstalling the package
will not suffice: the SELinux policy module itself is copied to the policy store
earlier (as part of the installation process) and is not removed from this store
by Portage. Instead, you will need to remove the module manually:
</p>
<pre caption="Uninstalling a SELinux policy module">
# <i>emerge -C selinux-screen</i>
# <i>semodule -r screen</i>
</pre>
</body>
</subsection>
</section>
</sections>
1.1 xml/htdocs/proj/en/hardened/selinux/hb-using-policies.xml
file : http://sources.gentoo.org/viewvc.cgi/gentoo/xml/htdocs/proj/en/hardened/selinux/hb-using-policies.xml?rev=1.1&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo/xml/htdocs/proj/en/hardened/selinux/hb-using-policies.xml?rev=1.1&content-type=text/plain
Index: hb-using-policies.xml
===================================================================
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE sections SYSTEM "/dtd/book.dtd">
<!-- The content of this document is licensed under the CC-BY-SA license -->
<!-- See http://creativecommons.org/licenses/by-sa/1.0 -->
<!-- $Header: /var/cvsroot/gentoo/xml/htdocs/proj/en/hardened/selinux/hb-using-policies.xml,v 1.1 2011/10/23 13:00:13 swift Exp $ -->
<sections>
<version>1</version>
<date>2011-10-15</date>
<section>
<title>SELinux Policy Language</title>
<subsection>
<title>Introduction</title>
<body>
<p>
By default, Gentoo provides a generic, yet tightly controlled policy which is
deemed a good start policy for the majority of users. However, the purpose
behind a Mandatory Access Control system is to put the security administrator in
control. As such, a handbook on SELinux without information on how to write
policies wouldn't be complete.
</p>
<p>
In this chapter, we'll talk a bit about the language behind SELinux policies and
give some pointers on how to create your own policies, roles, etc.
</p>
</body>
</subsection>
<subsection>
<title>Building a SELinux Module</title>
<body>
<p>
First, before we go into the art of SELinux policy writing, let's first make a
small SELinux module with a rule we can test, build the module and see if things
work. Although these steps are fairly easy, they are important nonetheless.
Modifying the SELinux policy as offered by Gentoo is best done through
additional SELinux policy modules. Only when the core policy (the base policy)
is not to your liking should you see on using a totally different policy.
</p>
<p>
Let's start with a skeleton for a policy module we'll call <e>testmod</e>.
</p>
<pre caption="Policy module skeleton">
policy_module(testmod, 1.0.0)
</pre>
<p>
Yes, that's it. But as you can see, it is fairly empty. So let's add a rule that
allows a regular user (in the user_t domain) to read ebuild files (of type
portage_ebuild_t).
</p>
<pre caption="Policy module testmod">
policy_module(testmod, 1.0.0)
require {
type user_t;
type portage_ebuild_t;
class file { read open getattr };
class dir { read search open getattr };
}
allow user_t portage_ebuild_t:file { read open getattr };
allow user_t portage_ebuild_t:dir { read search open getattr };
</pre>
<p>
As you can see, something as simple as allowing a user to read a file requires
quite a few privileges. The directory privileges are needed to allow a user to
navigate through the Portage tree structure whereas the file privileges are
needed for a user to be able to access and open the ebuilds. Save this file as
<path>testmod.te</path>.
</p>
<p>
To build the policy and convert it into the binary module that we can load into
the SELinux policy store, we can use the <path>Makefile</path> available in
<path>/usr/share/selinux/strict/include</path> (substitute strict with the
SELinux policy type you are using).
</p>
<pre caption="Building a binary policy module">
$ <i>make -f /usr/share/selinux/struct/include/Makefile testmod.pp</i>
</pre>
<p>
The filename (<path>testmod.pp</path>) is the destination binary SELinux module
name. The <path>Makefile</path> will automatically look for the
<path>testmod.te</path> file you have in the working directory.
</p>
<p>
As a result, you should now have a file called <path>testmod.pp</path>. This
module file can now be loaded in the SELinux policy store as follows:
</p>
<pre caption="Loading a binary module">
# <i>semodule -i /path/to/testmod.pp</i>
</pre>
<p>
Congratulations! You have now build your first SELinux policy module. If you
want to disable it, remove it through <c>semodule -r testmod</c>.
</p>
<p>
This method of building a policy (using the <path>Makefile</path> and
<c>semodule</c>) is something that you will need to do every time you want to
update the SELinux policy on your system. The contents of the policy however
does change as we will see in the rest of this document.
</p>
</body>
</subsection>
<subsection>
<title>Getting the SELinux Policy Interfaces</title>
<body>
<p>
To streamline policy development, the SELinux policy based on the reference
policy uses interfaces to access privileges within a module. If you have built
<path>selinux-base-policy</path> with <c>USE="doc"</c> then this information is
available at
<path>/usr/share/doc/selinux-base-policy-<version>/html</path>. It is
recommended to have this information at hand, since most policy
development/updates will be done through the interfaces offered by the policy.
</p>
<p>
If you are just interested, you can also find these interface definitions <uri
link="http://oss.tresys.com/docs/refpolicy/api/">online</uri>. Mind you though,
the online resource is only the reference policy and might differ a bit from the
policy available within Gentoo.
</p>
</body>
</subsection>
<subsection>
<title>Using Policy Interfaces</title>
<body>
<p>
Using the policy interfaces allows you to update the policy with more readable
functions. For instance, to allow the user_t domain to call and use Portage
applications, the module could look like so:
</p>
<pre caption="Example policy to allow user_t to use portage">
policy_module(testmod, 1.0.0)
require {
type user_t;
role user_r;
}
portage_run(user_t, user_r)
</pre>
<p>
Of course, this makes the user_t domain much more privileged than the previously
defined rules to read ebuild files: it allows the user to call portage, update
the system, etc. Of course, the user still requires the proper regular Linux
permissions (so he needs to be part of the portage group or become root).
Needless to say, we do not recommend to grant this to a regular user ;-)
</p>
</body>
</subsection>
</section>
<section>
<title>Full SELinux Policy Modules</title>
<subsection>
<title>Checking Out an Isolated Module</title>
<body>
<p>
With the above in mind, we can now go one step further and investigate a full
policy module, with both the type enforcement rules (<path>.te</path> file),
file contexts (<path>.fc</path>) and interfaces (<path>.if</path>).
</p>
<p>
You should know that writing a module requires you to get intimate with the
application. It isn't a matter of just hoping for the best: as a security
administrator, you will be responsible for defining what accesses are allowed
and which not. If you forget one, the application might break under the users'
hands. But if you add too much, you might grant privileges that can be abused
later on. And it will be a lot more difficult to track and remove privileges
later as you will be hesitating if the privilege is needed or not.
</p>
<p>
In this section, we will not divulge in how to write one. We have an excellent
<uri link="/proj/en/hardened/selinux-development.xml">Gentoo Hardened SELinux
Development</uri> resource that guides you in that. However, we will look into
such a full module to explain the other aspects of policy development.
</p>
</body>
</subsection>
<subsection>
<title>Type Enforcement File</title>
<body>
<p>
The <path>.te</path> file we wrote earlier is a <e>type enforcement file</e>.
Its purpose is to define the access rules related to the module that you are
building, but also - and more importantly - define new types (or even roles).
</p>
<p>
The example below is a snippet from a module for the skype application.
</p>
<pre caption="Snippet from skype.te">
policy_module(skype, 1.0.0)
type skype_t;
type skype_exec_t;
application_domain(skype_t, skype_exec_t)
type skype_home_t;
userdom_user_home_content(skype_home_t)
manage_dirs_pattern(skype_t, skype_home_t, skype_home_t)
manage_files_pattern(skype_t, skype_home_t, skype_home_t)
</pre>
<p>
In the above example, three new types are declared: <c>skype_t</c> (which will
be used for the application), <c>skype_exec_t</c> (which is the label given to
the application binary) and <c>skype_home_t</c> (which will be used for the
users' <path>~/.Skype</path> location). Also, the <c>skype_t</c> domain is given
some privileges with respect to the <c>skype_home_t</c> label (manage
directories and files).
</p>
</body>
</subsection>
<subsection>
<title>File Context File</title>
<body>
<p>
In the <path>.fc</path> file (which stands for <e>file context file</e>) the
module's resources (files, directories, sockets, ...) are defined. Once the
module is loaded, these rules are added so that file system relabeling will put
the correct context on the files.
</p>
<p>
The example below is a snippet from the skype modules' file context file.
</p>
<pre caption="Snippet from skype.fc">
HOME_DIR/\.Skype(/.*)? gen_context(system_u:object_r:skype_home_t,s0)
/opt/skype/skype -- gen_context(system_u:object_r:skype_exec_t,s0)
/usr/bin/skype -- gen_context(system_u:object_r:skype_exec_t,s0)
</pre>
<p>
The format of the file context file has the following syntax:
</p>
<ol>
<li>
The regular expression that matches the file(s) and directorie(s) affected
by that line
</li>
<li>
An optional identifier to differentiate the type of files (file, directory,
socket, symbolic link, ...)
</li>
<li>
A <c>gen_context</c> line that contains the context to assign to the file(s)
and directorie(s)
</li>
</ol>
</body>
</subsection>
<subsection>
<title>Interface File</title>
<body>
<p>
In the <path>.if</path> file (for <e>interface file</e>) interfaces are declared
which can be used by other modules. It is through interfaces that a nicely
defined policy can be built on top of other, existing policy modules.
</p>
<p>
One interface could be to allow users to call and execute an application. For
instance, the following interface can be found in the skype module.
</p>
<pre caption="Snippet from skype.if">
interface(`skype_role',`
gen_require(`
type skype_t, skype_exec_t, skype_tmpfs_t, skype_home_t;
')
role $1 types skype_t;
domtrans_pattern($2, skype_exec_t, skype_t)
allow $2 skype_t:process { ptrace signal_perms };
manage_dirs_pattern($2, skype_home_t, skype_home_t)
manage_files_pattern($2, skype_home_t, skype_home_t)
manage_lnk_files_pattern($2, skype_home_t, skype_home_t)
relabel_dirs_pattern($2, skype_home_t, skype_home_t)
relabel_files_pattern($2, skype_home_t, skype_home_t)
relabel_lnk_files_pattern($2, skype_home_t, skype_home_t)
ps_process_pattern($2, skype_t)
')
</pre>
<p>
Through this <c>skype_role</c>, we can then allow users to call skype, as can be
found in the <path>unprivuser.te</path> file (which defines the user_t domain):
</p>
<pre caption="Snippet from unprivuser.te to call skype">
optional_policy(`
skype_role(user_r, user_t)
')
</pre>
</body>
</subsection>
</section>
<section>
<title>Using audit2allow</title>
<subsection>
<title>Introduction</title>
<body>
<p>
When reading online resources on SELinux, you will notice that there are many
references to a tool called <c>audit2allow</c>. This tools' purpose is to read
AVC denial messages from the audit log file and transform them into a policy
module that you can load. The advantage is that it makes it a lot easier to
write policies. The downside is that the output (unless you use the <c>-R</c>
option) is not usable for the <path>Makefile</path> we used earlier to build
modules.
</p>
<p>
Another disadvantage is that the tool does not intelligently cope with changes.
It blindly accepts denials and treats them as if they need to be allowed, rather
than investigate if no other context should be given to the file, etc.
</p>
</body>
</subsection>
<subsection>
<title>Using audit2allow</title>
<body>
<p>
Using <c>audit2allow</c> is pretty straightforward. You send it the denials you
want to fix and store the result in a <path>.te</path> file. You then convert it
into an intermediary format which can then be translated into a <path>.pp</path>
file for final loading by <c>semodule</c>.
</p>
<p>
For instance, to catch all denials and transform them into allowed statements
from firefox-related denials:
</p>
<pre caption="Generate a new policy using audit2allow">
# <i>grep firefox /var/log/avc.log | audit2allow -m firefoxmod > firefoxmod.te</i>
# <i>checkmodule -m -o firefoxmod.mod firefoxmod.te</i>
# <i>semodule_package -o firefoxmod.pp -m firefoxmod.mod</i>
# <i>semodule -i firefoxmod.pp</i>
</pre>
</body>
</subsection>
</section>
</sections>
1.1 xml/htdocs/proj/en/hardened/selinux/hb-using-states.xml
file : http://sources.gentoo.org/viewvc.cgi/gentoo/xml/htdocs/proj/en/hardened/selinux/hb-using-states.xml?rev=1.1&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo/xml/htdocs/proj/en/hardened/selinux/hb-using-states.xml?rev=1.1&content-type=text/plain
Index: hb-using-states.xml
===================================================================
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE sections SYSTEM "/dtd/book.dtd">
<!-- The content of this document is licensed under the CC-BY-SA license -->
<!-- See http://creativecommons.org/licenses/by-sa/1.0 -->
<!-- $Header: /var/cvsroot/gentoo/xml/htdocs/proj/en/hardened/selinux/hb-using-states.xml,v 1.1 2011/10/23 13:00:13 swift Exp $ -->
<sections>
<version>1</version>
<date>2011-10-15</date>
<section>
<title>SELinux States</title>
<subsection>
<title>Introduction</title>
<body>
<p>
When SELinux is available, it will generally be in one of three states on your
system: disabled, permissive or enforcing.
</p>
</body>
</subsection>
<subsection>
<title>Disabled</title>
<body>
<p>
When <c>getenforce</c> returns "Disabled", then SELinux is not running on your
system. Even though it might be built in your kernel, it is definitely disabled.
Your system will still run with regular discretionary access controls (the usual
permission rules for standard Linux environments) but the mandatory access
controls are not active.
</p>
<p>
When SELinux is disabled, it also means that files, directories, etc that are
modified or created will not get the proper SELinux context assigned to them.
When you later start your system with SELinux enabled (permissive or enforcing),
issues will arise since the SELinux subsystem will not know which label the
files have (it will default the label to one that is not accessible by most
domains).
</p>
<p>
The best way to go forward in such case is to boot in permissive mode and then
relabel the entire file system:
</p>
<pre caption="Relabeling the entire file system">
# <i>rlpkg -a -r</i>
</pre>
</body>
</subsection>
<subsection>
<title>Permissive</title>
<body>
<p>
When SELinux is enabled in permissive mode (<c>getenforce</c> returns
"Permissive"), then SELinux is enabled and it has a policy loaded. Every access
a process makes is checked against the policy rules and, if an access is not
allowed, it will be logged (unless the denial is marked as dontaudit) but it
will <e>not</e> be prohibited.
</p>
<p>
The permissive mode is perfect to get acquainted with SELinux and have the
system made ready for future "enforcing" mode. While running in permissive mode,
applications <e>that are not SELinux aware</e> will behave as if SELinux is not
running. This is perfect to validate if a problem is caused by SELinux or not:
if in permissive mode the problem still persists, then it is not caused by
SELinux.
</p>
<p>
There is one caveat though: if the application is <e>SELinux-aware</e> (it knows
that it can run in a SELinux environment and is able to make SELinux-specific
calls) it might still react differently. Although this is often (but not always)
a bad programming practice, some applications check if SELinux is enabled and
base their functional flow on the results, regardless of the state being
permissive or enforcing.
</p>
<p>
To find out if an application is SELinux aware, simply check if it is linked
against libselinux (with <c>ldd</c> or <c>scanelf</c> - part of
<path>app-misc/pax-utils</path>):
</p>
<pre caption="Checking if /bin/ls is SELinux-aware">
# <i>scanelf -n /bin/ls</i>
TYPE NEEDED FILE
ET_DYN libselinux.so.1,librt.so.1,libc.so.6 /bin/ls
</pre>
</body>
</subsection>
<subsection>
<title>Enforcing</title>
<body>
<p>
If <c>getenforce</c> returns "Enforcing", then SELinux is loaded and will act
based on the policy. When a process tries some activity that is not allowed by
the policy, it will be logged (unless a dontaudit is set) and the activity will
not go through. This is the only mode where you can truely say that SELinux is
active, because it is only now that the policy is acted upon.
</p>
</body>
</subsection>
<subsection>
<title>Switching States</title>
<body>
<p>
Depending on your Linux kernel configuration, you can switch between states
using one of the following methods. The kernel configuration however can be made
so that some of these options are disabled (for instance, a fully hardened
system will not allow disabling SELinux in any way).
</p>
<p>
Using the command <c>setenforce</c>:
</p>
<pre caption="Switching between enforcing and permissive">
<comment>(Switching to permissive mode)</comment>
# <i>setenforce 0</i>
<comment>(Switching to enforcing mode)</comment>
# <i>setenforce 1</i>
</pre>
<p>
Using the kernel boot option <c>enforcing</c>:
</p>
<pre caption="Switching between enforcing and permissive through boot options">
<comment>(The following GRUB kernel line would boot in permissive mode)</comment>
kernel /kernel-2.6.39-hardened-r8 root=/dev/md3 rootflags=data=journal <i>enforcing=0</i>
</pre>
<p>
Using the <path>/etc/selinux/config</path> <c>SELINUX</c> variable:
</p>
<pre caption="/etc/selinux/config SELINUX setting">
# <i>cat /etc/selinux/config</i>
# This file controls the state of SELinux on the system on boot.
# SELINUX can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
<i>SELINUX=enforcing</i>
# SELINUXTYPE can take one of these four values:
# targeted - Only targeted network daemons are protected.
# strict - Full SELinux protection.
# mls - Full SELinux protection with Multi-Level Security
# mcs - Full SELinux protection with Multi-Category Security
# (mls, but only one sensitivity level)
SELINUXTYPE=strict
</pre>
<p>
When you want to switch from permissive to enforcing, it is recommended to do so
in the order given above:
</p>
<ol>
<li>
First boot up in permissive mode, log on, verify that your context is
correct (<c>id -Z</c>) and then switch to enforcing (<c>setenforce 1</c>).
You can now test if your system is still working properly.
</li>
<li>
Next, boot with <c>enforcing=1</c> as kernel parameter. This way, your
system will boot in enforcing mode, but if things go haywire, you can just
reboot, leave out the option and be back in permissive mode
</li>
<li>
Finally, edit <path>/etc/selinux/config</path> to persist this change.
</li>
</ol>
</body>
</subsection>
</section>
<section>
<title>SELinux Policy Types</title>
<subsection>
<title>Introduction</title>
<body>
<p>
Next to the SELinux state, SELinux also offers different policy types. These
types differentiate themselves in specific SELinux features that are enabled or
disabled. Within Gentoo, three are supported (and a fourth is available):
<c>targeted</c>, <c>strict</c>, <c>mcs</c> (and <c>mls</c>).
</p>
<p>
The type used on a system is declared in <path>/etc/selinux/config</path>:
</p>
<pre caption="The SELINUXTYPE information in /etc/selinux/config">
# <i>cat /etc/selinux/config</i>
# This file controls the state of SELinux on the system on boot.
# SELINUX can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=enforcing
# SELINUXTYPE can take one of these four values:
# targeted - Only targeted network daemons are protected.
# strict - Full SELinux protection.
# mls - Full SELinux protection with Multi-Level Security
# mcs - Full SELinux protection with Multi-Category Security
# (mls, but only one sensitivity level)
<i>SELINUXTYPE=strict</i>
</pre>
</body>
</subsection>
<subsection>
<title>strict (without unconfined domains)</title>
<body>
<p>
The <c>strict</c> policy type is the policy type that was described in the
earlier chapters, and coincidentally the type that is the easiest to understand.
With the strict policy type, each and every application runs in a domain that
has limited privileges. Although there are highly privileged domains, they are
never truely unlimited in their privileges.
</p>
</body>
</subsection>
<subsection>
<title>targeted (using unconfined domains)</title>
<body>
<p>
The <c>targeted</c> policy type is similar to the strict one, with one major
addition: support for unconfined domains. Applications (or users) that run in an
unconfined domain are almost unlimited in their privileges. The unconfined
domains are usually used for users and user applications, but also the init
system and other domains are marked as "unconfined" domains.
</p>
<p>
The idea behind the targeted policy is that network-facing services are running
in (confined) regular domains whereas the rest uses the standard discretionary
access controls offered by Linux. These other domains are running as
"unconfined".
</p>
</body>
</subsection>
<subsection>
<title>mcs (using multiple categories)</title>
<body>
<p>
The introduction of <c>mls</c> and <c>mcs</c> offers the ability for
<e>multi-tenancy</e>: multiple instances of the same application should be able
to run, but each instance should be confined with respect to the others (instead
of all these processes running in the same domain and, hence, the same
privileges).
</p>
<p>
A simple example is virtualization: a virtual guest which runs in the
<c>qemu_t</c> domain needs write privileges on the image file that contains the
guest operating system. However, if you run two guests, you do not want each
guest to write to the other guests' file. With regular domains, you will need to
provide this. With <c>mcs</c>, you can give each running instance a specific
category (number) and only grant it write privileges to the guest file with the
correct category (number).
</p>
</body>
</subsection>
<subsection>
<title>mls (using multiple security levels)</title>
<body>
<p>
The <c>mls</c> policy type is available but not yet supported by Gentoo
Hardened. With this policy type, it is possible to give sensitivity levels on
files and resources as well as domains. Sensitivity levels can best be expressed
in terms of <e>public</e>, <e>private</e>, <e>confidential</e> or <e>strictly
confidential</e>. With MLS, you can mark a file as one (or a set of)
sensitivity level(s) and ensure that only domains with the right sensitivity
level can access it.
</p>
</body>
</subsection>
<subsection>
<title>Switching Types</title>
<body>
<p>
It is not recommended to switch between types often. At best, you choose your
policy type at install type and stick with it. But it is not impossible (nor
that hard) to switch between types.
</p>
<p>
First, you need to edit <path>/etc/selinux/config</path> so that it both
switches the policy type as well as put the mode in <e>permissive</e>. This is
necessary, since at your next reboot, many labels might (or will) be incorrect.
</p>
<p>
Next, edit <path>/etc/fstab</path> and make sure that the domains you use there
are updated accordingly. For instance, the line for <path>/tmp</path>:
</p>
<pre caption="Changing /etc/fstab">
<comment># Example when switching from strict to mcs</comment>
tmpfs /tmp tmpfs defaults,noexec,nosuid,rootcontext=system_u:object_r:tmp_t<i>:c0</i> 0 0
</pre>
<p>
When this is done, reboot your system. Log on as root, and relabel your entire
file system using <c>rlpkg -a -r</c>. Finally, reboot again and then validate if
your context (such as when logged on as a user) is correct again. Once you are
confident that the domains and contexts are correct, switch the SELinux policy
mode back to "enforcing".
</p>
</body>
</subsection>
</section>
</sections>
1.1 xml/htdocs/proj/en/hardened/selinux/hb-using-troubleshoot.xml
file : http://sources.gentoo.org/viewvc.cgi/gentoo/xml/htdocs/proj/en/hardened/selinux/hb-using-troubleshoot.xml?rev=1.1&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo/xml/htdocs/proj/en/hardened/selinux/hb-using-troubleshoot.xml?rev=1.1&content-type=text/plain
Index: hb-using-troubleshoot.xml
===================================================================
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE sections SYSTEM "/dtd/book.dtd">
<!-- The content of this document is licensed under the CC-BY-SA license -->
<!-- See http://creativecommons.org/licenses/by-sa/1.0 -->
<!-- $Header: /var/cvsroot/gentoo/xml/htdocs/proj/en/hardened/selinux/hb-using-troubleshoot.xml,v 1.1 2011/10/23 13:00:13 swift Exp $ -->
<sections>
<version>0</version>
<date>2011-02-24</date>
<section>
<title>Unable To Load SELinux Policy</title>
<subsection>
<title>Problem Description</title>
<body>
<p>
If you notice that SELinux is not functioning at all, a quick run of
<c>sestatus</c> should give you closure if SELinux is enabled and loaded or not.
If you get the following output, no SELinux policy is loaded:
</p>
<pre caption="sestatus output">
SELinux status: disabled
</pre>
<p>
If this is the case, read on in this section to find out how to troubleshoot and
resolve this.
</p>
</body>
</subsection>
<subsection>
<title>No Policy Installed</title>
<body>
<p>
One potential reason would be that there is no policy to load to begin with.
Take a look inside <path>/usr/share/selinux/strict</path> or
<path>/usr/share/selinux/targeted</path> (depending on your configuration) and
look for a file called <path>base.pp</path>. If no such file exists, you will
need to install the base policy. This policy is offered by the
<path>sec-policy/selinux-base-policy</path> package, but it is better to read up
on the chapter regarding <uri link="?part=2&chap=1">Gentoo SELinux
Installation / Conversion</uri> as more important changes might be missing.
</p>
</body>
</subsection>
<subsection>
<title>Policy Not Loaded</title>
<body>
<p>
If the <path>base.pp</path> file exists in
<path>/usr/share/selinux/strict</path> (or <path>targeted/</path>), take a look
inside <path>/etc/selinux/strict/policy</path>. This location too should contain
a <path>base.pp</path> policy module (when a SELinux policy is loaded, it is
copied from the first location to the second).
</p>
<p>
If no <path>base.pp</path> file exists, install and load the policy:
</p>
<pre caption="Installing the base policy">
~# <i>semodule -n -B</i>
</pre>
<p>
This is a one-time operation - once installed and loaded, it will be reloaded
upon every reboot.
</p>
</body>
</subsection>
<subsection>
<title>Init Can Not Load the SELinux Policy</title>
<body>
<p>
During system boot, the <c>init</c> process is responsible for loading and
interacting with the SELinux policy in memory. If <c>init</c> does not support
SELinux, you will get no SELinux support in your environment.
</p>
<p>
To verify if <c>init</c> supports SELinux, we need to check if it uses the
<path>libselinux.so</path> shared object:
</p>
<pre caption="Checking if init supports SELinux">
~# <i>ldd /sbin/init</i>
linux-vdso.so.1 => (0x00006ace30e84000)
<comment>( You should see something similar to the following line: )</comment>
libselinux.so.1 => /lib/libselinux.so.1 (0x00006ace30a46000)
libc.so.6 => /lib/libc.so.6 (0x00006ace306e9000)
libdl.so.2 => /lib/libdl.so.2 (0x00006ace304e5000)
/lib64/ld-linux-x86-64.so.2 (0x00006ace30c68000)
</pre>
<p>
If this is not the case, make sure that <c>emerge --info</c> shows that the
selinux USE flag is in place, and reinstall <path>sys-apps/sysvinit</path>. If
the selinux USE flag is not in place, check your Gentoo profile and make sure it
points to a <path>selinux/v2refpolicy/...</path> profile.
</p>
</body>
</subsection>
</section>
<section>
<title>Unable to Log On</title>
<subsection>
<title>Problem Description</title>
<body>
<p>
If you are unable to log on in a particular situation (remote, local, as root,
as regular user, ...) there are a few possible problems which you might have
hit. However, to resolve them you'll need to be able to log on to the system as
<e>sysadm_r</e> in one way or the other.
</p>
<p>
If you can not log in as a <e>sysadm_r</e> user, disable SELinux (boot with
<c>enforcing=0</c>) so that no SELinux enforcements are made. Changes that you
make in permissive mode are equally effective as in enforcing mode.
</p>
</body>
</subsection>
<subsection>
<title>Incorrect Context</title>
<body>
<p>
In the majority of cases will you find that a security context is incorrect. Run
<c>sestatus -v</c> and compare the <e>Process contexts</e> or <e>File
contexts</e> that you see in the output with the next table.
</p>
<table>
<tr>
<th>Process</th>
<th>Context</th>
<th>If wrong context...</th>
</tr>
<tr>
<ti>Init context</ti>
<ti>system_u:system_r:init_t</ti>
<ti>
First, verify that init itself is correclty labeled. Check the output of
the previously run <c>sestatus -v</c> command for the
<path>/sbin/init</path> file and make sure that it is set to
system_u:object_r:init_exec_t. If that is not the case, relabel
<path>sys-apps/sysvinit</path> using <c>rlpkg sysvinit</c>. Also make the
same checks as in the <uri link="#doc_chap1">Unable To Load SELinux
Policy</uri> section. Reboot your system and retry.
</ti>
</tr>
<tr>
<ti>agetty context</ti>
<ti>system_u:system_r:getty_t</ti>
<ti>
Make sure that the <path>/sbin/agetty</path> binary is labeled
system_u:object_r:getty_exec_t. If not, relabel the
<path>sys-apps/util-linux</path> package using <c>rlpkg util-linux</c>. Then
restart all the agetty processes using <c>pkill agetty</c> (they will
automatically respawn).
</ti>
</tr>
<tr>
<th>File</th>
<th>Context</th>
<th>If wrong context...</th>
</tr>
<tr>
<ti>/bin/login</ti>
<ti>system_u:object_r:login_exec_t</ti>
<ti>
The login binary is part of <path>sys-apps/shadow</path>. Run <c>rlpkg
shadow</c> to relabel the files of that package and retry logging in.
</ti>
</tr>
<tr>
<ti>/sbin/unix_chkpwd</ti>
<ti>system_u:object_r:chkpwd_exec_t</ti>
<ti>
This binary is part of the <path>sys-libs/pam</path> package and is used by
SSH when it is configured to use PAM for user authentication. Relabel the
package using <c>rlpkg pam</c> and retry logging in.
</ti>
</tr>
<tr>
<ti>/etc/passwd</ti>
<ti>system_u:object_r:etc_t</ti>
<ti rowspan="2">
The <path>/etc/passwd</path> and <path>/etc/shadow</path> must be labeled
correctly, otherwise PAM will not be able to authenticate any user. Relabel
the files through <c>restorecon /etc/passwd /etc/shadow</c> and retry
logging in.
</ti>
</tr>
<tr>
<ti>/etc/shadow</ti>
<ti>system_u:object_r:shadow_t</ti>
</tr>
<tr>
<ti>/bin/bash</ti>
<ti>system_u:object_r:shell_exec_t</ti>
<ti>
The users' shell (in this case, <c>bash</c>) must be labeled correctly so
the user can transition into the user domain when logging in. To do so,
relabel the <path>app-shells/bash</path> package using <c>rlpkg bash</c>.
Then, try logging in again.
</ti>
</tr>
</table>
</body>
</subsection>
</section>
</sections>
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2011-10-23 13:01 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-10-23 13:00 [gentoo-commits] gentoo commit in xml/htdocs/proj/en/hardened/selinux: hb-intro-resources.xml hb-using-configuring.xml hb-using-policies.xml hb-using-states.xml hb-using-troubleshoot.xml Sven Vermeulen (swift)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox