aa-complain 命令将指定程序配置文件切换至抱怨模式,不拦截行为仅记录拒绝事件;需确保二进制存在且profile已加载,重启进程后生效,并通过aa-status和dmesg验证。

用 aa-complain 切换指定程序到 Complain 模式
直接执行 sudo aa-complain /path/to/binary 即可将对应 profile 置为 Complain 模式,不拦截行为、只记录拒绝事件。该命令会自动定位并修改 /etc/apparmor.d/ 下匹配的配置文件(按路径转点命名),无需手动编辑。
- 例如
sudo aa-complain /usr/bin/tcpdump会让 tcpdump 的 profile 进入 Complain 模式,之后所有被拒访问都会记入日志但不阻断运行 - 目标二进制必须已存在且有对应 profile,否则报错
Profile not found - 执行后 profile 状态立即变更,但仅对后续新启动的进程生效——已运行的 tcpdump 进程不受影响,需重启才走新策略
确认是否真的进入 Complain 模式
别信命令返回就完事,aa-complain 成功不代表 profile 已加载或生效。必须查 aa-status 输出中该程序是否标记为 complain:
- 运行
sudo aa-status | grep -A2 "tcpdump",看输出里是否含complain字样(不是enforce) - 若没出现,说明 profile 根本没加载:检查
/etc/apparmor.d/usr.bin.tcpdump是否存在、cat /sys/module/apparmor/parameters/enabled是否为Y、systemctl status apparmor是否 active -
aa-status不显示某程序,常见原因是它没通过 systemd 或 wrapper 启动,而是直接调用二进制(比如/usr/bin/tcpdump -i lo),此时 AppArmor 不会自动关联 profile
Complain 模式下怎么查被拦了什么
Complain 模式不会阻断,但会把所有越权行为写进内核日志。最准的排查方式是盯 dmesg 中的 APPARMOR_DENIED 记录:
- 实时监听:
sudo dmesg -w | grep -i "apparmor.*denied" - 回溯最近 10 条:
sudo dmesg | tail -10 | grep -i denied - 如果用
journalctl,优先过滤 kernel 日志:sudo journalctl -t kernel | grep -i denied - 注意日志里带的
operation="open"、name="/tmp/xxx"、profile="/usr/bin/tcpdump"字段——这些就是你要加进 profile 的精确路径和权限依据
别把 aa-complain 当成永久调试开关
Complain 模式只是临时收行为日志的手段,不能长期开着。它不阻止任何操作,等于裸奔;而且日志量大时可能撑爆 dmesg ring buffer 或填满磁盘。
- 调试完必须切回 enforce:
sudo aa-enforce /usr/bin/tcpdump - 切回去前务必补全规则:根据刚才
dmesg里看到的name=路径,在 profile 里加对应r、w、ix权限,再sudo apparmor_parser -r /etc/apparmor.d/usr.bin.tcpdump - aa-logprof 生成的建议往往太宽(比如给
/tmp/** rw,而非/tmp/foo.sock rw,),人工收紧才是关键
实际配置中容易忽略的是 profile 加载时机和进程启动方式——AppArmor 只在 execve 阶段绑定策略,改完 aa-complain 不重启进程,等于白调。


















