查看原文
其他

eCapture v0.8.0:CO-RE、非CO-RE二合一,交叉编译amd64、arm64双版本

CFC4N 榫卯江湖
2024-09-09

eCapture是什么

eCapture旁观者[1]是一个无需CA证书,无侵入的HTTPS/TLS明文抓包工具。可以在Linux 4.18以上版本使用,同时也支持Android arm64 5.5以上版本。项目发布共两年累计8200颗星。

新手友好 :CO-RE、非CO-RE二合一

下载

只下一个版本

使用eBPF技术实现的软件,总会分不清CO-RE[2](一次编译,到处运行),在选择CORE、非CORE版本而烦恼吗?不知道系统是否支持,也不知道什么是CORE。下载一个android版的eCapture,不知道要下android-aarch64.tar.gz还是android-aarch64-nocore.tar.gz

这下你不用纠结了,eCapture 0.8.0[3]起,实现了兼容,会自动选择CORE版本。而且,统一使用了面向产品化的CPU架构命名,分为amd64arm64两种,下载时注意区分。

使用

自动探测BTF、自动选择

eCapture 0.8.0[4]里,你只需要按照以往使用习惯,直接运行sudo ecapture tls等命令即可,无需关注系统是否支持BTF,eCapture会自动探测系统的支持情况,选择相应的eBPF字节码进行加载。

手动指定BTF

如果你在使用时,出现加载出错的情况,那么你也可以尝试手动指定eBPF字节码类型,让eCapture来指定加载。参数为-b--btf,值为3种:

  • 0:auto,自动探测、自动选择,即默认模式。
  • 1:core,CO-RE模式,一般支持CO-RE模式的内核,也都会支持non-CO-RE模式。
  • 2:non-core:非CO-RE模式,适用于CONFIG_DEBUG_INFO_BTF=n的情况。
sudo ./bin/ecapture -h
NAME:
 ecapture - capture text SSL content without CA cert by ebpf hook.
VERSION:
 linux_arm64:v0.8.0:5.15.0-105-generic
OPTIONS:
  -b, --btf=0  enable BTF mode.(0:auto; 1:core; 2:non-core)

Linux运行示例

使用-b=2参数指定后,捕获curl https://ecapture.cc,把保存的ecapture.pcapng文件用Wireshark打开。

可以看到,通过命令行参数-b=2指定后,加载的BPF bytecode模式为non-CORE,同时,加载的字节码文件也发生了变化。

同时,eCapture也准确的捕获了TLS 1.3的加密密钥、明文,以及准确的捕获了网络包所属进程curl,进程的PID 85432

Android版的eCapture使用方式与Linux一致,也是-b参数。

新版下载

eCapture v0.8.0 Github 下载

  • ecapture-v0.8.0-android-amd64.tar.gz[5]
  • ecapture-v0.8.0-android-arm64.tar.gz[6]
  • ecapture-v0.8.0-linux-amd64.tar.gz[7]
  • ecapture-v0.8.0-linux-arm64.tar.gz[8]

Warning

以下是面向eBPF开发者的内容,使用者可以不用看。

交叉编译 Cross-compilation

内核头文件

要交叉编译eCapture工具,您需要安装目标体系结构的内核头文件。需要安装linux-source软件包。

kernel_ver=`uname -r | cut -d'-' -f 1`
sudo apt-get install -y linux-source-$kernel_ver
cd /usr/src
sudo tar -xf linux-source-${kernel_ver}.tar.bz2
cd /usr/src/linux-source-${kernel_ver}
test -f .config || yes "" | sudo make oldconfig
yes "" | sudo make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- prepare V=0

更多交叉编译配置可参考仓库的workflows[9]

依赖环境

在amd64架构下,交叉编译arm64架构的二进制文件,需要安装gcc-aarch64-linux-gnu工具链。同样,在arm64架构下,交叉编译amd64架构的二进制文件,需要安装gcc-x86-64-linux-gnu工具链。

交叉编译器

  • amd64 : gcc-aarch64-linux-gnu
  • arm64 : gcc-x86-64-linux-gnu

编译命令

要在ubuntu amd64 系统上构建 arm64的产物,您可以设置 CROSS_ARCH环境变量来实现交叉编译。

CROSS_ARCH=arm64 make

产物构建 (交叉编译)

以Github Action中的release为例

- name: Release amd64
  run: |
    make clean
    make env
    make -f builder/Makefile.release release SNAPSHOT_VERSION=${{ github.ref_name }}
- name: Release arm64 (CROSS COMPILATION)
  run: |
    make clean
    make env
    CROSS_ARCH=arm64 make -f builder/Makefile.release release SNAPSHOT_VERSION=${{ github.ref_name }}

即可编译生成amd64、arm64两种CPU架构的eCapture二进制文件,包括Linux、Android两个系统版本。

技术难点

eCapture项目[10]是一个多语言实现的项目,内核空间代码使用C语言编写,用户空间代码使用Golang、CGO编写。其中eBPF加载器、eBPF Map读写是用纯Go实现。涉及到libpcap做cBPFeBPF的包过滤功能,是使用纯C编写的。

Kernel Space 内核空间代码

由于eCapture的大部分功能都是Uprobe,不太涉及内核的结构体。所以大部分情况下,都可以正常运行,只要解决编译问题。

CO-RE 头文件

CO-RE的版本,因为都支持重定位,只需要内置一个版本的vmlinux.h,能正常编译后,就可以放到支持CO-RE的内核上运行。

non-CO-RE 头文件

non-CO-RE版本,依赖编译时的内核头文件。在Ubuntu 22.04 Server上,只有当前CPU架构的完整头文件。如果需要交叉编译,则需要下载Linux 内核源码,重新生成目标CPU架构的头文件。这就是前面提到内核头文件预生成部分:make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- prepare

编译器

eBPF字节码的编译,完全使用llvm(clang)来编译,只需要编译参数中的-D__TARGET_ARCH_$(LINUX_ARCH)-target $(TARGET_ARCH) 是对应目标CPU架构信息即可。

User Space 用户空间代码

用户空间代码的核心功能是选择eBPF字节码,以及调用libpcap类库,将命令行参数转化解析编译成cBPF代码,再转化为eBPF字节码。再替换到过滤器中。

libpcap的交叉编译

项目本身是支持交叉编译的,需要指定目标架构,以及编译器CC、打包器AR。在amd64、arm64的Linux上,较为常见的交叉编译、打包归档工具为x86_64-linux-gnu-gccx86_64-linux-gnu-ar,编译参数中指定即可:

CC=$(CMD_CC_PREFIX)$(CMD_CC) AR=$(CMD_AR_PREFIX)$(CMD_AR) CFLAGS="-O2 -g -gdwarf-4 -static" ./configure --host=$(LIBPCAP_ARCH)

CGO混合编译

在golang的env里,默认的编译、打包工具是CC='gcc'AR='ar',及时你设定GOARCH=$(GOARCH) 来做Go层的交叉编译,但依旧无法完成CGO的交叉编译。所以,这里你需要重新设定他们为交叉编译的工具链,方法跟上面一致。

GOOS=linux GOARCH=$(GOARCH) CC=$(CMD_CC_PREFIX)$(CMD_CC) \
 $(CMD_GO) build -tags $(TARGET_TAG) -ldflags "-w -s -X 'github.com/gojue/ecapture/cli/cmd.GitVersion=$(TARGET_TAG)_$(GOARCH):$(VERSION_NUM):$(VERSION_FLAG)' -linkmode=external -extldflags -static " -o $(OUT_BIN)

听上去很简单,可笔者确是折腾了好久,掉了不知道多少根头发才解决。希望笔者的经验可以帮助到你,让你不掉头发。

社区新人

从上篇文章eCapture v0.7.4发布支持Pcap Filter包过滤语法 至今已经2个多月了,笔者一直没时间写。

近期工作特别忙,花在eCapture上的时间也很少。在这段时间内,社区涌现了好多为新人,持续提issue、提PR做贡献,尤其是ruitianzhong[11]sancpp[12]两位同学。

他们在社区提了issue后,我觉得打字效率太低,为了节省时间,跟他们约了视频会议讨论。说来也巧,他们在群里开场介绍后,发现都是西安电子科技大学的,现在通过eCapture认识了,有了共同的话题,相谈甚欢,还打算一起参加全国大学生计算机系统能力大赛[13]呢。

希望他们能取得好的比赛成绩,也欢迎更多的人参与到开源项目建设中。

参考资料
[1]

eCapture旁观者: https://ecapture.cc

[2]

CO-RE: https://facebookmicrosites.github.io/bpf/blog/2020/02/19/bpf-portability-and-co-re.html

[3]

eCapture 0.8.0: https://github.com/gojue/ecapture/releases/v0.8.0

[4]

eCapture 0.8.0: https://github.com/gojue/ecapture/releases/v0.8.0

[5]

ecapture-v0.8.0-android-amd64.tar.gz: https://github.com/gojue/ecapture/releases/download/v0.8.0/ecapture-v0.8.0-android-amd64.tar.gz

[6]

ecapture-v0.8.0-android-arm64.tar.gz: https://github.com/gojue/ecapture/releases/download/v0.8.0/ecapture-v0.8.0-android-arm64.tar.gz

[7]

ecapture-v0.8.0-linux-amd64.tar.gz: https://github.com/gojue/ecapture/releases/download/v0.8.0/ecapture-v0.8.0-linux-amd64.tar.gz

[8]

ecapture-v0.8.0-linux-arm64.tar.gz: https://github.com/gojue/ecapture/releases/download/v0.8.0/ecapture-v0.8.0-linux-arm64.tar.gz

[9]

workflows: https://github.com/gojue/ecapture/blob/master/.github/workflows/release.yml

[10]

eCapture项目: https://ecapture.cc/

[11]

ruitianzhong: https://github.com/ruitianzhong

[12]

sancpp: https://github.com/sancppp

[13]

全国大学生计算机系统能力大赛: https://os.educg.net/


个人观点,仅供参考
继续滑动看下一个
榫卯江湖
向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存