[securityguide] Added a section about systemd access control.

Bara Ančincová bancinco at fedoraproject.org
Sun Aug 10 23:00:27 UTC 2014


commit 0d2462d4c0297bdd7192a121094d43da02367733
Author: Barbora Ancincova <bancinco at 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>
+


More information about the docs-commits mailing list