diff --git a/Dockerfile b/Dockerfile index a5fd5d713..fa6a03849 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,7 +25,18 @@ RUN npm run build ### Base builder image for native builds architecture FROM golang:1.17-alpine AS builder-native-base ENV CGO_ENABLED=1 GOOS=linux -RUN apk add --no-cache libpcap-dev g++ perl-utils curl build-base binutils-gold bash +RUN apk add --no-cache \ + libpcap-dev \ + g++ \ + perl-utils \ + curl \ + build-base \ + binutils-gold \ + bash \ + clang \ + llvm \ + libbpf-dev \ + linux-headers COPY devops/install-capstone.sh . RUN ./install-capstone.sh @@ -33,23 +44,27 @@ RUN ./install-capstone.sh ### Intermediate builder image for x86-64 to x86-64 native builds FROM builder-native-base AS builder-from-amd64-to-amd64 ENV GOARCH=amd64 +ENV BPF_TARGET=amd64 BPF_CFLAGS="-O2 -g -D__TARGET_ARCH_x86" ### Intermediate builder image for AArch64 to AArch64 native builds FROM builder-native-base AS builder-from-arm64v8-to-arm64v8 ENV GOARCH=arm64 +ENV BPF_TARGET=arm64 BPF_CFLAGS="-O2 -g -D__TARGET_ARCH_arm64" ### Builder image for x86-64 to AArch64 cross-compilation -FROM up9inc/linux-arm64-musl-go-libpcap-capstone AS builder-from-amd64-to-arm64v8 +FROM up9inc/linux-arm64-musl-go-libpcap-capstone-bpf AS builder-from-amd64-to-arm64v8 ENV CGO_ENABLED=1 GOOS=linux ENV GOARCH=arm64 CGO_CFLAGS="-I/work/libpcap -I/work/capstone/include" +ENV BPF_TARGET=arm64 BPF_CFLAGS="-O2 -g -D__TARGET_ARCH_arm64 -I/usr/xcc/aarch64-linux-musl-cross/aarch64-linux-musl/include/" ### Builder image for AArch64 to x86-64 cross-compilation -FROM up9inc/linux-x86_64-musl-go-libpcap-capstone AS builder-from-arm64v8-to-amd64 +FROM up9inc/linux-x86_64-musl-go-libpcap-capstone-bpf AS builder-from-arm64v8-to-amd64 ENV CGO_ENABLED=1 GOOS=linux ENV GOARCH=amd64 CGO_CFLAGS="-I/libpcap -I/capstone/include" +ENV BPF_TARGET=amd64 BPF_CFLAGS="-O2 -g -D__TARGET_ARCH_x86 -I/usr/local/musl/x86_64-unknown-linux-musl/include/" ### Final builder image where the build happens @@ -88,6 +103,11 @@ ARG GIT_BRANCH ARG BUILD_TIMESTAMP ARG VER=0.0 +WORKDIR /app/tap/tlstapper + +RUN rm tlstapper_bpf* +RUN GOARCH=${BUILDARCH} go generate tls_tapper.go + WORKDIR /app/agent-build RUN go build -ldflags="-extldflags=-static -s -w \ diff --git a/devops/linux-arm64-musl-go-libpcap-capstone/Dockerfile b/devops/linux-arm64-musl-go-libpcap-capstone-bpf/Dockerfile similarity index 94% rename from devops/linux-arm64-musl-go-libpcap-capstone/Dockerfile rename to devops/linux-arm64-musl-go-libpcap-capstone-bpf/Dockerfile index 6f9fb0c8a..d75a43621 100644 --- a/devops/linux-arm64-musl-go-libpcap-capstone/Dockerfile +++ b/devops/linux-arm64-musl-go-libpcap-capstone-bpf/Dockerfile @@ -25,3 +25,6 @@ RUN curl https://github.com/capstone-engine/capstone/archive/4.0.2.tar.gz -Lo ./ WORKDIR /work/capstone RUN CAPSTONE_ARCHS="aarch64" CAPSTONE_STATIC=yes ./make.sh \ && cp /work/capstone/libcapstone.a /usr/xcc/aarch64-linux-musl-cross/lib/gcc/aarch64-linux-musl/*/ + +# Install eBPF related dependencies +RUN apt-get -y install clang llvm libbpf-dev diff --git a/devops/linux-arm64-musl-go-libpcap-capstone-bpf/build-push.sh b/devops/linux-arm64-musl-go-libpcap-capstone-bpf/build-push.sh new file mode 100755 index 000000000..384b05fdd --- /dev/null +++ b/devops/linux-arm64-musl-go-libpcap-capstone-bpf/build-push.sh @@ -0,0 +1,4 @@ +#!/bin/bash +set -e + +docker build . -t up9inc/linux-arm64-musl-go-libpcap-capstone-bpf && docker push up9inc/linux-arm64-musl-go-libpcap-capstone-bpf diff --git a/devops/linux-arm64-musl-go-libpcap-capstone/build-push.sh b/devops/linux-arm64-musl-go-libpcap-capstone/build-push.sh deleted file mode 100755 index 1048c1d52..000000000 --- a/devops/linux-arm64-musl-go-libpcap-capstone/build-push.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -set -e - -docker build . -t up9inc/linux-arm64-musl-go-libpcap-capstone && docker push up9inc/linux-arm64-musl-go-libpcap-capstone diff --git a/devops/linux-x86_64-musl-go-libpcap-capstone/Dockerfile b/devops/linux-x86_64-musl-go-libpcap-capstone-bpf/Dockerfile similarity index 81% rename from devops/linux-x86_64-musl-go-libpcap-capstone/Dockerfile rename to devops/linux-x86_64-musl-go-libpcap-capstone-bpf/Dockerfile index 14b3e4903..55f941e04 100644 --- a/devops/linux-x86_64-musl-go-libpcap-capstone/Dockerfile +++ b/devops/linux-x86_64-musl-go-libpcap-capstone-bpf/Dockerfile @@ -1,5 +1,18 @@ FROM messense/rust-musl-cross:x86_64-musl AS builder-from-arm64v8-to-amd64 +WORKDIR / + +# Install eBPF related dependencies +RUN apt-get update +RUN apt-get -y install clang llvm libelf-dev pkg-config + +# Build and install libbpf from source +RUN curl https://github.com/libbpf/libbpf/archive/refs/tags/v0.8.0.tar.gz -Lo ./libbpf.tar.gz \ + && tar -xzf libbpf.tar.gz && mv ./libbpf-* ./libbpf +WORKDIR /libbpf/src +RUN make && make install +WORKDIR / + ENV CROSS_TRIPLE x86_64-unknown-linux-musl ENV CROSS_ROOT /usr/local/musl @@ -12,7 +25,6 @@ ENV AS=${CROSS_ROOT}/bin/${CROSS_TRIPLE}-as \ FC=${CROSS_ROOT}/bin/${CROSS_TRIPLE}-gfortran # Install Go -WORKDIR / RUN curl https://go.dev/dl/go1.17.6.linux-arm64.tar.gz -Lo ./go.linux-arm64.tar.gz \ && curl https://go.dev/dl/go1.17.6.linux-arm64.tar.gz.asc -Lo ./go.linux-arm64.tar.gz.asc \ && curl https://dl.google.com/dl/linux/linux_signing_key.pub -Lo linux_signing_key.pub \ @@ -35,5 +47,5 @@ WORKDIR / RUN curl https://github.com/capstone-engine/capstone/archive/4.0.2.tar.gz -Lo ./capstone.tar.gz \ && tar -xzf capstone.tar.gz && mv ./capstone-* ./capstone WORKDIR /capstone -RUN ./make.sh \ +RUN CAPSTONE_ARCHS="x86" CAPSTONE_STATIC=yes ./make.sh \ && cp /capstone/libcapstone.a /usr/local/musl/lib/gcc/x86_64-unknown-linux-musl/*/ diff --git a/devops/linux-x86_64-musl-go-libpcap-capstone-bpf/build-push.sh b/devops/linux-x86_64-musl-go-libpcap-capstone-bpf/build-push.sh new file mode 100755 index 000000000..63c5e816e --- /dev/null +++ b/devops/linux-x86_64-musl-go-libpcap-capstone-bpf/build-push.sh @@ -0,0 +1,4 @@ +#!/bin/bash +set -e + +docker build . -t up9inc/linux-x86_64-musl-go-libpcap-capstone-bpf && docker push up9inc/linux-x86_64-musl-go-libpcap-capstone-bpf diff --git a/devops/linux-x86_64-musl-go-libpcap-capstone/build-push.sh b/devops/linux-x86_64-musl-go-libpcap-capstone/build-push.sh deleted file mode 100755 index 565f36705..000000000 --- a/devops/linux-x86_64-musl-go-libpcap-capstone/build-push.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -set -e - -docker build . -t up9inc/linux-x86_64-musl-go-libpcap-capstone && docker push up9inc/linux-x86_64-musl-go-libpcap-capstone diff --git a/tap/tlstapper/bpf-builder/build.sh b/tap/tlstapper/bpf-builder/build.sh index 1a6b56ef3..713931477 100755 --- a/tap/tlstapper/bpf-builder/build.sh +++ b/tap/tlstapper/bpf-builder/build.sh @@ -6,17 +6,22 @@ MIZU_HOME=$(realpath ../../../) docker build -t mizu-ebpf-builder . || exit 1 +BPF_TARGET=amd64 +BPF_CFLAGS="-O2 -g -D__TARGET_ARCH_x86" +ARCH=$(uname -m) +if [[ $ARCH == "aarch64" ]]; then + BPF_TARGET=arm64 + BPF_CFLAGS="-O2 -g -D__TARGET_ARCH_arm64" +fi + docker run --rm \ --name mizu-ebpf-builder \ -v $MIZU_HOME:/mizu \ -v $(go env GOPATH):/root/go \ -it mizu-ebpf-builder \ sh -c " - go generate tap/tlstapper/tls_tapper.go - chown $(id -u):$(id -g) tap/tlstapper/tlstapper_bpfeb.go - chown $(id -u):$(id -g) tap/tlstapper/tlstapper_bpfeb.o - chown $(id -u):$(id -g) tap/tlstapper/tlstapper_bpfel.go - chown $(id -u):$(id -g) tap/tlstapper/tlstapper_bpfel.o + BPF_TARGET=\"$BPF_TARGET\" BPF_CFLAGS=\"$BPF_CFLAGS\" go generate tap/tlstapper/tls_tapper.go + chown $(id -u):$(id -g) tap/tlstapper/tlstapper_bpf* " || exit 1 popd diff --git a/tap/tlstapper/bpf/common.c b/tap/tlstapper/bpf/common.c index d7f42f91b..7bdf11c07 100644 --- a/tap/tlstapper/bpf/common.c +++ b/tap/tlstapper/bpf/common.c @@ -80,10 +80,6 @@ static __always_inline void send_chunk(struct pt_regs *ctx, __u8* buffer, __u64 } static __always_inline void output_ssl_chunk(struct pt_regs *ctx, struct ssl_info* info, int count_bytes, __u64 id, __u32 flags) { - if (count_bytes <= 0) { - return; - } - if (count_bytes > (CHUNK_SIZE * MAX_CHUNKS_PER_OPERATION)) { log_error(ctx, LOG_ERROR_BUFFER_TOO_BIG, id, count_bytes, 0l); return; diff --git a/tap/tlstapper/bpf/go_uprobes.c b/tap/tlstapper/bpf/go_uprobes.c index d06930918..fbee44f3d 100644 --- a/tap/tlstapper/bpf/go_uprobes.c +++ b/tap/tlstapper/bpf/go_uprobes.c @@ -128,6 +128,15 @@ static __always_inline void go_crypto_tls_ex_uprobe(struct pt_regs *ctx, struct return; } + // In case of read, the length is determined on return + if (flags == FLAGS_IS_READ_BIT) { + info.buffer_len = GO_ABI_INTERNAL_PT_REGS_R1(ctx); // n in return n, nil + // This check achieves ignoring 0 length reads (the reads result with an error) + if (info.buffer_len <= 0) { + return; + } + } + output_ssl_chunk(ctx, &info, info.buffer_len, pid_tgid, flags); return; diff --git a/tap/tlstapper/bpf/openssl_uprobes.c b/tap/tlstapper/bpf/openssl_uprobes.c index 2f5151da9..e4be354bd 100644 --- a/tap/tlstapper/bpf/openssl_uprobes.c +++ b/tap/tlstapper/bpf/openssl_uprobes.c @@ -101,6 +101,9 @@ static __always_inline void ssl_uretprobe(struct pt_regs *ctx, struct bpf_map_de } int count_bytes = get_count_bytes(ctx, &info, id); + if (count_bytes <= 0) { + return; + } output_ssl_chunk(ctx, &info, count_bytes, id, flags); } diff --git a/tap/tlstapper/go_offsets.go b/tap/tlstapper/go_offsets.go index a963d9077..d5de61462 100644 --- a/tap/tlstapper/go_offsets.go +++ b/tap/tlstapper/go_offsets.go @@ -113,7 +113,11 @@ func getOffsets(filePath string) (offsets map[string]*goExtendedOffset, err erro return } - syms, err := se.Symbols() + var syms []elf.Symbol + syms, err = se.Symbols() + if err != nil { + return + } for _, sym := range syms { offset := sym.Value @@ -158,7 +162,7 @@ func getOffsets(filePath string) (offsets map[string]*goExtendedOffset, err erro } symBytes := textSectionData[symStartingIndex:symEndingIndex] - // disasemble the symbol + // disassemble the symbol var instructions []gapstone.Instruction instructions, err = engine.Disasm(symBytes, sym.Value, 0) if err != nil { diff --git a/tap/tlstapper/tls_tapper.go b/tap/tlstapper/tls_tapper.go index 4e7229ab6..578e28f36 100644 --- a/tap/tlstapper/tls_tapper.go +++ b/tap/tlstapper/tls_tapper.go @@ -12,7 +12,7 @@ import ( const GLOABL_TAP_PID = 0 -//go:generate go run github.com/cilium/ebpf/cmd/bpf2go@0d0727ef53e2f53b1731c73f4c61e0f58693083a -type tls_chunk tlsTapper bpf/tls_tapper.c -- -O2 -g -D__TARGET_ARCH_x86 +//go:generate go run github.com/cilium/ebpf/cmd/bpf2go@0d0727ef53e2f53b1731c73f4c61e0f58693083a -target $BPF_TARGET -cflags $BPF_CFLAGS -type tls_chunk tlsTapper bpf/tls_tapper.c type TlsTapper struct { bpfObjects tlsTapperObjects @@ -161,14 +161,14 @@ func setupRLimit() error { } func (t *TlsTapper) tapSsllibPid(pid uint32, sslLibrary string, namespace string) error { - logger.Log.Infof("Tapping TLS (pid: %v) (sslLibrary: %v)", pid, sslLibrary) - newSsl := sslHooks{} if err := newSsl.installUprobes(&t.bpfObjects, sslLibrary); err != nil { return err } + logger.Log.Infof("Tapping TLS (pid: %v) (sslLibrary: %v)", pid, sslLibrary) + t.sslHooksStructs = append(t.sslHooksStructs, newSsl) t.poller.addPid(pid, namespace) diff --git a/tap/tlstapper/tlstapper_bpfeb.o b/tap/tlstapper/tlstapper_bpfeb.o deleted file mode 100644 index 5098e04ad..000000000 Binary files a/tap/tlstapper/tlstapper_bpfeb.o and /dev/null differ diff --git a/tap/tlstapper/tlstapper_bpfel.o b/tap/tlstapper/tlstapper_bpfel.o deleted file mode 100644 index 260994b7f..000000000 Binary files a/tap/tlstapper/tlstapper_bpfel.o and /dev/null differ diff --git a/tap/tlstapper/tlstapper_bpfeb.go b/tap/tlstapper/tlstapper_bpfel_arm64.go similarity index 97% rename from tap/tlstapper/tlstapper_bpfeb.go rename to tap/tlstapper/tlstapper_bpfel_arm64.go index c6b046e97..871ee8242 100644 --- a/tap/tlstapper/tlstapper_bpfeb.go +++ b/tap/tlstapper/tlstapper_bpfel_arm64.go @@ -1,6 +1,6 @@ // Code generated by bpf2go; DO NOT EDIT. -//go:build arm64be || armbe || mips || mips64 || mips64p32 || ppc64 || s390 || s390x || sparc || sparc64 -// +build arm64be armbe mips mips64 mips64p32 ppc64 s390 s390x sparc sparc64 +//go:build arm64 +// +build arm64 package tlstapper @@ -208,5 +208,5 @@ func _TlsTapperClose(closers ...io.Closer) error { } // Do not access this directly. -//go:embed tlstapper_bpfeb.o +//go:embed tlstapper_bpfel_arm64.o var _TlsTapperBytes []byte diff --git a/tap/tlstapper/tlstapper_bpfel_arm64.o b/tap/tlstapper/tlstapper_bpfel_arm64.o new file mode 100644 index 000000000..78016c738 Binary files /dev/null and b/tap/tlstapper/tlstapper_bpfel_arm64.o differ diff --git a/tap/tlstapper/tlstapper_bpfel.go b/tap/tlstapper/tlstapper_bpfel_x86.go similarity index 96% rename from tap/tlstapper/tlstapper_bpfel.go rename to tap/tlstapper/tlstapper_bpfel_x86.go index a149b76f6..e0eecfc72 100644 --- a/tap/tlstapper/tlstapper_bpfel.go +++ b/tap/tlstapper/tlstapper_bpfel_x86.go @@ -1,6 +1,6 @@ // Code generated by bpf2go; DO NOT EDIT. -//go:build 386 || amd64 || amd64p32 || arm || arm64 || mips64le || mips64p32le || mipsle || ppc64le || riscv64 -// +build 386 amd64 amd64p32 arm arm64 mips64le mips64p32le mipsle ppc64le riscv64 +//go:build 386 || amd64 +// +build 386 amd64 package tlstapper @@ -208,5 +208,5 @@ func _TlsTapperClose(closers ...io.Closer) error { } // Do not access this directly. -//go:embed tlstapper_bpfel.o +//go:embed tlstapper_bpfel_x86.o var _TlsTapperBytes []byte diff --git a/tap/tlstapper/tlstapper_bpfel_x86.o b/tap/tlstapper/tlstapper_bpfel_x86.o new file mode 100644 index 000000000..c65c4516d Binary files /dev/null and b/tap/tlstapper/tlstapper_bpfel_x86.o differ