4、运行时完整性监控:内核完整性监控(IMA)、文件完整性监控(FIM)、进程白名单、系统调用审计
运行时完整性监控,说白了就是盯着系统「活着的时候」有没有被人动手脚。启动度量保证的是开机那一刻的信任链,但系统跑起来之后呢?恶意软件、配置篡改、提权攻击,全是在运行时发生的。我见过太多团队把安全重心全放在启动阶段,结果系统上线三天就被挖了矿——嗯,这就是典型的「门锁好了,窗户开着」。
这一章我们聊四个核心手段:IMA(内核完整性度量)、FIM(文件完整性监控)、进程白名单、系统调用审计。它们各有侧重,但组合起来能覆盖运行时攻击的绝大多数路径。
4.1 内核完整性监控(IMA)
IMA 是 Linux 内核内置的完整性度量框架。它不依赖用户态工具,直接在内核里记录文件的哈希值,并扩展到运行时度量。我个人习惯把 IMA 理解为「内核级别的文件指纹打卡机」——每次文件被读取或执行,IMA 都会记录它的度量值,并存入内核度量列表(Measurement Log)。
核心机制:IMA 基于 LSM(Linux Security Module)钩子,在文件打开、mmap、exec 等关键路径上拦截操作,计算文件的 SHA1/SHA256 哈希,并与预定义的「良好值」比对。如果哈希不匹配,可以记录告警或直接拒绝操作。
我在项目中遇到过一个问题:IMA 默认只度量文件内容,不度量文件的扩展属性(如 SELinux 上下文)。结果有人改了文件的 security.selinux 属性,绕过了访问控制。后来我们加上了 ima_appraise=fix 模式,配合 EVM(Extended Verification Module)才堵住这个洞。
IMA 部署要点
- 内核编译选项:需要开启
CONFIG_IMA、CONFIG_IMA_APPRAISE、CONFIG_IMA_MEASURE_PCR_IDX。我建议同时开启CONFIG_IMA_TEMPLATE使用二进制模板,减少度量日志大小。 - 策略配置:IMA 策略文件位于
/etc/ima/ima-policy。一个典型策略如下:
# 度量所有可执行文件和共享库
measure func=FILE_CHECK mask=MAY_EXEC uid=0
# 度量关键配置文件
measure func=FILE_CHECK mask=MAY_READ obj=type=etc_t
# 启用评估模式,拒绝未签名文件
appraise func=FILE_CHECK mask=MAY_EXEC appraise_type=imasig
- 度量日志读取:IMA 日志通过
/sys/kernel/security/ima/ascii_runtime_measurements导出。可以用ima-evm-utils工具解析:
# 查看最近 10 条度量记录
tail -10 /sys/kernel/security/ima/ascii_runtime_measurements | \
awk '{print $4, $5, $7}'
注意:IMA 度量日志会持续增长,生产环境建议配置日志轮转或远程发送到安全审计中心。我曾经见过一台运行半年的服务器,IMA 日志占用了 8GB 磁盘空间——嗯,这可不是什么好体验。
4.2 文件完整性监控(FIM)
FIM 是用户态的完整性监控方案。它不像 IMA 那样嵌入内核,而是通过定期扫描或 inotify 事件触发来检查文件变化。你想想看,IMA 虽然强,但部署门槛高,而且只覆盖内核路径。FIM 正好补上这个缺口——监控那些 IMA 管不到的地方,比如临时目录、用户家目录、容器挂载点。
我常用的 FIM 工具有 AIDE、Samhain、Osquery。其中 AIDE 最轻量,适合静态基线比对;Osquery 则适合实时查询。
AIDE 配置示例
# /etc/aide/aide.conf
# 定义监控规则
/etc/passwd NORMAL
/etc/shadow NORMAL
/var/log LSPP
/opt/app/bin CONTENT_EX
!/var/log/wtmp # 排除日志文件
初始化数据库:
aide --init
mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz
定期检查:
aide --check | grep "changed"
我的经验:FIM 的难点不在工具本身,而在「基线管理」。第一次扫描时,系统里可能有大量「合法」的临时文件或日志。我建议分阶段部署:先扫描并标记所有已知文件,然后逐步收紧规则。别一上来就全量告警,否则你会被误报淹死。
FIM 与 IMA 的对比
| 维度 | IMA | FIM |
|---|---|---|
| 层级 | 内核层 | 用户态 |
| 触发方式 | 系统调用拦截(实时) | 定时扫描 / 事件驱动 |
| 覆盖范围 | 文件打开、执行、mmap | 任意文件、目录、权限 |
| 性能开销 | 低(内核内计算) | 中(扫描时 I/O 密集) |
| 部署难度 | 高(需重新编译内核) | 低(包管理器安装) |
| 典型场景 | 关键二进制、内核模块 | 配置文件、日志、临时目录 |
4.3 进程白名单
进程白名单,说白了就是「只允许跑我批准的程序」。攻击者即使拿到了 shell,如果系统里没有 bash、python、curl 这些工具,他也干不了什么。我见过最极端的案例:某金融系统只允许运行三个二进制文件——业务进程、监控 agent、日志转发器。攻击者进去后连 ls 都用不了,最后只能干瞪眼。
实现方式有两种:
- 内核强制访问控制:SELinux、AppArmor 可以限制进程执行路径。例如 SELinux 的
execmod和execute_no_trans权限控制。 - 用户态白名单工具:如 Google gVisor、Cloudflare bpfman、Sysdig Falco。我个人倾向用 eBPF 方案,因为它不需要修改内核,而且可以动态加载规则。
基于 eBPF 的进程白名单示例
// 伪代码:eBPF 程序拦截 execve 系统调用
SEC("tracepoint/syscalls/sys_enter_execve")
int execve_whitelist(struct trace_event_raw_sys_enter *ctx) {
char comm[TASK_COMM_LEN];
bpf_get_current_comm(&comm, sizeof(comm));
// 白名单列表
if (comm == "nginx" || comm == "sshd" || comm == "rsyslogd") {
return 0; // 允许
}
// 记录告警
bpf_printk("BLOCKED: %s\n", comm);
return -EPERM; // 拒绝
}
注意:进程白名单不能只靠进程名。攻击者可以重命名恶意程序。我建议结合文件路径、数字签名、哈希值做多因子校验。例如:只允许执行 /usr/bin/ 目录下且经过 GPG 签名的二进制文件。
4.4 系统调用审计
系统调用是用户态和内核态的唯一通道。所有恶意行为——文件读写、网络连接、进程创建——最终都会落到系统调用上。审计系统调用,相当于在门口装了摄像头,谁进来、干了什么、什么时候走的,全有记录。
Linux 自带的 auditd 是标配。但说实话,auditd 的规则配置有点反人类。我更喜欢用 eBPF 或 Sysdig 来做实时审计,它们更灵活,而且能关联上下文。
auditd 规则示例
# 监控所有 execve 系统调用
-a always,exit -F arch=b64 -S execve -k process_exec
# 监控文件打开(排除正常路径)
-a always,exit -F arch=b64 -S openat -F dir=/tmp -k file_open_tmp
# 监控网络连接
-a always,exit -F arch=b64 -S connect -k network_connect
查看审计日志:
ausearch -k process_exec --start today | aureport -f
Sysdig 实时审计
# 监控所有容器内的 execve 调用
sysdig -c spy_users container.name=webapp
# 监控特定进程的文件写入
sysdig -c topfiles_bytes proc.name=nginx
避坑指南:我曾经在生产环境开启全量系统调用审计,结果 auditd 日志每秒写入 2000+ 条,直接把磁盘 IO 打满了。后来我改用 eBPF 的采样模式——只记录异常行为(如非 root 用户执行 chmod 777),正常操作直接放过。性能开销从 15% 降到了 0.5% 以下。
4.5 四者协同:运行时完整性监控体系
单独用任何一个手段都有盲区。IMA 管内核路径但不管用户态;FIM 覆盖广但实时性差;进程白名单防执行但防不了提权;系统调用审计记录全但噪音大。我的做法是:分层部署,数据关联。
下面这张图展示了四者的协同关系:
部署时我建议按这个优先级:
- 先上系统调用审计——成本最低,快速建立基线。
- 再部署 FIM——覆盖配置文件、脚本等易变区域。
- 然后启用 IMA——保护关键二进制和内核模块。
- 最后收紧进程白名单——这是最严格的防线,需要充分测试。
关键原则:运行时完整性监控不是「部署完就完事」的。你需要持续调优规则、处理误报、更新基线。我每个季度会做一次规则审计,删除过时的白名单条目,补充新业务的监控点。安全是动态的,监控策略也得跟着变。