读《eBPF云原生安全》第三部分的云端乱想
1. 获取进程名最好不要使用 bpf_get_current_comm()、task->comm,而要用 task->mm->arg_start。用下面的命令自己看区别
bpftrace -e 'tracepoint:syscalls:sys_enter_clone* {printf("%s, %s, %s\n", comm, curtask->comm, str(uptr(curtask->mm->arg_start)));}'
2. BPF_KSYSCALL 糖太甜啦!其实我不是很喜欢这种甜度的糖,包括 BPF_PROG、BPF_KPROBE 等,掩盖了每类 bpf 各有不同参数 context 的细节,本来简单的概念包了一层之后反而我看不懂了。
3. BTF tracepoint 非常好!然后你惊讶地发现 bpftrace -e tracepoint 居然没有利用这项四年前就合并的功能,这难道不是给 bpftrace 做贡献的好机会?(@ _) 从性能上看把 bpf_probe_read 调用都优化成一条 load mem 指令,没有理由不用它。
4. 入口事件+返回事件联合 trace,先暂存事件到 map 再在返回时读出来设置上 retval 是比我更好的思路,我蠢到用两个独立事件在用户态关联,笑死。用 PERCPU_ARRAY 获得更好性能。
5. bpf_send_signal 想过异步信号问题没,即,信号可能并不会立刻投递给进程?对于 SIGKILL 来说没问题,对有些信号可能有问题吗,急需重新背诵 TLPI。
6. bpf_probe_write_user 在有些桌面 linux 默认禁用,比如 ubuntu 2204 integrity lockdown。以前用 Dell ubuntu 的时候也必须把 BIOS secure boot 关了才行。但是似乎 Ubuntu server 2204 又可以用它。
7. 我才知道经典的 tcpdump 的实现已经支持接受 ebpf 了。tcpdump 是通过 socket(AF_PACKET, SOCK_RAW) 然后 setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, cbpf_prog) 来实现的。现早已支持 setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, ebpf_fd) 使用 ebpf 过滤。其实这里有很大的想象空间,比如支持一下对 mark, cb, 甚至 sk 的过滤和输出肯定是可以做到的。甚至进程关联岂不是也易如反掌。
8. 用 cgroup/{connect4, connect6, sendmsg4, sendmsg6} + bpf_get_socket_cookie 来关联 skb 和进程信息似乎是更好的做法,我也是从那个项目学到的。
9. iter/task_file 太吓人了,岂不是我们 可以 必须搞一个 bpf iter 版本的 lsof ? 考虑到 lsof 那蹩脚的无限循环 open /proc/*,bpf 版本性能十倍起跳很合理吧(
10. kprobe/fd_install 记录 fd 的 filename 很精彩,但是unix socket 传递 fd 之类的情况是不是就漏了?fork 继承 fd 的情况呢?算了管他的😋
11. bpf 隐藏进程的能力很吓人。如果能用 bpf_probe_write_user 那 bpftool 的输出也一样能篡改,一个精心编写的已经获取 root 的挖矿进程借助 bpf 可以做到:top/ps 不显示正确的 cpu 使用率、隐藏恶意进程、隐藏恶意 bpf 程序、隐藏恶意流量。不知怎么办,管他的,睡觉要紧。
能给我带来启发和思考的书我都觉得是好书,算是迟来的推荐吧🥵感谢黄老师来上海捧场且没有在QA环节把我问得下不了台的不杀之恩
1. 获取进程名最好不要使用 bpf_get_current_comm()、task->comm,而要用 task->mm->arg_start。用下面的命令自己看区别
bpftrace -e 'tracepoint:syscalls:sys_enter_clone* {printf("%s, %s, %s\n", comm, curtask->comm, str(uptr(curtask->mm->arg_start)));}'
2. BPF_KSYSCALL 糖太甜啦!其实我不是很喜欢这种甜度的糖,包括 BPF_PROG、BPF_KPROBE 等,掩盖了每类 bpf 各有不同参数 context 的细节,本来简单的概念包了一层之后反而我看不懂了。
3. BTF tracepoint 非常好!然后你惊讶地发现 bpftrace -e tracepoint 居然没有利用这项四年前就合并的功能,这难道不是给 bpftrace 做贡献的好机会?(@ _) 从性能上看把 bpf_probe_read 调用都优化成一条 load mem 指令,没有理由不用它。
4. 入口事件+返回事件联合 trace,先暂存事件到 map 再在返回时读出来设置上 retval 是比我更好的思路,我蠢到用两个独立事件在用户态关联,笑死。用 PERCPU_ARRAY 获得更好性能。
5. bpf_send_signal 想过异步信号问题没,即,信号可能并不会立刻投递给进程?对于 SIGKILL 来说没问题,对有些信号可能有问题吗,急需重新背诵 TLPI。
6. bpf_probe_write_user 在有些桌面 linux 默认禁用,比如 ubuntu 2204 integrity lockdown。以前用 Dell ubuntu 的时候也必须把 BIOS secure boot 关了才行。但是似乎 Ubuntu server 2204 又可以用它。
7. 我才知道经典的 tcpdump 的实现已经支持接受 ebpf 了。tcpdump 是通过 socket(AF_PACKET, SOCK_RAW) 然后 setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, cbpf_prog) 来实现的。现早已支持 setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, ebpf_fd) 使用 ebpf 过滤。其实这里有很大的想象空间,比如支持一下对 mark, cb, 甚至 sk 的过滤和输出肯定是可以做到的。甚至进程关联岂不是也易如反掌。
8. 用 cgroup/{connect4, connect6, sendmsg4, sendmsg6} + bpf_get_socket_cookie 来关联 skb 和进程信息似乎是更好的做法,我也是从那个项目学到的。
9. iter/task_file 太吓人了,岂不是我们 可以 必须搞一个 bpf iter 版本的 lsof ? 考虑到 lsof 那蹩脚的无限循环 open /proc/*,bpf 版本性能十倍起跳很合理吧(
10. kprobe/fd_install 记录 fd 的 filename 很精彩,但是unix socket 传递 fd 之类的情况是不是就漏了?fork 继承 fd 的情况呢?算了管他的😋
11. bpf 隐藏进程的能力很吓人。如果能用 bpf_probe_write_user 那 bpftool 的输出也一样能篡改,一个精心编写的已经获取 root 的挖矿进程借助 bpf 可以做到:top/ps 不显示正确的 cpu 使用率、隐藏恶意进程、隐藏恶意 bpf 程序、隐藏恶意流量。不知怎么办,管他的,睡觉要紧。
能给我带来启发和思考的书我都觉得是好书,算是迟来的推荐吧🥵感谢黄老师来上海捧场且没有在QA环节把我问得下不了台的不杀之恩