最近在学eBPF,发现了BeiChen师傅之前写的FakeToa,学习一下拿Go写了一下用户态程序。理论上是修改成功的。
hook到sockops
,关于sockops
可以稍微参考一下BPF 进阶笔记(五):几种 TCP 相关的 BPF(sockops、struct_ops、header options),但是里面提到的东西并不算多。可以再具体看一下[PATCH v3 bpf-next 6/9] bpf: tcp: Allow bpf prog to write and parse TCP header option - Martin KaFai Lau
因此其实非常简单,就是给个flag是BPF_SOCK_OPS_WRITE_HDR_OPT_CB_FLAG
然后在里面bpf_store_hdr_opt(skops, &fakeToa, sizeof(fakeToa), 0);
就可以了。
并没有考虑其他的cgroup,程序里写死了绑定到/sys/fs/cgroup
。
cgroup, err := link.AttachCgroup(link.CgroupOptions{
Path: "/sys/fs/cgroup",
Attach: ebpf.AttachCGroupSockOps,
Program: objs.BpfSockopsHandler,
})
也没有直接将程序pin到文件系统,停止程序就意味着停止hook。别的没太多坑点。
环境搭建参考Cilium的官方文档吧:Getting Started - ebpf-go Documentation
我的Linux版本:
uname -a
Linux ubuntu-linux-22-04-02-desktop 6.5.13-060513-generic #202311281736 SMP PREEMPT_DYNAMIC Tue Nov 28 18:10:14 UTC 2023 aarch64 aarch64 aarch64 GNU/Linux
至少版本不能太低吧。而且要支持cgroup v2。
配置好之后需要自己修改gen.go
里的配置,基本上改个架构应该就行。
运行:
go generate
go build -o main
./main -h
Usage of ./main:
-ip string
ip of Tcp Option Address that you want to fake (default "8.8.8.8")
-opcode uint
opcode of Tcp Option Address (default 254)
-port uint
port of Tcp Option Address (default 80)
go build -o main &&./main -ip 1.2.3.4 -port 39123
wireshark抓包证明修改成功。
但是一直没找到能真正显示出这个TOA中ip的网站,找了很多都不支持。
BPF 进阶笔记(五):几种 TCP 相关的 BPF(sockops、struct_ops、header options)