ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

基于eBPF与IMA LSM构建Linux内核态文件完整性监控工具

基于eBPF与IMA LSM构建Linux内核态文件完整性监控工具 在做 Linux 主机安全监控和文件完整性治理时很多团队第一个想到的是部署一套 agent然后依赖 inotify、auditd 或者商业终端安全软件。但如果你对内核机制有兴趣会发现 Linux 其实自带了一套非常强大的完整性度量框架再叠加 eBPF 的实时观测能力完全可以在不修改内核、不加载内核模块的前提下搭建一条“内核态感知文件访问 完整性校验 告警”的链路。本文分享的就是一个实验性质的项目使用 eBPF 和 IMA LSM 构建一个极简的“玩具级”内核态杀毒监控工具。它不追求产品级能力重点是把 ring-0 安全监控的核心思路和实现路径讲清楚。适合对 eBPF、LSM、Linux 安全子系统感兴趣的开发者也适合想入门内核安全编程的读者。1. 背景与核心概念1.1 什么是 ring-0为什么杀毒软件需要它x86 体系结构里CPU 把特权级别分为几个环ring-0 是最高特权级别也就是内核态。操作系统内核运行在 ring-0可以执行特权指令、访问所有内存和设备。普通应用程序运行在 ring-3用户态通过系统调用向内核请求服务。传统杀毒软件之所以需要 ring-0 能力是因为它要做的很多事情在用户态根本做不了拦截文件打开、进程创建、网络连接等系统调用行为读取进程内存、内核对象在内核层面阻止恶意驱动加载对文件读取和执行的请求做实时校验。之前版本的杀毒软件通常用内核驱动实现这些能力。Windows 上常见的是 WFPWindows Filtering Platform驱动和文件系统迷你过滤驱动Microsoft Defender Antivirus Service 也包含内核态组件。Linux 下传统做法是编写内核模块但内核模块维护成本高一旦出 bug 可能直接崩溃整个系统。eBPF 出现后情况发生了变化它可以安全地在内核态运行受限的字节码程序不需要编写普通内核模块也不需要重新编译内核这让内核态安全监控的开发和部署门槛大幅降低。1.2 Linux 安全模块 LSMLSM 全称是 Linux Security Module也就是 Linux 安全模块是内核提供的一套安全钩子框架。它在内核的关键路径上预留了 hook 点比如打开文件、执行程序、读写 inode、创建 socket 等。内核中的安全模块可以注册这些 hook 点在操作发生前做检查拦截或放行。当前主流的 LSM 包括 SELinux、AppArmor、Smack、Tomoyo以及本文要讲的 IMA 也在 LSM 框架中承担完整性度量的职责。LSM 的价值在于把安全逻辑从内核主体逻辑中剥离出来提供标准化的 hook 机制支持多个安全模块叠加目前部分场景支持栈式叠加比如 SELinux IMA在没有用户态 agent 常驻的情况下也能在内核侧完成一部分安全动作。1.3 IMA完整性度量架构IMA 全称是 Integrity Measurement Architecture即完整性度量架构。它是 Linux 内核中用来度量文件完整性的一种机制简单来说可以理解为内核在“文件被访问、被映射、被执行”时对文件内容计算哈希并把哈希记录到一个可验证的度量列表里。IMA 的工作模式大致分为三类measure只做度量把文件的哈希记录到运行时度量列表中appraise在度量基础上做校验如果文件内容与预期哈希不符直接拒绝访问protect阻止对受保护文件的未授权修改。在实现上IMA 以 LSM 模块的形式注册到内核安全子系统中常见的处理函数就是ima_file_check它会在security_file_permission、security_mmap_file等 hook 点被调用。对安全监控来说IMA 最直接的价值是无论用户态进程怎么操作只要文件在内核里被执行或读取IMA 就有机会记录下“内核视角”的文件哈希。应用层算的哈希可以被伪造、被绕过但 IMA 是内核里的钩子可信度更高。1.4 eBPF 与技术原理eBPF 扩展了传统 BPF伯克利包过滤器让开发者可以在内核中运行沙箱化的字节码。eBPF 程序可以挂载到 kprobe、tracepoint、perf event、LSM hook 等位置收集内核数据、跟踪函数调用、甚至对部分安全逻辑做决策。对安全监控场景来说eBPF 有这几个优势不需要重新编译内核也不需要加载普通内核模块执行前会做严格的安全校验内存越界等非法操作会被拒绝栈空间受限、循环有条件限制天然避免死循环性能高事件处理开销远低于用户态轮询可以通过 map 和 perf event/ring buffer 与用户态通信。回到本文的项目整体的设计思路是用 eBPF 挂钩 IMA 的文件检查函数实时监听被检查文件、进程、访问类型用户态脚本接收事件结合已知恶意文件哈希库做比对同时参考 IMA 运行时度量列表中的哈希记录形成“内核观测 用户态判定”的闭环。2. 环境准备与版本说明2.1 内核要求要运行这个项目内核需要满足以下条件Linux 内核版本建议 4.19 以上越新越好内核需要启用 eBPF 相关配置包括CONFIG_BPF、CONFIG_BPF_SYSCALL、CONFIG_DEBUG_INFO_BTF新版本建议开启内核需要启用 IMA也就是CONFIG_IMAysecurityfs 需要挂载通常路径是/sys/kernel/security。可以使用下面的命令快速检查内核版本和 IMA 支持情况uname -r # 查看 securityfs 是否挂载 ls /sys/kernel/security # 查看 IMA 接口目录是否存在 ls /sys/kernel/security/ima如果/sys/kernel/security/ima不存在说明当前内核没有启用 IMA或者 securityfs 没有挂载。部分云厂商的虚拟化内核会去掉 IMA需要确认发行版内核配置。2.2 安装 BCC 工具集本文示例使用的是 BCCBPF Compiler Collection它提供了一套 Python API可以免去很多手写底层加载逻辑的麻烦。Ubuntu / Debian 系统安装命令sudo apt-get update sudo apt-get install -y bpfcc-tools linux-headers-$(uname -r) python3-bpfccCentOS / RHEL 系统可以参考sudo yum install -y bcc-tools kernel-devel如果发行版仓库里没有 BCC也可以直接从源码编译安装但需要额外安装 LLVM、clang、libbpf、cmake 等工具链。本文示例以 BCC 为主命令使用的是python3-bpfcc。2.3 检查 root 权限eBPF 程序的加载和 IMA 策略的写入都需要 root 权限。后续所有命令都建议使用普通用户编写代码通过sudo或切换到 root 用户执行验证。整个环境准备完成后可以先运行一个最简单的 eBPF Hello World 程序确认 BCC 可以正常加载和卸载 eBPF 程序避免后续排查时区分不清是环境问题还是代码问题。3. 核心原理与系统架构3.1 IMA 度量流程先来看一张简化的 IMA 调用流程用户进程打开/执行文件 | v 安全子系统 LSM hook | v ima_file_check(file, mask) | ------------------- measure 模式计算哈希写入运行时度量列表 | ------------------- appraise 模式比对扩展属性或签名中的哈希 | --- 校验失败则拒绝访问在这个流程里ima_file_check是核心入口之一。无论文件是读取还是执行都会经过这个检查点。mask参数表示访问模式常见的值包括MAY_EXEC执行MAY_WRITE写入MAY_READ读取。内核通过inum、i_ino、文件路径等信息来决定是否对文件执行 IMA 策略。3.2 eBPF 与 IMA 的协同方式在真正动手前需要明确一个概念eBPF 不能直接修改 IMA 的内核逻辑除非使用 BPF LSM 特性挂载 LSM hook。本文项目里的协同方式更偏向“旁路观测”IMA 负责在内核侧执行文件完整性度量并对部分文件做哈希记录eBPF 程序通过 kprobe 挂载ima_file_check函数获取内核正在检查哪个文件、由哪个进程触发、访问类型是什么用户态接收到 eBPF 事件后查询本地恶意文件哈希库做出命中判断。这种模式很像传统杀毒软件的“扫描引擎 实时保护”组合实时监控层负责捕捉行为扫描引擎负责判定已知文件。3.3 玩具杀毒系统的模块设计整个系统分为三层模块职责运行位置IMA 内核子系统对文件执行完整性度量记录哈希可选做 appraise 拦截ring-0eBPF 监控程序捕获 IMA 检查事件提取进程、文件名、访问掩码ring-0用户态 Python 程序加载 eBPF接收事件结合恶意哈希库判定并输出告警用户态用一个“恶意文件”检测的例子来说明整个链路用户把一个文件放到受保护目录用户执行或读取该文件内核经过 LSM hook调用ima_file_checkeBPF kprobe 捕获事件把 pid、uid、文件名、访问掩码提交到用户态用户态脚本定位受保护目录里的文件计算 SHA256 哈希与malware_hash.db中的恶意哈希比对命中则输出 ALERT 告警。4. 实战构建基于 eBPF IMA LSM 的玩具杀毒工具4.1 项目结构为了便于维护和演示整个项目使用下面的目录结构ima-toy-antivirus/ ├── ima_av.py # 用户态主程序加载 eBPF 并处理事件 ├── ima_policy.sh # 配置 IMA measure 策略 ├── malware_hash.db # 恶意文件哈希库JSON 格式 ├── av_audit.log # 运行后自动生成的告警日志 └── demo/ └── create_sample.py # 生成一个测试用“恶意样本”创建目录mkdir -p ima-toy-antivirus/demo cd ima-toy-antivirus4.2 配置 IMA 策略首先要让 IMA 工作起来。默认情况下大多数发行版不会自动添加有效的 IMA 策略需要手动写入策略。创建ima_policy.sh#!/bin/bash # ima_policy.sh - 为当前内核添加一条 IMA measure 策略 set -e IMA_POLICY/sys/kernel/security/ima/policy if [ ! -w $IMA_POLICY ]; then echo 错误: $IMA_POLICY 不可写请检查是否以 root 运行 echo 以及当前内核是否启用了 IMA (CONFIG_IMA)。 exit 1 fi #
返回列表