4、Linux内核完整性度量:IMA框架介绍、IMA策略配置、IMA日志收集与分析
好,我们进入第四章。这一章讲的是IMA——Integrity Measurement Architecture,内核完整性度量架构。
说白了,IMA就是给Linux内核装了一个“行为记录仪”。它盯着所有被加载执行的文件、动态库、内核模块,记录它们的哈希值,然后跟一个“预期值”做比对。你想想看,如果攻击者替换了系统里的一个二进制文件,IMA能立刻发现。
我在项目中遇到过好几次,客户说“我的系统被篡改了但不知道从哪进来的”。后来部署了IMA,一查日志,发现是某个第三方驱动在启动时被替换了。嗯,这就是IMA的价值。
4.1 IMA框架:它到底在度量什么?
IMA是Linux内核安全子系统的一部分,从2.6.30开始就合入主线了。它不复杂,核心就三件事:
- 度量(Measure):计算文件的哈希值,存入内核度量列表(Measurement List)。
- 评估(Appraise):拿度量值跟预置的“好值”比对,决定是否允许执行。
- 保护(Protect):防止度量列表本身被篡改——通常配合TPM使用。
IMA的度量发生在文件被mmap、exec、open(只读)的时候。它不度量写操作,因为写操作会改变文件内容,度量没有意义。
核心概念:IMA度量列表
IMA度量列表是一个内核维护的、只增不减的链表。每个条目包含:文件名、文件哈希值、模板名称(如ima-ng)、PCR编号(如果用了TPM)。这个列表可以通过安全文件系统securityfs导出到用户态。
我个人的习惯是,在部署IMA之前,先搞清楚你的系统里哪些文件需要被度量。不是所有文件都需要——比如临时文件、日志文件,度量它们只会增加开销。
4.2 IMA策略配置:怎么写规则?
IMA策略就是一组规则,告诉内核“度量什么、怎么度量”。策略文件通常放在/etc/ima/ima-policy,或者通过内核启动参数ima_policy=指定。
来看一个典型的策略配置:
# 度量所有可执行文件和共享库
measure func=FILE_CHECK mask=MAY_EXEC uid=0
# 度量所有内核模块加载
measure func=MODULE_CHECK
# 度量关键配置文件(只读打开)
measure func=FILE_CHECK mask=MAY_READ obj=type=etc_t
# 对度量结果进行签名验证(评估模式)
appraise func=FILE_CHECK mask=MAY_EXEC appraise_type=imasig
每条规则由三部分组成:
- 动作:
measure(度量)、appraise(评估)、audit(审计)。 - 条件:
func=(触发函数)、mask=(访问模式)、uid=(用户ID)、obj=(安全上下文)。 - 修饰符:
appraise_type=(评估类型)、template=(模板格式)。
避坑指南
我曾经在配置IMA策略时,忘了加uid=0限制,结果所有用户的所有文件操作都被度量了。系统日志暴涨,性能直接掉了30%。记住:策略越精确,性能越好。
策略的加载顺序很重要。IMA支持内置策略和自定义策略。内置策略在编译内核时指定,自定义策略在启动后通过echo写入/sys/kernel/security/ima/policy。但注意:一旦写入自定义策略,内置策略就被覆盖了。
4.3 IMA日志收集:数据从哪来?
IMA日志有两个来源:
- 内核度量列表:通过
/sys/kernel/security/ima/measurement_list读取,二进制格式。 - 系统审计日志:通过
auditd捕获,记录在/var/log/audit/audit.log中,文本格式。
我个人更推荐用审计日志做日常监控,因为它可读性好,而且能跟其他安全事件关联。但如果你要做远程证明(Remote Attestation),必须用内核度量列表——它包含TPM PCR扩展值,是可信根的一部分。
来看一条典型的IMA审计日志:
type=IMA_MEASURE msg=audit(1700000000.123:456):
pid=1234 uid=0 auid=0 ses=1
subj=system_u:system_r:init_t:s0
comm="bash" exe="/usr/bin/bash"
hash="sha256:abc123def456..."
template=ima-ng
这条日志告诉我们:
- 进程
bash(PID 1234)被执行了 - 它的哈希值是
abc123def456... - 使用的模板是
ima-ng(默认模板,包含SHA256哈希和文件名)
4.4 IMA日志分析:怎么发现异常?
日志收集完了,关键是怎么分析。我一般分三步走:
- 建立基线:在系统刚安装完、确认没有被篡改时,收集所有度量值,生成“白名单”。
- 实时比对:用工具(如
ima-evm-utils)将当前度量值与白名单比对。 - 异常告警:发现不匹配的条目,立即告警并阻断(如果开启了
appraise模式)。
下面是一个简单的分析脚本思路:
#!/bin/bash
# 从审计日志中提取IMA度量记录
grep "type=IMA_MEASURE" /var/log/audit/audit.log | \
awk '{print $NF}' | \
sort | uniq -c | \
while read count hash; do
# 在白名单中查找
if ! grep -q "$hash" /etc/ima/whitelist; then
echo "ALERT: Unknown hash $hash seen $count times"
fi
done
重要提醒
IMA日志分析不能只看哈希值。文件名、安全上下文、进程信息都要看。我曾经遇到过一个案例:哈希值匹配,但文件名被改了——攻击者把恶意程序重命名为/usr/bin/ls,但内容完全不同。幸好IMA记录了完整路径,才没被蒙混过关。
4.5 IMA与TPM的联动:让度量结果不可篡改
IMA单独使用,只能“发现”篡改,不能“防止”篡改。因为度量列表存在内存里,攻击者如果有root权限,可以清空或伪造度量列表。
解决方案:把IMA度量值扩展到TPM的PCR寄存器中。TPM的PCR只能扩展(extend),不能重置(除非重启)。这样,攻击者即使篡改了内存中的度量列表,也无法伪造TPM中的PCR值。
配置方法很简单:在内核启动参数中加上ima_tpm,IMA就会自动将每次度量值扩展到PCR 10(默认)。
# 在GRUB配置中添加
GRUB_CMDLINE_LINUX="ima_tpm ima_policy=tcb"
然后,你可以用tpm2_pcrread查看PCR 10的值:
# tpm2_pcrread sha256:10
sha256:
10: 0xABCDEF1234567890...
这个值就是所有已度量文件的哈希值的聚合结果。任何文件的改变,都会导致这个值变化。
4.6 本章知识体系总览
下面这张图展示了IMA的核心工作流程和组件关系:
4.7 实战建议:从零开始部署IMA
如果你现在就想动手试试,我建议按这个顺序来:
- 确认内核支持:
cat /boot/config-$(uname -r) | grep CONFIG_IMA,确保相关选项都是y或m。 - 启用IMA:在GRUB启动参数中添加
ima_tpm ima_policy=tcb,重启。 - 查看度量列表:
cat /sys/kernel/security/ima/measurement_list | head -20。 - 收集基线:用
ima-evm-utils的ima_measure工具导出所有度量值。 - 模拟篡改:替换一个系统文件(比如
/bin/ls),观察IMA日志的变化。
小技巧
刚开始测试时,别开appraise模式——它会把系统锁死。先用measure模式收集数据,等基线建立好了,再逐步开启评估。我当年第一次部署时就是太心急,直接开了appraise,结果连登录都进不去了……
IMA不是银弹,但它是一个非常好的“系统行为基线”工具。配合TPM和远程证明,它能让你对系统的完整性状态做到心中有数。嗯,这一章的内容就到这,希望你能动手试试看。