如何使用eBPF捕获文件删除前事件并获取路径完成备份?
eBPF文件删除前事件捕获与备份方案
首先明确结论:完全可以通过eBPF实现该需求,以下是可落地的实现思路,覆盖所有已知卡点:
优先推荐方案:基于VFS层入口钩子实现(兼容性最好,无路径获取限制)
- 挂载点选择:优先使用fentry(内核5.5+支持,性能损耗低)或kprobe挂载
do_unlinkat函数,该函数是所有用户态删除操作(unlink、rm、unlinkat系统调用)的VFS层统一入口,上下文属于进程上下文,不存在bpf_d_path接口调用限制。 - 路径获取逻辑:直接调用
bpf_d_path接口传入函数参数中的struct path指针对象,即可稳定拿到待删除文件的完整绝对路径,不需要自行实现dentry遍历逻辑,避免内存访问风险和边界场景兼容问题。 - 拦截备份流程:
- eBPF程序捕获到删除事件后,先将文件路径、发起进程的PID、UID等元数据通过环形缓冲区(ring buffer)上报到用户态管控程序。
- eBPF程序临时拦截本次删除请求,返回
-EPERM等错误码阻塞删除动作执行。 - 用户态管控程序收到事件后完成目标文件备份,再根据配置主动调用删除接口完成原操作,或者为对应进程的删除请求添加白名单,放行后续的删除动作。
备选方案:基于LSM BPF钩子实现(适合强安全管控场景)
如果需要使用LSM钩子实现更高优先级的删除管控,可按以下逻辑解决路径获取问题:
- 挂载点选择:使用
SEC("lsm/path_unlink")挂载security_path_unlink钩子,内核5.17+版本已经支持在LSM钩子上下文中直接调用bpf_d_path获取路径。 - 低版本内核兼容逻辑:
- 禁止自行在内核态实现dentry路径遍历逻辑,该逻辑需要处理RCU引用、挂载点跳转、伪文件系统适配等大量边界场景,极易出现内核崩溃或者路径获取错误。
- 替代方案:eBPF程序先将待删除文件的inode号、设备号、发起进程PID上报到用户态,用户态通过
/proc/<pid>/mountinfo+ inode匹配的方式反查完整文件路径,备份完成后再通过eBPF程序控制是否放行本次删除请求。
Tracee方案适配说明
Tracee默认挂载security_inode_unlink的逻辑仅适用于事后监控场景,要适配删除前拦截备份的需求,只需将挂载点调整为security_path_unlink,保留其dentry元数据提取逻辑,补充上述用户态路径反查逻辑即可快速落地。
内容的提问来源于stack exchange,提问作者Dinakaran P
相关产品推荐
相关产品推荐

