操作系统大赛:基于 eBPF 的容器监控工具 Eunomia 初赛报告(系统设计、ebpf 探针设计)

Eunomia是一个使用eBPF技术的容器监控工具,具备系统设计、模块化和探针设计。系统由tracker_manager、container_manager等模块组成,支持process、syscall、tcp等五种ebpf探针。探针分为C代码和C++部分,通过事件处理链来处理上报信息,支持Prometheus导出和安全分析。Eunomia允许动态添加和移除探针,实现灵活的监控策略。
摘要由CSDN通过智能技术生成

项目仓库:https://github.com/yunwei37/Eunomia

4.1. 系统设计

请添加图片描述

系统架构

关于详细的系统架构设计和模块划分,请参考 系统设计文档

4.2. 模块设计

  • tracker_manager

    负责启动和停止 ebpf 探针,并且和 ebpf 探针通信(每个 tracer 是一个线程);

    • start tracker
    • stop tracker(remove tracker)

    我们主要有五个ebpf探针:

    • process
    • syscall
    • tcp
    • files
    • ipc
  • container_manager

    负责观察 container 的启动和停止,保存每个 container 的相关信息:(cgroup,namespace),同时负责 container id, container name 等 container mata 信息到 pid 的转换(提供查询接口)

  • seccomp_manager

    负责对 process 进行 seccomp 限制

  • handler/data collector

    负责处理 ebpf 探针上报的事件

  • security analyzer

    容器安全检测规则引擎和安全分析模块,通过ebpf采集到的底层相关数据,运用包括AI在内的多种方法进行安全性分析,可以帮助您检测事件流中的可疑行为模式。

  • prometheus exporter

    将数据导出成Prometheus需要的格式,在Prometheus中保存时序数据,方便后续持久化和可视化功能。

  • config loader

    解析 toml

  • cmd

    命令行解析模块,将命令行字符串解析成对应的参数选项,对Eunomia进行配置。

  • core

    负责装配所需要的 tracker,配置对应的功能用例,并且启动系统。

  • server

    http 通信:通过 graphql 在远程发起 http 请求并执行监控工具,将产生的数据进行聚合后返回,用户可自定义运行时扩展插件进行在线数据分析。这一个部分还没有完成。

4.3. ebpf 主要观测点

  • process追踪模块

    进程的追踪模块本项目主要设置了两个 tracepoint 挂载点。
    第一个挂载点形式为

            SEC("tp/sched/sched_process_exec")
            int handle_exec(struct trace_event_raw_sched_process_exec *ctx)
            {
         
        
            }
    

    当进程被执行时,该函数会被调用,函数体中会从传入的上下文内容提取内容,我们需要的信息记录在Map中。
    第二个挂载点形式为

            SEC("tp/sched/sched_process_exit")
            int handle_exit(struct trace_event_raw_sched_process_template *ctx)
            {
         
                
            }
    

    当有进程退出时,该函数会被调用,函数体同样会从传入的上下文内容提取内容,我们需要的信息记录在Map中。

  • syscall追踪模块

    对于系统调用的追踪模块设置了一个 tracepoint 挂载点。挂载点形式为

            SEC("tracepoint/raw_syscalls/sys_enter")
            int sys_enter(struct trace_event_raw_sys_enter *args)
            {
         
        
            }
    

    当有syscall发生时,其经过sys_enter执行点时我们的函数将会被调用,将相关信息存入map后供用户态读取。

  • file追踪模块

    对于文件系统,我们设置了两个 kprobe 挂载点。第一个挂载点形式为

            SEC("kprobe/vfs_read")
            int BPF_KPROBE(vfs_read_entry, struct file *file, char *buf, size_t count, loff_t *pos)
            {
         
        
            }
    

    第二个挂载点形式为

            SEC("kprobe/vfs_write")
            int BPF_KPROBE(vfs_write_entry, struct file *file, const char *buf, size_t count, loff_t *pos)
            {
         
        
            }
    

    当系统中发生了文件读或写时,这两个执行点下的函数会被触发,记录相应信息。

  • tcp追踪模块

            SEC("kprobe/tcp_v6_connect")
            int BPF_KPROBE(tcp_v6_connect, struct sock *sk) {
         
              return enter_tcp_connect(ctx, sk);
            }
    
            SEC("kretprobe/tcp_v6_connect")
            int BPF_KRETPROBE(tcp_v6_connect_ret, int ret) {
         
              return exit_tcp_connect(ctx, ret, 6);
            }
    

4.4. ebpf 探针设计

采用 ebpf 探针的方式,可以获取到安全事件的相关信息,并且可以通过 prometheus 监控指标进行监控和分析。

我们的探针代码分为两个部分,其一是在 bpftools 中,是针对相关 ebpf 程序的 libbpf 具体探针接口实现,负责1ebpf 程序的加载、配置、以及相关用户态和内核态通信的代码;另外一部分是在 src 中,针对 ebpf 探针上报的信息进行具体处理的 C++ 类实现,负责根据配置决定ebpf上报的信息将会被如何处理。

4.4.1. ebpf 探针相关 C 代码设计,以 process 为例:

process 部分的代码主要负责获取进程的执行和退出时和进程相关的以下的信息:

  • pid
  • cgroup
  • namespace:user pid mount
  • ppid
  • command
  • 可执行文件路径

其中容器相关信息会保存起来并被其他 tracker 用以查询。

ebpf 代码:在 bpftools\process\process.bpf.c 中,这里贴出来的代码经过了一定程度的化简。

static __always_inline void fill_event_basic(pid_t pid, struct task_struct *task, struct process_event *e)
{
   
	e->common.pid = pid;
	e->common.ppid = BPF_CORE_READ(task, real_parent, tgid);
	e->common
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值