apparmor默认以enforce模式运行,排查时需切complain模式收集拒绝日志;通过aa-status、journalctl和dmesg定位被拦路径与操作,再在/usr.sbin.nginx中添加精确路径规则,并重载profile后重启nginx生效。

AppArmor 默认以 enforce 模式运行,但排查问题时需灵活切换到 complain 模式收集拒绝事件;日志分析不能只看表面报错,得定位到具体被拦的路径和操作类型,才能精准补规则。
确认当前 AppArmor 状态与模式
先验证 AppArmor 是否启用、Nginx profile 是否加载、当前是 enforce 还是 complain:
-
sudo aa-status —— 查看整体状态,“apparmor module is enabled” 表示已激活;“profiles are loaded” 列表里应含
/usr/sbin/nginx -
sudo aa-status | grep nginx —— 输出类似
/usr/sbin/nginx (enforce)或(complain),明确当前策略执行模式 - sudo systemctl status apparmor —— 确保服务处于 active (running) 状态
快速判断是不是 AppArmor 在拦截
别靠猜测,直接查日志抓证据:
宝塔Linux面板11.8.1为官网当前正式版,新增AI建站能力并经过宝塔网站工程师深度调教,开放自定义AI功能API,同时对WAF进行界面重构和深度优化,提升拦截能力与运维效率。
-
sudo journalctl -u nginx --since "1 hour ago" | grep -i denied —— 若出现
operation not permitted或Permission denied,且带apparmor="DENIED"字样,基本就是它 - sudo dmesg -t | grep -i "apparmor.*denied" —— 内核环缓冲区里也会记下被拒动作,适合刚启动失败时查
- 关键字段要会读:
profile="/usr/sbin/nginx"(哪个策略)、name="/var/www/myapp/private.key"(哪个文件)、operation="open"(想干什么)、denied_mask="r"(读被拒)
切换模式:从 enforce 到 complain 收集线索
生产环境必须用 enforce,但调策略时可临时切 complain 模式,让请求跑通并记录所有越界行为:
- sudo aa-complain /usr/sbin/nginx —— 将 Nginx profile 切为 complain 模式(不阻断,只记日志)
- 复现一次出错请求(比如访问 HTTPS 页面触发私钥读取)
-
sudo aa-logprof —— 自动读取 audit 日志,生成建议规则(注意:它常加太宽,如
/var/www/**,需人工收紧) - 改完再切回:sudo aa-enforce /usr/sbin/nginx
解析拒绝日志并补写精确规则
日志里暴露的 name=... 路径,就是你必须加进 profile 的真实路径:
- 编辑 /etc/apparmor.d/usr.sbin.nginx,在
/usr/sbin/nginx PUx,下方追加规则 - 常见路径示例(按实际路径调整):
/run/php/php*.sock rw,(PHP-FPM 套接字,用通配兼容版本升级)/etc/ssl/private/** r,(SSL 私钥目录,**允许子路径,但仍是只读)/var/log/nginx/myapp.* log,(自定义日志,log是 AppArmor 特殊权限,支持 logrotate) - 避免
/var/**或/**这类宽泛规则——它等于关掉防护,审计时会被标高危
让新规则真正生效
改完配置不会自动起作用,必须 reload profile + restart 服务两步到位:
- sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.nginx —— 重载单个 profile(比重启整个 apparmor service 更安全)
- sudo systemctl restart nginx —— 新进程才会加载新策略
- 验证是否成功:sudo aa-status --verbose | grep nginx,检查无 parse error,且状态为
(enforce)










