4、Linux内核的IMA机制:IMA概述、IMA策略配置、IMA日志收集与解析

好,咱们进入可信启动实战的第四个模块——IMA。说实话,IMA 这玩意儿,我第一次接触的时候也觉得有点绕。但搞明白了之后,你会发现它其实是内核给你的一把「审计放大镜」。它能盯着每一个文件,看它到底被谁执行了、内容有没有被改过。

我当年在做一个等保三级项目时,客户要求「所有可执行文件必须被度量」。当时第一反应就是上 IMA。嗯,今天我就把 IMA 的底裤给你扒干净。

4.1 IMA 概述:它到底在度量什么?

IMA,全称 Integrity Measurement Architecture,中文叫「完整性度量架构」。说白了,它就是在文件被访问(比如执行、mmap)之前,先算个哈希,然后把这个哈希记录下来。

你想想看,如果某个恶意程序替换了 /bin/ls,你肉眼根本看不出来。但 IMA 会记录下这个文件的度量值。你只要对比一下就知道——嗯,这个 ls 已经不是原来的 ls 了。

核心要点:IMA 度量的是文件的「内容完整性」,不是「权限完整性」。它只关心文件内容有没有变,不关心谁改了它。

IMA 的工作流程其实很简单:

  • 触发点:文件被打开执行(BPRM_CHECK)、文件被 mmap 到内存(FILE_MMAP)、文件被读取(FILE_READ)。
  • 动作:内核计算文件的 SHA1/SHA256 哈希值。
  • 记录:将哈希值、文件路径、元数据写入内核度量列表(IMA_MEASURE)。
  • 扩展:将度量值扩展到 TPM PCR 10 中(如果配置了 TPM)。

我记得有一次,客户说「为什么我改了配置文件,IMA 没报警?」我一看,原来他改的是 /etc/ssh/sshd_config,但这个文件不是可执行文件,默认策略不度量它。所以,IMA 不是什么都管的,它只度量你策略里指定的文件类型。

4.2 IMA 策略配置:怎么让它听你的?

IMA 的策略,说白了就是一组规则。规则写在 /etc/ima/ima-policy 或者内核启动参数里。我个人习惯把策略放在 /etc/ima/ima-policy,然后在 /etc/default/grub 里加上 ima_policy=tcb 来加载。

策略的语法长这样:

# 度量所有可执行文件
measure func=BPRM_CHECK

# 度量所有 mmap 的可执行文件
measure func=FILE_MMAP mask=MAY_EXEC

# 度量所有 root 用户读取的文件
measure func=FILE_READ uid=0

# 不度量 /tmp 目录下的文件
dont_measure func=FILE_READ fsmagic=0x01021994

这里有几个关键字段,我列个表给你看:

字段 含义 常用值
func 触发函数 BPRM_CHECK, FILE_MMAP, FILE_READ
mask 访问权限掩码 MAY_EXEC, MAY_READ, MAY_WRITE
uid 用户 ID 0(root), 1000(普通用户)
fsmagic 文件系统魔数 0x01021994(tmpfs), 0xEF53(ext4)
appraise 是否校验 appraise, dont_appraise

小技巧:如果你不想度量 /proc、/sys 这些伪文件系统,一定要加 dont_measure 规则。否则 IMA 日志会被刷爆。我曾经在一个生产环境上忘了加,结果一天之内日志涨了 2GB……嗯,教训深刻。

配置好策略后,用这个命令加载:

# 加载策略
echo "measure func=BPRM_CHECK" > /sys/kernel/security/ima/policy

# 查看当前策略
cat /sys/kernel/security/ima/policy

注意,/sys/kernel/security/ima/policy 这个文件只能写一次。如果你想重新加载,得重启系统。所以,我建议你在测试环境里先调好策略,再部署到生产。

4.3 IMA 日志收集与解析:怎么从日志里挖出真相?

IMA 的日志,主要存在两个地方:

  • 内核度量列表:在 /sys/kernel/security/ima/ascii_runtime_measurements 里,这是人类可读的格式。
  • 审计日志:如果开启了 auditd,IMA 事件会记录到 /var/log/audit/audit.log 里。

我们先看看 ascii_runtime_measurements 长什么样:

10 1a2b3c4d5e6f7890 ima-ng sha1:abcdef1234567890abcdef1234567890abcdef12 /usr/bin/bash
10 2b3c4d5e6f78901a ima-ng sha1:1234567890abcdef1234567890abcdef12345678 /usr/bin/ls
10 3c4d5e6f78901a2b ima-ng sha1:abcdefabcdefabcdefabcdefabcdefabcdefabcd /etc/passwd

每一行的格式是:

  1. PCR 编号:通常是 10,表示这个度量扩展到了 TPM PCR 10。
  2. 哈希值:模板哈希,用于校验完整性。
  3. 模板名称:一般是 ima-ng 或 ima-sig。
  4. 文件哈希:文件的 SHA1/SHA256 值。
  5. 文件路径:被度量文件的绝对路径。

那审计日志里的 IMA 事件呢?我 grep 给你看:

# 从 audit.log 中提取 IMA 事件
ausearch -m INTEGRITY_RULE -ts today

# 或者直接 grep
grep "ima" /var/log/audit/audit.log | head -5

输出大概是这样:

type=INTEGRITY_RULE msg=audit(1700000000.123:456): action=measure func=BPRM_CHECK
type=INTEGRITY_MEASURE msg=audit(1700000001.456:789): pid=1234 uid=0 auid=1000 ses=1 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 comm="bash" exe="/usr/bin/bash" hash="sha1:abcdef1234567890abcdef1234567890abcdef12"

这里的关键字段:

  • action:度量动作,measure 表示度量,appraise 表示校验。
  • comm:进程名。
  • exe:可执行文件路径。
  • hash:文件的哈希值。

注意:审计日志里的 IMA 事件默认可能不开启。你需要在 /etc/audit/rules.d/ima.rules 里加一条规则:-w /sys/kernel/security/ima/ascii_runtime_measurements -p wa -k ima_log。否则,你只能从 ascii_runtime_measurements 里看。

解析 IMA 日志,我一般用这个脚本:

#!/bin/bash
# 解析 IMA 度量列表,提取文件路径和哈希值
cat /sys/kernel/security/ima/ascii_runtime_measurements | while read line; do
    pcr=$(echo $line | awk '{print $1}')
    file_hash=$(echo $line | awk '{print $4}')
    file_path=$(echo $line | awk '{print $5}')
    echo "PCR: $pcr | Hash: $file_hash | File: $file_path"
done

当然,你也可以用 evmctl 工具来验证:

# 验证文件的 IMA 度量值
evmctl ima_verify /usr/bin/bash

# 查看文件的 IMA 扩展属性
getfattr -d -m "security.ima" /usr/bin/bash

这里有个坑——evmctl ima_verify 需要文件有 security.ima 扩展属性。如果文件没有这个属性,它会报错。我曾经在 CentOS 7 上遇到过,后来发现是内核没开启 CONFIG_IMA_APPRAISE。所以,编译内核时一定要确认这个选项。

4.4 IMA 知识体系总览

下面这张图,是我梳理的 IMA 核心逻辑。你可以把它当作一个「地图」,以后遇到 IMA 相关的问题,先看这张图定位问题。

IMA 知识体系总览 触发点:文件操作 策略匹配:func + mask + uid + fsmagic 度量:计算哈希值 扩展:写入 TPM PCR 10 日志记录:ascii_runtime_measurements 审计事件:/var/log/audit/audit.log 解析与验证:evmctl / ausearch / 自定义脚本 结果:文件完整性是否被篡改 说明 IMA 只度量策略 匹配的文件

从这张图你可以看到,IMA 的整个链路是:文件操作 → 策略匹配 → 度量/扩展 → 日志记录 → 解析验证 → 结果判定。任何一个环节出问题,都会导致度量失败。

我个人建议,在生产环境部署 IMA 之前,先在测试环境里跑一遍这个流程。特别是策略配置,一定要确认你度量了「该度量的」,排除了「不该度量的」。否则,要么漏报,要么日志爆炸。