From c41e2bac84c6e31056431493363a22d7937bc8ca Mon Sep 17 00:00:00 2001 From: Anupam kumari Date: Wed, 6 Mar 2024 23:13:53 +0530 Subject: [PATCH] removed existing ebpf code --- .github/workflows/ci.yaml | 6 -- .gitignore | 1 - .golangci.yml | 2 - Makefile | 14 --- go.sum | 2 - pkg/nodeagent/capture_exec.go | 44 ++++++--- pkg/nodeagent/ebpf/c/capture_exec.bpf.c | 77 --------------- pkg/nodeagent/ebpf/doc.go | 2 - pkg/nodeagent/ebpf/exec.go | 126 ------------------------ pkg/nodeagent/nodeagent.go | 2 +- 10 files changed, 30 insertions(+), 246 deletions(-) delete mode 100644 pkg/nodeagent/ebpf/c/capture_exec.bpf.c delete mode 100644 pkg/nodeagent/ebpf/doc.go delete mode 100644 pkg/nodeagent/ebpf/exec.go diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index c32e488c..9f4863af 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -58,12 +58,6 @@ jobs: go-version: "1.21" cache: false - - name: EBPF prerequisites - run: | - set -x - sudo apt update && sudo apt install -y jq pkg-config libelf-dev clang - make ebpf - - name: Run unit tests run: make unit-test diff --git a/.gitignore b/.gitignore index 34a013c3..0c2362d9 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,6 @@ /vendor /.local /.vscode -/pkg/**/capture_exec.bpf.o /pkg/tarianpb/api.pb.go /pkg/tarianpb/types.pb.go coverage.xml diff --git a/.golangci.yml b/.golangci.yml index 1c891453..d9fe769e 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,8 +1,6 @@ run: timeout: 10m concurrency: 4 - skip-files: - - pkg/nodeagent/ebpf/exec.go linters: disable-all: true diff --git a/Makefile b/Makefile index aedd51c6..c01c7fd3 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,6 @@ default: help help: ## Display this help. @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) -##@ eBPF BASEDIR = $(abspath ./) OUTPUT = ./output @@ -60,7 +59,6 @@ CGO_LDFLAGS_DYN = "-lelf -lz -lbpf" BTFFILE = /sys/kernel/btf/vmlinux BPFTOOL = $(shell which bpftool || /bin/false) VMLINUXH = $(OUTPUT)/vmlinux.h -NODEAGENT_EBPF_DIR = pkg/nodeagent/ebpf # extracts the major, minor, and patch version numbers of the kernel version KERNEL_VERSION = $(word 1, $(subst -, ,$(shell uname -r))) @@ -97,18 +95,6 @@ $(VMLINUXH): $(OUTPUT) $(BPFTOOL) btf dump file $(BTFFILE) format c > $(VMLINUXH); \ fi -# libbpf - -$(LIBBPF_OBJ): $(LIBBPF_SRC) $(wildcard $(LIBBPF_SRC)/*.[ch]) | $(OUTPUT)/libbpf - CC="$(CC)" CFLAGS="$(CFLAGS)" LD_FLAGS="$(LDFLAGS)" \ - $(MAKE) -C $(LIBBPF_SRC) \ - BUILD_STATIC_ONLY=1 \ - OBJDIR=$(LIBBPF_OBJDIR) \ - DESTDIR=$(LIBBPF_DESTDIR) \ - INCLUDEDIR= LIBDIR= UAPIDIR= install - -libbpfgo-static: $(VMLINUXH) | $(LIBBPF_OBJ) - ##@ Development generate: bin/controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. diff --git a/go.sum b/go.sum index 23772d28..033536ee 100644 --- a/go.sum +++ b/go.sum @@ -280,8 +280,6 @@ github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/intelops/tarian-detector v0.0.0-20240223205958-674f5351cece h1:lai7AMQVv7tyoNqYdt4u4ibaxT5CjvoCI0paH2rpVJY= -github.com/intelops/tarian-detector v0.0.0-20240223205958-674f5351cece/go.mod h1:u7VW9+KOi2ujvIevz/LtfaXkjfkBp7BKgGuPcSq814E= github.com/intelops/tarian-detector v0.0.0-20240226164335-7701e4e67daa h1:ExaZjScIYDDIfCOygau+d09cvJdJdrWEN3yfHdehgbE= github.com/intelops/tarian-detector v0.0.0-20240226164335-7701e4e67daa/go.mod h1:u7VW9+KOi2ujvIevz/LtfaXkjfkBp7BKgGuPcSq814E= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= diff --git a/pkg/nodeagent/capture_exec.go b/pkg/nodeagent/capture_exec.go index 088eecfc..fb37179a 100644 --- a/pkg/nodeagent/capture_exec.go +++ b/pkg/nodeagent/capture_exec.go @@ -1,11 +1,12 @@ package nodeagent import ( + "context" "fmt" + "github.com/aquasecurity/libbpfgo" "github.com/intelops/tarian-detector/pkg/detector" "github.com/intelops/tarian-detector/tarian" - "github.com/kube-tarian/tarian/pkg/nodeagent/ebpf" "github.com/sirupsen/logrus" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" @@ -48,12 +49,16 @@ type ExecEvent struct { // CaptureExec captures and processes execution events, associating them with Kubernetes Pods. // It uses eBPF (Extended Berkeley Packet Filter) to capture execution events in the Linux kernel. type CaptureExec struct { - eventsChan chan ExecEvent // Channel for sending captured execution events - shouldClose bool // Flag indicating whether the capture should be closed - bpfCaptureExec *ebpf.BpfCaptureExec // Instance of eBPF capture execution - nodeName string // The name of the node where the capture is running - logger *logrus.Logger // Logger instance for logging + ctx context.Context + eventsChan chan ExecEvent // Channel for sending captured execution events + shouldClose bool // Flag indicating whether the capture should be closed + bpfModule *libbpfgo.Module + bpfProg *libbpfgo.BPFProg + bpfRingBuffer *libbpfgo.RingBuffer + nodeName string // The name of the node where the capture is running + logger *logrus.Logger // Logger instance for logging eventsDetectorChan chan map[string]any + eventsDetector *detector.EventsDetector } // NewCaptureExec creates a new CaptureExec instance for capturing and processing execution events. @@ -65,8 +70,9 @@ type CaptureExec struct { // Returns: // - *CaptureExec: A new instance of CaptureExec. // - error: An error if creating the eBPF capture execution instance fails. -func NewCaptureExec(logger *logrus.Logger) (*CaptureExec, error) { +func NewCaptureExec(ctx context.Context, logger *logrus.Logger) (*CaptureExec, error) { return &CaptureExec{ + ctx: ctx, eventsChan: make(chan ExecEvent, 1000), logger: logger, eventsDetectorChan: make(chan map[string]any, 1000), @@ -100,7 +106,7 @@ func (c *CaptureExec) Start() error { } watcher.Start() - err = c.GetTarianDetectorEvents() + err = c.GetTarianDetectorEbpfEvents() if err != nil { return fmt.Errorf("CaptureExec.Start: failed to get tarian detector events: %w", err) } @@ -141,7 +147,7 @@ func (c *CaptureExec) Start() error { // Create an ExecEvent and send it to the events channel. execEvent := ExecEvent{ - Pid: pid, + Pid: pid, ContainerID: containerID, K8sPodName: podName, K8sPodUID: podUID, @@ -158,6 +164,7 @@ func (c *CaptureExec) Start() error { // Close stops the capture process and closes associated resources. func (c *CaptureExec) Close() { c.shouldClose = true + c.eventsDetector.Close() } // GetEventsChannel returns the channel for receiving execution events. @@ -165,16 +172,18 @@ func (c *CaptureExec) GetEventsChannel() chan ExecEvent { return c.eventsChan } -func (c *CaptureExec) GetTarianDetectorEvents() error { +func (c *CaptureExec) GetTarianDetectorEbpfEvents() error { tarianEbpfModule, err := tarian.GetModule() if err != nil { - c.logger.Error("error while get tarian ebpf module: %v", err) + fmt.Println("error while get tarian ebpf module: ", err) + c.logger.Errorf("error while get tarian ebpf module: %v", err) return fmt.Errorf("error while get tarian-detector ebpf module: %w", err) } tarianDetector, err := tarianEbpfModule.Prepare() if err != nil { - c.logger.Error("error while prepare tarian detector: %v", err) + fmt.Printf("error while prepare tarian detector: %v", err) + c.logger.Errorf("error while prepare tarian detector: %v", err) return fmt.Errorf("error while prepare tarian-detector: %w", err) } @@ -187,16 +196,20 @@ func (c *CaptureExec) GetTarianDetectorEvents() error { // Start and defer Close err = eventsDetector.Start() if err != nil { + fmt.Printf("error while start tarian detector: %v", err) c.logger.Errorf("error while start tarian detector: %v", err) return fmt.Errorf("error while start tarian-detector: %w", err) } - defer eventsDetector.Close() + c.eventsDetector = eventsDetector + + defer c.eventsDetector.Close() go func() { for { - event, err := eventsDetector.ReadAsInterface() + event, err := c.eventsDetector.ReadAsInterface() if err != nil { + fmt.Printf("error while read event: %v", err) fmt.Print("error while read event as interface: ", err) c.logger.WithError(err).Error("error while read event") continue @@ -210,6 +223,7 @@ func (c *CaptureExec) GetTarianDetectorEvents() error { } }() - return nil + <-c.ctx.Done() + return c.ctx.Err() } diff --git a/pkg/nodeagent/ebpf/c/capture_exec.bpf.c b/pkg/nodeagent/ebpf/c/capture_exec.bpf.c deleted file mode 100644 index 9b7d75e0..00000000 --- a/pkg/nodeagent/ebpf/c/capture_exec.bpf.c +++ /dev/null @@ -1,77 +0,0 @@ -//+build ignore -#include "vmlinux.h" -#include - -#ifdef asm_inline -#undef asm_inline -#define asm_inline asm -#endif - -#define ARGLEN 32 -#define ARGSIZE 1024 - -char __license[] SEC("license") = "Dual MIT/GPL"; - -struct event { - u32 pid; - u8 comm[80]; - u8 filename[ARGSIZE]; -}; - -// /sys/kernel/debug/tracing/events/syscalls/sys_enter_execve/format -struct trace_event_execve { - u16 common_type; // offset:0; size:2; signed:0; - u8 common_flags; // offset:2; size:1; signed:0; - u8 common_preempt_count; // offset:3; size:1; signed:0; - s32 common_pid; // offset:4; size:4; signed:1; - - s32 syscall_nr; // offset:8; size:4; signed:1; - u32 pad; // offset:12; size:4; signed:0; (pad) - const u8 *filename; // offset:16; size:8; signed:0; (ptr) - const u8 *const *argv; // offset:24; size:8; signed:0; (ptr) - const u8 *const *envp; // offset:32; size:8; signed:0; (ptr) -}; - -struct { - __uint(type, BPF_MAP_TYPE_RINGBUF); - __uint(max_entries, 1 << 24); -} events SEC(".maps"); - -// Zero values of any char[ARGSIZE] or char[ARGLEN][ARGSIZE] arrays. -static char zero[ARGSIZE] SEC(".rodata") = {0}; -static char zero_argv[ARGLEN][ARGSIZE] SEC(".rodata") = {0}; - -// Force emitting struct event into the ELF. -const struct event *unused __attribute__((unused)); - -SEC("tracepoint/syscalls/sys_enter_execve") -s32 enter_execve(struct trace_event_execve *trace_evt) { - u64 id = bpf_get_current_pid_tgid(); - u32 tgid = id >> 32; - struct event *evt; - - evt = bpf_ringbuf_reserve(&events, sizeof(struct event), 0); - if (!evt) { - return 0; - } - - s64 ret = bpf_probe_read_kernel(&evt->filename, sizeof(zero), &zero); - if (ret) { - bpf_printk("zero out filename: %d", ret); - bpf_ringbuf_discard(evt, 0); - return 1; - } - - evt->pid = tgid; - bpf_get_current_comm(&evt->comm, 80); - ret = bpf_probe_read_user_str(evt->filename, sizeof(evt->filename), trace_evt->filename); - if (ret < 0) { - bpf_printk("could not read filename into event struct: %d", ret); - bpf_ringbuf_discard(evt, 0); - return 1; - } - - bpf_ringbuf_submit(evt, 0); - - return 0; -} diff --git a/pkg/nodeagent/ebpf/doc.go b/pkg/nodeagent/ebpf/doc.go deleted file mode 100644 index df7d7aa5..00000000 --- a/pkg/nodeagent/ebpf/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package ebpf wraps ebpf programs and provides simpler abstraction -package ebpf diff --git a/pkg/nodeagent/ebpf/exec.go b/pkg/nodeagent/ebpf/exec.go deleted file mode 100644 index 69a9c56e..00000000 --- a/pkg/nodeagent/ebpf/exec.go +++ /dev/null @@ -1,126 +0,0 @@ -package ebpf - -import ( - "bytes" - "encoding/binary" - "fmt" - - "github.com/aquasecurity/libbpfgo" - "github.com/sirupsen/logrus" - - _ "embed" -) - -var bpfObjName = "capture_exec.bpf.o" - -//go:embed capture_exec.bpf.o -var captureExecBpfObj []byte - -// BpfExecEvent represents the structure of an eBPF execution event. -type BpfExecEvent struct { - Pid uint32 - Comm [80]uint8 - Filename [1024]uint8 -} - -// BpfCaptureExec handles the capturing and processing of eBPF events. -type BpfCaptureExec struct { - shouldClose bool - - bpfEventsChan chan []byte - execEventsChan chan BpfExecEvent - - bpfModule *libbpfgo.Module - bpfProg *libbpfgo.BPFProg - bpfRingBuffer *libbpfgo.RingBuffer - - logger *logrus.Logger -} - -// NewBpfCaptureExec creates a new BpfCaptureExec instance for capturing and processing eBPF events. -// It takes a logger as input. -// -// Parameters: -// - logger: A logger instance for logging. -// -// Returns: -// - *BpfCaptureExec: A new instance of BpfCaptureExec. -// - error: An error if loading the eBPF object or initializing the capture fails. -func NewBpfCaptureExec(logger *logrus.Logger) (*BpfCaptureExec, error) { - b := &BpfCaptureExec{ - bpfEventsChan: make(chan []byte, 1000), - execEventsChan: make(chan BpfExecEvent, 1000), - logger: logger, - } - - // Load the eBPF object and initialize the capture. - err := b.loadBpfObject() - if err != nil { - return nil, fmt.Errorf("NewBpfCaptureExec: failed to load bpf object: %w", err) - } - - return b, nil -} - -// loadBpfObject loads the eBPF object and sets up the eBPF program and ring buffer. -// It returns an error if any of these steps fails. -func (b *BpfCaptureExec) loadBpfObject() error { - var err error - b.bpfModule, err = libbpfgo.NewModuleFromBuffer(captureExecBpfObj, bpfObjName) - if err != nil { - return err - } - - b.bpfModule.BPFLoadObject() - - b.bpfRingBuffer, err = b.bpfModule.InitRingBuf("events", b.bpfEventsChan) - if err != nil { - return err - } - - b.bpfProg, err = b.bpfModule.GetProgram("enter_execve") - if err != nil { - return err - } - - _, err = b.bpfProg.AttachTracepoint("syscalls", "sys_enter_execve") - if err != nil { - return err - } - - return nil -} - -// Start starts the eBPF ring buffer and processes captured events. -// It continues processing events until the shouldClose flag is set to true. -func (b *BpfCaptureExec) Start() { - b.bpfRingBuffer.Start() - - for { - evt := <-b.bpfEventsChan - - if b.shouldClose { - break - } - - var bpfExecEvent BpfExecEvent - if err := binary.Read(bytes.NewBuffer(evt), binary.LittleEndian, &bpfExecEvent); err != nil { - b.logger.WithError(err).Error("error parsing ringbuf event") - continue - } - - b.execEventsChan <- bpfExecEvent - } -} - -// Close stops the eBPF ring buffer and closes the eBPF module. -func (b *BpfCaptureExec) Close() { - b.shouldClose = true - b.bpfRingBuffer.Close() - b.bpfModule.Close() -} - -// GetExecEventsChannel returns the channel for receiving eBPF execution events. -func (b *BpfCaptureExec) GetExecEventsChannel() chan BpfExecEvent { - return b.execEventsChan -} diff --git a/pkg/nodeagent/nodeagent.go b/pkg/nodeagent/nodeagent.go index 9382b9bf..235e54f1 100644 --- a/pkg/nodeagent/nodeagent.go +++ b/pkg/nodeagent/nodeagent.go @@ -196,7 +196,7 @@ func (n *NodeAgent) SyncConstraints() { // Returns: // - error: An error, if any, encountered during the loop. func (n *NodeAgent) loopValidateProcesses(ctx context.Context) error { - captureExec, err := NewCaptureExec(n.logger) + captureExec, err := NewCaptureExec(ctx, n.logger) if err != nil { return fmt.Errorf("nodeagent: %w", err) }