4. IMA框架集成:内核IMA配置、IMA策略编写、IMA日志收集
好,咱们进入第四章。IMA(Integrity Measurement Architecture)这东西,说白了就是内核里的一把锁——它负责在文件被访问、被执行之前,先算个哈希,记个账。你想想看,如果固件启动后,谁改了关键文件都不知道,那前面做的所有信任链工作都白费了。
我个人习惯把IMA看作“运行时度量的大门”。它不负责度量谁,但它提供了一套机制:你写策略,它执行;你收日志,它记录。今天我们就从配置、策略、日志三个角度把它讲透。
核心要点:IMA 不是默认开启的,需要内核配置 + 启动参数 + 策略文件三者配合。缺一个,度量就出不来。
4.1 内核IMA配置
先看内核配置。我记得第一次搞IMA时,光找配置项就花了半天。其实没那么复杂,关键就几个开关。
| 配置项 | 说明 | 推荐值 |
|---|---|---|
CONFIG_IMA |
IMA 主开关,不选这个后面全白搭 | y |
CONFIG_IMA_MEASURE_PCR_IDX |
度量值写入 TPM 的哪个 PCR 寄存器 | 10 |
CONFIG_IMA_AUDIT |
是否开启审计日志,建议开 | y |
CONFIG_IMA_WRITE_POLICY |
允许运行时写入策略,调试阶段很有用 | y |
CONFIG_IMA_READ_POLICY |
允许读取当前策略,方便验证 | y |
CONFIG_IMA_APPRAISE |
IMA 评估模式,不仅度量还校验签名 | 按需 |
配置完这些,重新编译内核。嗯,这里要注意:如果你用的是发行版内核,可能已经带了IMA,但策略是空的。你可以先检查一下:
# 检查内核是否支持 IMA
cat /boot/config-$(uname -r) | grep CONFIG_IMA
# 如果输出是 CONFIG_IMA=y,说明内核已经支持
# 如果没输出,那就得自己编译内核了
小技巧:我建议在开发阶段把 CONFIG_IMA_WRITE_POLICY 和 CONFIG_IMA_READ_POLICY 都打开。这样你可以动态调整策略,不用每次改完都重启。等生产环境再关掉。
4.2 IMA策略编写
策略是IMA的灵魂。没有策略,IMA就是个空壳子,啥也不干。策略文件通常放在 /etc/ima/ 或者 /sys/kernel/security/ima/policy 里。
策略的语法其实不复杂,核心就是:谁(路径/文件类型)在什么条件下(执行/读取)做什么(度量/评估)。
4.2.1 策略语法基础
一条策略长这样:
# 格式:action func [mask] [fsmagic] [fsuuid] [uid] [gid] [fowner] [fgroup]
measure func=BPRM_CHECK
measure func=FILE_MMAP mask=MAY_EXEC
appraise func=FILE_CHECK mask=MAY_READ fowner=0
我来解释一下这几个关键字段:
- action:
measure(度量)、appraise(评估)、audit(审计) - func:触发点,比如
BPRM_CHECK(执行程序时)、FILE_MMAP(内存映射时)、FILE_CHECK(文件打开时) - mask:访问权限,
MAY_EXEC、MAY_READ、MAY_WRITE - fowner:文件所有者,0 表示 root
避坑指南:我曾经在生产环境上犯过一个错——策略写得太宽,把所有文件都度量了。结果系统启动慢了3倍,日志文件几分钟就撑爆了。记住:策略要精准,只度量你关心的关键路径。
4.2.2 实战策略示例
下面是我在项目中常用的一个策略模板,你可以直接拿来改:
# 度量所有可执行文件
measure func=BPRM_CHECK
# 度量所有 root 拥有的关键配置文件
measure func=FILE_CHECK mask=MAY_READ fowner=0
# 度量 /etc 下的所有文件
measure func=FILE_CHECK mask=MAY_READ fsmagic=0x01021994
# 度量特定路径
measure func=FILE_CHECK mask=MAY_READ obj=/usr/bin/*
# 不度量临时目录(提高性能)
dont_measure func=FILE_CHECK mask=MAY_READ obj=/tmp/*
dont_measure func=FILE_CHECK mask=MAY_READ obj=/var/tmp/*
加载策略的方式有两种:
# 方式一:启动时通过内核参数加载
# 在 GRUB 中添加 ima_policy=tcb
# 方式二:运行时写入(需要 CONFIG_IMA_WRITE_POLICY)
echo "measure func=BPRM_CHECK" > /sys/kernel/security/ima/policy
个人经验:我建议先用方式二调试。写一条策略,看一条日志,确认没问题了再固化到启动参数里。这样出了问题好回滚。
4.3 IMA日志收集
策略写好了,度量也跑了,日志在哪看?IMA 的日志主要有两个去处:内核环形缓冲区和 安全文件系统。
4.3.1 查看实时日志
最直接的方式是看 dmesg:
# 查看 IMA 相关的内核日志
dmesg | grep -i ima
# 输出示例:
# [ 5.123456] ima: No TPM chip found, activating TPM-bypass!
# [ 5.123789] ima: Allocated hash algorithm: sha256
# [ 5.124012] ima: No policy loaded, measuring everything
但 dmesg 只显示启动阶段的日志。运行时度量记录在 /sys/kernel/security/ima/ 下:
# 查看度量列表
cat /sys/kernel/security/ima/ascii_runtime_measurements
# 输出格式:
# PCR 模板哈希 文件名 文件哈希 签名
# 10 sha256:xxx /usr/bin/bash sha256:yyy none
4.3.2 日志格式解析
每一条度量记录包含以下字段:
| 字段 | 说明 | 示例 |
|---|---|---|
| PCR | 写入的 PCR 索引 | 10 |
| 模板哈希 | 度量模板的哈希值 | sha256:abc123... |
| 文件名 | 被度量文件的路径 | /usr/bin/bash |
| 文件哈希 | 文件内容的哈希值 | sha256:def456... |
| 签名 | 文件的数字签名(如果有) | none / 签名值 |
4.3.3 日志持久化
默认情况下,IMA 日志只存在内存里,重启就丢了。如果你需要持久化,我建议用 auditd 配合:
# 安装 auditd
apt-get install auditd
# 配置 auditd 捕获 IMA 事件
echo "-w /sys/kernel/security/ima/ascii_runtime_measurements -p r -k ima_log" >> /etc/audit/rules.d/ima.rules
# 重启 auditd
systemctl restart auditd
# 查看 IMA 审计日志
ausearch -k ima_log
注意:日志量可能会很大。我曾经在一个高负载服务器上,每秒产生上千条度量记录。建议设置日志轮转,或者只度量关键路径。
4.4 IMA 框架整体流程
为了让你更直观地理解 IMA 的工作流程,我画了一张图:
4.5 常见问题与排查
最后,我总结几个我在项目中踩过的坑:
- 日志为空:检查策略是否加载成功。
cat /sys/kernel/security/ima/policy看看有没有内容。 - 度量不生效:确认内核参数
ima_policy=是否正确。我曾经因为拼写错误,策略根本没加载。 - TPM 报错:如果没有 TPM 芯片,IMA 会进入 bypass 模式,日志照常记录,但不会扩展 PCR。这不影响功能。
- 性能问题:如果系统变慢,检查是不是度量了太多文件。用
dont_measure排除临时目录和只读文件系统。
调试小技巧:我习惯在开发阶段把 ima_policy=tcb 和 ima_appraise=off 一起用。这样只度量不评估,既能看日志又不会因为签名校验失败导致程序跑不起来。