eBPF入门系列:学习资料及概念

学习资料

  • https://www.ebpf.top/

  • https://github.com/DavadDi/bpf_study

  • https://github.com/nevermosby/linux-bpf-learning

  • https://davidlovezoe.club/wordpress/archives/tag/bpf

  • https://github.com/Asphaltt/learn-by-example

  • cilium文档:BPF和XDP参考指南

  • XDP教程:https://github.com/xdp-project

  • eBPF和GO: https://networkop.co.uk/post/2021-03-ebpf-intro/

eBPF介绍

使用LLVM/clang编译bpf程序为bpf字节码;

可以通过bcc/bpftrace开发bpf程序;

BPF Maps

BPF Maps可以被内核和用户空间同时访问,可用于用户态程序读取内核的数据,也可以从用户态向内核态bpf程序传配置;

源码定义:https://elixir.bootlin.com/linux/v5.15.86/source/include/uapi/linux/bpf.h#L878

内核文档定义:https://docs.kernel.org/bpf/maps.html

BPF Program

bpf程序类型:kprobe(性能低、灵活性高)、tracepoints(性能高、灵活性低)

helper函数:https://man7.org/linux/man-pages/man7/bpf-helpers.7.html

bpf系统调用函数:https://man7.org/linux/man-pages/man2/bpf.2.html

编译

注意点

1、clang编译器可以通过 -g 参数生成CO-RE需要的内核数据结构BTF文件;

2、gcc 12版本编译 BPF 程序支持 CO-RE 特性;

检查 eBPF 对象文件

加载并挂载程序

BPF程序和挂载类型

BPF程序类型、挂载类型和ELF Sections 对应关系 libbpf 文档

Tracing(跟踪类型)

  • Kprobes 和 Kretprobes

    kprobes 用于挂载到内核函数入口点,也可以通过指令挂载到入口点偏移量位置(不稳定);kretprobes 用于挂载到内核函数退出点。

    bpf程序参数类型根据挂载点类型而不同,函数第一个参数为函数名。

  • Fentry 和 Fexit

    内核版本5.5引入的更高效的挂载到内核函数入口点和出口点的程序类型。

    kprobe类型程序代码可以无缝迁移到fentry。

    fexit类型程序还可以访问函数入参,而kretprobes不能

  • Tracepoints

    tracepoints 是跟踪内核中被标记的代码位置。tracepoints在不同内核版本相对稳定

    查看当前版本内核可用的子系统跟踪点通过文件 /sys/kernel/tracing/available_events

    查看跟踪点函数参数方式,以execve函数入口点系统调用为例:cat /sys/kernel/tracing/events/syscalls/sys_enter_execve/format

    Raw_tracepoints类型程序相对于tracepoints可以获得更好的性能,通过修改 raw_tp/raw_tracepoint代替tp。

  • BTF-Enabled Tracepoints

    启动BTD的tracepoints,解决内核数据接口在不同版本定义发生变化问题。

    函数第一个参数结构体名字格式:trace_event_raw_+跟踪点名

  • Uprobes and Uretprobes

    uprobes和uretprobes挂载用户空间函数入口点和退出点,USDTs (user statically defined tracepoints)挂载特殊的tracepoints到用户空间的应用代码/库文件。

    复用 kprobes 程序类型定义。

    在检测⽤⼾空间代码时需要注意⼀些问题:...

  • LSM

    BPF_PROG_TYPE_LSM类型程序用于挂载到Linux安全模块API,

Networking

需要的Linux capabilities: CAP_NET_ADMIN, CAP_BPF, CAP_SYS_ADMIN。

BPF程序类型在网络协议栈的钩子

BPF-proggram-typs-hook-in-network-stack

使用场景:

1、通过 bpf 程序告诉内核如何处理数据包:重定向、丢弃、正常处理;

2、修改数据包或者socket参数;

  • Sockets

    程序类型:

    • BPF_PROG_TYPE_SOCKET_FILTER:过滤复制到可观察工具(tcpdump)sockets。

    • BPF_PROG_TYPE_SOCK_OPS:允许拦截或者操作socket,例如设置socket各种参数

    • BPF_PROG_TYPE_SK_SKB:与sockmap一起使用,用于重定向socket流量

  • Traffic Control

    eBPF程序可以挂载到自定义的filters或者classifiers,出入向都可以。

    使用tc命令操作ebpf 程序

  • XDP

    可以使用ip link命令操作XDP程序

    只能作用于ingress方向数据包,无法针对egress方向数据包

  • Flow Dissector(流解剖器)

    BPF_PROG_TYPE_FLOW_DISSECTOR: 可以自定义解剖数据包

  • Lightweight Tunnels

    BPF_PROG_TYPE_LWT_* 程序类型 : 实现数据包封装

  • Cgroups

    用于控制一个Cgroup中的进程组的行为,比如控制一个Cgroup的socket是否被请求或者传输

    程序类型:

    • BPF_CGROUP_SYSCTL:控制sysctl命令

    • BPF_PROG_TYPE_CGROUP_SOCK :

    • BPF_PROG_TYPE_CGROUP_SKB

  • Infrared Controllers

环境依赖

是BPF程序一次编译随处运行(CO-RE:Compile Once-Run Everywhere)的关键,解决了 eBPF 程序在不同内核版本之间可移植的问题.

Last updated