当前位置:网站首页>Introduction to ebpf

Introduction to ebpf

2022-06-24 05:00:00 fluyy

1. BPF The past and this life

bpf Full name: Berkeley packet filter (Berkeley Packet Filte),bpf Technology was born in 1992 year , In the early days, it was mainly used to improve packet filtering performance , But early bpf Fewer instructions are provided , It limits its scope of application . This article will introduce ebpf yes bpf Extended version of , Compared to earlier versions of bpf Become more powerful , since 2014 Since the introduction of the kernel in ,BPF Now it has developed into a general engine in the kernel , Through correlation API We can easily read the contents of the kernel memory , Can also pass through BPF Overwrite runtime memory , Have strong programming ability . It's no exaggeration to say ,BPF Technology is the scripting language in the kernel .

BPF Application scenarios of

BPF It has a wide range of application scenarios , To sum up, there are mainly the following areas .

Performance analysis : BPF Provides high visibility into the kernel and Applications , Through programming, we can realize rich statistical functions , Extremely high performance , It can avoid the impact on the observation procedure .

Improve the observability of the program : adopt BPF technology , You can perform instrumentation monitoring at different stages of function calls , Be able to observe the program memory at run time ,

By improving the observability of the program , It is convenient for us to locate low probability recurrence bug.

Security : bpf Technology can observe system calls , Sense which processes are running , Which files were overwritten , face 0day Loophole , Can also quickly write the corresponding detection program .

In addition to the major directions listed above .K8s Have gone through BPF Technology to improve the network security performance of the container and rich monitoring and troubleshooting capabilities . It even provides a Cilium Load balancing capability of .(k8s What we use Cilium frame )

BPF The basic principle of :

go-1a1bb6f1e64b1ad5597f57dc17cf1350.png

( quote :https://ebpf.io/what-is-ebpf#introduction-to-ebpf

BPF The program is first BPF The verifier has passed the verification , Then the compiler compiles it into a specific bytecode . Finally, by running in the kernel bpf The virtual machine interprets and executes . The kernel also provides some helper function , Here's the detailed documentation : https://man7.org/linux/man-pages/man7/bpf-helpers.7.html

maps yes eBPF Storage structure provided . We can use maps Make statistics , Store some custom variables , Then, it can be passed in the user mode API Reading this data .

BPF The program runs in the sandbox , And the safety verification is carried out by the verifier , Can prevent bpf The program destroys the system . If in bpf The program has written an infinite loop , Or there is logic that the array is out of bounds , The verifier will directly report a failure , Prevent programs from harming the kernel .

How to write ebpf Tools ?

There are many tools available today ( for example cilium, bcc, bpftrace), Yes bpf More advanced abstractions , It can be convenient for us to bpf Application development . These tools will eventually be compiled into by the compiler bpf Bytecode .

install bcc Related compilation tools

yum install bcc

Install header file

 yum install kernel-headers

stay /usr/share/bcc/tools There are many written tools in this directory , What are these tools python Written , You can view the code directly . These tools keep linux The tool has a consistent style , So it's easy to use , There is not much to describe here . Let's take a look at how to write BPF Program .

First, implement a function , Output a string

#include <stdio.h>
void print_str(char* s) {
	printf("%s %c\n", s, 's');
}

int main() {
    char foo2[] = "foo2";
	print_str(foo2);
	return 0;
}

Then write a paragraph BPF Program , Through to print_str Function to insert piles to intercept , Rewrite the output of the original program .

#!/usr/bin/python
from __future__ import print_function
from bcc import BPF
from time import sleep

#  Write here bpf Program , Will be loaded into the kernel to execute 
b = BPF(text="""
#include <uapi/linux/ptrace.h>
int change_msg(struct pt_regs *ctx) {
    if (!PT_REGS_PARM1(ctx))
        return 0;
    char buf[32];
    char foo2[] = "zan";
    u64 res = bpf_probe_read_user(&buf, sizeof(buf), (void *)PT_REGS_PARM1(ctx));
    bpf_trace_printk("msg:%s,%d\\n",  buf, res);
   
    bpf_probe_write_user((void *)PT_REGS_PARM1(ctx), foo2, sizeof(foo2));
    return 0;
};
""")
b.attach_uprobe(name="./a.out", sym="print_str", fn_name="record_chown")


# sleep until Ctrl-C
try:
    while True:
        b.trace_print()
        sleep(1)
except KeyboardInterrupt:
    pass

Yes bpf The code does some simple explanation :

PT_REGS_PARM1(ctx)

adopt ctx Get the first variable of the tracked function , Here is the corresponding print_str Functional char *s, If there are other variables

The corresponding is changed to PT_REGS_PARM2,PT_REGS_PARM3

u64 res = bpf_probe_read_user(&buf, sizeof(buf), (void *)PT_REGS_PARM1(ctx));

adopt bpf_probe_read_user Function reads data from user space into variables

bpf_trace_printk: similar printf The function of , To write ebpf The program is in debug It's more useful when

bpf_probe_write_user((void *)PT_REGS_PARM1(ctx), foo2, sizeof(foo2));

adopt bpf_probe_write_user Function to rewrite the content data in user mode , It's going to be C In program foo2 Changed to zan

b.attach_uprobe(name="./a.out", sym="print_str", fn_name="change_msg")

Finally through attach_uprobe High speed bpf Program , When it is necessary to track programs in user mode a.out, Function to trace print_str, And corresponding bpf When dealing with functions change_msg

Finally, the effect :

原网站

版权声明
本文为[fluyy]所创,转载请带上原文链接,感谢
https://yzsam.com/2021/08/20210828124716672T.html