- apparmor.service
apparmor.service is a service related to apparmor. The files are located in /lib/systemd/system/ and /usr/lib/systemd/system/, and the contents are as follows:
[Unit]
Description=Load AppArmor profiles
DefaultDependencies=no
Before=sysinit.target
After=local-fs.target
After=systemd-journald-audit.socket
RequiresMountsFor=/var/cache/apparmor
AssertPathIsReadWrite=/sys/kernel/security/apparmor/.load
ConditionSecurity=apparmor
Documentation=man:apparmor(7)
Documentation=https://gitlab.com/apparmor/apparmor/wikis/home/
# Don't start this unit on the Ubuntu Live CD
ConditionPathExists=!/rofs/etc/apparmor.d
# Don't start this unit on the Debian Live CD when using overlayfs
ConditionPathExists=!/run/live/overlay/work
[Service]
Type=oneshot
ExecStart=/lib/apparmor/apparmor.systemd reload
ExecReload=/lib/apparmor/apparmor.systemd reload
# systemd maps 'restart' to 'stop; start' which means removing AppArmor confinement
# from running processes (and not being able to re-apply it later).
# Upstream systemd developers refused to implement an option that allows overriding
# this behaviour, therefore we have to make ExecStop a no-op to error out on the
# safe side.
#
# If you really want to unload all AppArmor profiles, run aa-teardown
ExecStop=/bin/true
RemainAfterExit=yes
[Install]
WantedBy=sysinit.target
The most important of these is /lib/apparmor/apparmor.systemd.
- apparmor.systemd
The apparmor.systemd file is located in the /lib/apparmor/ path, and the content is as follows:
#!/bin/sh
# ----------------------------------------------------------------------
# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public
# License published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, contact Novell, Inc.
# ----------------------------------------------------------------------
APPARMOR_FUNCTIONS=/lib/apparmor/rc.apparmor.functions
aa_action()
{
echo "$1"
shift
"$@"
return $?
}
aa_log_warning_msg()
{
echo "Warning: $*"
}
aa_log_failure_msg()
{
echo "Error: $*"
}
aa_log_action_start()
{
echo "$@"
}
aa_log_action_end()
{
printf ""
}
aa_log_daemon_msg()
{
echo "$@"
}
aa_log_skipped_msg()
{
echo "Skipped: $*"
}
aa_log_end_msg()
{
printf ""
}
# source apparmor function library
if [ -f "${APPARMOR_FUNCTIONS}" ]; then
# shellcheck source=rc.apparmor.functions
. "${APPARMOR_FUNCTIONS}"
else
aa_log_failure_msg "Unable to find AppArmor initscript functions"
exit 1
fi
case "$1" in
start)
if [ -x /usr/bin/systemd-detect-virt ] && \
systemd-detect-virt --quiet --container && \
! is_container_with_internal_policy; then
aa_log_daemon_msg "Not starting AppArmor in container"
aa_log_end_msg 0
exit 0
fi
apparmor_start
rc=$?
;;
stop)
apparmor_stop
rc=$?
;;
restart|reload|force-reload)
if [ -x /usr/bin/systemd-detect-virt ] && \
systemd-detect-virt --quiet --container && \
! is_container_with_internal_policy; then
aa_log_daemon_msg "Not starting AppArmor in container"
aa_log_end_msg 0
exit 0
fi
apparmor_restart
rc=$?
;;
try-restart)
apparmor_try_restart
rc=$?
;;
kill)
apparmor_kill
rc=$?
;;
status)
apparmor_status
rc=$?
;;
*)
exit 1
;;
esac
exit "$rc"
Take /lib/apparmor/apparmor.systemd reload in /lib/systemd/system/apparmor.service above as an example to analyze the script.
(1) Look at the first paragraph first. The code snippet is as follows:
restart|reload|force-reload)
if [ -x /usr/bin/systemd-detect-virt ] && \
systemd-detect-virt --quiet --container && \
! is_container_with_internal_policy; then
aa_log_daemon_msg "Not starting AppArmor in container"
aa_log_end_msg 0
exit 0
fi
apparmor_restart
rc=$?
;;
Regardless of whether the parameter behind /lib/apparmor/apparmor.systemd is restart, reload or force-reload, it will enter this code.
1) First check whether /usr/bin/systemd-detect-virt exists and is executable. This is a binary file that does exist on my computer, as shown below:
$ ls -l /usr/bin/systemd-detect-virt
-rwxr-xr-x 1 root root 23416 2月15日 00:36 /usr/bin/systemd-detect-virt
systemd-detect-virt is used to detect whether the operating environment of the system is a virtualized environment, and to further detect which virtualized environment it is, such as which virtual machine or container.
2) Next, execute systemd-detect-virt related commands for detection.
Where: the --container option only detects containers (shared kernel virtualization).
The result of running this command on the author's system is:
$ systemd-detect-virt --quiet --container
$
That is to say, the judgment of the if statement in the above script is false, the statement in it will not be executed, and the if statement will be skipped and executed.
3) Next, execute the sentence of apparmor_restart.
apparmor_restart is a function, in /lib/apparmor/rc.apparmor.functions, the code is as follows:
apparmor_restart() {
if ! is_apparmor_loaded ; then
apparmor_start
rc=$?
return "$rc"
fi
__apparmor_restart
return $?
}
The apparmor_start function is in the same file (/lib/apparmor/rc.apparmor.functions), the code is as follows:
apparmor_start() {
aa_log_daemon_msg "Starting AppArmor"
if ! is_apparmor_present ; then
aa_log_failure_msg "Starting AppArmor - failed, To enable AppArmor, ensure your kernel is configured with CONFIG_SECURITY_APPARMOR=y the n add 'security=apparmor apparmor=1' to the kernel command line"
aa_log_end_msg 1
return 1
elif ! is_apparmor_loaded ; then
aa_log_failure_msg "Starting AppArmor - AppArmor control files aren't available under /sys/kernel/security/, please make sure securityfs is mounted."
aa_log_end_msg 1
return 1
fi
if [ ! -w "$SFS_MOUNTPOINT/.load" ] ; then
aa_log_failure_msg "Loading AppArmor profiles - failed, Do you have the correct privileges?"
aa_log_end_msg 1
return 1
fi
# if there is anything in the profiles file don't load
if ! read -r _ < "$SFS_MOUNTPOINT/profiles"; then
parse_profiles load
else
aa_log_skipped_msg ": already loaded with profiles."
return 0
fi
aa_log_end_msg 0
return 0
}
The __apparmor_restart function is also in the same file (/lib/apparmor/rc.apparmor.functions), the code is as follows:
__apparmor_restart() {
if [ ! -w "$SFS_MOUNTPOINT/.load" ] ; then
aa_log_failure_msg "Loading AppArmor profiles - failed, Do you have the correct privileges?"
return 4
fi
aa_log_daemon_msg "Restarting AppArmor"
parse_profiles reload
rc=$?
aa_log_end_msg "$rc"
return "$rc"
}
The is_apparmor_loaded function is also in /lib/apparmor/rc.apparmor.functions, the code is as follows:
is_apparmor_loaded() {
if ! is_securityfs_mounted ; then
mount_securityfs
fi
if [ -f "${SFS_MOUNTPOINT}/profiles" ]; then
return 0
fi
is_apparmor_present
return $?
}
The is_securityfs_mounted function is also in lib/apparmor/rc.apparmor.functions, the code is as follows:
is_securityfs_mounted() {
test -d "$SECURITYFS" -a -d /sys/fs/cgroup/systemd || grep -q securityfs /proc/filesystems && grep -q securityfs /proc/mounts
return $?
}
The is_apparmor_present function is also in lib/apparmor/rc.apparmor.functions, the code is as follows:
# Test if the apparmor "module" is present.
is_apparmor_present() {
[ -d /sys/module/apparmor ]
}
In the author's system, the /sys/module/apparmor directory exists, as shown below:
$ ls /sys/module/apparmor -ld
drwxr-xr-x 3 root root 0 5月22日 13:47 /sys/module/apparmor
Therefore, the execution result of the is_apparmor_present function is 0.
Actually execute the /lib/apparmor/apparmor.systemd reload command in /lib/systemd/system/apparmor.service, the result is as follows:
$ sudo /lib/apparmor/apparmor.systemd reload
Restarting AppArmor
Reloading AppArmor profiles
In this way, it can be seen that the script actually takes the branch of apparmor_restart -> __apparmor_restart -> parse_profiles.
This article is too long, and the rest will continue to be analyzed in subsequent articles.