AppArmor

出自 ArchWiki

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 安全模块的初始化顺序。内核配置的 lsm= 值可以使用 zgrep CONFIG_LSM= /proc/config.gz 找到,当前值可以使用 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.

抱怨模式下,配置文件的策略违规行为是被允许的,但会被记录下来。抱怨模式用于测试新配置文件。请注意,即使在抱怨模式下,配置文件的拒绝规则也会被强制执行/阻止。

强制模式下,配置文件的策略违规行为会被阻止并记录下来。

解析配置文件

要加载(强制或抱怨)、卸载、重新加载、缓存和统计配置文件,请使用 apparmor_parser。默认操作 (-a) 是以强制模式加载新配置文件,使用 -C 开关可以以抱怨模式加载,为了覆盖现有配置文件,请使用 -r 选项,要删除配置文件,请使用 -R。每个操作也可能应用于多个配置文件。有关更多信息,请参阅 apparmor_parser(8) 手册页。

禁用加载

通过卸载当前会话的所有配置文件来禁用 AppArmor

# aa-teardown 

要阻止 AppArmor 配置文件在下次启动时加载,禁用 apparmor.service。要阻止内核加载 AppArmor,请删除 设置 AppArmor 时添加的 lsm= 内核参数

配置

审计和生成配置文件

要创建新配置文件,审计框架应该正在运行。这是因为 Arch Linux 采用了 systemd,默认情况下不将内核日志记录到文件。AppArmor 可以从用户空间的 auditd 守护程序获取内核审计日志,从而允许您构建配置文件。

注意: Apparmor 审计消息使用 AVC 记录类型,并且在使用 ausearch 搜索日志时可能会破坏审计日志解析。查看错误报告 [2], [3], [4]

新的 AppArmor 配置文件可以通过使用 aa-genprof(8)aa-autodep(8) 创建。配置文件首先在抱怨模式下创建:在这种模式下,策略违规行为仅被报告但不被强制执行。规则由 aa-logprof(8) 工具交互式创建,该工具在 apparmor 软件包中可用。最后,应使用 aa-enforce(8) 将配置文件设置为强制模式。在这种模式下,尊重配置文件中的规则定义的策略将被强制执行。如果需要,可以通过重复执行 aa-logprof(8) 来添加其他规则,或者可以使用 aa-complain(8) 将配置文件设置回抱怨模式。有关使用这些工具的详细指南,请访问 AppArmor wiki - 使用工具进行配置文件分析

请注意,aa-logprof(8) 还提供拒绝规则,根据 AppArmor 的基本逻辑,并非明确允许的所有内容都被禁止,因此实际上并非绝对必要。但是,拒绝规则有两个目的

  1. 拒绝规则优先于允许规则。它们经常在 /etc/apparmor.d/abstractions 中的许多 抽象中使用,以阻止对重要文件夹/文件的任何访问。这确保了无意中创建的允许规则不会使配置文件过于宽松。
  2. 拒绝规则会使日志记录静默,并使后续的 aa-logprof 运行不那么嘈杂。重要的是要记住,拒绝规则也在抱怨模式下强制执行 - 因此,如果应用程序即使在抱怨模式下也无法正常工作,则应检查配置文件或包含的抽象之一中的拒绝规则是否是罪魁祸首。

或者,也可以手动创建配置文件,请参阅 AppArmor wiki - 手动配置文件分析 提供的指南。

除了 /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 — 读取:读取数据
  • w — 写入:创建、删除、写入文件并扩展它
  • m — 内存映射可执行文件:内存映射一个可执行文件
  • x — 执行:执行文件;需要以 限定符 开头

请记住,这些权限不允许二进制文件超出自主访问控制 (DAC) 规定的权限。

这仅仅是一个简短的概述,有关更详细的指南,请务必查看 apparmor.d(5) 手册页和 文档

技巧与诀窍

获取关于 DENIED 操作的桌面通知

通知守护程序在 AppArmor 拒绝程序访问时显示桌面通知。要在登录时自动启动 aa-notify 守护程序,请按照以下步骤操作

安装 审计框架 并启用和启动用户空间 Linux 审计守护程序。通过将您的桌面用户添加到 audit 用户组,允许其读取 /var/log/audit 中的审计日志

# groupadd -r audit
# gpasswd -a user audit

audit 组添加到 auditd.conf

/etc/audit/auditd.conf
log_group = audit
提示: 您可以使用其他已存在的系统组,例如 wheeladm

安装 python-notify2python-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
注意: 自 2.13.1 起,默认缓存位置为 /var/cache/apparmor/,之前为 /etc/apparmor.d/cache.d/

重启并再次检查 AppArmor 启动时间以查看改进

$ systemd-analyze blame | grep apparmor

故障排除

启动 Samba SMB/CIFS 服务器失败

请参阅 Samba#AppArmor 上的权限问题

aa-logprof 没有捕获到事件

审计框架日志可能包含特殊字符 0x1d[5]。 有一个 AppArmor 错误报告,但一个临时的解决方案是运行

# aa-logprof -f <(sed 's/\x1d.*//' < /var/log/audit/audit.log)

升级到 AppArmor v4 后无法登录

在极少数情况下,升级到 AppArmor 版本 4 后,可能无法登录任何系统帐户

system 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 用户读取(即,这些文件的权限位可能完全未设置)。 因此,一个可能的解决方案是

  1. 重启,并通过在启动期间编辑相应的启动引导程序条目或使用未启用 AppArmor 的备用启动条目,禁用 AppArmor
  2. root 身份登录,并设置正确的文件权限:chmod 600 /etc/shadow /etc/gshadow
  3. 再次重启。

Linux 发行版之间的差异

您经常找到的关于 AppArmor 的信息是关于 Ubuntu 的,这可能会让人感到困惑,因为 Ubuntu 携带了许多关于 AppArmor 的内核补丁。 其他发行版也可能携带自己的内核补丁,而 Arch Linux 使用接近主线的内核。

例如,虽然 apparmor.d(5) 已经记录了 dbus 规则,但它们需要来自 AppArmor 用户空间工具、内核和 D-Bus 守护进程的支持[6]。 相应的内核补丁[7] 由 Ubuntu 应用,但未包含在主线 Linux 和官方 Arch 内核中。(支持也因 D-Bus 实现而异。)

Ubuntu 应用的 AppArmor 特定的内核补丁可以在以下位置找到(将 oracular 替换为您感兴趣的 Ubuntu 版本的代号)

https://git.launchpad.net/~ubuntu-kernel/ubuntu/+source/linux/+git/oracular/log/?qt=grep&q=UBUNTU%3A+SAUCE%3A+apparmor

用户空间工具支持的 ABI 版本可以在 /etc/apparmor.d/abi/ 中找到。 当前运行的内核支持的 ABI 可以通过以下方式显示

$ aa-features-abi --extract

参见