AppArmor 常见问题和快速指南

2025-08-14 18:21:00
丁国栋
原创 115
摘要:本文记录 AppArmor 的一些常见问题笔记。

AppArmor 是一种保护机制,这个保护机制让人又爱又恨,需要正确掌握和遇到问题时经常想到它。

例如你把 MySQL 的数据目录移动到了其他目录,而又把这个目录链接到 /var/lib/mysql,启动 MySQL 服务时依然报错 [Server] Can't create test file 或 OS errno 13 - Permission denied 或 [Server] Failed to create file 等,这都可能是 AppArmor 在拦截。

在这个例子中我们可以找到  /etc/apparmor.d/usr.sbin.mysqld 编辑添加我们需要允许 mysqld 访问的目录。


# Allow data dir access
  /var/lib/mysql/ r,
  /var/lib/mysql/** rwk,
  /data/mysql/ r,
  /data/mysql/** rwk,


在修改配置文件后,需要重新加载 AppArmor。

一般两种方法:


systemctl reload apparmor
apparmor_parser -r /etc/apparmor.d/usr.sbin.mysqld
如果不重新加载,AppArmor 可能依然会拦截。


---

AppArmor 它在拦截某个进程时,有时并不记录日志(这点令人不解)。例如我们以为可以使用命令 journalctl -u apparmor --no-pager 查看它的拦截日志,但并不能在这里找到。这时我们需要去查看内核日志,使用 dmesg 命令。

例如我们通过 dmesg 命令可以查找到以下信息:


audit: type=1400 audit(1755139115.947:235): apparmor="DENIED" operation="open" class="file" profile="/usr/sbin/mysqld" name="/data/mysql/auto.cnf" pid=10385 comm="mysqld" requested_mask="wrc" denied_mask="wrc" fsuid=107 ouid=107
这样就很容易确认是 AppArmor 拦截的了。也可以直接使用 dmesg | grep 'apparmor="DENIED"' 来查找。


---

有时我们安装一个deb包、flatpak包、或者AppImage都会遇到一些奇奇怪怪的启动问题,不要怀疑,也是 AppArmor 在拦截。

比如:https://github.com/arduino/arduino-ide/issues/2429#issuecomment-2099775010 和 https://github.com/electron/electron/issues/42510

这里面除了创建一个 /etc/apparmor.d/usr.bin.app-exec-name 的配置文件之外,它还提到了一个临时的解决方案:


sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=1
确实也能解决✅。


例如我在使用 Termius 时,它总是提示:


[1522078.998650] audit: type=1400 audit(1755221276.764:9227): apparmor="DENIED" operation="userns_create" class="namespace" info="Userns create restricted - failed to find unprivileged_userns profile" error=-13 profile="unconfined" pid=2861742 comm="termius-app" requested="userns_create" denied="userns_create" target="unprivileged_userns"
而我创建了一个 /etc/apparmor.d/usr.bin.termius-app 的 AppArmor 配置文件:
abi <abi/4.0>,
include <tunables/global>
profile termius-app flags=(unconfined) {
  #include <abstractions/base>
  
  # 允许用户命名空间创建
  userns,
  
  # 允许 CAP_SYS_ADMIN 能力
  capability sys_admin,
  
  # 其他可能需要的基本权限
  network,
  unix,
  
  # 可选的:允许访问主目录
  owner @{HOME}/ r,
  owner @{HOME}/** rw,
}

注意:每一个 AppArmor 的配置文件可以写多个 profile。而 profile 后面紧跟的名称需要和 dmesg 中 apparmor="DENIED" 中的 profile 的名称一致。

结果并不起作用,它报的错误是:

[2916040:0815/111455.492472:FATAL:setuid_sandbox_host.cc(157)] The SUID sandbox helper binary was found, but is not configured correctly. Rather than run without sandboxing I'm aborting now. You need to make sure that /opt/Termius/chrome-sandbox is owned by root and has mode 4755.
[1]    2916040 trace trap (core dumped)  termius-app

但实际上 /opt/Termius/chrome-sandbox 并没有问题,通过 dmesg 命令确认发现还是 AppArmor 的问题。临时解决方案仍然是 sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=1 🤔。这个解决方案可以去参考 Restricted unprivileged user namespaces are coming to Ubuntu 23.10。虽然可以通过添加参数 --no-sandbox 启动也可以解决,但因为安全原因不推荐。

提示:类似的问题还有一个解决方案,如果是通过 apt 或 dpkg 安装的,则可以使用 snap 安装。通过 snap 安装的包可以规避这类启动问题。

--

发表评论
博客分类