Ubuntu 的 GRUB 审计为何仍检测不到 AppArmor 参数?
结论
审计脚本把所有以 linux 开头的 GRUB 命令都当作 Ubuntu 内核条目检查。你贴出的失败输出指向 memtest86+x64.bin。这是 memtest 启动项,不是 Ubuntu Linux 内核启动项,通常不会带有 apparmor=1 和 security=apparmor。因此,即使修复已经把参数写入普通内核启动项,审计也可能因为 memtest 行缺少参数而失败。
此外,脚本用两次 grep -v 分别检查参数是否存在。这样检查的是“每一行是否包含该参数”,并不能确认目标内核启动项是否同时包含两个参数。
检查 GRUB 配置中的内核条目
下面的脚本逐行检查 GRUB 配置中的 linux、linuxefi 和 linux16 命令,跳过镜像路径包含 memtest 的条目,并要求其余条目都包含两个完整参数:
#!/usr/bin/env bash
set -o pipefail
cfg=/boot/grub/grub.cfg
if [[ ! -r "$cfg" ]]; then
echo "无法读取 $cfg" >&2
exit 2
fi
awk '
/^[[:space:]]*(linux|linuxefi|linux16)[[:space:]]/ {
# 第二列是内核镜像路径;memtest 不是 Ubuntu Linux 内核条目。
if ($2 ~ /(^|\/)memtest[^/]*$/) next
checked++
has_apparmor = 0
has_security = 0
for (i = 3; i <= NF; i++) {
if ($i == "apparmor=1") has_apparmor = 1
if ($i == "security=apparmor") has_security = 1
}
if (!has_apparmor || !has_security) {
printf "缺少参数的内核条目:%s\n", $0
failed = 1
}
}
END {
if (checked == 0) {
print "未找到可检查的 Linux 内核条目" > "/dev/stderr"
exit 2
}
if (failed) exit 1
print "所有检查到的 Linux 内核条目均包含所需参数"
}
' "$cfg"
该检查按空白分隔 GRUB 命令参数,并逐字段进行完整匹配,不会把相似但不同的参数值误认为目标参数。如果没有找到待检查的内核条目,它也会返回错误,避免空结果被当作审计通过。
跳过 memtest 是根据你给出的输出,以及“检查 Linux 内核启动参数”这一目的作出的处理。如果你的合规规则要求检查所有 GRUB linux 命令,应按规则调整筛选条件,不要为了让检查通过而忽略实际要求检查的条目。
核对修复是否已写入配置
修复脚本会更新 /etc/default/grub 中的 GRUB_CMDLINE_LINUX,再通过 update-grub 生成 GRUB 配置。可以分别查看配置变量和生成后的内核命令:
grep '^GRUB_CMDLINE_LINUX=' /etc/default/grub
grep -E '^[[:space:]]*(linux|linuxefi|linux16)[[:space:]]' /boot/grub/grub.cfg
确认生成的配置中,目标内核条目确实包含这两个参数。修复脚本打印 CONFIGURED: Reboot required 时也提示了需要重启。重新生成配置后,当前运行中的内核还不一定使用了新参数。
检查当前运行内核
重启后,可以检查当前内核实际收到的参数:
tr ' ' '\n' </proc/cmdline | grep -Fx -e 'apparmor=1' -e 'security=apparmor'
这个命令查看的是当前启动会话,不能代替对所有 GRUB 启动项的配置审计。检查生成的配置可以确认启动项;检查 /proc/cmdline 可以确认当前运行内核。两项检查的结果和用途不同。
备注:内容仅供参考。
