Translation(s): English - Español - Français - Italiano - 한국어 - Russian - Brasileiro - 简体中文
systemd - system and service manager
Contents
Introduction
systemd is a system and service manager for Linux. It is the default init system for Debian since Debian 8 ("jessie"). Systemd is compatible with SysV and LSB init scripts. It can work as a drop-in replacement for sysvinit. Systemd
- Provides aggressive parallelization capabilities
- Uses socket and D-Bus activation for starting services
- Offers on-demand starting of daemons
- Implements transactional dependency-based service control logic
- Tracks processes using Linux cgroups
- Supports snapshotting and restoring
- Maintains mount and automount points
Systemd runs as a daemon with PID 1.
Systemd tasks are organized as units. The most common units are services (.service), mount points (.mount), devices (.device), sockets (.socket), or timers (.timer). For instance, starting the secure shell daemon is done by the unit ssh.service.
Systemd puts every service into a dedicated control group (cgroup) named after the service. Modern kernels support process isolation and resource allocation based on cgroups.
Targets are groups of units. Targets call units to put the system together. For instance, graphical.target calls all units that are necessary to start a workstation with graphical user interface. Targets can build on top of another or depend on other targets. At boot time, systemd activates the target default.target which is an alias for another target such as graphical.target.
Systemd creates and manages the sockets used for communication between system components. For instance, it first creates the socket /dev/log and then starts the syslog daemon. This approach has two advantages: Firstly, processes communicating with syslog via /dev/log can be started in parallel. Secondly, crashed services can be restarted without processes that communicate via sockets with them losing their connection. The kernel will buffer the communication while the process restarts.
Please see the upstream systemd page for more information.
Basic usage
systemctl is the main tool used to introspect and control the state of the "systemd" system and service manager. You can use systemctl for instance to enable/disable services permanently or only for the current session. Refer to the systemctl(1) manpage for more details.
Getting information on system status
Show system status:
$ systemctl status
List failed units:
$ systemctl --failed
List installed unit files:
$ systemctl list-unit-files
Managing services
List all running services:
$ systemctl
Activates the service "example1" immediately:
# systemctl start example1
Deactivates the service "example1" immediately:
# systemctl stop example1
Restarts the service "example1" immediately:
# systemctl restart example1
Shows status of the service "example1":
# systemctl status example1
Enables "example1" to be started on bootup:
# systemctl enable example1
Disables "example1" to not start during bootup:
# systemctl disable example1
Displays the configuration for "example1":
# systemctl cat example1
Creating or altering services
Units are defined by individual configuration files, called unit files. The type of the unit is recognized by the file name suffix, .mount in case of a mount point. Unit files provided by Debian are located in the /lib/systemd/system directory. If an identically named local unit file exists in the directory /etc/systemd/system, it will take precedence and systemd will ignore the file in the /lib/systemd/system directory. Some units are created by systemd without a unit file existing in the file system.
System administrators should put new or heavily-customized unit files in /etc/systemd/system.
Small tweaks
For small tweaks to a unit file, system administrators should use the "drop-in directory" feature (documented in systemd.unit(5)).
Start by determining the canonical systemd service name (e.g. ssh.service, not an alias like sshd.service). We'll use "name.service" for this example.
Use the command # systemctl edit name.service to create or edit a file /etc/systemd/system/name.service.d/override.conf and make changes as needed.
This brings up the default editor with all the sections and settings from the units .conf-file commented out and instructions on how to override theese.
- If needed, create more files inside this directory ending with a ".conf" suffix to separate overrides in atomic units. For example, /etc/systemd/system/name.service.d/local.conf
- Each file should contain the section headers and section options to be overridden, using the same format as unit files.
If you're overriding ExecStart=, you need to put an empty ExecStart= line in the override file, to "clear out" the existing command list. Otherwise, all non-empty ExecStart= lines append a new command to the list.
Here's an example:
# cat /etc/systemd/system/name.service.d/local.conf [Service] ExecStart= ExecStart=/usr/sbin/name-service --my-options
For information about writing your own services, see systemd/Services.
Installing and Testing
systemd was included in Debian wheezy as a technology preview. Please make sure that you are using Debian jessie or newer to get a recent version of systemd.
Installation
To install systemd run:
# apt-get update # apt-get install systemd
This will install the systemd packages but will not configure systemd as your init system.
Configuring for testing
To test systemd before switching to it by default, you can add the following boot parameter to the kernel:
init=/lib/systemd/systemd
This can be done in the grub menu for a single boot - press "e" in the grub menu and add this to the kernel line. For example, depending on the options required for your particular system, it might look something like:
linux /vmlinuz-3.13-1-amd64 root=/dev/mapper/root-root init=/lib/systemd/systemd ro quiet
If PID 1 is systemd then your system is running with systemd.
Configuring as default
In order to use systemd you should also install systemd-sysv which provides the symlinks links for /sbin/init. It is recommended to run this when already running under systemd, as described in the previous section.
# apt-get install systemd-sysv
In order to boot your system with the newly installed systemd, simply reboot.
# reboot
If you run a self-compiled kernel, make sure you have 2.6.39 or newer and enable the following options:
* CONFIG_DEVTMPFS=y * CONFIG_CGROUPS=y * CONFIG_AUTOFS4_FS=[y|m] * CONFIG_IPV6=[y|m], optional, but highly recommended * CONFIG_FANOTIFY=y, optional, required for systemd readahead. available in Linux kernel >= 2.6.37.
For an up-to-date list, see section "REQUIREMENTS" in the upstream README file.
Daemon Security
Overview
A significant feature of systemd is the ability to consistently manage the access that daemons are granted to the system. Prior to systemd's adoption the expectation was that every daemon would call setgid(2), setuid(2), and daemon(3) to limit the scope of damage if the daemon is compromised. But before the daemon dropped privileges any bug, configuration error, or attack could cause unlimited damage. If a daemon was under the control of a hostile party from the initialisation phase and started manually by the sysadmin it could use the TIOCSTI ioctl to stuff characters into the keyboard buffer to take over the system, this was a difficult problem to solve as some daemons wanted the sysadmin to enter a password on startup (a web server with encrypted SSL keys was a common example).
To address this systemd manages the daemon startup process, has systemd-ask-password(1) and associated programs for getting passwords on daemon startup and apart from that gives them no direct access to the sysadmin terminal. The daemon can be started under a specific UID/GID, a specific SELinux security context, and with the full range of Linux access control mechanisms (private mounts, read-only mounts, limits to system calls, etc). See the documentation for systemd-exec for all the options.
Checking Daemon Security
The following command shows a list of all units and the exposure number from 0 to 10 (high is bad):
systemd-analyze security
The following command shows the details of the exposure of the rsyslog service:
systemd-analyze security rsyslog.service
Generally you want to decrease the numbers as much as possible within the scope of what they do. But a login program (sshd, getty, xdm, etc) that allows either a direct root login or access to run su/sudo can't be meaningfully restricted much.
Increasing Daemon Security
See the ?Small Tweaks section of this document for information on tweaking a daemon configuration, for security or other reasons.
One of the most important things to set is the list of permitted capabilities for the daemon. The CapabilityBoundingSet is the list of capabilities that are permitted (space separated on a single line) or the list of capabilities to be blocked prefixed with a ~. Here is an example of allowing a daemon to have DAC_OVERRIDE (read files that aren't permitted by Unix permissions when running as UID 0), SETUID and SETGID (for dropping privs - not needed if you use systemd to run under the required UID/GID), PTRACE, and memory locking. All other capabilities will be denied:
CapabilityBoundingSet=CAP_DAC_OVERRIDE CAP_SETGID CAP_SETUID CAP_SYS_PTRACE CAP_IPC_LOCK
There is a full list of capabilities with their descriptions in the file /usr/include/linux/capability.h from package linux-libc-dev. Usually it's best to just list the capabilities that are to be permitted as it's a smaller set.
Working out which capabilities are needed for a daemon is difficult, usually the logs don't indicate what was missing.
Another good option for restricting is system calls. The following example lists some system calls that are known to be risky (such as the @clock group and the @mount group as well as some that aren't usually used and which can be safely restricted to reduce the attack surface such as @cpu-emulation and @raw-io. Filtering system calls has some overlap with restricting capabilities but it's good to restrict things in two ways. It usually isn't difficult to map error messages logged by a daemon to which groups of syscalls were filtered and then do a binary search for the most restrictive options.
SystemCallFilter=~@mount @cpu-emulation @debug @raw-io @reboot @resources @swap @module @obsolete @clock
The following is recommended for every daemon that doesn't directly interact with user files. Daemons such as database servers almost never need to access user home directories and should be prevented from accessing /home by default.
ProtectHome=true
The following settings are good for protecting the overall OS installation. You can use these on most daemons with little risk of breaking things:
ProtectKernelLogs=true ProtectControlGroups=true ProtectKernelModules=true MemoryDenyWriteExecute=true ProtectHostname=true LockPersonality=true RestrictRealtime=true DevicePolicy=closed ProtectClock=true RestrictSUIDSGID=true ProtectKernelTunables=true PrivateDevices=true
The following setting is good to prevent a daemon being attacked by a user or another daemon via /tmp race conditions. It's unlikely to cause any problems.
PrivateTmp=true
The following is good for daemons which need no networking. This allows Unix domain sockets by filesystem (EG /run/$DAEMON/whatever.sock) but not the abstract socket namespace. The risk of this is PAM services that use networking or other indirect network access. This is a good option for the sysadmin who is locking down their own system but risky for the package maintainer.
PrivateNetwork=true
The NoNewPrivileges option prevents a daemon from running a SETUID program to gain privileges that are undesired. But there are some corner cases for this such as running a program that has a SE Linux automatic domain transition to LESS privileges can be denied.
NoNewPrivileges=true
Debugging
Failed units
In some cases units enter a failed state. The statuscommand can be used to find out some details:
$ systemctl status <UNITNAME>
Failed units can be manually cleared out:
# systemctl reset-failed
Verify units
To check that we didn't misspell anything or used any unknown options when writing units, systemd-analyze
$ systemd-analyze verify <UNITNAME-or-PATHTOUNIT>
No output means everything checks out.
systemd hangs on startup or shutdown
Sometimes it is necessary to investigate why systemd hangs on startup or on reboot/shutdown.
Solution #0: Remove "quiet" from Kernel command line (so called "cmdline" or "grub line")
Solution #1: Increase verbosity via cmdline: Add "systemd.log_target=kmsg systemd.log_level=debug"
Of course you can have a "temporary" persistent solution:
[ /etc/default/grub ] GRUB_CMDLINE_LINUX="systemd.log_target=kmsg systemd.log_level=debug" <--- Add here (by uncommenting you can easily switch to debug) # update-grub
Solution #2: Increase verbosity via /etc/systemd/system.conf
LogLevel=debug <--- Uncomment this line and use "debug" (default: commented and "info") LogTarget=syslog-or-kmsg <--- Uncomment this line (default: commented)
Solution #3: Boot an emergency shell: Add systemd.unit=rescue.target or just 1 (the number one) to the kernel command line.
Solution #4: Enable the debug shell: Run systemctl enable debug-shell.service. (You can do this in a chroot environment after booting a rescue system.) This starts a root shell on TTY 9.
HINT: "man systemd" and "man systemd-system.conf"
HINT: Extensive debugging information about systemd is on this FreeDesktop page.
HINT: How to check Kernel command line parameters/options?
# cat /proc/cmdline
NOTE on LogLevel (see systemd(1) and systemd-system.conf(5)):
"Set log level. As an argument this accepts a numerical log level or the well-known syslog(3) symbolic names (lowercase): emerg, alert, crit, err, warning, notice, info, debug."
HINT: Keep a copy of /sbin/init from sysvinit package in case of rescue (so you can use init=/sbin/init.sysvinit in cmdline)!
# cp -av /sbin/init /sbin/init.sysvinit <--- Before installing systemd-sysv package
See also https://fedoraproject.org/wiki/How_to_debug_Systemd_problems
Kernel debug without systemd debug in Jessie
Using the old "debug" kernel parameter in Jessie will turn on systemd debug logging as well as kernel debug logging. To get the old behaviour, do not use "debug", instead use the kernel parameter "loglevel=7".
Bugs and Bug-Tracking-Systems
- For known bugs please see topic "Known Issues and Workarounds"
Known Issues and Workarounds
Shared bind mounts
The default behavior of bind mounts changes under systemd. The Linux kernel makes bind mounts of anything below / PRIVATE. Systemd changes this to SHARED.
Thus, when you do this:
mount --bind / $CHROOT mount --bind /dev/ $CHROOT/dev umount $CHROOT/dev
then /dev will be unmounted in your base/parent system as well!
What you can do now instead, is to:
mount --bind --make-rslave / $CHROOT mount --bind --make-rslave /dev/ $CHROOT/dev
this will propagate mount changes (also mount options) in the base/parent system into the $CHROOT but not from the $CHROOT back to the parent.
The rationale for the change of the default behavior can be found in bug 739593, particularly in Lenart's comment therein.
SSH session doesn't cleanly terminate on reboot/shutdown
If you happen to reboot/shutdown remote machine over ssh you may find out that your session isn't terminated properly, leaving you with the non-reacting terminal until long a timeout has been reached. There was bug 751636 about it. A workaround to this problem was to install:
apt-get install libpam-systemd
which would terminate the ssh session before the network was dropped. Please note, that that would require PAM to be enabled in sshd.
Missing startup messages on console(tty1) after the boot
With systemd console(tty1) is handled differently and if you used to check it to see how did your boot go now you'll see only couple of non-informative lines.
To be able to get full transcript of the system boot on your console you need to perform two steps.
1. Add to the kernel options systemd.show_status=1, for example via /etc/default/grub:
GRUB_CMDLINE_LINUX_DEFAULT="quiet systemd.show_status=1"
and run update-grub2.
2. Create file /etc/systemd/system/getty@tty1.service.d/noclear.conf with the content:
[Service] TTYVTDisallocate=no
to disable clearing of the terminal on getty invocation.
Virtual and serial console changes
Those used to change inittab to enable/disable virtual or serial consoles will notice that that file is gone from clean installs. This is all managed through systemd directly now. For example, you can enable a serial console on COM1 with:
systemctl enable serial-getty@ttyS0.service systemctl start serial-getty@ttyS0.service
However, it is generally preferable to add console=ttyS0 on the kernel commandline, since this also enables kernel output on reboots. For, e.g. GRUB, this is done by adding the following to /etc/default/grub:
GRUB_CMDLINE_LINUX="console=ttyS0"
... and running update-grub. This will take effect only on the next reboot, however.
Note also that Linux supports multiple consoles for output - but only one for input - the last named (or default if none named) from the kernel commandline specifies which is used for input, and all are used for output. E.g. for GRUB:
GRUB_CMDLINE_LINUX="console=tty0 console=ttyS0"
That will, after running update-grub and rebooting, have console input from /dev/ttyS0 and output to both that and /dev/tty0 device. Note also that serial parameters can also be specified, e.g.:
GRUB_CMDLINE_LINUX="console=tty0 console=ttyS0,9600n8"
Orphaned processes
Because it manages user sessions (taking over the role of X or other components), systemd may slightly change how processes survive a logoff. By default, when X shuts down all processes should exit and systemd will clean up the session, but there are some corner cases where certain processes don't cleanup after themselves properly.
You can configure how systemd manages leftover processes with the KillUserProcesses= parameter in logind.conf. By setting this to yes, processes will be forcibly killed when the session terminates. Note that this will break tools like screen or tmux, unless they are configured to run under a distinct user@.service unit and if enable-linger is set to yes in loginctl. A simple way to do this on the fly is to run the program in a "transient scope", using systemd-run:
systemd-run --scope --user screen
Now, normally sessions should cleanup after themselves, and such issues should be fixed without having to revert to the KillUserProcesses=yes sledgehammer. A good way to list the affected processes is to group them by "control group", with the systemd-cgls command:
systemd-cgls
Some known misbehaving applications:
redshift-gtk? - workaround: run as a systemd service, 827098
Where to get help?
Systemd is a young project with a strong emphasis on solving problems in a distribution agnostic manner.
mailing-list @ https://lists.freedesktop.org/mailman/listinfo/systemd-devel
#systemd (irc.libera.chat)
Debian specific channels include
mailing-list @ https://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-systemd-maintainers
#debian-systemd (irc.oftc.net)
Several other distributions are using systemd
Installing without systemd
See Init, under "Changing the init system - at installation time"
Debian Resources
Other Resources
So ... wouldn't it be better to, rather than put kernel command line and/or GRUB bits here that aren't systemd specific, instead link to somewhere else where they're better and more authoritatively documented on Debian's wiki ... if that exists ... or when it comes to exist?