From 4a6283603324afb3da50c14a3283c5df2cc01960 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 28 Sep 2017 19:14:10 +0200 Subject: [PATCH] man: document the new logic --- man/systemd.exec.xml | 91 +++++++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 34 deletions(-) diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 06ae6b3252..02d2e9e259 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -220,10 +220,13 @@ cannot leave files around after unit termination. Moreover ProtectSystem=strict and ProtectHome=read-only are implied, thus prohibiting the service to write to arbitrary file system locations. In order to allow the service to write to certain directories, they have to be whitelisted - using ReadWritePaths=, but care must be taken so that UID/GID recycling doesn't - create security issues involving files created by the service. Use RuntimeDirectory= (see - below) in order to assign a writable runtime directory to a service, owned by the dynamic user/group and - removed automatically when the unit is terminated. Defaults to off. + using ReadWritePaths=, but care must be taken so that UID/GID recycling doesn't create + security issues involving files created by the service. Use RuntimeDirectory= (see below) in + order to assign a writable runtime directory to a service, owned by the dynamic user/group and removed + automatically when the unit is terminated. Use StateDirectory=, + CacheDirectory= and LogsDirectory= in order to assign a set of writable + directories for specific purposes to the service in a way that they are protected from vulnerabilities due to + UID reuse (see below). Defaults to off. @@ -1753,23 +1756,58 @@ CapabilityBoundingSet=~CAP_B CAP_C RuntimeDirectory= + StateDirectory= + CacheDirectory= + LogsDirectory= + ConfigurationDirectory= - Takes a whitespace-separated list of directory names. The specified directory names must be - relative, and may not include . or ... If set, one or more directories - including their parents by the specified names will be created below /run (for system - services) or below $XDG_RUNTIME_DIR (for user services) when the unit is started. The - lowest subdirectories are removed when the unit is stopped. It is possible to preserve the directories if - RuntimeDirectoryPreserve= is configured to or . - The lowest subdirectories will have the access mode specified in RuntimeDirectoryMode=, - and be owned by the user and group specified in User= and Group=. - This implies ReadWritePaths=, that is, the directories specified - in this option are accessible with the access mode specified in RuntimeDirectoryMode= - even if ProtectSystem= is set to . - Use this to manage one or more runtime directories of the unit and bind their - lifetime to the daemon runtime. This is particularly useful for unprivileged daemons that cannot create + These options take a whitespace-separated list of directory names. The specified directory + names must be relative, and may not include . or ... If set, one or more + directories by the specified names will be created (including their parents) below /run + (or $XDG_RUNTIME_DIR for user services), /var/lib (or + $XDG_CONFIG_HOME for user services), /var/cache (or + $XDG_CACHE_HOME for user services), /var/log (or + $XDG_CONFIG_HOME/log for user services), or /etc + (or $XDG_CONFIG_HOME for user services), respectively, when the unit is started. + + In case of RuntimeDirectory= the lowest subdirectories are removed when the unit is + stopped. It is possible to preserve the specified directories in this case if + RuntimeDirectoryPreserve= is configured to or + (see below). The directories specified with StateDirectory=, + CacheDirectory=, LogsDirectory=, + ConfigurationDirectory= are not removed when the unit is stopped. + + Except in case of ConfigurationDirectory=, the innermost specified directories will be + owned by the user and group specified in User= and Group=. If the + specified directories already exist and their owning user or group do not match the configured ones, all files + and directories below the specified directories as well as the directories themselves will have their file + ownership recursively changed to match what is configured. As an optimization, if the specified directories are + already owned by the right user and group, files and directories below of them are left as-is, even if they do + not match what is requested. The innermost specified directories will have their access mode adjusted to the + what is specified in RuntimeDirectoryMode=, StateDirectoryMode=, + CacheDirectoryMode=, LogsDirectoryMode= and + ConfigurationDirectoryMode=. + + Except in case of ConfigurationDirectory=, these options imply + ReadWritePaths= for the specified paths. When combined with + RootDirectory= or RootImage= these paths always reside on the host and + are mounted from there into the unit's file system namespace. If DynamicUser= is used in + conjunction with RuntimeDirectory=, StateDirectory=, + CacheDirectory= and LogsDirectory=, the behaviour of these options is + slightly altered: the directories are created below /run/private, + /var/lib/private, /var/cache/private and + /var/log/private, respectively, which are host directories made inaccessible to + unprivileged users, which ensures that access to these directories cannot be gained through dynamic user ID + recycling. Symbolic links are created to hide this difference in behaviour. Both from perspective of the host + and from inside the unit, the relevant directories hence always appear directly below + /run, /var/lib, /var/cache and + /var/log. + + Use RuntimeDirectory= to manage one or more runtime directories for the unit and bind + their lifetime to the daemon runtime. This is particularly useful for unprivileged daemons that cannot create runtime directories in /run due to lack of privileges, and to make sure the runtime - directory is cleaned up automatically after use. For runtime directories that require more complex or - different configuration or lifetime guarantees, please consider using + directory is cleaned up automatically after use. For runtime directories that require more complex or different + configuration or lifetime guarantees, please consider using tmpfiles.d5. Example: if a system service unit has the following, @@ -1779,22 +1817,7 @@ CapabilityBoundingSet=~CAP_B CAP_C except /run/foo are owned by the user and group specified in User= and Group=, and removed when the service is stopped. - - - StateDirectory= - CacheDirectory= - LogsDirectory= - ConfigurationDirectory= - - Takes a whitespace-separated list of directory names. If set, as similar to - RuntimeDirectory=, one or more directories including their parents by the specified names - will be created below /var/lib, /var/cache, /var/log, - or /etc, respectively, when the unit is started. - Unlike RuntimeDirectory=, the directories are not removed when the unit is stopped. - The lowest subdirectories will be owned by the user and group specified in User= - and Group=. The options imply ReadWritePaths=. -