diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index e699b3b46261..643f1181eb5d 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -634,6 +634,8 @@ in { traefik = handleTestOn ["x86_64-linux"] ./traefik.nix {}; trafficserver = handleTest ./trafficserver.nix {}; transmission = handleTest ./transmission.nix {}; + # tracee requires bpf + tracee = handleTestOn ["x86_64-linux"] ./tracee.nix {}; trezord = handleTest ./trezord.nix {}; trickster = handleTest ./trickster.nix {}; trilium-server = handleTestOn ["x86_64-linux"] ./trilium-server.nix {}; diff --git a/nixos/tests/tracee.nix b/nixos/tests/tracee.nix new file mode 100644 index 000000000000..26d0ada931b1 --- /dev/null +++ b/nixos/tests/tracee.nix @@ -0,0 +1,46 @@ +import ./make-test-python.nix ({ pkgs, ... }: { + name = "tracee-integration"; + nodes = { + machine = { config, pkgs, ... }: { + # EventFilters/trace_only_events_from_new_containers requires docker + # podman with docker compat will suffice + virtualisation.podman.enable = true; + virtualisation.podman.dockerCompat = true; + + environment.systemPackages = [ + # build the go integration tests as a binary + (pkgs.tracee.overrideAttrs (oa: { + pname = oa.pname + "-integration"; + patches = oa.patches or [] ++ [ + # change the prefix from /usr/bin to /run to find nix processes + ../../pkgs/tools/security/tracee/test-EventFilters-prefix-nix-friendly.patch + # skip magic_write test that currently fails + ../../pkgs/tools/security/tracee/test-EventFilters-magic_write-skip.patch + ]; + buildPhase = '' + runHook preBuild + # just build the static lib we need for the go test binary + make $makeFlags ''${enableParallelBuilding:+-j$NIX_BUILD_CORES -l$NIX_BUILD_CORES} bpf-core ./dist/btfhub ./dist/libbpf/libbpf.a + # then compile the tests to be ran later + CGO_CFLAGS="-I$PWD/dist/libbpf" CGO_LDFLAGS="-lelf -lz $PWD/dist/libbpf/libbpf.a" go test -tags core,ebpf,integration -p 1 -c -o $GOPATH/tracee-integration ./tests/integration/... + runHook postBuild + ''; + doCheck = false; + installPhase = '' + mkdir -p $out/bin + cp $GOPATH/tracee-integration $out/bin + ''; + doInstallCheck = false; + })) + ]; + }; + }; + + testScript = '' + with subtest("run integration tests"): + # EventFilters/trace_only_events_from_new_containers also requires a container called "alpine" + machine.succeed('tar cv -C ${pkgs.pkgsStatic.busybox} . | podman import - alpine --change ENTRYPOINT=sleep') + + print(machine.succeed('TRC_BIN="${pkgs.tracee}" tracee-integration -test.v')) + ''; +}) diff --git a/pkgs/tools/security/tracee/bpf-core-clang-bpf.patch b/pkgs/tools/security/tracee/bpf-core-clang-bpf.patch deleted file mode 100644 index f73e52841d3e..000000000000 --- a/pkgs/tools/security/tracee/bpf-core-clang-bpf.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/Makefile b/Makefile -index d5cd754..db1c1d3 100644 ---- a/Makefile -+++ b/Makefile -@@ -411,7 +411,7 @@ $(OUTPUT_DIR)/tracee.bpf.core.o: \ - $(TRACEE_EBPF_OBJ_CORE_HEADERS) - # - $(MAKE) $(OUTPUT_DIR)/tracee.bpf -- $(CMD_CLANG) \ -+ $(CMD_CLANG_BPF) \ - -D__TARGET_ARCH_$(LINUX_ARCH) \ - -D__BPF_TRACING__ \ - -DCORE \ diff --git a/pkgs/tools/security/tracee/default.nix b/pkgs/tools/security/tracee/default.nix index 7d93e6d76f7d..e85911fc7511 100644 --- a/pkgs/tools/security/tracee/default.nix +++ b/pkgs/tools/security/tracee/default.nix @@ -6,67 +6,61 @@ , pkg-config , zlib -, libelf +, elfutils +, libbpf + +, nixosTests +, testers +, tracee }: let inherit (llvmPackages_13) clang; - clang-with-bpf = - (clang.overrideAttrs (o: { pname = o.pname + "-with-bpf"; })).override (o: { - extraBuildCommands = o.extraBuildCommands + '' - # make a separate wrapped clang we can target at bpf - cp $out/bin/clang $out/bin/clang-bpf - # extra flags to append after the cc-cflags - echo '-target bpf -fno-stack-protector' > $out/nix-support/cc-cflags-bpf - # use sed to attach the cc-cflags-bpf after cc-cflags - sed -i -E "s@^(extraAfter=\(\\$\NIX_CFLAGS_COMPILE_.*)(\))\$@\1 $(cat $out/nix-support/cc-cflags-bpf)\2@" $out/bin/clang-bpf - ''; - }); in buildGoModule rec { pname = "tracee"; - version = "0.7.0"; + version = "0.8.3"; src = fetchFromGitHub { owner = "aquasecurity"; repo = pname; rev = "v${version}"; - sha256 = "sha256-Y++FWxADnj1W5S3VrAlJAnotFYb6biCPJ6dpQ0Nin8o="; - # Once libbpf hits 1.0 we will migrate to the nixpkgs libbpf rather than the - # pinned copy in submodules - fetchSubmodules = true; + sha256 = "sha256-VxTJcl7gHRZEXpFbxU4iMwqxuR1r0BNSseWQ5ijWHU4="; }; - vendorSha256 = "sha256-C2RExp67qax8+zJIgyMJ18sBtn/xEYj4tAvGCCpBssQ="; - - patches = [ - # bpf-core can't be compiled with wrapped clang since it forces the target - # we need to be able to replace it with another wrapped clang that has - # it's target as bpf - ./bpf-core-clang-bpf.patch - # add -s to ldflags for smaller binaries - ./disable-go-symbol-table.patch - ]; - + vendorSha256 = "sha256-szPoJUtzya3+8dOnkDxHEs3+a1LTVoMMLjUSrUlfiGg="; enableParallelBuilding = true; + # needed to build bpf libs + hardeningDisable = [ "stackprotector" ]; - strictDeps = true; - nativeBuildInputs = [ pkg-config clang-with-bpf ]; - buildInputs = [ zlib libelf ]; + nativeBuildInputs = [ pkg-config clang ]; + # ensure libbpf version exactly matches the version added as a submodule + buildInputs = [ libbpf zlib elfutils ]; makeFlags = [ "VERSION=v${version}" - "CMD_CLANG_BPF=clang-bpf" + "GO_DEBUG_FLAG=-s -w" # don't actually need git but the Makefile checks for it "CMD_GIT=echo" ]; + # TODO: patch tracee to take libbpf.a and headers via include path + preBuild = '' + mkdir -p 3rdparty/libbpf/src + mkdir -p ./dist + cp -r ${libbpf}/lib ./dist/libbpf + chmod +w ./dist/libbpf + cp -r ${libbpf}/include/bpf ./dist/libbpf/ + ''; buildPhase = '' runHook preBuild - make $makeFlags ''${enableParallelBuilding:+-j$NIX_BUILD_CORES + make $makeFlags ''${enableParallelBuilding:+-j$NIX_BUILD_CORES} bpf-core all runHook postBuild ''; + # tests require a separate go module + # integration tests are ran within a nixos vm + # see passthru.tests.integration doCheck = false; installPhase = '' @@ -95,6 +89,15 @@ buildGoModule rec { runHook postInstallCheck ''; + passthru.tests = { + integration = nixosTests.tracee; + version = testers.testVersion { + package = tracee; + version = "v${version}"; + command = "tracee-ebpf --version"; + }; + }; + meta = with lib; { homepage = "https://aquasecurity.github.io/tracee/latest/"; changelog = "https://github.com/aquasecurity/tracee/releases/tag/v${version}"; diff --git a/pkgs/tools/security/tracee/disable-go-symbol-table.patch b/pkgs/tools/security/tracee/disable-go-symbol-table.patch deleted file mode 100644 index 2aba5f5c338f..000000000000 --- a/pkgs/tools/security/tracee/disable-go-symbol-table.patch +++ /dev/null @@ -1,22 +0,0 @@ -diff --git a/Makefile b/Makefile -index d5cd754..0b74a79 100644 ---- a/Makefile -+++ b/Makefile -@@ -471,7 +471,7 @@ ifeq ($(BTFHUB), 1) - endif - $(GO_ENV_EBPF) $(CMD_GO) build \ - -tags $(GO_TAGS_EBPF) \ -- -ldflags="-w \ -+ -ldflags="-s -w \ - -extldflags \"$(CGO_EXT_LDFLAGS_EBPF)\" \ - -X main.version=\"$(VERSION)\" \ - " \ -@@ -552,7 +552,7 @@ $(OUTPUT_DIR)/tracee-rules: \ - # - $(GO_ENV_RULES) $(CMD_GO) build \ - -tags $(GO_TAGS_RULES) \ -- -ldflags="-w \ -+ -ldflags="-s -w \ - -extldflags \"$(CGO_EXT_LDFLAGS_RULES)\" \ - " \ - -v -o $@ \ diff --git a/pkgs/tools/security/tracee/skip-init-test.patch b/pkgs/tools/security/tracee/skip-init-test.patch deleted file mode 100644 index 612e56e4446f..000000000000 --- a/pkgs/tools/security/tracee/skip-init-test.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/tests/integration/integration_test.go b/tests/integration/integration_test.go -index 8601eb9..57088d2 100644 ---- a/tests/integration/integration_test.go -+++ b/tests/integration/integration_test.go -@@ -149,6 +149,7 @@ func checkUidzero(t *testing.T, gotOutput *bytes.Buffer) { - - // only capture pids of 1 - func checkPidOne(t *testing.T, gotOutput *bytes.Buffer) { -+ t.Skip("Not compatible with systemd init") - _, _ = exec.Command("init", "q").CombinedOutput() - - waitForTraceeOutput(gotOutput, time.Now()) diff --git a/pkgs/tools/security/tracee/skip-magic_write-test.patch b/pkgs/tools/security/tracee/skip-magic_write-test.patch deleted file mode 100644 index 99869a18f0e8..000000000000 --- a/pkgs/tools/security/tracee/skip-magic_write-test.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/tests/integration/integration_test.go b/tests/integration/integration_test.go -index 8601eb9..a8a3eed 100644 ---- a/tests/integration/integration_test.go -+++ b/tests/integration/integration_test.go -@@ -75,6 +75,7 @@ func waitForTraceeOutput(gotOutput *bytes.Buffer, now time.Time) { - - // small set of actions to trigger a magic write event - func checkMagicwrite(t *testing.T, gotOutput *bytes.Buffer) { -+ t.Skip() - // create a temp dir for testing - d, err := ioutil.TempDir("", "Test_MagicWrite-dir-*") - require.NoError(t, err) diff --git a/pkgs/tools/security/tracee/test-EventFilters-magic_write-skip.patch b/pkgs/tools/security/tracee/test-EventFilters-magic_write-skip.patch new file mode 100644 index 000000000000..878327efd492 --- /dev/null +++ b/pkgs/tools/security/tracee/test-EventFilters-magic_write-skip.patch @@ -0,0 +1,16 @@ +diff --git a/tests/integration/integration_test.go b/tests/integration/integration_test.go +index afbc5330..3b38a1b8 100644 +--- a/tests/integration/integration_test.go ++++ b/tests/integration/integration_test.go +@@ -205,11 +205,6 @@ func Test_EventFilters(t *testing.T) { + filterArgs []string + eventFunc func(*testing.T, *[]trace.Event) + }{ +- { +- name: "do a file write", +- filterArgs: []string{"event=magic_write"}, +- eventFunc: checkMagicwrite, +- }, + { + name: "execute a command", + filterArgs: []string{"comm=ls"}, diff --git a/pkgs/tools/security/tracee/test-EventFilters-prefix-nix-friendly.patch b/pkgs/tools/security/tracee/test-EventFilters-prefix-nix-friendly.patch new file mode 100644 index 000000000000..88a3e4972507 --- /dev/null +++ b/pkgs/tools/security/tracee/test-EventFilters-prefix-nix-friendly.patch @@ -0,0 +1,15 @@ +diff --git a/tests/integration/integration_test.go b/tests/integration/integration_test.go +index afbc5330..13745c70 100644 +--- a/tests/integration/integration_test.go ++++ b/tests/integration/integration_test.go +@@ -246,8 +246,8 @@ func Test_EventFilters(t *testing.T) { + eventFunc: checkExecve, + }, + { +- name: "trace only execve events that starts with /usr/bin", +- filterArgs: []string{"event=execve", "execve.pathname=/usr/bin*"}, ++ name: "trace only execve events that starts with /run", ++ filterArgs: []string{"event=execve", "execve.pathname=/run*"}, + eventFunc: checkExecve, + }, + { diff --git a/pkgs/tools/security/tracee/test.nix b/pkgs/tools/security/tracee/test.nix deleted file mode 100644 index cb639ed03173..000000000000 --- a/pkgs/tools/security/tracee/test.nix +++ /dev/null @@ -1,41 +0,0 @@ -{ pkgs ? import ../../../../. { } }: - -# manually run `nix-build ./pkgs/tools/security/tracee/test.nix` to test -pkgs.nixosTest ({ - name = "tracee-test"; - nodes = { - machine = { config, pkgs, ... }: { - environment.systemPackages = [ - pkgs.tracee - # build the go integration tests as a binary - (pkgs.tracee.overrideAttrs (oa: { - pname = oa.pname + "-integration"; - patches = oa.patches or [] ++ [ - # skip test that runs `init -q` which is incompatible with systemd init - ./skip-init-test.patch - # skip magic_write test that currently fails - ./skip-magic_write-test.patch - ]; - # just build the static lib we need for the go test binary - makeFlags = oa.makeFlags ++ [ "./dist/libbpf/libbpf.a" ]; - postBuild = '' - # by default the tests are disabled and this is intended to be commented out - sed -i '/t.Skip("This test requires root privileges")/d' ./tests/integration/integration_test.go - CGO_CFLAGS="-I$PWD/dist/libbpf" CGO_LDFLAGS="-lelf -lz $PWD/dist/libbpf/libbpf.a" go test -tags ebpf,integration -c -o $GOPATH/tracee-integration ./tests/integration - ''; - doCheck = false; - installPhase = '' - mkdir -p $out/bin - cp $GOPATH/tracee-integration $out/bin - ''; - doInstallCheck = false; - })) - ]; - }; - }; - - testScript = '' - with subtest("run integration tests"): - print(machine.succeed('TRC_BIN="$(which tracee-ebpf)" tracee-integration -test.v -test.run "Test_Events"')) - ''; -})