- apparmor.service
apparmor.service es un servicio relacionado con apparmor. Los archivos se encuentran en /lib/systemd/system/ y /usr/lib/systemd/system/, y el contenido es el siguiente:
[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
El más importante de estos es /lib/apparmor/apparmor.systemd.
- apparmor.systemd
El archivo apparmor.systemd se encuentra en la ruta /lib/apparmor/ y el contenido es el siguiente:
#!/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"
Tome /lib/apparmor/apparmor.systemd reload en /lib/systemd/system/apparmor.service arriba como ejemplo para analizar el script.
(1) Mire primero el primer párrafo. El fragmento de código es el siguiente:
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=$?
;;
Independientemente de si el parámetro detrás de /lib/apparmor/apparmor.systemd es reiniciar, recargar o recargar a la fuerza, ingresará este código.
1) Primero verifique si /usr/bin/systemd-detect-virt existe y es ejecutable. Este es un archivo binario que existe en mi computadora, como se muestra a continuación:
$ ls -l /usr/bin/systemd-detect-virt
-rwxr-xr-x 1 root root 23416 2月15日 00:36 /usr/bin/systemd-detect-virt
Referencia: systemd-detect-virt Chinese Manual - systemd Chinese Manual - Documentación de desarrollo - Blog de Wenjiang
systemd-detect-virt se utiliza para detectar si el entorno operativo del sistema es un entorno virtualizado y para detectar qué entorno virtualizado es, como qué máquina virtual o contenedor.
2) A continuación, ejecute los comandos relacionados con systemd-detect-virt para la detección.
Dónde: la opción --container solo detecta contenedores (virtualización de kernel compartida).
El resultado de ejecutar este comando en el sistema del autor es:
$ systemd-detect-virt --quiet --container
$
Es decir, el juicio de la declaración if en el script anterior es falso, la declaración en él no se ejecutará y la declaración if se omitirá y se ejecutará.
3) A continuación, ejecute la sentencia de apparmor_restart.
apparmor_restart es una función, en /lib/apparmor/rc.apparmor.functions, el código es el siguiente:
apparmor_restart() {
if ! is_apparmor_loaded ; then
apparmor_start
rc=$?
return "$rc"
fi
__apparmor_restart
return $?
}
La función apparmor_start está en el mismo archivo (/lib/apparmor/rc.apparmor.functions), el código es el siguiente:
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
}
La función __apparmor_restart también está en el mismo archivo (/lib/apparmor/rc.apparmor.functions), el código es el siguiente:
__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"
}
La función is_apparmor_loaded también está en /lib/apparmor/rc.apparmor.functions, el código es el siguiente:
is_apparmor_loaded() {
if ! is_securityfs_mounted ; then
mount_securityfs
fi
if [ -f "${SFS_MOUNTPOINT}/profiles" ]; then
return 0
fi
is_apparmor_present
return $?
}
La función is_securityfs_mounted también está en lib/apparmor/rc.apparmor.functions, el código es el siguiente:
is_securityfs_mounted() {
test -d "$SECURITYFS" -a -d /sys/fs/cgroup/systemd || grep -q securityfs /proc/filesystems && grep -q securityfs /proc/mounts
return $?
}
La función is_apparmor_present también está en lib/apparmor/rc.apparmor.functions, el código es el siguiente:
# Test if the apparmor "module" is present.
is_apparmor_present() {
[ -d /sys/module/apparmor ]
}
En el sistema del autor, existe el directorio /sys/module/apparmor, como se muestra a continuación:
$ ls /sys/module/apparmor -ld
drwxr-xr-x 3 root root 0 5月22日 13:47 /sys/module/apparmor
Por lo tanto, el resultado de la ejecución de la función is_apparmor_present es 0.
En realidad, ejecute el comando de recarga /lib/apparmor/apparmor.systemd en /lib/systemd/system/apparmor.service, el resultado es el siguiente:
$ sudo /lib/apparmor/apparmor.systemd reload
Restarting AppArmor
Reloading AppArmor profiles
De esta forma, se puede ver que el script en realidad toma la rama de apparmor_restart -> __apparmor_restart -> parse_profiles.
Este artículo es demasiado largo, y el resto se seguirá analizando en artículos posteriores.