summaryrefslogtreecommitdiff
path: root/src/analyze/analyze-security.h
Commit message (Collapse)AuthorAgeFilesLines
* analyze: systematically name verb entry point functions verb_xyz()Lennart Poettering2022-02-211-1/+1
| | | | | | Some of the functions so far were named do_xyz(), others dump_xyz() and even others test_xyz(). let's instead name them exactly like the verb exposed in the command line, just prefixed with verb_
* analyze: fully move "security" verb to analyze-security.[ch]Lennart Poettering2022-02-211-21/+1
| | | | let's move the verb entropy point too, like for the other verbs now.
* analyze: add --profile switch to security verbLuca Boccassi2021-11-261-0/+1
| | | | | | | Allows to pass a portable profile when doing offline analysis of units. Especially useful for analyzing portable images, since a lot of the security-relevant settings in those cases come from the profiles, but they are not shipped in the portable images.
* systemd-analyze: add new option to generate JSON output of security analysis ↵Maanya Goenka2021-09-061-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | table The new option --json= works with the 'security' verb and takes in one of three format flags. These are off which is the default, pretty and short which use JSON format flags for output. When set to true, it generates a JSON formatted output of the security analysis table. The format is a JSON array with objects containing the following fields: set which indicates if the id has been set or not, name which is what is used to refer to the id, json_field which is the equivalent JSON formatted id name only used for JSON outputs, description which is an outline of the id state, and exposure which is an unsigned integer in the range 0.0..10.0, where a higher value corresponds to a higher security threat. The JSON version of the table is printed on the standard output file. Example Run: The unit file testfile.service was created to test the --json= option maanya-goenka@debian:~/systemd (json-security)$ cat <<EOF >testfile.service > [Service] > ExecStart = echo hello > PrivateNetwork = yes > PrivateMounts = yes > PrivateDevices = yes > EOF Both the JSON output and the security analysis table below have been truncated to increase readability. 1. Testing for when --json=off maanya-goenka@debian:~/systemd (json-security)$ sudo build/systemd-analyze security --json=off --root= --offline=true testfile.service --no-pager /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. /home/maanya-goenka/systemd/foo.service:2: Unknown key name 'foo' in section 'Unit', ignoring. NAME DESCRIPTION EXPOSURE ✓ PrivateNetwork= Service has no access to the host's network ✗ User=/DynamicUser= Service runs as root user 0.4 ✗ CapabilityBoundingSet=~CAP_SET(UID|GID|PCAP) Service may change UID/GID identities/capabilities 0.3 ✗ CapabilityBoundingSet=~CAP_NET_ADMIN Service has administrator privileges 0.3 → Overall exposure level for testfile.service: 8.3 EXPOSED 🙁 2. Testing for when --json=pretty maanya-goenka@debian:~/systemd (json-security)$ sudo build/systemd-analyze security --json=pretty --root= --offline=true testfile.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. /home/maanya-goenka/systemd/foo.service:2: Unknown key name 'foo' in section 'Unit', ignoring. [ { "set" : true, "name" : "PrivateNetwork=", "json-field" : "PrivateNetwork", "description" : "Service has no access to the host's network", "exposure" : null }, { "set" : false, "name" : "User=/DynamicUser=", "json-field" : "UserOrDynamicUser", "decsription" : "Service runs as root user", "exposure" : "0.4" }, { "set" : false, "name" : "CapabilityBoundingSet=~CAP_SET(UID|GID|PCAP)", "json_field" : "CapabilityBoundingSet_CAP_SET_UID_GID_PCAP", "description" : "Service may change UID/GID identities/capabilities", "exposure" : "0.3" }, { "set" : false, "name" : "CapabilityBoundingSet=~CAP_NET_ADMIN", "json_field" : "CapabilityBoundingSet_CAP_NET_ADMIN", "description" : "Service has administrator privileges", "exposure" : "0.3" }, ... ] 3. Testing for when --json=short maanya-goenka@debian:~/systemd (json-security)$ sudo build/systemd-analyze security --json=short --root= --offline=true testfile.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. /home/maanya-goenka/systemd/foo.service:2: Unknown key name 'foo' in section 'Unit', ignoring. [{"set":true,"name":"PrivateNetwork=", "json_field":"PrivateNetwork", "description":"Service has no access to the host's network","exposure":null}, ...]
* systemd-analyze: add new 'security' option to allow user to choose custom ↵Maanya Goenka2021-08-311-2/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | requirements A new option --security-policy= is added to work with the 'security' verb in order to enable users to create and pass in a JSON file consisting of user defined requirements against which to compare the specified unit file(s). These requirements then serve as the measure of security threats for the file instead of the initial hard coded set of requirements that the 'security' verb of systemd-analyze relied on. Example Run: A snapshot of the user defined testfile.json file is shown below instead of the complete file for readability purposes. { "PrivateDevices": {"description_good": "Service has no access to hardware devices", "description_bad": "Service potentially has access to hardware devices", "weight": 1000, "range": 1 }, "PrivateMounts": {"description_good": "Service cannot install system mounts", "description_bad": "Service may install system mounts", "weight": 1000, "range": 1 }, "PrivateNetwork": {"description_good": "Service has no access to the host's network", "description_bad": "Service has access to the host's network", "weight": 2500, "range": 1 }, "PrivateTmp": {"description_good": "Service has no access to other software's temporary files", "description_bad": "Service has access to other software's temporary files", "weight": 1000, "range": 1 }, "PrivateUsers": {"description_good": "Service does not have access to other users", "description_bad": "Service has access to other users", "weight": 1000, "range": 1 } } 1. I created the jsontest.service file in order to test the --security-policy= option as follows: maanya-goenka@debian:~/systemd (custom-security)$ cat<<EOF>jsontest.service > [Service] > ExecStart = echo hello > PrivateNetwork = yes > PrivateDevices = yes > PrivateMounts = yes > EOF The security analysis table outputted below has been truncated to include only the first few lines for readability. maanya-goenka@debian:~/systemd (custom-security)$ sudo build/systemd-analyze security --root= --offline=true --security-policy=src/analyze/testfile.json jsontest.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 ✓ PrivateNetwork Service has no access to the host's network ✗ UserOrDynamicUser Service runs as root user ✗ CapabilityBoundingSet_CAP_SET_UID_GID_PCAP Service may change UID/GID identities/capabilities ✓ PrivateMounts Service cannot install system mounts ✓ PrivateDevices Service has no access to hardware devices → Overall exposure level for jsontest.service: 8.3 EXPOSED 🙁 maanya-goenka@debian:~/systemd (custom-security)$ echo $? 0 2. In order to ensure that the JSON data was actually being correctly parsed, I made some changes to the JSON file, specifically to the id "PrivateNetwork" as follows: Before: -------- "PrivateNetwork": {"description_good": "Service has no access to the host's network", "description_bad": "Service has access to the host's network", "weight": 2500, "range": 1 } After: -------- "PrivateNetwork": {"description_good": "Service runs without access to host network", "description_bad": "Service has access to the host's network", "weight": 6000, "range": 1 } As expected, the new description for the description_good field of the Private Network id was updated in the analysis table outputted below and the overall exposure level of the unit file decreased because the weight assigned to 'Private Network' (which is set to yes) increased from 2500 to 6000. maanya-goenka@debian:~/systemd (custom-security)$ sudo build/systemd-analyze security --root= --offline=true --security-policy=src/analyze/testfile.json jsontest.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 ✓ PrivateNetwork Service runs without access to the host's network ✗ UserOrDynamicUser Service runs as root user ✗ CapabilityBoundingSet_CAP_SET_UID_GID_PCAP Service may change UID/GID identities/capabilities ✓ PrivateMounts Service cannot install system mounts ✓ PrivateDevices Service has no access to hardware devices → Overall exposure level for jsontest.service: 7.8 EXPOSED 🙁 maanya-goenka@debian:~/systemd (custom-security)$ echo $? 0 3. When paired with security's --threshold= option, systemd-analyze exits with a non-zero error status indicating that the overall exposure level for the unit file (=78) is greater than the set threshold (=70). The same jsontest.service file is used for the demo run below: maanya-goenka@debian:~/systemd (custom-security)$ sudo build/systemd-analyze security --root= --offline=true --security-policy=src/analyze/testfile.json --threshold=70 jsontest.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 ✓ PrivateNetwork Service runs without access to host network ✗ UserOrDynamicUser Service runs as root user ✗ CapabilityBoundingSet_CAP_SET_UID_GID_PCAP Service may change UID/GID identities/capabilities ✓ PrivateMounts Service cannot install system mounts ✓ PrivateDevices Service has no access to hardware devices → Overall exposure level for jsontest.service: 7.8 EXPOSED 🙁 maanya-goenka@debian:~/systemd (custom-security)$ echo $? 1 new option
* systemd-analyze: add new 'security' option to compare unit's overall ↵Maanya Goenka2021-08-201-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* systemd-analyze: 'security' option to perform offline reviews of the ↵Maanya Goenka2021-08-201-1/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* license: LGPL-2.1+ -> LGPL-2.1-or-laterYu Watanabe2020-11-091-1/+1
|
* analyze: add new security verbLennart Poettering2018-11-301-0/+12