2023-04-13 16:34:56 +08:00

117 lines
8.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 第十章 系统集成开发eBPF
安卓系统的安全攻防技术日新月异现如今进入了一个全新的高度。随着eBPF技术的崛起国内外安全人员人业也在积极发掘eBPF技术在安全领域的应用场景。
本章将为安卓系统开发与定制人员提供一种代码修改与eBPF可观测性相结合的系统定制细路旨在为安全行业的发展发挥一点抛砖引玉的作用。
## 10.1 eBPF概述
eBPF(extended Berkeley Packet Filter) 是一种现代化的Linux内核技术它允许开发人员对网络数据包进行更细粒度的过滤和修改。与传统的Berkeley Packet Filter(BPF)相比eBPF具有更灵活、可扩展性和安全性的优势因此得到了广泛的应用和认可。在实际应用中eBPF可以实现网络流量监控、日志记录、流量优化和安全审计等功能因此具有广泛的应用前景。
### 10.1.1 eBPF发展背景
在2008年Linux内核开发者提出了BPF(Berkeley Packet Filter)的概念它是一种用于过滤和修改网络数据包的内核模块。BPF是一种非常强大的工具它允许开发人员对网络数据包进行细粒度的过滤和修改从而实现网络流量监控、日志记录、性能优化等功能。
然而BPF也有一些限制。首先BPF模块需要由内核开发人员手动编写和编译因此对于非专业开发人员来说编写BPF模块是一项具有挑战性的任务。其次BPF模块的编写需要一定的技术知识和经验否则可能会导致内核崩溃或其他问题。最后BPF模块的访问权限非常高意味着它们可以访问系统的所有内存和网络资源因此需要严格的安全控制。
为了解决这些问题Linux内核开发者在2014年引入了eBPF(extended Berkeley Packet Filter) 技术。eBPF是一种扩展的BPF它提供了更多的功能和权限控制同时降低了内核开发人员的编写难度和风险。与传统的BPF相比eBPF具有更灵活、可扩展性和安全性的优势因此得到了广泛的应用和认可。
eBPF发展之初是为了用于高效的网络数据包的过滤。在发展过程中除了对传统的数据包过滤字节码格式进行扩展外还支持更多类型的eBPF程序它们可以在整个操作系统的不同模块中运行。最初提倡的可观测性领域也扩展为支持数据的观测与修改包括用户态数据与内核函数返回值。这样的发展路径让eBPF技术看起来更像是一个现代化的Hook技术框架。这也是安全从业人员其对爱不释手的原因。
相信随着内核版本的更新其内置的eBPF功能支持也会越来越丰富。而作为eBPF的能力核心-eBPF内核方法接口也会越来越多基于这些接口实现的安全功能势必会影响到整个行业的发展。
### 10.1.2 eBPF的工作原理
eBPF的工作原理可以概括为三个步骤解析、执行和卸载。
1. 解析
在系统启动时内核会将eBPF符号表(eBPF symbol table) 加载到内存中。eBPF符号表是一个二进制文件它包含了eBPF模块的所有符号和参数。内核还会将eBPF模块的二进制代码转换为机器码并将其加载到内存中。
2. 执行
当网络数据包到达时内核会首先检查数据包是否被匹配到eBPF模块。如果数据包被匹配到内核会执行eBPF模块中的代码对网络数据包进行过滤或修改。在执行期间内核会使用eBPF的运行时数据结构体(runtime data structure)来存储和传递参数和上下文信息。
3. 卸载
当eBPF模块执行完毕后内核会将其卸载并从内存中清除。卸载时内核会将所有符号和参数还原成二进制码并将其从内存中清除。
### 10.1.3 eBPF的应用场景
eBPF是一种非常强大的技术它可以实现许多网络流量监控、日志记录、性能优化等功能。下面列举了一些常见的eBPF应用场景:
1. 日志记录
eBPF可以用于记录网络流量、系统调用、错误事件等信息从而实现全面的系统监控和日志记录。目前这方面技术应用于云原生安全较多。如`sysdig``falco`这类安全监控工具新版本就使用了eBPF来实现系统调用的监控。
2. 流量控制
eBPF 可以用于实现网络流量控制,例如限制同一主机的网络流量、限制同一端口的网络流量等。这个应用最多的就是防火墙,比如大名鼎鼎的`iptables`就有了基于eBPF的扩展版本。
3. 流量优化
eBPF可以用于优化网络流量例如过滤重复数据包、压缩数据包、优化TCP/IP协议栈等。在网络应用上典型的是可以使用eBPF开发透明代理工具、网络数据镜像转发工具、流量优化工具等。
4. 安全审计
eBPF可以用于实现安全审计功能例如记录系统用户的操作、检查系统资源使用情况等。在这个应用领域如主机安全类防护产品`HIDS`就有了发展的空间。安全工具`Tracee`就是属于这类应用。
## 10.2 eBPF相关的开发工具
eBPF是一种现代化的Linux内核技术它允许开发者在内核中安全地运行外部程序用于处理网络数据包、系统调用等场景。eBPF相比传统的内核模块有更高的安全性和可移植性因此得到了越来越广泛的应用。eBPF虽然运行在内核但是控制它的程序却是运行在用户态下面将介绍一下它的开发方法。
在开发eBPF相关工具时常用的有bcc、bpftrace和libbpf。下面将对这三个工具/库进行介绍。
### 10.2.1 bcc
`bcc`是一款开源的eBPF快速开发工具。最初使用python作为eBPF程序的开发语言随着社区的发展该工具支持了C语言开发eBPF程序。该项目是一个开源工具它的仓库地址是https://github.com/iovisor/bcc。该仓库提供了一组python语言编写的eBPF工具集位于tools目录下涉及的功能包含了文件、进程、网络、延时、性能观测等多个应用场景的工具;同时也提供了一组C语言编写的eBPF工具集位于libbpf-tools工具下这下面的工具很多是tools的C语言实现版本是非常好的eBPF入门学习资料。
该工具的项目README中有列出eBPF可以运行的不同系统位置的分布图。也提供了tools目录下工具用途的介绍。比如监控文件的打开操作可以执行如下命令
```
$ sudo python3 tools/opensnoop
```
### 10.2.2 bpftrace
`bpftrace`的主要用途是用于记录和追踪系统方法调用。eBPF程序可以用于处理网络数据包、系统调用、文件访问等场景。使用`bpftrace`开发者可以可以快速验证要观测的函数是否支持eBPF来实现。
`bpftrace`是开源的工具它的仓库地址是https://github.com/iovisor/bpftrace。按照官方的说明安装好该工具后会提供一个`bpftrace`工具。这个主程序接受单选的命令与一个bt格式的脚本程序作为输入。脚本中可以设置观测程序的入口和出口、参数传递等信息非常方便。需要注意的是目前`bpftrace`只提供了观测功能,没有提供数据的修改功能。这点上不如`bcc``libbpf`
执行下面的命令,可以观测所有的文件打开操作:
```
$ sudo bpftrace -e 'tracepoint:syscalls:sys_enter_openat { printf("%s %s\n", comm, str(args->filename)); }'
```
### 10.2.3 libbpf
libbpf是一个用于编写和运行eBPF程序的开源库。它的仓库地址是https://github.com/libbpf/libbpf。 它提供了一组C接口的函数允许开发者使用C/Rust语言编写和运行eBPF程序。libbpf官方还单独提供了一些使用libbpf开发eBPF程序的样例。仓库地址是https://github.com/libbpf/libbpf-bootstrap。该仓库下的examples/c目录下的演示代码整体的风格与bcc的libbpf-tools目录下类似前者代码简洁后者功能更丰富。
总的来说,`bcc``bpftrace``libbpf`都是用于开发eBPF相关工具的重要工具它们提供了丰富的功能和工具方便开发者进行eBPF程序的开发、调试和追踪。
## 10.3 安卓系统集成eBPF功能
### 10.3.1 不同版本内核对eBPF的影响
### 10.3.2 为低版本系统打上eBPF补丁
### 10.3.3 一些需要注意的内核配置
## 10.4 测试eBPF功能
### 10.4.1 运行bcc工具
### 10.4.2 运行bpftrace工具
### 10.4.3 如何编译基于libbpf的eBPF程序
## 10.5 eBPF实现安卓系统进程跟踪
在这里不得不提一个两个功能强大的方法:`bpf_probe_read_user``bpf_probe_write_user`这两个接口允许eBPF读取与写入内存地址指定的数据它们拥有内核一样的能力却有着比内核高得多的稳定性功能不可谓不强大。
## 10.6 小结