79 lines
2.0 KiB
Markdown
79 lines
2.0 KiB
Markdown
# 练手用的 LSM-BPF 模块
|
||
|
||
## Quick Start
|
||
|
||
### 环境
|
||
|
||
- clang
|
||
- 我的在 clang15,但是理论上略微旧一点没关系。如果提示头文件缺失或者是不支持 bpf target,请升级
|
||
- kernel with BTF
|
||
- 参考:https://github.com/aquasecurity/btfhub/blob/main/docs/supported-distros.md
|
||
- golang 1.17+
|
||
- bpftool
|
||
- `bpftool btf dump file /sys/kernel/btf/vmlinux format c > vmlinux.h`
|
||
- bpf2go
|
||
- cilium 的工具
|
||
|
||
### 启动
|
||
|
||
- 一个终端
|
||
```bash
|
||
go build -o bin/demo
|
||
sudo ./bin/demo $PWD
|
||
```
|
||
- 另一个终端
|
||
```bash
|
||
watch ls
|
||
```
|
||
- 如果要看日志(不要tail)
|
||
```bash
|
||
sudo cat /sys/kernel/debug/tracing/trace_pipe
|
||
```
|
||
|
||
## 代码解释
|
||
|
||
### 内核态的 eBPF 程序: [./bpf/lsm.c](./bpf/lsm.c)
|
||
|
||
内核态程序主要是三部分:
|
||
- 生成的 BTF 定义,这个理论上可以在支持 BTF 的发行版上直接用,不需要改
|
||
- map: 内核和用户态通信的数据结构
|
||
- hook: 入口点
|
||
|
||
和普通的 C 非常像,可以当 C 来写。但是栈空间只有 512 B。我没打错,就 512 Byte。
|
||
|
||
#### BTF 定义生成
|
||
|
||
```bash
|
||
bpftool btf dump file /sys/kernel/btf/vmlinux format c > vmlinux.h
|
||
```
|
||
|
||
#### map
|
||
|
||
map 不在栈空间中,一般用来让
|
||
- 用户态配置 eBPF 程序
|
||
- eBPF 程序向用户态传递结果或者性能数据
|
||
|
||
参考
|
||
- https://docs.kernel.org/bpf/maps.html#map-types
|
||
|
||
#### hook
|
||
|
||
hook 就是一个函数,可以配置为在特定时机被 hook 点调起。
|
||
|
||
我们这个 demo 主要是希望尝试写 lsm 模块,比如说和 file_open 这个 hook 有关的信息在
|
||
- https://github.com/torvalds/linux/blob/master/security/security.c#L2793
|
||
|
||
主要是需要关注 hook 需要接受的参数。
|
||
|
||
也有很多其他的 hook 点,比如说 kprobe 和 xdp 有关的。我们这个仓库暂时不关心。
|
||
|
||
### 用户态
|
||
|
||
用户态我选择了用 cilium 的 wrapper,理论上可以用 libbpf 啊或者类似的其他工具来实现。
|
||
|
||
### 构建
|
||
|
||
整体来说项目是
|
||
- (一次性)生成 vmlinux.h
|
||
- bpf2go 工具编译 ebpf 字节码,生成 stub
|
||
- 编译 go 的二进制 |