commit 0d2462d4c0297bdd7192a121094d43da02367733
Author: Barbora Ancincova <bancinco(a)redhat.com>
Date: Sun Aug 10 22:31:26 2014 +0200
Added a section about systemd access control.
en-US/Security_Guide.xml | 1 +
en-US/Systemd_Access_Control.xml | 629 ++++++++++++++++++++++++++++++++++++++
2 files changed, 630 insertions(+), 0 deletions(-)
---
diff --git a/en-US/Security_Guide.xml b/en-US/Security_Guide.xml
index c468cba..ba9b989 100644
--- a/en-US/Security_Guide.xml
+++ b/en-US/Security_Guide.xml
@@ -28,6 +28,7 @@
<xi:include href="Managing_Users.xml"
xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include>
<xi:include href="SVirt.xml"
xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include>
<xi:include href="Secure_Linux_Containers.xml"
xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include>
+ <xi:include href="Systemd_Access_Control.xml"
xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include>
<xi:include href="Troubleshooting.xml"
xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include>
<xi:include href="Further_Information.xml"
xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include>
diff --git a/en-US/Systemd_Access_Control.xml b/en-US/Systemd_Access_Control.xml
new file mode 100644
index 0000000..ab8d609
--- /dev/null
+++ b/en-US/Systemd_Access_Control.xml
@@ -0,0 +1,629 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+
+<section id="chap-Security-Enhanced_Linux-Systemd_Access_Control">
+ <title>SELinux <systemitem>systemd</systemitem> Access
Control</title>
+
+ <para>
+ In current version of &PRODUCT;, system services are controlled by the
<systemitem class="daemon">systemd</systemitem> daemon. In previous
releases, daemons could be started in two ways:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ At boot time, the System V <systemitem>init</systemitem> daemon launched
an <systemitem>init.rc</systemitem> script and then this script launched the
desired daemon. For example, the Apache server, which was started at boot, got the
following SELinux label:
+ </para>
+
+ <screen>system_u:system_r:httpd_t:s0</screen>
+ </listitem>
+ <listitem>
+ <para>
+ An administrator launched the <systemitem>init.rc</systemitem> script
manually, causing the daemon to run. For example, when the <command>systemctl
restart httpd.service</command> command was invoked on the Apache server, the
resulting SELinux label looked as follows:
+ </para>
+
+ <screen>unconfined_u:system_r:httpd_t:s0</screen>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ When launched manually, the process adopted the user portion of the SELinux label that
started it, making the labeling in the two scenarios above inconsistent. With the
<systemitem class="daemon">systemd</systemitem> daemon, the
transitions are very different. As <systemitem
class="daemon">systemd</systemitem> handles all the calls to start and
stop daemons on the system, using the <systemitem>init_t</systemitem> type, it
can override the user part of the label when a daemon is restarted manually. As a result,
the labels in both scenarios above are
<literal>system_u:system_r:httpd_t:s0</literal> as expected and the SELinux
policy could be improved to govern which domains are able to control which units.
+
+ <!-- <remark>expand this description?</remark>
+
+ init_t @ httpd_exec_t -> httpd_t
+ system_u:system_r:httpd_t:s0
+
+ But if you want to restart the Apache daemon as admin you now do.
+ unconfined_t === init_t @ httpd_exec_t -> httpd_t
+ system_u:system_r:httpd_t:s0
+ -->
+ </para>
+
+ <section id="sec-systemd_Access_Control-new_access_class">
+
+ <title>SELinux Access Permissions for Services</title>
+
+ <para>
+ In previous versions of &PRODUCT;, an administrator was able to control, which
users or applications were able to start or stop services based on the label of the System
V Init script. Now, <systemitem class="daemon">systemd</systemitem>
starts and stops all services, and users and processes communicate with <systemitem
class="daemon">systemd</systemitem> using the
<systemitem>systemctl</systemitem> utility. The <systemitem
class="daemon">systemd</systemitem> daemon has the ability to consult
the SELinux policy and check the label of the calling process and the label of the unit
file that the caller tries to manage, and then ask SELinux whether or not the caller is
allowed the access. This approach strengthens access control to critical system
capabilities, which include starting and stopping system services.
+ </para>
+
+ <para>
+ For example, previously, administrators had to allow NetworkManager to execute
<systemitem>systemctl</systemitem> to send a D-Bus message to <systemitem
class="daemon">systemd</systemitem>, which would in turn start or stop
whatever service NetworkManager requested. In fact, NetworkManager was allowed to do
everything <systemitem>systemctl</systemitem> could do. It was also impossible
to setup confined administrators so that they could start or stop just particular
services.
+ </para>
+ <!-- We could no longer allow the webadm_t to only start/stop httpd_t. -->
+
+ <para>
+ To fix these issues, <systemitem
class="daemon">systemd</systemitem> also works as an SELinux Access
Manager. It can retrieve the label of the process running
<systemitem>systemctl</systemitem> or the process that sent a D-Bus message to
<systemitem class="daemon">systemd</systemitem>. The daemon then
looks up the label of the unit file that the process wanted to configure. Finally,
<systemitem class="daemon">systemd</systemitem> can retrieve
information from the kernel if the SELinux policy allows the specific access between the
process label and the unit file label. This means a compromised application that needs to
interact with <systemitem class="daemon">systemd</systemitem> for a
specific service can now be confined via SELinux. Policy writers can also use these
fine-grained controls to confine administrators. Policy changes involve a new class called
<literal>service</literal>, with the following permissions:
+ </para>
+
+ <screen>
+class service
+{
+ start
+ stop
+ status
+ reload
+ kill
+ load
+ enable
+ disable
+}
+ </screen>
+
+ <para>
+ For example, a policy writer can now allow a domain to get the status of a service or
start and stop a service, but not enable or disable a service. Access control operations
in SELinux and <systemitem class="daemon">systemd</systemitem> do
not match in all cases. A mapping was defined to line up <systemitem
class="daemon">systemd</systemitem> method calls with SELinux access
checks. <xref linkend="tab-systemd-unit-methods" /> maps access checks on
unit files while <xref linkend="tab-systemd-system-methods" /> covers
access checks for the system in general. If no match is found in either table, then the
<literal>undefined</literal> system check is called.
+ </para>
+
+
+ <table id="tab-systemd-unit-methods">
+ <title>Mapping of systemd unit file method calls on SELinux access
checks</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>
+ <systemitem class="daemon">systemd</systemitem> unit file
method
+ </entry>
+ <entry>
+ SELinux access check
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ DisableUnitFiles
+ </entry>
+ <entry>
+ disable
+ </entry>
+ </row>
+ <row>
+ <entry>
+ EnableUnitFiles
+ </entry>
+ <entry>
+ enable
+ </entry>
+ </row>
+ <row>
+ <entry>
+ GetUnit
+ </entry>
+ <entry>
+ status
+ </entry>
+ </row>
+ <row>
+ <entry>
+ GetUnitByPID
+ </entry>
+ <entry>
+ status
+ </entry>
+ </row>
+ <row>
+ <entry>
+ GetUnitFileState
+ </entry>
+ <entry>
+ status
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Kill
+ </entry>
+ <entry>
+ stop
+ </entry>
+ </row>
+ <row>
+ <entry>
+ KillUnit
+ </entry>
+ <entry>
+ stop
+ </entry>
+ </row>
+ <row>
+ <entry>
+ LinkUnitFiles
+ </entry>
+ <entry>
+ enable
+ </entry>
+ </row>
+ <row>
+ <entry>
+ ListUnits
+ </entry>
+ <entry>
+ status
+ </entry>
+ </row>
+ <row>
+ <entry>
+ LoadUnit
+ </entry>
+ <entry>
+ status
+ </entry>
+ </row>
+ <row>
+ <entry>
+ MaskUnitFiles
+ </entry>
+ <entry>
+ disable
+ </entry>
+ </row>
+ <row>
+ <entry>
+ PresetUnitFiles
+ </entry>
+ <entry>
+ enable
+ </entry>
+ </row>
+ <row>
+ <entry>
+ ReenableUnitFiles
+ </entry>
+ <entry>
+ enable
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Reexecute
+ </entry>
+ <entry>
+ start
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Reload
+ </entry>
+ <entry>
+ reload
+ </entry>
+ </row>
+ <row>
+ <entry>
+ ReloadOrRestart
+ </entry>
+ <entry>
+ start
+ </entry>
+ </row>
+ <row>
+ <entry>
+ ReloadOrRestartUnit
+ </entry>
+ <entry>
+ start
+ </entry>
+ </row>
+ <row>
+ <entry>
+ ReloadOrTryRestart
+ </entry>
+ <entry>
+ start
+ </entry>
+ </row>
+ <row>
+ <entry>
+ ReloadOrTryRestartUnit
+ </entry>
+ <entry>
+ start
+ </entry>
+ </row>
+ <row>
+ <entry>
+ ReloadUnit
+ </entry>
+ <entry>
+ reload
+ </entry>
+ </row>
+ <row>
+ <entry>
+ ResetFailed
+ </entry>
+ <entry>
+ stop
+ </entry>
+ </row>
+ <row>
+ <entry>
+ ResetFailedUnit
+ </entry>
+ <entry>
+ stop
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Restart
+ </entry>
+ <entry>
+ start
+ </entry>
+ </row>
+ <row>
+ <entry>
+ RestartUnit
+ </entry>
+ <entry>
+ start
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Start
+ </entry>
+ <entry>
+ start
+ </entry>
+ </row>
+ <row>
+ <entry>
+ StartUnit
+ </entry>
+ <entry>
+ start
+ </entry>
+ </row>
+ <row>
+ <entry>
+ StartUnitReplace
+ </entry>
+ <entry>
+ start
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Stop
+ </entry>
+ <entry>
+ stop
+ </entry>
+ </row>
+ <row>
+ <entry>
+ StopUnit
+ </entry>
+ <entry>
+ stop
+ </entry>
+ </row>
+ <row>
+ <entry>
+ TryRestart
+ </entry>
+ <entry>
+ start
+ </entry>
+ </row>
+ <row>
+ <entry>
+ TryRestartUnit
+ </entry>
+ <entry>
+ start
+ </entry>
+ </row>
+ <row>
+ <entry>
+ UnmaskUnitFiles
+ </entry>
+ <entry>
+ enable
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="tab-systemd-system-methods">
+ <title>Mapping of systemd general system calls on SELinux access
checks</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>
+ <systemitem class="daemon">systemd</systemitem> general system
call
+ </entry>
+ <entry>
+ SELinux access check
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ ClearJobs
+ </entry>
+ <entry>
+ reboot
+ </entry>
+ </row>
+ <row>
+ <entry>
+ FlushDevices
+ </entry>
+ <entry>
+ halt
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Get
+ </entry>
+ <entry>
+ status
+ </entry>
+ </row>
+ <row>
+ <entry>
+ GetAll
+ </entry>
+ <entry>
+ status
+ </entry>
+ </row>
+ <row>
+ <entry>
+ GetJob
+ </entry>
+ <entry>
+ status
+ </entry>
+ </row>
+ <row>
+ <entry>
+ GetSeat
+ </entry>
+ <entry>
+ status
+ </entry>
+ </row>
+ <row>
+ <entry>
+ GetSession
+ </entry>
+ <entry>
+ status
+ </entry>
+ </row>
+ <row>
+ <entry>
+ GetSessionByPID
+ </entry>
+ <entry>
+ status
+ </entry>
+ </row>
+ <row>
+ <entry>
+ GetUser
+ </entry>
+ <entry>
+ status
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Halt
+ </entry>
+ <entry>
+ halt
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Introspect
+ </entry>
+ <entry>
+ status
+ </entry>
+ </row>
+ <row>
+ <entry>
+ KExec
+ </entry>
+ <entry>
+ reboot
+ </entry>
+ </row>
+ <row>
+ <entry>
+ KillSession
+ </entry>
+ <entry>
+ halt
+ </entry>
+ </row>
+ <row>
+ <entry>
+ KillUser
+ </entry>
+ <entry>
+ halt
+ </entry>
+ </row>
+ <row>
+ <entry>
+ ListJobs
+ </entry>
+ <entry>
+ status
+ </entry>
+ </row>
+ <row>
+ <entry>
+ ListSeats
+ </entry>
+ <entry>
+ status
+ </entry>
+ </row>
+ <row>
+ <entry>
+ ListSessions
+ </entry>
+ <entry>
+ status
+ </entry>
+ </row>
+ <row>
+ <entry>
+ ListUsers
+ </entry>
+ <entry>
+ status
+ </entry>
+ </row>
+ <row>
+ <entry>
+ LockSession
+ </entry>
+ <entry>
+ halt
+ </entry>
+ </row>
+ <row>
+ <entry>
+ PowerOff
+ </entry>
+ <entry>
+ halt
+ </entry>
+ </row>
+ <row>
+ <entry>
+ Reboot
+ </entry>
+ <entry>
+ reboot
+ </entry>
+ </row>
+ <row>
+ <entry>
+ SetUserLinger
+ </entry>
+ <entry>
+ halt
+ </entry>
+ </row>
+ <row>
+ <entry>
+ TerminateSeat
+ </entry>
+ <entry>
+ halt
+ </entry>
+ </row>
+ <row>
+ <entry>
+ TerminateSession
+ </entry>
+ <entry>
+ halt
+ </entry>
+ </row>
+ <row>
+ <entry>
+ TerminateUser
+ </entry>
+ <entry>
+ halt
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <example id="ex-selinux-systemd-policy">
+ <title>SELinux Policy for a System Service</title>
+
+ <para>
+ By using the <systemitem>sesearch</systemitem> utility, you can list
policy rules for a system service. For example, calling the <command>sesearch -A -s
NetworkManager_t -c service</command> command returns:
+ </para>
+
+<screen>allow NetworkManager_t dnsmasq_unit_file_t : service { start stop status
reload kill load } ;
+allow NetworkManager_t nscd_unit_file_t : service { start stop status reload kill load }
;
+allow NetworkManager_t ntpd_unit_file_t : service { start stop status reload kill load }
;
+allow NetworkManager_t pppd_unit_file_t : service { start stop status reload kill load }
;
+allow NetworkManager_t polipo_unit_file_t : service { start stop status reload kill load
} ;
+</screen>
+ </example>
+
+ </section>
+
+ <section id="sec-systemd_Access_Control-journald">
+
+ <title>SELinux and <systemitem
class="daemon">journald</systemitem></title>
+
+ <para>
+ In <systemitem class="daemon">systemd</systemitem>, the
<systemitem class="daemon">journald</systemitem> daemon (also known
as <systemitem class="daemon">systemd-journal</systemitem>) is the
alternative for the <systemitem>syslog</systemitem> utility, which is a system
service that collects and stores logging data. It creates and maintains structured and
indexed journals based on logging information that is received from the kernel, from user
processes using the <systemitem>libc</systemitem>
<systemitem>syslog()</systemitem> function, from standard and error output of
system services, or using its native API. It implicitly collects numerous metadata fields
for each log message in a secure way.
+ </para>
+
+ <para>
+ The <systemitem>systemd-journal</systemitem> service can be used with
SELinux to increase security. SELinux controls processes by only allowing them to do what
they were designed to do; sometimes even less, depending on the security goals of the
policy writer. For example, SELinux prevents a compromised
<systemitem>ntpd</systemitem> process from doing anything other than handle
Network Time. However, the <systemitem>ntpd</systemitem> process sends
<systemitem>syslog</systemitem> messages, so that SELinux would allow the
compromised process to continue to send those messages. The compromised
<systemitem>ntpd</systemitem> could format
<systemitem>syslog</systemitem> messages to match other daemons and
potentially mislead an administrator, or even worse, a utility that reads the
<systemitem>syslog</systemitem> file into compromising the whole system.
+ </para>
+
+ <para>
+ The <systemitem>systemd-journal</systemitem> daemon
verifies all log messages and, among other things, adds SELinux labels to them. It is then
easy to detect inconsistencies in log messages and prevent an attack of this type before
it occurs. You can use the <systemitem>journalctl</systemitem> utility to
query logs of <systemitem class="daemon">systemd</systemitem>
journals. If no command-line arguments are specified, running this utility lists the full
content of the journal, starting from the oldest entries. To see all logs generated on the
system, including logs for system components, execute
<systemitem>journalctl</systemitem> as root. If you execute it as a non-root
user, the output will be limited only to logs related to the currently logged-in user.
+ </para>
+ <example id="ex-journalctl_and_SELinux">
+ <title>Listing Logs with
<systemitem>journalctl</systemitem></title>
+ <para>
+ It is possible to use
<systemitem>journalctl</systemitem> for listing all logs related to a
particular SELinux label. For example, the following command lists all logs logged under
the <systemitem>system_u:system_r:policykit_t:s0</systemitem> label:
+
+ <screen>~]# <command>journalctl
_SELINUX_CONTEXT=system_u:system_r:policykit_t:s0</command>
+Oct 21 10:22:42 localhost.localdomain polkitd[647]: Started polkitd version 0.112
+Oct 21 10:22:44 localhost.localdomain polkitd[647]: Loading rules from directory
/etc/polkit-1/rules.d
+Oct 21 10:22:44 localhost.localdomain polkitd[647]: Loading rules from directory
/usr/share/polkit-1/rules.d
+Oct 21 10:22:44 localhost.localdomain polkitd[647]: Finished loading, compiling and
executing 5 rules
+Oct 21 10:22:44 localhost.localdomain polkitd[647]: Acquired the name
org.freedesktop.PolicyKit1 on the system bus Oct 21 10:23:10 localhost polkitd[647]:
Registered Authentication Agent for unix-session:c1 (system bus name :1.49, object path
/org/freedesktop/PolicyKit1/AuthenticationAgent, locale en_US.UTF-8) (disconnected from
bus)
+Oct 21 10:23:35 localhost polkitd[647]: Unregistered Authentication Agent for
unix-session:c1 (system bus name :1.80 [/usr/bin/gnome-shell --mode=classic], object path
/org/freedesktop/PolicyKit1/AuthenticationAgent, locale en_US.utf8)
+</screen>
+ </para>
+ </example>
+
+
+ <para>
+ For more information about
<systemitem>journalctl</systemitem>, see the
<citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
manual page.
+ </para>
+
+ </section>
+
+</section>
+