如何解读AppArmor的拦截日志?
美国、香港服务器
如何解读AppArmor的拦截日志?
12-20 来源:
解读 AppArmor 拦截日志的核心是提取关键字段,明确 “哪个进程、做了什么操作、访问了什么资源、为什么被拦截”,从而判断是正常防护生效,还是规则配置过严导致业务异常。以下是详细的日志字段解析、典型场景解读及排查方法。
一、 AppArmor 拦截日志的基本格式
AppArmor 拦截日志(DENIED 类型)会写入系统日志(/var/log/syslog 或 /var/log/kern.log),典型格式如下:
plaintext
Oct 25 14:30:00 ubuntu kernel: [12345.678901] audit: type=1400 audit(1729879800.123:45): apparmor="DENIED" operation="open" profile="/usr/sbin/mysqld" name="/root/test.txt" pid=6789 comm="mysqld" requested_mask="w" denied_mask="w" fsuid=112 ouid=0
日志由 内核标记、审计信息、AppArmor 核心字段 三部分组成,我们只需关注 apparmor= 及后续的关键字段。
二、 核心字段解析(按优先级排序)
字段 格式示例 含义 解读价值
apparmor apparmor="DENIED" 日志类型 表示操作被 AppArmor 强制拦截;若为 apparmor="COMPLAIN",则是投诉模式下的提醒(未实际拦截)。
profile profile="/usr/sbin/mysqld" 触发规则的进程配置文件 明确是哪个进程被拦截(如 mysqld/nginx/php-fpm),对应 AppArmor 配置文件 /etc/apparmor.d/usr.sbin.mysqld。
operation operation="open" 被拦截的操作类型 常见值:
- open:文件 / 目录的打开 / 读写
- connect:网络连接
- exec:执行命令 / 脚本
- mkdir:创建目录
- unlink:删除文件
name name="/root/test.txt" 进程尝试访问的资源 关键字段,明确被拦截的文件路径、网络端口或命令。
示例:
- 文件:/root/test.txt、/tmp/malicious.sh
- 网络:tcp://192.168.1.100:3306
requested_mask requested_mask="w" 进程请求的权限 权限标识:
- r= 读、w= 写、x= 执行、k= 文件锁定、m= 修改
示例:rw 表示进程尝试读写目标资源。
denied_mask denied_mask="w" AppArmor 拒绝的权限 与 requested_mask 对应,表示哪部分权限被拦截。若 requested_mask=rw、denied_mask=w,说明读权限允许,写权限被拒。
comm comm="mysqld" 进程名称 与 profile 对应,进一步确认进程身份(防止同名进程混淆)。
pid pid=6789 触发拦截的进程 PID 可通过 ps -p 6789 查看进程的详细信息(如运行用户、启动参数)。
fsuid fsuid=112 进程的文件系统用户 ID 对应系统用户(如 112 通常是 mysql 用户,33 是 www-data 用户),可通过 id 112 确认。
三、 典型场景日志解读
结合实际业务场景,以下是常见拦截日志的解读案例,区分 “正常防护” 和 “规则过严” 两种情况。
场景 1:MySQL 尝试写入敏感目录(正常防护)
日志内容:
plaintext
apparmor="DENIED" operation="open" profile="/usr/sbin/mysqld" name="/root/test.txt" pid=6789 comm="mysqld" requested_mask="w" denied_mask="w" fsuid=112 ouid=0
解读:
profile=/usr/sbin/mysqld → MySQL 进程被拦截;
operation=open + requested_mask=w → MySQL 尝试写入文件 /root/test.txt;
denied_mask=w → AppArmor 拒绝了写权限。
结论:这是 正常防护生效。因为 /root 是系统敏感目录,AppArmor 配置中明确禁止 MySQL 访问,拦截了攻击者可能的提权行为。
场景 2:Nginx 无法读取自定义配置文件(规则过严)
日志内容:
plaintext
apparmor="DENIED" operation="open" profile="/usr/sbin/nginx" name="/data/nginx/conf.d/site.conf" pid=1234 comm="nginx" requested_mask="r" denied_mask="r" fsuid=33 ouid=0
解读:
profile=/usr/sbin/nginx → Nginx 进程被拦截;
operation=open + requested_mask=r → Nginx 尝试读取自定义配置文件 /data/nginx/conf.d/site.conf;
denied_mask=r → 读权限被拒。
结论:这是 规则配置过严。因为 /data/nginx 是自定义配置目录,AppArmor 默认配置中未添加该路径的读权限,导致业务无法正常运行。
解决方案:在 Nginx 的 AppArmor 配置文件中添加规则:
ini
/data/nginx/** r,
场景 3:PHP-FPM 尝试执行 shell 命令(异常行为)
日志内容:
plaintext
apparmor="DENIED" operation="exec" profile="/usr/sbin/php-fpm8.1" name="/bin/bash" pid=5678 comm="php-fpm8.1" requested_mask="x" denied_mask="x" fsuid=33 ouid=0
解读:
profile=/usr/sbin/php-fpm8.1 → PHP-FPM 进程被拦截;
operation=exec + requested_mask=x → PHP-FPM 尝试执行 /bin/bash 命令;
denied_mask=x → 执行权限被拒。
结论:这是 异常行为。PHP-FPM 作为 Web 后端进程,正常业务无需执行 shell 命令,大概率是攻击者通过 Web 漏洞(如代码注入)尝试提权,AppArmor 成功阻断了攻击链。
场景 4:MySQL 尝试发起外部网络连接(可疑行为)
日志内容:
plaintext
apparmor="DENIED" operation="connect" profile="/usr/sbin/mysqld" name="tcp://103.XX.XX.XX:8080" pid=6789 comm="mysqld" requested_mask="send receive" denied_mask="send receive"
解读:
operation=connect → MySQL 尝试发起 TCP 网络连接;
name=tcp://103.XX.XX.XX:8080 → 目标是境外 IP 的 8080 端口;
requested_mask=send receive → 尝试发送 / 接收数据。
结论:这是 可疑行为。若 MySQL 无主从同步、备份等外网业务需求,该连接大概率是木马程序利用 MySQL 权限发起的恶意通信,需进一步排查 MySQL 是否被入侵。
四、 日志解读的核心原则
区分 “正常拦截” 和 “误拦截”
正常拦截:进程访问敏感资源(如 /root、/etc/shadow、/bin/bash),拦截日志是防护生效的表现;
误拦截:进程访问业务必需资源(如自定义配置目录、合法数据文件),拦截日志会导致业务异常,需调整 AppArmor 规则。
结合配置文件验证看到拦截日志后,需对照对应进程的 AppArmor 配置文件,确认是否存在相关规则:
若配置中明确 deny 目标资源 → 正常拦截;
若配置中未允许目标资源 → 规则遗漏,需添加允许规则。
警惕异常操作类型若日志中出现 exec(执行命令)、connect(外网连接)、unlink(删除系统文件)等操作,且无合理业务解释,需立即排查进程是否被入侵。
五、 快速排查工具
过滤特定进程的拦截日志
bash
运行
# 过滤 MySQL 的 DENIED 日志
sudo grep -i "apparmor=DENIED.*mysqld" /var/log/syslog
统计高频拦截资源
找出被频繁拦截的资源,判断是攻击还是规则问题:
bash
运行
sudo grep -i "apparmor=DENIED" /var/log/syslog | awk "{print $10}" | sort | uniq -c | sort -nr
($10 对应 name= 字段,需根据实际日志格式调整列数)
三二互联专业提供香港VPS,美国VPS主机,香港云服务器租用等业务香港美国到大陆CN2 GIA速度最快