在WSL2上支持EBPF环境

发表于 2023-05-03

五一假期,闲里偷闲,在Windows电脑上将EBPF环境在WSL2上调试成功了,这里记录下调试过程,以待后续查阅。

WSL2

WSL2 (Windows Subsystem for Linux 2) 适用于 Linux 的 Windows 子系统,是在Win10、Win11系统支持的轻量化的Linux环境,相比较VMWare、Hyper-V而言更加轻量。

同时,常用开发软件比如 VSCodeIDEA等 对WSL的支持是非常优秀的,个人认为比远程SSH的支持还要优秀。

我这里选择的是WSL2 中的Ubuntu系统,安装命令 wsl --install -d Ubuntu,也可以通过微软软件商店来安装。经过测试微软软件商店的成功率更高,因为wsl命令要访问raw.githubusercontent.com,而该域名经常由于高科技原因造成无法在中国大陆访问。

将WSL默认使用Root用户:

1C:\> ubuntu.exe config --default-user root

由于背景全白,这里调整Bash的提示符以作醒目:

1export PS1="[\[\033[01;32m\]\u❄\h\[\033[00m\]:\[\033[01;34m\]\W\[\033[00m\]]☭ "

EBPF

eBPF (extended Berkeley Packet Filter) 允许程序在不修改内核源代码的情况下,向内核添加eBPF模块来扩展内核的功能。

KERNEL

当在WSL中安装并执行bpftool时,提示如下:

bpftool提示报错

bpftool会查找/lib/modules/5.10.16.3-microsoft-standard-WSL2路径的kernel header文件,但由于linux kernel 5.10.16.3-microsoft并不在Ubuntu的官方仓库里,所以唯一的办法就是自己从源代码编译kernel,并将kernel header安装到/lib/modules目录。

编译Kernel

1# 我这里选择了当前WSL2的最新版本的Kernel
2$ wget https://codeload.github.com/microsoft/WSL2-Linux-Kernel/tar.gz/refs/tags/linux-msft-wsl-6.1.21.1 -O /usr/src/linux-msft-wsl-6.1.21.1.tar.gz
3$ cd /usr/src && tar zxvf linux-msft-wsl-6.1.21.1.tar.gz && rm -fr linux-msft-wsl-6.1.21.1.tar.gz
4$ cd /usr/srcWSL2-Linux-Kernel-linux-msft-wsl-6.1.21.1/
5$ cp -af Microsoft/config-wsl .config

修改.config文件,增加BPF相关的配置:

 1CONFIG_BPF=y
 2CONFIG_BPF_SYSCALL=y
 3# [for tc filters]
 4CONFIG_NET_CLS_BPF=y
 5# [for tc actions]
 6CONFIG_NET_ACT_BPF=y
 7CONFIG_BPF_JIT=y
 8# [for Linux kernel versions 4.1 through 4.6]
 9CONFIG_HAVE_BPF_JIT=y
10# [for Linux kernel versions 4.7 and later]
11CONFIG_HAVE_EBPF_JIT=y
12# [for kprobes]
13CONFIG_BPF_EVENTS=y
14# Need kernel headers through /sys/kernel/kheaders.tar.xz
15CONFIG_IKHEADERS=y

安装必要的工具链及BPF需要的依赖包,并编译内核:

1$ apt install make build-essential flex bison bc pahole pkg-config libelf-dev libssl-dev clang llvm
2$ make -j 4
3$ make modules_install

安装Kernel

WSL2的Kernel启动,需要将Kernel拷贝到Windows系统中,并修改在Windows中的wsl配置文件。

1$ mkdir -p /mnt/c/WSL2Kernel/
2$ cp -af arch/x86/boot/bzImage /mnt/c/WSL2Kernel/

修改 WSL2的配置文件: C:\Users\{UserName}\.wslconfig:

1[wsl2]
2kernel=C:\\WSL2Kernel\\bzImage

重启WSL2

1C:\> wsl --shutdown
2C:\> bash

检查内核:

1$ ls /lib/modules/$(uname -r)
检查Kernel是否正确

BPFTOOL

由于BPFTool依赖Kernel,所以需要从源码安装BPFTOOL

1$ git clone https://github.com/libbpf/bpftool.git
2$ cd bpftool && git submodule update --init
3$ cd src && make && cp -af bpftool /usr/sbin/bpftool

验证一下:

验证bpftool工具

BPFTrace

使用Ubuntu包管理器安装的bpftrace,是一个strip掉sym的版本,在执行bpftrace -e 'BEGIN { printf("hi\n") }'时会报错:

验证bpftrace工具

所以这里也需要从源码编译bpftrace:

 1$ apt install -y libbpfcc-dev
 2$ apt install -y cmake g++ git zlib1g-dev libfl-dev systemtap-sdt-dev \
 3    binutils-dev libcereal-dev llvm-dev llvm-runtime libclang-dev \
 4    libpcap-dev libgtest-dev libgmock-dev asciidoctor
 5$ git clone https://github.com/iovisor/bpftrace --recurse-submodules
 6$ mkdir bpftrace/build; cd bpftrace/build;
 7$ ../build-libs.sh
 8$ cmake -DCMAKE_BUILD_TYPE=Release ..
 9$ make -j8
10$ make install && cp -af src/bpftrace /usr/bin/bpftrace

再次验证,则显示正常:

验证bpftrace工具

PERF

PERF也是依赖内核源代码的,直接使用Ubuntu包管理的perf命令会报错:

验证perf工具

我们这里直接使用Kernel 源码中的perf进行编译并安装即可:

1$ cd /usr/src/WSL2-Linux-Kernel-linux-msft-wsl-6.1.21.1/tools/perf/
2$ make && cp perf /usr/bin/perf

再次验证则显示正常:

验证perf工具

结束

至此,EBPF On WSL2环境算是搭建完毕,可以在这个轻量级Linux系统中使用EBPF随意的玩耍了。

上一篇 在M1芯片上使用Qemu安装Ubuntu 下一篇 EBPF 随笔