AppArmor 常见问题和快速指南
- 2025-08-14 18:21:00
- 丁国栋
- 原创 115
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 安装的包可以规避这类启动问题。
--