跳转到内容

AppArmor

来自 Arch Linux 中文维基

AppArmor 是一种强制访问控制(Mandatory Access Control, MAC)系统,基于 Linux 安全模块(Linux Security Modules, LSM)实现。

就像其他大多数的 Linux 安全模块一样,AppArmor 是对默认的的自主访问控制(Discretionary Access Control, DAC)的补充,而非替代。因此,程序通过 AppArmor 获取到的权限不可能大于原本在 DAC 下拥有的权限。

Ubuntu,SUSE 和许多其他的发行版默认使用 AppArmor,而 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 查看。
  • lsm= 中不应包含 capability,因为它始终会被自动隐式包含。

自定义内核[编辑 | 编辑源代码]

自行编译内核时,需要启用以下选项:

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 模式下,违反策略的访问将被允许,但该行为会被记录在日志中。complain 模式常用于了解程序正常运行所需要的权限,或是测试新撰写的配置文件是否合适。但是,需要注意的是,在配置文件中被设定为 deny 的规则在 complain 模式下仍然会强制执行。

enforce 模式下,违反策略的访问将被拒绝,并记录到日志中。

解析配置文件[编辑 | 编辑源代码]

使用 apparmor_parser 以加载、卸载、重启、缓存或是统计配置文件。默认行为(-a)是以 enforce 模式加载配置文件。要以 complain 模式加载,请使用 -C 参数。要覆盖已有配置文件,使用 -r 参数。要删除配置文件,使用 -R 参数。每次操作也可能应用到多个配置文件上。参见 apparmor_parser(8) 手册页面以了解详情。

停用[编辑 | 编辑源代码]

要在当前会话临时停用 AppArmor,执行以下命令以停用所有配置文件:

# aa-teardown 

要永久停用 AppArmor 配置文件,请停用 apparmor.service。要阻止内核加载 AppArmor,删除在安装 AppArmor 时添加的 lsm= 内核参数

配置[编辑 | 编辑源代码]

审计与生成配置文件[编辑 | 编辑源代码]

要创建新的配置文件,确保 Audit 框架英语Audit framework正在运行,因为 Arch Linux 使用 systemd,内核日志默认不会保存到文件中。AppArmor 可以从用户空间的 auditd 进程抓取内核日志,从而协助编写配置文件。

注意:AppArmor audit 消息使用 AVC 记录格式,使用 ausearch 搜索时可能破坏 audit 日志的解析。在此查看漏洞报告:[2][3][4]

可以使用 aa-genprof(8)aa-autodep(8) 创建新的 AppArmor 配置文件。新创建的配置文件默认处于 complain 模式:此模式下,违反规则的行为仅会被记录,不会被拒绝。要交互式地创建配置文件,可以使用 apparmor 包中的 aa-logprof(8)。配置完成后,请使用 aa-enforce(8) 将配置文件设置为 enforce 模式。此模式下,配置文件中的规则将被严格执行。此外,可以重复执行 aa-logprof(8) 以添加额外的规则,也可以使用 aa-complain(8) 将配置文件重新设置为 complain 模式。可以在此找到更为详细的教程:AppArmor wiki - Profiling with tools

需要注意的是,aa-logprof(8) 也提供 deny 规则。不过根据 AppArmor 的设计逻辑,除非规则明确允许,否则任何行为都将被拒绝,因此严格来说没有必要使用 deny 规则。不过,deny 规则有以下两个用途:

  1. deny 规则的优先级比 allow 规则更高,在 /etc/apparmor.d/abstractions 中的许多 abstraction 中都有使用,用来阻断任何对重要文件(夹)的访问。这样做能防止创建 allow 规则时可能的疏忽,使得配置文件不会太宽松。
  2. deny 规则执行时不会在日志中记录,使得后续执行 aa-logprof 时产生更为简洁的日志。需要注意的是,即使是在 complain 模式下,deny 规则也会被严格执行――因此,如果程序在 complain 模式下还是会出错,应该检查在某一配置文件或其包含的 abstraction 中,是否有一条 deny 规则导致了此问题。

另外,也可以手动编写配置文件, 在此查看教程:AppArmor wiki - Profiling by hand

除了 /etc/apparmor.d/ 中的默认配置文件外,在 /usr/share/apparmor/extra-profiles/ 中还有更多预定义的配置文件。不过,这些配置文件并非一定适用于生产环境,因此可能需要手动修改或使用 aa-logprof(8)

也可以在 apparmor.d 项目处找到额外的 AppArmor 规则集。不过,直到撰写本文时,该项目并非稳定可用。

解读配置文件[编辑 | 编辑源代码]

配置文件是可读性很高的文本文件,保存在 /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,
}

@ 符号开头的字符串是在 abstraction(/etc/apparmor.d/abstractions/),tunables(/etc/apparmor.d/tunables/或配置文件本身中定义的变量。#include 将其他配置文件中的内容包含到此配置文件中来。路径后的字符是访问权限。使用 AppArmor 的通配符语法以实现模式匹配。

以下权限涵盖了最常见的使用场景:

  • r — 读取:读取数据
  • w — 写入:创建,删除,写入文件,或是附加内容到文件尾部
  • m — 映射:将文件映射为可执行内存
  • x — 执行:执行文件。需要在前面加上修饰符,形如 px(执行时切换配置文件)

注意,定义的权限始终无法使程序获得大于原本在 DAC 中拥有的权限。

此处仅提到了很浅显的内容。要查询更为详细的文档,请查看 apparmor.d(5) 手册页和 官方文档

提示与技巧[编辑 | 编辑源代码]

拒绝访问后发出桌面通知[编辑 | 编辑源代码]

当AppArmor拒绝了程序的访问后,通知进程可以显示桌面通知。通过以下步骤,可以在登录时自动启动aa-notify进程:

安装Audit framework并且启动/启用用户空间的Linux Audit进程。之后将你的桌面用户添加到 audit用户组,从而允许其读取审计日志(audit logs):

# groupadd -r audit
# gpasswd -a user audit

Add audit group to auditd.conf:

/etc/audit/auditd.conf
log_group = audit
提示:You may use other already existing system groups like wheel or adm.

Install python-notify2 and python-psutil.

Create a desktop launcher with the below content:

~/.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

Reboot and check if the aa-notify process is running:

$ pgrep -ax aa-notify
注意:Depending on your specific system configuration there could be A LOT of notifications displayed.

For more information, see aa-notify(8).

缓存配置文件以提高 AppArmor 启动速度[编辑 | 编辑源代码]

Since AppArmor has to translate the configured profiles into a binary format it may significantly increase the boot time. You can check current AppArmor startup time with:

$ systemd-analyze blame | grep apparmor

To enable caching AppArmor profiles, uncomment:

/etc/apparmor/parser.conf
## Turn creating/updating of the cache on by default
write-cache

To change default cache location add:

/etc/apparmor/parser.conf
cache-loc=/path/to/location
注意:Since 2.13.1 default cache location is /var/cache/apparmor/, previously it was /etc/apparmor.d/cache.d/.

Reboot and check AppArmor startup time again to see improvement:

$ systemd-analyze blame | grep apparmor

排错[编辑 | 编辑源代码]

无法启动 Samba SMB/CIFS 服务[编辑 | 编辑源代码]

参见 Samba#AppArmor_权限问题

aa-logprof 无法抓取事件[编辑 | 编辑源代码]

Audit framework英语Audit framework 日志可能包含特殊字符 0x1d[5]。这个问题有一个 AppArmor bug report。解决办法是执行以下命令:

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

升级到 AppArmor v4 后无法登录[编辑 | 编辑源代码]

在非常罕见的情况下,升级到 AppArmor v4 会导致无法登录到任何账户

系统日志中可能包含类似如下内容的错误:

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"

这可能是由于 root 账户无法读取 /etc/shadow 和/或 /etc/gshadow 导致的(例如,这些文件的权限位(Permission bits)尚未设定)。因此,可以试试以下解决办法:

  1. 重启,然后停用 AppArmor(在启动时编辑 Bootloader 参数,或者使用尚未启用 AppArmor 的 fallback 启动项)。
  2. root 身份登录,然后设定正确的文件权限:chmod 600 /etc/shadow /etc/gshadow
  3. 再次重启。

不同 Linux 发行版之间的区别[编辑 | 编辑源代码]

Information you find often is about AppArmor on Ubuntu, which can be confusing, since Ubuntu carries a lot of kernel patches regarding AppArmor. Other distributions may also carry their own kernel patches, while Arch Linux uses a close-to-mainline kernel.

For example, while apparmor.d(5) already documents dbus rules, they require support from AppArmor userspace tools, kernel and D-Bus daemon[6]. The corresponding kernel patch[7] is applied by Ubuntu, but not included in mainline Linux and official Arch kernels. (Support also varies by D-Bus implementation.)

AppArmor-specific kernel patches applied by Ubuntu can be found at (replace oracular with the codename of the Ubuntu version you are interested in):

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

The ABI versions supported by the userland tools can be found in /etc/apparmor.d/abi/. The ABI supported by the currently running kernel can be shown with:

$ aa-features-abi --extract

参见[编辑 | 编辑源代码]