2021-06-16 15:35:12 -04:00
#compdef systemd-analyze
2020-11-09 13:23:58 +09:00
# SPDX-License-Identifier: LGPL-2.1-or-later
2013-07-29 14:12:55 -05:00
2018-12-24 05:15:38 -06:00
(( $+functions[_systemd-analyze_log-level] )) ||
2019-04-05 11:39:14 +02:00
_systemd-analyze_log-level() {
local -a _levels
_levels=(debug info notice warning err crit alert emerg)
_describe -t level 'logging level' _levels || compadd "$@"
}
2013-08-22 23:25:28 -04:00
2018-12-24 05:15:38 -06:00
(( $+functions[_systemd-analyze_log-target] )) ||
2019-04-05 11:39:14 +02:00
_systemd-analyze_log-target() {
local -a _targets
_targets=(console journal kmsg journal-or-kmsg null)
_describe -t target 'logging target' _targets || compadd "$@"
}
2017-09-07 23:23:33 +02:00
2018-12-24 05:15:38 -06:00
(( $+functions[_systemd-analyze_verify] )) ||
2019-04-05 11:39:14 +02:00
_systemd-analyze_verify() {
_sd_unit_files
}
2014-07-21 21:11:56 -04:00
2018-12-24 05:15:38 -06:00
(( $+functions[_systemd-analyze_service-watchdogs] )) ||
2019-04-05 11:39:14 +02:00
_systemd-analyze_service-watchdogs() {
local -a _states
_states=(on off)
_describe -t state 'state' _states || compadd "$@"
}
2018-01-24 07:43:41 +03:00
2020-04-26 23:16:55 -07:00
(( $+functions[_systemd-analyze_cat-config] )) ||
_systemd-analyze_cat-config() {
_files -W '(/run/systemd/ /etc/systemd/ /usr/lib/systemd/)' -P 'systemd/'
}
(( $+functions[_systemd-analyze_security] )) ||
_systemd-analyze_security() {
_sd_unit_files
}
2018-12-24 05:15:38 -06:00
(( $+functions[_systemd-analyze_commands] )) ||
2019-04-05 11:39:14 +02:00
_systemd-analyze_commands(){
local -a _systemd_analyze_cmds
# Descriptions taken from systemd-analyze --help.
_systemd_analyze_cmds=(
'time:Print time spent in the kernel before reaching userspace'
'blame:Print list of running units ordered by time to init'
'critical-chain:Print a tree of the time critical chain of units'
'plot:Output SVG graphic showing service initialization'
'dot:Dump dependency graph (in dot(1) format)'
'dump:Dump server status'
2020-04-26 23:16:55 -07:00
'cat-config:Cat systemd config files'
'unit-files:List files and symlinks for units'
2019-04-05 11:39:14 +02:00
'unit-paths:List unit load paths'
2020-04-26 23:16:55 -07:00
'exit-status:List known exit statuses'
2019-04-05 11:39:14 +02:00
'syscall-filter:List syscalls in seccomp filter'
2020-04-26 23:16:55 -07:00
'condition:Evaluate Condition*= and Assert*= assignments'
2019-04-05 11:39:14 +02:00
'verify:Check unit files for correctness'
'calendar:Validate repetitive calendar time events'
2020-04-26 23:16:55 -07:00
'timestamp:Parse a systemd syntax timestamp'
'timespan:Parse a systemd syntax timespan'
'security:Analyze security settings of a service'
# 'log-level:Get/set systemd log threshold'
# 'log-target:Get/set systemd log target'
# 'service-watchdogs:Get/set service watchdog status'
2019-04-05 11:39:14 +02:00
)
2013-07-29 14:12:55 -05:00
2019-04-05 11:39:14 +02:00
if (( CURRENT == 1 )); then
_describe "options" _systemd_analyze_cmds
else
local curcontext="$curcontext"
cmd="${${_systemd_analyze_cmds[(r)$words[1]:*]%%:*}}"
if (( $#cmd )); then
if (( $+functions[_systemd-analyze_$cmd] )) && (( CURRENT == 2 )); then
_systemd-analyze_$cmd
else
_message "no more options"
fi
2013-08-22 23:25:28 -04:00
else
2019-04-05 11:39:14 +02:00
_message "unknown systemd-analyze command: $words[1]"
2013-08-22 23:25:28 -04:00
fi
fi
2019-04-05 11:39:14 +02:00
}
2013-07-29 14:12:55 -05:00
_arguments \
2015-01-12 21:43:45 +01:00
{-h,--help}'[Show help text]' \
'--version[Show package version]' \
'--system[Operate on system systemd instance]' \
'--user[Operate on user systemd instance]' \
2018-02-08 12:09:28 +01:00
'--global[Show global user instance config]' \
2021-06-30 09:57:54 -07:00
'--root=[Add support for root argument]:PATH' \
2021-06-30 10:02:51 -07:00
'--image=[Add support for discrete images]:PATH' \
systemd-analyze: option to exit with an error when 'verify' fails
The commit introduces a callback invoked from log_syntax_internal.
Use it from systemd-analyze to gather a list of units that contain
syntax warnings. A new command line option is added to make use of this.
The new option --recursive-errors takes in three possible modes:
1. yes - which is the default. systemd-analyze exits with an error when syntax warnings arise during verification of the
specified units or any of their dependencies.
3. no - systemd-analyze exits with an error when syntax warnings arise during verification of only the selected unit.
Analyzing and loading any dependencies will be skipped.
4. one - systemd-analyze exits with an error when syntax warnings arise during verification
of only the selected units and their direct dependencies.
Below are two service unit files that I created for the purposes of testing:
1. First, we run the commands on a unit that does not have dependencies but has a non-existing key-value setting (i.e. foo = bar).
> cat <<EOF>testcase.service
[Unit]
foo = bar
[Service]
ExecStart = echo hello
EOF
OUTPUT:
maanya-goenka@debian:~/systemd (log-error)$ sudo build/systemd-analyze verify testcase.service
/home/maanya-goenka/systemd/testcase.service:2: Unknown key name 'foo' in section 'Unit', ignoring.
/usr/lib/systemd/system/plymouth-start.service:15: Unit configured to use KillMode=none. This is unsafe, as it disables systemd's process lifecycle management for the service. Please update your service to use a safer KillMode=, such as 'mixed' or 'control-group'. Support for KillMode=none is deprecated and will eventually be removed.
/usr/lib/systemd/system/dbus.socket:5: ListenStream= references a path below legacy directory /var/run/, updating /var/run/dbus/system_bus_socket → /run/dbus/system_bus_socket; please update the unit file accordingly.
/usr/lib/systemd/system/gdm.service:30: Standard output type syslog is obsolete, automatically updating to journal. Please update your unit file, and consider removing the setting altogether.
maanya-goenka@debian:~/systemd (log-error)$ echo $?
1
maanya-goenka@debian:~/systemd (log-error)$ sudo build/systemd-analyze verify --recursive-errors=yes testcase.service
/home/maanya-goenka/systemd/testcase.service:2: Unknown key name 'foo' in section 'Unit', ignoring.
/usr/lib/systemd/system/plymouth-start.service:15: Unit configured to use KillMode=none. This is unsafe, as it disables systemd's process lifecycle management for the service. Please update your service to use a safer KillMode=, such as 'mixed' or 'control-group'. Support for KillMode=none is deprecated and will eventually be removed.
/usr/lib/systemd/system/dbus.socket:5: ListenStream= references a path below legacy directory /var/run/, updating /var/run/dbus/system_bus_socket → /run/dbus/system_bus_socket; please update the unit file accordingly.
/usr/lib/systemd/system/gdm.service:30: Standard output type syslog is obsolete, automatically updating to journal. Please update your unit file, and consider removing the setting altogether.
maanya-goenka@debian:~/systemd (log-error)$ echo $?
1
maanya-goenka@debian:~/systemd (log-error)$ sudo build/systemd-analyze verify --recursive-errors=no testcase.service
/home/maanya-goenka/systemd/testcase.service:2: Unknown key name 'foo' in section 'Unit', ignoring.
maanya-goenka@debian:~/systemd (log-error)$ echo $?
1
maanya-goenka@debian:~/systemd (log-error)$ sudo build/systemd-analyze verify --recursive-errors=one testcase.service
/home/maanya-goenka/systemd/testcase.service:2: Unknown key name 'foo' in section 'Unit', ignoring.
/usr/lib/systemd/system/plymouth-start.service:15: Unit configured to use KillMode=none. This is unsafe, as it disables systemd's process lifecycle management for the service. Please update your service to use a safer KillMode=, such as 'mixed' or 'control-group'. Support for KillMode=none is deprecated and will eventually be removed.
/usr/lib/systemd/system/dbus.socket:5: ListenStream= references a path below legacy directory /var/run/, updating /var/run/dbus/system_bus_socket → /run/dbus/system_bus_socket; please update the unit file accordingly.
/usr/lib/systemd/system/gdm.service:30: Standard output type syslog is obsolete, automatically updating to journal. Please update your unit file, and consider removing the setting altogether.
maanya-goenka@debian:~/systemd (log-error)$ echo $?
1
2. Next, we run the commands on a unit that is syntactically valid but has a non-existing dependency (i.e. foo2.service)
> cat <<EOF>foobar.service
[Unit]
Requires = foo2.service
[Service]
ExecStart = echo hello
EOF
OUTPUT:
maanya-goenka@debian:~/systemd (log-error)$ sudo build/systemd-analyze verify foobar.service
/usr/lib/systemd/system/plymouth-start.service:15: Unit configured to use KillMode=none. This is unsafe, as it disables systemd's process lifecycle management for the service. Please update your service to use a safer KillMode=, such as 'mixed' or 'control-group'. Support for KillMode=none is deprecated and will eventually be removed.
/usr/lib/systemd/system/dbus.socket:5: ListenStream= references a path below legacy directory /var/run/, updating /var/run/dbus/system_bus_socket → /run/dbus/system_bus_socket; please update the unit file accordingly.
/usr/lib/systemd/system/gdm.service:30: Standard output type syslog is obsolete, automatically updating to journal. Please update your unit file, and consider removing the setting altogether.
foobar.service: Failed to create foobar.service/start: Unit foo2.service not found.
maanya-goenka@debian:~/systemd (log-error)$ echo $?
1
maanya-goenka@debian:~/systemd (log-error)$ sudo build/systemd-analyze verify --recursive-errors=yes foobar.service
/usr/lib/systemd/system/plymouth-start.service:15: Unit configured to use KillMode=none. This is unsafe, as it disables systemd's process lifecycle management for the service. Please update your service to use a safer KillMode=, such as 'mixed' or 'control-group'. Support for KillMode=none is deprecated and will eventually be removed.
/usr/lib/systemd/system/dbus.socket:5: ListenStream= references a path below legacy directory /var/run/, updating /var/run/dbus/system_bus_socket → /run/dbus/system_bus_socket; please update the unit file accordingly.
/usr/lib/systemd/system/gdm.service:30: Standard output type syslog is obsolete, automatically updating to journal. Please update your unit file, and consider removing the setting altogether.
foobar.service: Failed to create foobar.service/start: Unit foo2.service not found.
maanya-goenka@debian:~/systemd (log-error)$ echo $?
1
maanya-goenka@debian:~/systemd (log-error)$ sudo build/systemd-analyze verify --recursive-errors=no foobar.service
maanya-goenka@debian:~/systemd (log-error)$ echo $?
0
maanya-goenka@debian:~/systemd (log-error)$ sudo build/systemd-analyze verify --recursive-errors=one foobar.service
/usr/lib/systemd/system/plymouth-start.service:15: Unit configured to use KillMode=none. This is unsafe, as it disables systemd's process lifecycle management for the service. Please update your service to use a safer KillMode=, such as 'mixed' or 'control-group'. Support for KillMode=none is deprecated and will eventually be removed.
/usr/lib/systemd/system/dbus.socket:5: ListenStream= references a path below legacy directory /var/run/, updating /var/run/dbus/system_bus_socket → /run/dbus/system_bus_socket; please update the unit file accordingly.
/usr/lib/systemd/system/gdm.service:30: Standard output type syslog is obsolete, automatically updating to journal. Please update your unit file, and consider removing the setting altogether.
foobar.service: Failed to create foobar.service/start: Unit foo2.service not found.
maanya-goenka@debian:~/systemd (log-error)$ echo $?
1
2021-07-26 13:02:17 -07:00
'--recursive-errors=[When verifying a unit, control dependency verification]:MODE' \
systemd-analyze: 'security' option to perform offline reviews of the specified unit file(s)
New option --offline which works with the 'security' command and takes in a boolean value. When set to true,
it performs an offline security review of the specified unit file(s). It does not rely on PID 1 to acquire
security information for the files like 'security' when used by itself does. It makes use of the refactored
security_info struct instead (commit #8cd669d3d3cf1b5e8667acc46ba290a9e8a8e529). This means that --offline can be
used with --image and --root as well. When used with --threshold, if a unit's overall exposure level is above
that set by the user, the default value being 100, --offline returns a non-zero exit status.
Example Run:
1. testcase.service is a unit file created for testing the --offline option
maanya-goenka@debian:~/systemd (systemd-security)$ cat<<EOF>testcase.service
> [Service]
> ExecStart = echo hello
> EOF
For the purposes of this demo, the security table outputted below has been cut to show only the first two security settings.
maanya-goenka@debian:~/systemd (systemd-security)$ sudo build/systemd-analyze security --offline=true testcase.service
/usr/lib/systemd/system/plymouth-start.service:15: Unit configured to use KillMode=none. This is unsafe, as it disables systemd's
process lifecycle management for the service. Please update your service to use a safer KillMode=, such as 'mixed' or 'control-group'.
Support for KillMode=none is deprecated and will eventually be removed.
/usr/lib/systemd/system/gdm.service:30: Standard output type syslog is obsolete, automatically updating to journal. Please update your
unit file, and consider removing the setting altogether.
/usr/lib/systemd/system/dbus.socket:5: ListenStream= references a path below legacy directory /var/run/, updating
/var/run/dbus/system_bus_socket → /run/dbus/system_bus_socket; please update the unit file accordingly.
NAME DESCRIPTION EXPOSURE
✗ PrivateNetwork= Service has access to the host's network 0.5
✗ User=/DynamicUser= Service runs as root user 0.4
→ Overall exposure level for testcase.service: 9.6 UNSAFE 😨
maanya-goenka@debian:~/systemd (systemd-security)$ echo $? 0
2. The testcase.service unit file is modified to set PrivateNetwork to "yes". This reduces the exposure level from 9.6 to 9.1.
maanya-goenka@debian:~/systemd (systemd-security)$ nano testcase.service
> [Service]
> ExecStart = echo hello
> PrivateNetwork = yes
> EOF
maanya-goenka@debian:~/systemd (systemd-security)$ sudo build/systemd-analyze security --offline=true testcase.service
/usr/lib/systemd/system/plymouth-start.service:15: Unit configured to use KillMode=none. This is unsafe, as it disables systemd's
process lifecycle management for the service. Please update your service to use a safer KillMode=, such as 'mixed' or 'control-group'.
Support for KillMode=none is deprecated and will eventually be removed.
/usr/lib/systemd/system/gdm.service:30: Standard output type syslog is obsolete, automatically updating to journal. Please update your
unit file, and consider removing the setting altogether.
/usr/lib/systemd/system/dbus.socket:5: ListenStream= references a path below legacy directory /var/run/, updating
/var/run/dbus/system_bus_socket → /run/dbus/system_bus_socket; please update the unit file accordingly.
NAME DESCRIPTION EXPOSURE
✓ PrivateNetwork= Service has access to the host's network
✗ User=/DynamicUser= Service runs as root user 0.4
→ Overall exposure level for testcase.service: 9.1 UNSAFE 😨
maanya-goenka@debian:~/systemd (systemd-security)$ echo $? 0
3. Next, we use the same testcase.service unit file but add the additional --threshold=60 option to see how --threshold works with
--offline. Since the overall exposure level is 91 which is greater than the threshold value set by the user (= 60), we can expect
a non-zero exit status.
maanya-goenka@debian:~/systemd (systemd-security)$ sudo build/systemd-analyze security --offline=true --threshold=60 testcase.service
/usr/lib/systemd/system/plymouth-start.service:15: Unit configured to use KillMode=none. This is unsafe, as it disables systemd's
process lifecycle management for the service. Please update your service to use a safer KillMode=, such as 'mixed' or 'control-group'.
Support for KillMode=none is deprecated and will eventually be removed.
/usr/lib/systemd/system/gdm.service:30: Standard output type syslog is obsolete, automatically updating to journal. Please update your
unit file, and consider removing the setting altogether.
/usr/lib/systemd/system/dbus.socket:5: ListenStream= references a path below legacy directory /var/run/, updating
/var/run/dbus/system_bus_socket → /run/dbus/system_bus_socket; please update the unit file accordingly.
NAME DESCRIPTION EXPOSURE
✓ PrivateNetwork= Service has access to the host's network
✗ User=/DynamicUser= Service runs as root user 0.4
→ Overall exposure level for testcase.service: 9.1 UNSAFE 😨
maanya-goenka@debian:~/systemd (systemd-security)$ echo $? 1
2021-08-17 10:25:38 -07:00
'--offline=[Perform a security review of the specified unit file(s)]:BOOL' \
systemd-analyze: add new 'security' option to compare unit's overall exposure level with
--threshold option added to work with security verb and with the --offline option so that
users can determine what qualifies as a security threat. The threshold set by the user is
compared with the overall exposure level assigned to a unit file and if the exposure is
higher than the threshold, 'security' will return a non-zero exit status. The default value
of the --threshold option is 100.
Example Run:
1. testcase.service is a unit file created for testing the --threshold option
maanya-goenka@debian:~/systemd (systemd-security)$ cat<<EOF>testcase.service
> [Service]
> ExecStart = echo hello
> EOF
For the purposes of this demo, the security table outputted below has been cut to show only the first two security settings.
maanya-goenka@debian:~/systemd (systemd-security)$ sudo build/systemd-analyze security --offline=true testcase.service
/usr/lib/systemd/system/plymouth-start.service:15: Unit configured to use KillMode=none. This is unsafe, as it disables systemd's
process lifecycle management for the service. Please update your service to use a safer KillMode=, such as 'mixed' or 'control-group'.
Support for KillMode=none is deprecated and will eventually be removed.
/usr/lib/systemd/system/gdm.service:30: Standard output type syslog is obsolete, automatically updating to journal. Please update your
unit file, and consider removing the setting altogether.
/usr/lib/systemd/system/dbus.socket:5: ListenStream= references a path below legacy directory /var/run/, updating
/var/run/dbus/system_bus_socket → /run/dbus/system_bus_socket; please update the unit file accordingly.
NAME DESCRIPTION EXPOSURE
✗ PrivateNetwork= Service has access to the host's network 0.5
✗ User=/DynamicUser= Service runs as root user 0.4
→ Overall exposure level for testcase.service: 9.6 UNSAFE 😨
maanya-goenka@debian:~/systemd (systemd-security)$ echo $? 0
2. Next, we use the same testcase.service file but add an additional --threshold=60 parameter. We would expect 'security' to exit
with a non-zero status because the overall exposure level (= 96) is higher than the set threshold (= 60).
maanya-goenka@debian:~/systemd (systemd-security)$ sudo build/systemd-analyze security --offline=true --threshold=60 testcase.service
/usr/lib/systemd/system/plymouth-start.service:15: Unit configured to use KillMode=none. This is unsafe, as it disables systemd's
process lifecycle management for the service. Please update your service to use a safer KillMode=, such as 'mixed' or 'control-group'.
Support for KillMode=none is deprecated and will eventually be removed.
/usr/lib/systemd/system/gdm.service:30: Standard output type syslog is obsolete, automatically updating to journal. Please update your
unit file, and consider removing the setting altogether.
/usr/lib/systemd/system/dbus.socket:5: ListenStream= references a path below legacy directory /var/run/, updating
/var/run/dbus/system_bus_socket → /run/dbus/system_bus_socket; please update the unit file accordingly.
NAME DESCRIPTION EXPOSURE
✗ PrivateNetwork= Service has access to the host's network 0.5
✗ User=/DynamicUser= Service runs as root user 0.4
→ Overall exposure level for testcase.service: 9.6 UNSAFE 😨
maanya-goenka@debian:~/systemd (systemd-security)$ echo $? 1
2021-08-17 10:40:15 -07:00
'--threshold=[Set a value to compare the overall security exposure level with]: NUMBER' \
2015-01-12 21:43:45 +01:00
'--no-pager[Do not pipe output into a pager]' \
2015-01-26 15:29:14 +01:00
'--man=[Do (not) check for existence of man pages]:boolean:(1 0)' \
2013-07-29 14:12:55 -05:00
'--order[When generating graph for dot, show only order]' \
'--require[When generating graph for dot, show only requirement]' \
2015-01-12 21:43:45 +01:00
'--fuzz=[When printing the tree of the critical chain, print also services, which finished TIMESPAN earlier, than the latest in the branch]:TIMESPAN' \
'--from-pattern=[When generating a dependency graph, filter only origins]:GLOB' \
'--to-pattern=[When generating a dependency graph, filter only destinations]:GLOB' \
2014-07-21 21:11:56 -04:00
{-H+,--host=}'[Operate on remote host]:userathost:_sd_hosts_or_user_at_host' \
2015-04-22 11:07:38 -07:00
{-M+,--machine=}'[Operate on local container]:machine:_sd_machines' \
2018-12-24 05:15:38 -06:00
'*::systemd-analyze commands:_systemd-analyze_commands'