summaryrefslogtreecommitdiffstats
path: root/test/units/testsuite-63.sh
diff options
context:
space:
mode:
authorMaanya Goenka <t-magoenka@microsoft.com>2021-08-25 18:44:26 +0200
committerMaanya Goenka <t-magoenka@microsoft.com>2021-08-31 17:02:08 +0200
commit4b6221194d796c5839314e0462ca6a65f28dd1d1 (patch)
tree93385ddb47b4407040dafdb3096f5b107aa7a4e3 /test/units/testsuite-63.sh
parentsystemd-analyze: allow parsing of JSON file to obtain custom security require... (diff)
downloadsystemd-4b6221194d796c5839314e0462ca6a65f28dd1d1.tar.xz
systemd-4b6221194d796c5839314e0462ca6a65f28dd1d1.zip
test: add integration tests for systemd-analyze
Diffstat (limited to 'test/units/testsuite-63.sh')
-rwxr-xr-xtest/units/testsuite-63.sh574
1 files changed, 574 insertions, 0 deletions
diff --git a/test/units/testsuite-63.sh b/test/units/testsuite-63.sh
new file mode 100755
index 0000000000..207dfeff68
--- /dev/null
+++ b/test/units/testsuite-63.sh
@@ -0,0 +1,574 @@
+#!/usr/bin/env bash
+# shellcheck disable=SC2016
+set -eux
+
+systemd-analyze log-level debug
+
+mkdir -p /tmp/img/usr/lib/systemd/system/
+mkdir -p /tmp/img/opt/
+
+touch /tmp/img/opt/script0.sh
+chmod +x /tmp/img/opt/script0.sh
+
+cat <<EOF >/tmp/img/usr/lib/systemd/system/testfile.service
+[Service]
+ExecStart = /opt/script0.sh
+EOF
+
+set +e
+# Default behaviour is to recurse through all dependencies when unit is loaded
+systemd-analyze verify --root=/tmp/img/ testfile.service \
+ && { echo 'unexpected success'; exit 1; }
+
+# As above, recurses through all dependencies when unit is loaded
+systemd-analyze verify --recursive-errors=yes --root=/tmp/img/ testfile.service \
+ && { echo 'unexpected success'; exit 1; }
+
+# Recurses through unit file and its direct dependencies when unit is loaded
+systemd-analyze verify --recursive-errors=one --root=/tmp/img/ testfile.service \
+ && { echo 'unexpected success'; exit 1; }
+
+set -e
+
+# zero exit status since dependencies are ignored when unit is loaded
+systemd-analyze verify --recursive-errors=no --root=/tmp/img/ testfile.service
+
+rm /tmp/img/usr/lib/systemd/system/testfile.service
+
+cat <<EOF >/tmp/testfile.service
+[Unit]
+foo = bar
+
+[Service]
+ExecStart = echo hello
+EOF
+
+cat <<EOF >/tmp/testfile2.service
+[Unit]
+Requires = testfile.service
+
+[Service]
+ExecStart = echo hello
+EOF
+
+# Zero exit status since no additional dependencies are recursively loaded when the unit file is loaded
+systemd-analyze verify --recursive-errors=no /tmp/testfile2.service
+
+set +e
+# Non-zero exit status since all associated dependencies are recusrively loaded when the unit file is loaded
+systemd-analyze verify --recursive-errors=yes /tmp/testfile2.service \
+ && { echo 'unexpected success'; exit 1; }
+set -e
+
+rm /tmp/testfile.service
+rm /tmp/testfile2.service
+
+cat <<EOF >/tmp/testfile.service
+[Service]
+ExecStart = echo hello
+EOF
+
+
+# Zero exit status since the value used for comparison determine exposure to security threats is by default 100
+systemd-analyze security --offline=true /tmp/testfile.service
+
+set +e
+#The overall exposure level assigned to the unit is greater than the set threshold
+systemd-analyze security --threshold=90 --offline=true /tmp/testfile.service \
+ && { echo 'unexpected success'; exit 1; }
+set -e
+
+rm /tmp/testfile.service
+
+cat <<EOF >/tmp/img/usr/lib/systemd/system/testfile.service
+[Service]
+ExecStart = echo hello
+PrivateNetwork = yes
+PrivateDevices = yes
+PrivateUsers = yes
+EOF
+
+# The new overall exposure level assigned to the unit is less than the set thresholds
+# Verifies that the --offline= option works with --root=
+systemd-analyze security --threshold=90 --offline=true --root=/tmp/img/ testfile.service
+
+# Added an additional "INVALID_ID" id to the .json to verify that nothing breaks when input is malformed
+# The PrivateNetwork id description and weight was changed to verify that 'security' is actually reading in
+# values from the .json file when required. The default weight for "PrivateNetwork" is 2500, and the new weight
+# assigned to that id in the .json file is 6000. This increased weight means that when the "PrivateNetwork" key is
+# set to 'yes' (as above in the case of testfile.service) in the content of the unit file, the overall exposure
+# level for the unit file should decrease to account for that increased weight.
+cat <<EOF >/tmp/testfile.json
+{"User_Or_DynamicUser":
+ {"description_bad": "Service runs as root user",
+ "weight": 2000,
+ "range": 10
+ },
+"SupplementaryGroups":
+ {"description_good": "Service has no supplementary groups",
+ "description_bad": "Service runs with supplementary groups",
+ "description_na": "Service runs as root, option does not matter",
+ "weight": 200,
+ "range": 1
+ },
+"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 doesn't have access to the host's network",
+ "description_bad": "Service has access to the host's network",
+ "weight": 6000,
+ "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
+ },
+"ProtectControlGroups":
+ {"description_good": "Service cannot modify the control group file system",
+ "description_bad": "Service may modify the control group file system",
+ "weight": 1000,
+ "range": 1
+ },
+"ProtectKernelModules":
+ {"description_good": "Service cannot load or read kernel modules",
+ "description_bad": "Service may load or read kernel modules",
+ "weight": 1000,
+ "range": 1
+ },
+"ProtectKernelTunables":
+ {"description_good": "Service cannot alter kernel tunables (/proc/sys, …)",
+ "description_bad": "Service may alter kernel tunables",
+ "weight": 1000,
+ "range": 1
+ },
+"ProtectKernelLogs":
+ {"description_good": "Service cannot read from or write to the kernel log ring buffer",
+ "description_bad": "Service may read from or write to the kernel log ring buffer",
+ "weight": 1000,
+ "range": 1
+ },
+"ProtectClock":
+ {"description_good": "Service cannot write to the hardware clock or system clock",
+ "description_bad": "Service may write to the hardware clock or system clock",
+ "weight": 1000,
+ "range": 1
+ },
+"ProtectHome":
+ {"weight": 1000,
+ "range": 10
+ },
+"ProtectHostname":
+ {"description_good": "Service cannot change system host/domainname",
+ "description_bad": "Service may change system host/domainname",
+ "weight": 50,
+ "range": 1
+ },
+"ProtectSystem":
+ {"weight": 1000,
+ "range": 10
+ },
+"RootDirectory_Or_RootImage":
+ {"description_good": "Service has its own root directory/image",
+ "description_bad": "Service runs within the host's root directory",
+ "weight": 200,
+ "range": 1
+ },
+"LockPersonality":
+ {"description_good": "Service cannot change ABI personality",
+ "description_bad": "Service may change ABI personality",
+ "weight": 100,
+ "range": 1
+ },
+"MemoryDenyWriteExecute":
+ {"description_good": "Service cannot create writable executable memory mappings",
+ "description_bad": "Service may create writable executable memory mappings",
+ "weight": 100,
+ "range": 1
+ },
+"NoNewPrivileges":
+ {"description_good": "Service processes cannot acquire new privileges",
+ "description_bad": "Service processes may acquire new privileges",
+ "weight": 1000,
+ "range": 1
+ },
+"CapabilityBoundingSet_CAP_SYS_ADMIN":
+ {"description_good": "Service has no administrator privileges",
+ "description_bad": "Service has administrator privileges",
+ "weight": 1500,
+ "range": 1
+ },
+"CapabilityBoundingSet_CAP_SET_UID_GID_PCAP":
+ {"description_good": "Service cannot change UID/GID identities/capabilities",
+ "description_bad": "Service may change UID/GID identities/capabilities",
+ "weight": 1500,
+ "range": 1
+ },
+"CapabilityBoundingSet_CAP_SYS_PTRACE":
+ {"description_good": "Service has no ptrace() debugging abilities",
+ "description_bad": "Service has ptrace() debugging abilities",
+ "weight": 1500,
+ "range": 1
+ },
+"CapabilityBoundingSet_CAP_SYS_TIME":
+ {"description_good": "Service processes cannot change the system clock",
+ "description_bad": "Service processes may change the system clock",
+ "weight": 1000,
+ "range": 1
+ },
+"CapabilityBoundingSet_CAP_NET_ADMIN":
+ {"description_good": "Service has no network configuration privileges",
+ "description_bad": "Service has network configuration privileges",
+ "weight": 1000,
+ "range": 1
+ },
+"CapabilityBoundingSet_CAP_SYS_RAWIO":
+ {"description_good": "Service has no raw I/O access",
+ "description_bad": "Service has raw I/O access",
+ "weight": 1000,
+ "range": 1
+ },
+"CapabilityBoundingSet_CAP_SYS_MODULE":
+ {"description_good": "Service cannot load kernel modules",
+ "description_bad": "Service may load kernel modules",
+ "weight": 1000,
+ "range": 1
+ },
+"CapabilityBoundingSet_CAP_AUDIT":
+ {"description_good": "Service has no audit subsystem access",
+ "description_bad": "Service has audit subsystem access",
+ "weight": 500,
+ "range": 1
+ },
+"CapabilityBoundingSet_CAP_SYSLOG":
+ {"description_good": "Service has no access to kernel logging",
+ "description_bad": "Service has access to kernel logging",
+ "weight": 500,
+ "range": 1
+ },
+"CapabilityBoundingSet_CAP_SYS_NICE_RESOURCE":
+ {"description_good": "Service has no privileges to change resource use parameters",
+ "description_bad": "Service has privileges to change resource use parameters",
+ "weight": 500,
+ "range": 1
+ },
+"CapabilityBoundingSet_CAP_MKNOD":
+ {"description_good": "Service cannot create device nodes",
+ "description_bad": "Service may create device nodes",
+ "weight": 500,
+ "range": 1
+ },
+"CapabilityBoundingSet_CAP_CHOWN_FSETID_SETFCAP":
+ {"description_good": "Service cannot change file ownership/access mode/capabilities",
+ "description_bad": "Service may change file ownership/access mode/capabilities unrestricted",
+ "weight": 1000,
+ "range": 1
+ },
+"CapabilityBoundingSet_CAP_DAC_FOWNER_IPC_OWNER":
+ {"description_good": "Service cannot override UNIX file/IPC permission checks",
+ "description_bad": "Service may override UNIX file/IPC permission checks",
+ "weight": 1000,
+ "range": 1
+ },
+"CapabilityBoundingSet_CAP_KILL":
+ {"description_good": "Service cannot send UNIX signals to arbitrary processes",
+ "description_bad": "Service may send UNIX signals to arbitrary processes",
+ "weight": 500,
+ "range": 1
+ },
+"CapabilityBoundingSet_CAP_NET_BIND_SERVICE_BROADCAST_RAW":
+ {"description_good": "Service has no elevated networking privileges",
+ "description_bad": "Service has elevated networking privileges",
+ "weight": 500,
+ "range": 1
+ },
+"CapabilityBoundingSet_CAP_SYS_BOOT":
+ {"description_good": "Service cannot issue reboot()",
+ "description_bad": "Service may issue reboot()",
+ "weight": 100,
+ "range": 1
+ },
+"CapabilityBoundingSet_CAP_MAC":
+ {"description_good": "Service cannot adjust SMACK MAC",
+ "description_bad": "Service may adjust SMACK MAC",
+ "weight": 100,
+ "range": 1
+ },
+"CapabilityBoundingSet_CAP_LINUX_IMMUTABLE":
+ {"description_good": "Service cannot mark files immutable",
+ "description_bad": "Service may mark files immutable",
+ "weight": 75,
+ "range": 1
+ },
+"CapabilityBoundingSet_CAP_IPC_LOCK":
+ {"description_good": "Service cannot lock memory into RAM",
+ "description_bad": "Service may lock memory into RAM",
+ "weight": 50,
+ "range": 1
+ },
+"CapabilityBoundingSet_CAP_SYS_CHROOT":
+ {"description_good": "Service cannot issue chroot()",
+ "description_bad": "Service may issue chroot()",
+ "weight": 50,
+ "range": 1
+ },
+"CapabilityBoundingSet_CAP_BLOCK_SUSPEND":
+ {"description_good": "Service cannot establish wake locks",
+ "description_bad": "Service may establish wake locks",
+ "weight": 25,
+ "range": 1
+ },
+"CapabilityBoundingSet_CAP_WAKE_ALARM":
+ {"description_good": "Service cannot program timers that wake up the system",
+ "description_bad": "Service may program timers that wake up the system",
+ "weight": 25,
+ "range": 1
+ },
+"CapabilityBoundingSet_CAP_LEASE":
+ {"description_good": "Service cannot create file leases",
+ "description_bad": "Service may create file leases",
+ "weight": 25,
+ "range": 1
+ },
+"CapabilityBoundingSet_CAP_SYS_TTY_CONFIG":
+ {"description_good": "Service cannot issue vhangup()",
+ "description_bad": "Service may issue vhangup()",
+ "weight": 25,
+ "range": 1
+ },
+"CapabilityBoundingSet_CAP_SYS_PACCT":
+ {"description_good": "Service cannot use acct()",
+ "description_bad": "Service may use acct()",
+ "weight": 25,
+ "range": 1
+ },
+"UMask":
+ {"weight": 100,
+ "range": 10
+ },
+"KeyringMode":
+ {"description_good": "Service doesn't share key material with other services",
+ "description_bad": "Service shares key material with other service",
+ "weight": 1000,
+ "range": 1
+ },
+"ProtectProc":
+ {"description_good": "Service has restricted access to process tree(/proc hidepid=)",
+ "description_bad": "Service has full access to process tree(/proc hidepid=)",
+ "weight": 1000,
+ "range": 3
+ },
+"ProcSubset":
+ {"description_good": "Service has no access to non-process/proc files(/proc subset=)",
+ "description_bad": "Service has full access to non-process/proc files(/proc subset=)",
+ "weight": 10,
+ "range": 1
+ },
+"NotifyAccess":
+ {"description_good": "Service child processes cannot alter service state",
+ "description_bad": "Service child processes may alter service state",
+ "weight": 1000,
+ "range": 1
+ },
+"RemoveIPC":
+ {"description_good": "Service user cannot leave SysV IPC objects around",
+ "description_bad": "Service user may leave SysV IPC objects around",
+ "description_na": "Service runs as root, option does not apply",
+ "weight": 100,
+ "range": 1
+ },
+"Delegate":
+ {"description_good": "Service does not maintain its own delegated control group subtree",
+ "description_bad": "Service maintains its own delegated control group subtree",
+ "weight": 100,
+ "range": 1
+ },
+"RestrictRealtime":
+ {"description_good": "Service realtime scheduling access is restricted",
+ "description_bad": "Service may acquire realtime scheduling",
+ "weight": 500,
+ "range": 1
+ },
+"RestrictSUIDSGID":
+ {"description_good": "SUID/SGIDfilecreationbyserviceisrestricted",
+ "description_bad": "ServicemaycreateSUID/SGIDfiles",
+ "weight": 1000,
+ "range": 1
+ },
+"RestrictNamespaces_CLONE_NEWUSER":
+ {"description_good": "Servicecannotcreateusernamespaces",
+ "description_bad": "Servicemaycreateusernamespaces",
+ "weight": 1500,
+ "range": 1
+ },
+"RestrictNamespaces_CLONE_NEWNS":
+ {"description_good": "Service cannot create file system namespaces",
+ "description_bad": "Service may create file system namespaces",
+ "weight": 500,
+ "range": 1
+ },
+"RestrictNamespaces_CLONE_NEWIPC":
+ {"description_good": "Service cannot create IPC namespaces",
+ "description_bad": "Service may create IPC namespaces",
+ "weight": 500,
+ "range": 1
+ },
+"RestrictNamespaces_CLONE_NEWPID":
+ {"description_good": "Service cannot create process namespaces",
+ "description_bad": "Service may create process namespaces",
+ "weight": 500,
+ "range": 1
+ },
+"RestrictNamespaces_CLONE_NEWCGROUP":
+ {"description_good": "Service cannot create cgroup namespaces",
+ "description_bad": "Service may create cgroup namespaces",
+ "weight": 500,
+ "range": 1
+ },
+"RestrictNamespaces_CLONE_NEWNET":
+ {"description_good": "Service cannot create network namespaces",
+ "description_bad": "Service may create network namespaces",
+ "weight": 500,
+ "range": 1
+ },
+"RestrictNamespaces_CLONE_NEWUTS":
+ {"description_good": "Service cannot create hostname namespaces",
+ "description_bad": "Service may create hostname namespaces",
+ "weight": 100,
+ "range": 1
+ },
+"RestrictAddressFamilies_AF_INET_INET6":
+ {"description_good": "Service cannot allocate Internet sockets",
+ "description_bad": "Service may allocate Internet sockets",
+ "weight": 1500,
+ "range": 1
+ },
+"RestrictAddressFamilies_AF_UNIX":
+ {"description_good": "Service cannot allocate local sockets",
+ "description_bad": "Service may allocate local sockets",
+ "weight": 25,
+ "range": 1
+ },
+"RestrictAddressFamilies_AF_NETLINK":
+ {"description_good": "Service cannot allocate netlink sockets",
+ "description_bad": "Service may allocate netlink sockets",
+ "weight": 200,
+ "range": 1
+ },
+"RestrictAddressFamilies_AF_PACKET":
+ {"description_good": "Service cannot allocate packet sockets",
+ "description_bad": "Service may allocate packet sockets",
+ "weight": 1000,
+ "range": 1
+ },
+"RestrictAddressFamilies_OTHER":
+ {"description_good": "Service cannot allocate exotic sockets",
+ "description_bad": "Service may allocate exotic sockets",
+ "weight": 1250,
+ "range": 1
+ },
+"SystemCallArchitectures":
+ {"weight": 1000,
+ "range": 10
+ },
+"SystemCallFilter_swap":
+ {"weight": 1000,
+ "range": 10
+ },
+"SystemCallFilter_obsolete":
+ {"weight": 250,
+ "range": 10
+ },
+"SystemCallFilter_clock":
+ {"weight": 1000,
+ "range": 10
+ },
+"SystemCallFilter_cpu_emulation":
+ {"weight": 250,
+ "range": 10
+ },
+"SystemCallFilter_debug":
+ {"weight": 1000,
+ "range": 10
+ },
+"SystemCallFilter_mount":
+ {"weight": 1000,
+ "range": 10
+ },
+"SystemCallFilter_module":
+ {"weight": 1000,
+ "range": 10
+ },
+"SystemCallFilter_raw_io":
+ {"weight": 1000,
+ "range": 10
+ },
+"SystemCallFilter_reboot":
+ {"weight": 1000,
+ "range": 10
+ },
+"SystemCallFilter_privileged":
+ {"weight": 700,
+ "range": 10
+ },
+"SystemCallFilter_resources":
+ {"weight": 700,
+ "range": 10
+ },
+"IPAddressDeny":
+ {"weight": 1000,
+ "range": 10
+ },
+"DeviceAllow":
+ {"weight": 1000,
+ "range": 10
+ },
+"AmbientCapabilities":
+ {"description_good": "Service process does not receive ambient capabilities",
+ "description_bad": "Service process receives ambient capabilities",
+ "weight": 500,
+ "range": 1
+ },
+"INVALID_ID":
+ {"weight": 1000,
+ "range": 10
+ }
+}
+EOF
+
+# Reads in custom security requirements from the parsed .json file and uses these for comparison
+systemd-analyze security --threshold=90 --offline=true \
+ --security-policy=/tmp/testfile.json \
+ --root=/tmp/img/ testfile.service
+
+set +e
+systemd-analyze security --threshold=50 --offline=true \
+ --security-policy=/tmp/testfile.json \
+ --root=/tmp/img/ testfile.service \
+ && { echo 'unexpected success'; exit 1; }
+set -e
+
+rm /tmp/img/usr/lib/systemd/system/testfile.service
+
+systemd-analyze log-level info
+
+echo OK >/testok
+
+exit 0