基于ubuntu22.04-深入浅出 eBPF

news2024/10/7 16:19:57

笔者在很早之前就看eBPF这类似的文章,那时候看这个技术一脸懵逼,不知道它是用来做什么,可以解决什么问题。所以也没有太关注这个技术。很庆幸最近刚好有机会研究这个技术。

什么是BPF

BPF的全称是Berkaley Packet Filter,即伯克利报文过法器,它的设计思想来源于 1992 年Steven McCanne和Van Jacobson写的一篇论文“The BSD packet filter. A New architecture for user-level packet apture’ (《BSD数据包过滤器:一种用于用户级数据包捕获的新休系结构》)。最初,BPF是在 BSD 内核实现的,后来,由于其出色的设计思想,其他操作系统也将其引入包括 Linux。

在这篇论文中,作者描述了他们如何在Unix内核实现网络数据包过滤,这种新的技术比当时最先进的数据包过滤技术快20倍。如下图来源于论文:

通俗易懂的理解上图,BPF是作为网络报文传输的旁路链路,当接收到的网络报文到达内阁驱动程序后,网络报文在传输给网络协议栈的同时,会额外将网络报文的副本传输给BPF。之后网络报文会经过BPF程序的内部逻辑进行过滤,最终再送到用户程序。

BPF 在数据包过滤上引入了两大革新:

  • 一个新的虚拟机(VM)设计,可以有效地工作在基于寄存器结构的CPU之上;
  • 应用程序使用缓存只复制与过滤数据包相关的数据,不会复制数据包的所有信息,最大程度地减少BPF处理的数据,提高处理效率。

我们熟悉的tcpdump就是基于BPF技术,好比一个神器站另外一个神器的绝作。

什么是eBPF

BPF发展到现在名称升级为eBPF: 「extended Berkeley Packet Filter」。它演进成为了一套通用执行引擎,提供可基于系统或程序事件高效安全执行特定代码的通用能力,通用能力的使用者不再局限于内核开发者。其使用场景不再仅仅是网络分析,可以基于eBPF开发性能分析、系统追踪、网络优化等多种类型的工具和平台。

eBPF原理

** eBPF技术架构图:**

eBPF主要分为用户空间程序与内核程序两大部分:

  • 在用户空间,程序通过LLVM/Clang被编译成eBPF可接受的字节码并提交到内核,以及负责读取内核回传的消息事件或统计信息。eBPF提供了两种内核态与用户态传递数据的方式,内核态可以将自定义perf_event消息事件发往用户态,或用户态通过文件描述符读写存储在内核中的k/v Map数据。

  • 在内核空间,为了稳定与安全,eBPF接收的字节码首先会交给Verifier进行安全验证,如验证程序循环次数,数组越界问题,无法访问的指令等等。只有校验通过的字节码才会提交到内核自带编译器或JIT编译器编译成可直接执行的机器指令。同时,eBPF对提交程序提出限制,如程序大小限制,最大可使用堆栈大小限制,可调用函数限制,循环次数限制等。

  • 从上面的架构图可以看出,eBPF在内核态会依赖内核探针进行工作,其中kprobes实现内核函数动态跟踪;uprobes实现用户函数动态跟踪;tracepoints是内核中的静态跟踪点;perf_events支持定时采样和PMC。

eBPF环境搭建

为了有一个eBPF程序编写验证的平台,我在ubuntu22.04中搭建了eBPF环境,ubuntu22.04安装流程在这里不在过多的介绍。以下的操作都在root用户下执行

  1. 更新系统的包索引和包列表:
# apt update
  1. 编译 BPF 程序需要系统安装必备的 linux-headers 包:
# sudo apt install linux-headers-$(uname -r)
  1. 安装eBPF依赖工具:
# apt install -y bison flex build-essential git cmake make libelf-dev strace tar libfl-dev libssl-dev libedit-dev zlib1g-dev  python  python3-distutils
  1. 安装LLVM,并检查一下版本:
# apt install llvm
# llc -version
Ubuntu LLVM version 14.0.0
  
.....
    wasm32     - WebAssembly 32-bit
    wasm64     - WebAssembly 64-bit
    x86        - 32-bit X86: Pentium-Pro and above
    x86-64     - 64-bit X86: EM64T and AMD64
    xcore      - XCore
# 
  1. 安装Clang,并检查一下版本:
# apt install clang
# clang -version
Ubuntu clang version 14.0.0-1ubuntu1
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
# 
  1. 查看但钱ubuntu的内核版本,安装对应的内核源码,并解压源码:
# apt-cache search linux-source
linux-source - Linux kernel source with Ubuntu patches
linux-source-5.19.0 - Linux kernel source for version 5.19.0 with Ubuntu patches
# apt install linux-source-5.19.0
# cd /usr/src
# tar -jxvf linux-source-5.19.0.tar.bz2
# cd linux-source-5.19.0
  1. 编译内核源码的bpf模块,如果没有报错,说明已经完成环境搭建:
# cp -v /boot/config-$(uname -r) .config
# make oldconfig && make prepare
# make headers_install
# apt-get install libcap-dev 
# make M=samples/bpf
  CC  samples/bpf/../../tools/testing/selftests/bpf/cgroup_helpers.o
  CC  samples/bpf/../../tools/testing/selftests/bpf/trace_helpers.o
  CC  samples/bpf/cookie_uid_helper_example.o
  CC  samples/bpf/cpustat_user.o
  CC  samples/bpf/fds_example.o
....

WARNING: Symbol version dump "Module.symvers" is missing.
         Modules may not have dependencies or modversions.
         You may get many unresolved symbol warnings.

eBPF样例编写

在内核源码的samples/bpf目录下提供了很多实例供我们学习,通过目录下的makefile就可以构建里面的bpf程序,如果我们用 C 语言编写的 BPF 程序编译可以直接在该目录提供的环境中进行编译。

samples/bpf 下的程序一般组成方式是 xxx_user.c 和 xxx_kern.c:

  • xxx_user.c:为用户空间的程序用于设置 BPF 程序的相关配置、加载 BPF 程序至内核、设置 BPF 程序中的 map 值和读取 BPF 程序运行过程中发送至用户空间的消息等。目前 xxx_user.c 与 xxx_kern.c 程序在交互实现都是基于 bpf() 系统调用完成的。直接使用 bpf() 系统调用涉及的参数和细节比较多,使用门槛较高,因此为了方便用户空间程序更加易用,内核提供了 libbpf 库封装了对于 bpf() 系统调用的细节。
  • xxx_kern.c:为 BPF 程序代码,通过 clang 编译成字节码加载至内核中,在对应事件触发的时候运行,可以接受用户空间程序发送的各种数据,并将运行时产生的数据发送至用户空间程序。

编写一个样例流程,在目录samples/bpf中新建两个文件:youyeetoo_user.c和youyeetoo_kern.c,并且在makefile中加入构建:

  1. youyeetoo_user.c的内容:
#include <stdio.h>
#include <unistd.h>
#include <bpf/libbpf.h>
#include "trace_helpers.h"

int main(int ac, char **argv)
{
	struct bpf_link *link = NULL;
	struct bpf_program *prog;
	struct bpf_object *obj;
	char filename[256];

	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
	obj = bpf_object__open_file(filename, NULL);
	if (libbpf_get_error(obj)) {
		fprintf(stderr, "ERROR: opening BPF object file failed\n");
		return 0;
	}

	prog = bpf_object__find_program_by_name(obj, "bpf_prog");
	if (!prog) {
		fprintf(stderr, "ERROR: finding a prog in obj file failed\n");
		goto cleanup;
	}

	/* load BPF program */
	if (bpf_object__load(obj)) {
		fprintf(stderr, "ERROR: loading BPF object file failed\n");
		goto cleanup;
	}

	link = bpf_program__attach(prog);
	if (libbpf_get_error(link)) {
		fprintf(stderr, "ERROR: bpf_program__attach failed\n");
		link = NULL;
		goto cleanup;
	}

	read_trace_pipe();

cleanup:
	bpf_link__destroy(link);
	bpf_object__close(obj);
	return 0;
}

  1. youyeetoo_kern.c的内容:
#include <uapi/linux/bpf.h>
#include <linux/version.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>

SEC("tracepoint/syscalls/sys_enter_execve")
int bpf_prog1(struct pt_regs *ctx)
{
  char fmt[] = "youyeetoo %s !\n";
	char comm[16];
	bpf_get_current_comm(&comm, sizeof(comm));  
  bpf_trace_printk(fmt, sizeof(fmt), comm);
  
	return 0;
}

char _license[] SEC("license") = "GPL";
u32 _version SEC("version") = LINUX_VERSION_CODE;
  1. Makefile 文件修改:
# diff -u Makefile.old Makefile
--- Makefile.old	2021-09-26 03:16:16.883348130 +0000
+++ Makefile	2021-09-26 03:20:46.732277872 +0000
@@ -55,6 +55,7 @@
 tprogs-y += xdp_sample_pkts
 tprogs-y += ibumad
 tprogs-y += hbm
+tprogs-y += youyeetoo

 # Libbpf dependencies
 LIBBPF = $(TOOLS_PATH)/lib/bpf/libbpf.a
@@ -113,6 +114,7 @@
 xdp_sample_pkts-objs := xdp_sample_pkts_user.o
 ibumad-objs := ibumad_user.o
 hbm-objs := hbm.o $(CGROUP_HELPERS)
+youyeetoo-objs := youyeetoo_user.o $(TRACE_HELPERS)

 # Tell kbuild to always build the programs
 always-y := $(tprogs-y)
@@ -174,6 +176,7 @@
 always-y += hbm_out_kern.o
 always-y += hbm_edt_kern.o
 always-y += xdpsock_kern.o
+always-y += youyeetoo_kern.o

 ifeq ($(ARCH), arm)
 # Strip all except -D__LINUX_ARM_ARCH__ option needed to handle linux

eBPF样例验证

  1. 编译样例:
# make M=samples/bpf
  CC  samples/bpf/../../tools/testing/selftests/bpf/cgroup_helpers.o
  CC  samples/bpf/../../tools/testing/selftests/bpf/trace_helpers.o
  CC  samples/bpf/cookie_uid_helper_example.o
  CC  samples/bpf/cpustat_user.o
  CC  samples/bpf/fds_example.o
....
  LD  samples/bpf/youyeetoo
  CLANG-bpf  samples/bpf/youyeetoo_kern.o
WARNING: Symbol version dump "Module.symvers" is missing.
         Modules may not have dependencies or modversions.
         You may get many unresolved symbol warnings.
  1. 在samples/bpf下查看编译结果,可以看到youyeetoo可执行文件:
# ls -al youyeetoo*
-rwxr-xr-x 1 root root 407976  6月  9 19:08 youyeetoo
-rw-r--r-- 1 root root    451  6月  9 10:44 youyeetoo_kern.c
-rw-r--r-- 1 root root   5216  6月  9 19:08 youyeetoo_kern.o
-rw-r--r-- 1 root root    997  6月  9 10:40 youyeetoo_user.c
-rw-r--r-- 1 root root   3360  6月  9 19:08 youyeetoo_user.o
  1. 在ubuntu中运行两个终端,用来测试youyeetoo:

  1. 在终端以运行youyeetoo可执行文件,在终端2中执行任意命令,在终端1查看程序是否能够监测到,如果成功监测到新进程运行便会输出一条“bpf_trace_printk: Hello”

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/641883.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机视觉的应用7-利用YOLOv5模型启动电脑摄像头进行目标检测

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下计算机视觉的应用7-利用YOLOv5模型启动电脑摄像头进行目标检测&#xff0c;本文将详细介绍YOLOv5模型的原理&#xff0c;YOLOv5模型的结构&#xff0c;并展示如何利用电脑摄像头进行目标检测。文章将提供样例代码&a…

【GitLab】-HTTP Basic: Access denied.remote:You must use a personal access token

写在前面 本文简要说明GitLab配置accessToken以及双因子认证&#xff08;Two-factor authentication&#xff09;。 目录 写在前面一、场景描述二、具体步骤1.环境说明2.配置accessToken3.克隆项目4.双因子认证 三、参考资料写在后面 一、场景描述 在使用账号和密码的方式拉取公…

数据库的 Schema 变更实现

一、减少元数据变更的措施 元数据变更是数据库管理中不可避免的工作项&#xff0c;减少元数据变更次数可降低数据库维护和管理成本&#xff0c;减轻对业务的影响。这里我们可以优先考虑以下 3 点&#xff1a; 精细计划 在数据库设计和开发阶段&#xff0c;精细设计元数据结构…

月度精华汇总 | 最新XR行业资讯、场景案例、活动都在这一篇里啦!

​ 在过去的一个月中&#xff0c;平行云为您带来了关于XR领域的一系列精彩文章&#xff0c;涵盖了行业资讯、应用案例&#xff0c;市场互动&#xff0c;帮助您掌握XR领域最新动态&#xff0c;了解实时云渲染、Cloud XR技术的价值&#xff0c;以及平行云实时云渲染解决方案LarkX…

【每日算法】【160. 相交链表】

☀️博客主页&#xff1a;CSDN博客主页 &#x1f4a8;本文由 我是小狼君 原创&#xff0c;首发于 CSDN&#x1f4a2; &#x1f525;学习专栏推荐&#xff1a;面试汇总 ❗️游戏框架专栏推荐&#xff1a;游戏实用框架专栏 ⛅️点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd;&…

【陈老板赠书活动 - 04期】- 【C++、Linux、算法等系列众书】

陈老老老板&#x1f9b8; &#x1f468;‍&#x1f4bb;本文专栏&#xff1a;赠书活动专栏&#xff08;为大家争取的福利&#xff0c;免费送书&#xff09; &#x1f468;‍&#x1f4bb;本文简述&#xff1a;与几分醉意.一起搞的赠书活动一次30本书哦&#xff01;&#xff01;…

软件项目质量管理的4大注意事项

1、制定质量计划和评估标准 项目质量管理首先需要制定详细的质量计划&#xff0c;明确项目质量目标&#xff0c;制定质量评估标准和验收方案。质量计划需与项目计划密切相关&#xff0c;并确保项目质量管理与项目进度和成本控制相配合。 软件项目质量管理的4大注意事项 2、构建…

Java+Swing+mysql仿QQ聊天工具

JavaSwingmysql仿QQ聊天工具 一、系统介绍二、功能展示1.用户登陆2.好友列表3.好友聊天4.服务器日志 三、系统实现四、其它1.其他系统实现2.获取源码 一、系统介绍 系统主要功能&#xff1a;用户登陆、好友列表、好友聊天、服务器日志 二、功能展示 1.用户登陆 2.好友列表 3…

想要避免计划外停机?预测性维护技术是关键

在现代工业领域&#xff0c;非计划停机是一项令人头疼的问题&#xff0c;它导致生产损失、利润减少&#xff0c;并给运营团队带来巨大的压力。然而&#xff0c;基于时间的维护策略并不能有效应对所有设备故障&#xff0c;因为大部分故障表现出随机模式&#xff0c;难以准确预测…

深入探索基于Webdriver的分层自动化框架搭建

目录 前言&#xff1a; 1、基于webdriver的分层自动化框架及平台搭建&#xff0c;目前刚好在做这一块的工作&#xff0c;对于分层次和平台搭建&#xff0c;想问下大神有什么好的建议&#xff1f; 2、希望大神能自己的工作经历和经验&#xff0c;对初入测试行业的后辈有何建议…

SpringCloudAlibaba环境搭建版本说明

可以通过www.github.com网站搜索alibaba&#xff0c;点击第一个超链接 点击wiki 点击版本说明 里面有对应版本&#xff1a; 也可以通过版本说明 alibaba/spring-cloud-alibaba Wiki GitHub这个链接直接访问

模板学堂|DataEase地图视图功能详解

DataEase开源数据可视化分析平台于2022年6月正式发布模板市场&#xff08;https://dataease.io/templates/&#xff09;。模板市场旨在为DataEase用户提供专业、美观、拿来即用的仪表板模板&#xff0c;方便用户根据自身的业务需求和使用场景选择对应的仪表板模板&#xff0c;并…

【渗透测试学习】RCE漏洞是什么意思?其危害是什么?

RCE漏洞是网络安全中非常常见的漏洞之一&#xff0c;该漏洞又叫做远程代码执行漏洞&#xff0c;属于高危漏洞&#xff0c;其有着巨大的危害和影响。但很多人初识网络安全时&#xff0c;对RCE漏洞并不是很了解&#xff0c;到底是什么是RCE漏洞?RCE漏洞危害是什么?又该如何预防…

全国PMO专业人士年度盛会︱2023第十二届中国PMO大会会议日程

由PMO评论主办的第十二届中国PMO大会拟定于2023年8月12-13日在北京召开&#xff0c;本次大会主题为&#xff1a;“拥抱变革 展现PMO力量”&#xff0c;将特邀知名企业卓有建树的PMO实践精英来演讲&#xff0c;交流经验分享智慧&#xff0c;推动PMO在变革中不断成长、进化&#…

mac bash: python: command not found

问题&#xff1a;今天安装canvas的时候&#xff0c;报错提示python: command not found /bin/bash下不好使 ln -s /usr/bin/python3 /usr/local/bin/python zsh下不好使&#xff1a; 解决办法&#xff1a; # bashMacBook-Pro ~ % echo "alias python/usr/bin/python3&…

Arduino模块化编程

当用Arduino做复杂工程项目时&#xff0c;程序难免会变得很大。这时候要修改个别参数或函数的时候会变得麻烦&#xff0c;简而言之&#xff0c;项目程序管理难度增高了&#xff0c;程序代码维护会变得困难。这时候&#xff0c;就产生了将一个ino文件分解成多个功能相对独立的源…

屏幕录制为什么没有声音?录屏如何录入声音?

案例&#xff1a;我刚刚对电脑屏幕进行了录制&#xff0c;录制完成之后&#xff0c;查看录屏文件&#xff0c;才发现视频没有声音&#xff0c;顿时感觉到很崩溃。 【很多时候录制电脑屏幕的同时&#xff0c;还需要录制声音。那录屏的时候怎么把声音一起录进去&#xff1f;求一…

steam/csgo搬砖全套操作流程之如何选品(第②课)

Steam游戏搬砖项目已经在网赚圈存在好多年了&#xff0c;懂行的朋友一定明白&#xff1a;项目越稳定&#xff0c;赚钱越长久&#xff01;今天阿阳继续给大家分享这个项目最核心的部分&#xff1a; 第二课 Steam装备选品一直是这个项目的核心&#xff0c;阿阳也罗列了几个的问题…

Pandas+Pyecharts | 中国高校及专业数据分析可视化

文章目录 &#x1f3f3;️‍&#x1f308; 1. 导入模块&#x1f3f3;️‍&#x1f308; 2. Pandas数据处理2.1 读取数据 &#x1f3f3;️‍&#x1f308; 3. Pyecharts数据可视化3.1 全国高校分布地图3.2 全国高校分布城市地图3.3 本科/专科占比3.4 985/211/双一流高校数量占比…

【Python】一文带你认识 异常处理 + 简单操作

作者主页&#xff1a;爱笑的男孩。的博客_CSDN博客-深度学习,活动,python领域博主爱笑的男孩。擅长深度学习,活动,python,等方面的知识,爱笑的男孩。关注算法,python,计算机视觉,图像处理,深度学习,pytorch,神经网络,opencv领域.https://blog.csdn.net/Code_and516?typeblog个…