AppArmor
AppArmor 是一个 强制访问控制 (MAC) 系统,基于 Linux 安全模块 (LSM) 实现。
AppArmor 与大多数其他 LSM 一样,是对默认的自主访问控制 (DAC) 的补充而非替代。因此,不可能授予进程比其最初拥有的更多的权限。
Ubuntu、SUSE 和其他一些发行版默认使用它。RHEL (及其变种) 使用 SELinux,它需要良好的用户空间集成才能正常工作。SELinux 为所有文件、进程和对象打上标签,因此非常灵活。然而,配置 SELinux 被认为非常复杂,并且需要支持的文件系统。而 AppArmor 则通过文件路径工作,其配置可以轻松调整。
AppArmor 通过在每个应用程序的基础上强制执行一组特定的规则集,主动保护操作系统和应用程序免受外部或内部威胁,甚至零日攻击。安全策略完全定义了单个应用程序可以访问哪些系统资源以及拥有何种权限。如果没有配置文件另行规定,则默认拒绝访问。AppArmor 包含一些默认策略,并通过结合高级静态分析和基于学习的工具,可以在数小时内成功部署非常复杂的应用程序的 AppArmor 策略。
每一次策略违规都会在系统日志中触发一条消息,并且 AppArmor 可以配置为通过弹出桌面实时违规警告来通知用户。
安装
AppArmor 在所有 官方支持的内核 中都可用。
安装 apparmor 以获取用于控制 AppArmor 的用户空间工具和库。要在启动时加载所有 AppArmor 配置文件,请启用 apparmor.service。
要启用 AppArmor 作为每次启动时的默认安全模型,请设置以下 内核参数
lsm=landlock,lockdown,yama,integrity,apparmor,bpf
lsm= 内核参数设置 Linux 安全模块的初始化顺序。可以通过 zgrep CONFIG_LSM= /proc/config.gz 找到内核配置的 lsm= 值,并使用 cat /sys/kernel/security/lsm 找到当前值。- 确保
apparmor是列表中第一个“主要”模块。[1] 有效值及其顺序的示例可以在 security/Kconfig 中找到。 capability应从lsm=中省略,因为它总是自动包含。
自定义内核
在编译内核时,至少需要设置以下选项
CONFIG_SECURITY_APPARMOR=y CONFIG_AUDIT=y
要默认启用 AppArmor Linux 安全模型并避免设置内核参数的需要,请另外设置 CONFIG_LSM 选项,并将 apparmor 指定为列表中的第一个“主要”模块
CONFIG_LSM="landlock,lockdown,yama,integrity,apparmor,bpf"
用法
查看当前状态
测试 AppArmor 是否已正确启用
$ aa-enabled
Yes
要显示当前加载状态,请使用 aa-status(8)
# aa-status
apparmor module is loaded. 44 profiles are loaded. 44 profiles are in enforce mode. ... 0 profiles are in complain mode. 0 processes have profiles defined. 0 processes are in enforce mode. 0 processes are in complain mode. 0 processes are unconfined but have a profile defined.
在 *complain mode* 模式下,允许配置文件违规,但会记录下来。Complain mode 用于测试新配置文件。请注意,即使在 complain mode 下,配置文件中的 deny 规则也会被强制执行/阻止。
在 *enforce mode* 模式下,配置文件违规会被阻止并记录下来。
解析配置文件
要加载(enforce 或 complain)、卸载、重新加载、缓存和统计配置文件,请使用 apparmor_parser。默认操作 (-a) 是以 enforce 模式加载新配置文件,使用 -C 开关可以将其加载到 complain 模式,使用 -r 选项可以覆盖现有配置文件,使用 -R 可以删除配置文件。每个操作也可以应用于多个配置文件。有关更多信息,请参阅 apparmor_parser(8) man 页。
禁用加载
通过卸载当前会话的所有配置文件来禁用 AppArmor
# aa-teardown
要阻止 AppArmor 配置文件在下次启动时加载,请禁用 apparmor.service。要阻止内核加载 AppArmor,请在 内核参数 中附加 apparmor=0,或者删除 设置 AppArmor 时添加的 lsm= 内核参数。
配置
审计和生成配置文件
要创建新配置文件,应运行 审计框架。这是因为 Arch Linux 采用了 systemd,并且默认情况下不将内核日志记录到文件。AppArmor 可以从用户空间的 auditd 守护进程获取内核审计日志,从而允许您构建配置文件。
可以使用 aa-genprof(8) 或 aa-autodep(8) 创建新的 AppArmor 配置文件。配置文件首先在 *complain mode* 下创建:在此模式下,仅报告策略违规,而不强制执行。规则由 aa-logprof(8) 工具(在 apparmor 包中提供)交互式创建。最后,应使用 aa-enforce(8) 将配置文件设置为 *enforce mode*。在此模式下,将强制执行相应配置文件中规则定义的策略。如有必要,可以通过反复执行 aa-logprof(8) 来添加其他规则,或者可以使用 aa-complain(8) 将配置文件设置回 complain mode。有关使用这些工具的详细指南,请参阅 AppArmor wiki - Profiling with tools。
请注意,aa-logprof(8) 还提供了 *deny* 规则,这些规则实际上并非严格必需,因为根据 AppArmor 的基本逻辑,所有未明确允许的规则都是被禁止的。但是,*deny* 规则有两个目的:
- *
deny* 规则优先于 *allow* 规则。它们经常用于/etc/apparmor.d/abstractions中位于/etc/apparmor.d/abstractions的许多 抽象 中,以阻止对重要文件夹/文件的任何访问。这确保了无意中创建的 allow 规则不会使配置文件过于宽松。 - *
deny* 规则会使日志记录静默,并减少后续运行 *aa-logprof* 时产生的噪音。需要注意的是,*deny* 规则在 *complain mode* 下也会被强制执行 - 因此,如果一个应用程序即使在 complain mode 下也无法正常工作,则应检查是否是配置文件中的 deny 规则或包含的抽象之一导致了问题。
或者,也可以手动创建配置文件,请参阅 AppArmor wiki - Profiling by hand 提供的指南。
除了 /etc/apparmor.d/ 中的默认配置文件外,/usr/share/apparmor/extra-profiles/ 中还有更多预定义的配置文件。请注意,这些不一定被认为是生产就绪的,因此可能需要手动干预或使用 aa-logprof(8)。
另一组 AppArmor 配置文件可以在 apparmor.d 项目中找到,但截至撰写本文时,该项目尚未稳定。
理解配置文件
配置文件是位于 /etc/apparmor.d/ 下的可读文本文件,用于描述二进制文件在执行时应如何被处理。一个基本的配置文件看起来像这样:
/etc/apparmor.d/usr.bin.test
#include <tunables/global>
profile test /usr/lib/test/test_binary {
#include <abstractions/base>
# Main libraries and plugins
/usr/share/TEST/** r,
/usr/lib/TEST/** rm,
# Configuration files and logs
@{HOME}/.config/ r,
@{HOME}/.config/TEST/** rw,
}
以 @ 符号开头的字符串是由抽象 (/etc/apparmor.d/abstractions/)、可调参数 (/etc/apparmor.d/tunables/) 或配置文件本身定义的变量。#include 直接包含其他配置文件。后跟一组字符的路径是 访问权限。模式匹配使用 AppArmor 的 globbing 语法。
最常见的用例由以下语句涵盖:
r— read: 读取数据w— write: 创建、删除、写入文件并扩展它m— memory map executable: 将文件内存映射为可执行文件x— execute: 执行文件;需要由一个 限定符 前导
请记住,这些权限不允许二进制文件超出自主访问控制 (DAC) 所规定的权限。
这只是一个简要概述,更详细的指南请查看 apparmor.d(5) man 页和 文档。
技巧与提示
在 DENIED 操作时获得桌面通知
通知守护进程会在 AppArmor 拒绝程序访问时显示桌面通知。要让 aa-notify 守护进程在登录时自动启动,请遵循以下步骤:
安装 审计框架,并启用和启动用户空间的 Linux Audit 守护进程。允许您的桌面用户读取 /var/log/audit 中的审计日志,方法是将其添加到 audit 用户组
# groupadd -r audit # gpasswd -a user audit
将 audit 组添加到 auditd.conf
/etc/audit/auditd.conf
log_group = audit
tmpfiles.d 配置文件集,其中包含以下行:/usr/lib/tmpfiles.d/audit.conf
[...] d /var/log/audit 700 root root - - [...] z /var/log/audit 700 root root - -
这些配置会在每次调用 systemd-tmpfiles(例如通过 pacman 进行系统升级时)时,使 /var/log/audit 对仅属于 audit 用户组的用户帐户不可读。您可以覆盖此行为,方法是创建以下文件:
/etc/tmpfiles.d/audit.conf
z /var/log/audit 750 root audit - -
wheel 或 adm。安装 python-notify2 和 python-psutil。
创建一个 桌面启动器,内容如下:
~/.config/autostart/apparmor-notify.desktop
[Desktop Entry] Type=Application Name=AppArmor Notify Comment=Receive on screen notifications of AppArmor denials TryExec=aa-notify Exec=aa-notify -p -s 1 -w 60 -f /var/log/audit/audit.log StartupNotify=false NoDisplay=true
重启并检查 aa-notify 进程是否正在运行
$ pgrep -ax aa-notify
有关更多信息,请参阅 aa-notify(8)。
通过缓存配置文件加速 AppArmor 启动
由于 AppArmor 需要将配置的配置文件转换为二进制格式,这可能会显著增加启动时间。您可以使用以下命令检查当前的 AppArmor 启动时间:
$ systemd-analyze blame | grep apparmor
要启用 AppArmor 配置文件的缓存,请取消注释:
/etc/apparmor/parser.conf
## Turn creating/updating of the cache on by default write-cache
要更改默认缓存位置,请添加:
/etc/apparmor/parser.conf
cache-loc=/path/to/location
/var/cache/apparmor/,之前是 /etc/apparmor.d/cache.d/。重启并再次检查 AppArmor 启动时间,以查看改进。
$ systemd-analyze blame | grep apparmor
故障排除
Samba SMB/CIFS 服务器启动失败
请参阅 Samba#Permission issues on AppArmor。
升级到 AppArmor v4 后无法登录
在极少数情况下,升级到 AppArmor 版本 4 后,可能无法登录任何系统帐户。
系统的 journal 可能包含类似以下的错误:
unix_chkpwd[1612]: check pass; user unknown unix_chkpwd[1612]: password check failed for user (john) gdm-password][1574]: pam_unix(gdm-password:auth): authentication failure; logname= uid=0 euid=0 tty=/dev/tty1 ruser= rhost= user=john kernel: audit: type=1400 audit(1730844640.468:171): apparmor="DENIED" operation="capable" class="cap" profile="unix-chkpwd" pid=1612 comm="unix_chkpwd" capability=2 capname="dac_read_search" kernel: audit: type=1400 audit(1730844640.468:172): apparmor="DENIED" operation="capable" class="cap" profile="unix-chkpwd" pid=1612 comm="unix_chkpwd" capability=1 capname="dac_override"
这可能是由于 /etc/shadow 和/或 /etc/gshadow 对 root 用户不可读(即这些文件的权限位可能完全未设置)引起的。因此,一个可能的解决方案是:
- 重启,并禁用 AppArmor,方法是在启动时编辑相应的 引导加载程序 条目,或使用不启用 AppArmor 的备用引导项。
- 以
root身份登录,并设置正确的文件权限:chmod 600 /etc/shadow /etc/gshadow - 再次重启。
Linux 发行版之间的差异
您经常会找到关于 Ubuntu 上 AppArmor 的信息,这可能会令人困惑,因为 Ubuntu 对 AppArmor 进行了许多内核补丁。其他发行版也可能拥有自己的内核补丁,而 Arch Linux 使用接近主线的内核。
例如,apparmor.d(5) 在其 6.17 版本中记录了 dbus 规则,这比其在主线内核中的支持早了数年 [5]。支持也因 D-Bus 实现 而异:dbus 包在没有 AppArmor 支持的情况下构建,而这对于应用 dbus AppArmor 规则是必需的。
Ubuntu 应用的 AppArmor 特定内核补丁可以在以下位置找到(将 jammy 替换为您感兴趣的 Ubuntu 版本的代号):
https://git.launchpad.net/~ubuntu-kernel/ubuntu/+source/linux/+git/jammy/log/?qt=grep&q=UBUNTU%3A+SAUCE%3A+apparmor
用户空间工具支持的 ABI 版本可以在 /etc/apparmor.d/abi/ 中找到。当前运行的内核支持的 ABI 可以使用以下命令显示:
$ aa-features-abi --extract
或者
$ ls /sys/kernel/security/apparmor/features/
参见
- Wikipedia:AppArmor
- AppArmor wiki
- AppArmor Core Policy Reference — 对配置文件中可用选项的详细描述
- Ubuntu 教程 — 可用实用工具和配置文件创建的通用概述
- Ubuntu Wiki — 基本命令概述
- AppArmor 版本 — 版本概述和相应发行说明的链接
- 内核接口 — AppArmor 内核模块的底层接口
- wikipedia:Linux Security Modules — AppArmor 所基于的 Linux 内核模块
- AppArmor in openSUSE Security Guide