New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
nixos/containers: add oci-seccomp-bpf-hook #96761
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Requesting changes for now as this is a large dependency to add. (kernel, etc)
The 20.09 branch off is very soon, I'd like to leave this until after. We can backport it if we do go ahead with it. |
Sounds good. Do we wanna make it optional? I'm still not sure if we need something like |
|
Yes I think so. The hook has to choose the same kernel sources like present on the system. I switched to the latest 5.8 kernel and applied a small patch to the hook: diff --git a/oci-seccomp-bpf-hook.go b/oci-seccomp-bpf-hook.go
index 416c6f6..6d075d9 100644
--- a/oci-seccomp-bpf-hook.go
+++ b/oci-seccomp-bpf-hook.go
@@ -10,7 +10,6 @@ import (
"io/ioutil"
"log/syslog"
"os"
- "os/exec"
"os/signal"
"path/filepath"
"runtime"
@@ -20,6 +19,7 @@ import (
"sync"
"syscall"
"time"
+ "unsafe"
"github.com/iovisor/gobpf/bcc"
spec "github.com/opencontainers/runtime-spec/specs-go"
@@ -30,6 +30,12 @@ import (
logrus_syslog "github.com/sirupsen/logrus/hooks/syslog"
)
+/*
+#cgo LDFLAGS: -lbcc
+#include <bcc/bcc_common.h>
+*/
+import "C"
+
const (
// BPFTimeout is the timeout in seconds to wait for the child process to signal
// that the eBPF program finished compiling and attached to the tracee.
@@ -95,23 +101,25 @@ func main() {
}
}
-// modprobe the specified module.
-func modprobe(module string) error {
- bin, err := exec.LookPath("modprobe")
- if err != nil {
- // Fallback to `/usr/sbin/modprobe`. The environment may be
- // empty. If that doesn't exist either, we'll fail below.
- bin = "/usr/sbin/modprobe"
+func initBPF() error {
+ logrus.Info("Initializing BFP")
+ cs := C.CString("")
+ defer C.free(unsafe.Pointer(cs))
+
+ c := C.bpf_module_create_c_from_string(cs, 2, nil, 0, true, nil)
+ if c == nil {
+ return errors.New("building BPF module from string failed")
+
}
- return exec.Command(bin, module).Run()
+ logrus.Info("BFP up and running")
+ return nil
}
// detachAndTrace re-executes the current executable to "fork" in go-ish way and
// traces the provided PID.
func detachAndTrace() error {
- logrus.Info("Trying to load `kheaders` module")
- if err := modprobe("kheaders"); err != nil {
- logrus.Infof("Loading `kheaders` failed, continuing in hope kernel headers reside on disk: %v", err)
+ if err := initBPF(); err != nil {
+ return errors.Wrap(err, "init BPF")
}
// Read the State spec from stdin and unmarshal it. Then running the hook should build an example BPF module which automatically loads the kernel headers, but:
The funny part is now, this issue only happens if the hook gets executed through Podman. If I run the hook manually (with sudo on my current user), then it seems to pick the right path and every further invocation of the hook (even through podman) will work from now on. I applied a small patch |
@saschagrunert Can you try #96892 please? |
Requires now #96892 |
Sorry, I focused on the
I'd be in favour of making it optional. |
Sounds good, changed the implementation to only modify the config if the hook is enabled. |
475438d
to
9c7c12a
Compare
Rebased on top of the latest master to resolve the issues. |
Another nit, sorry. Could you flip the enable around please? diff --git a/nixos/modules/virtualisation/containers.nix b/nixos/modules/virtualisation/containers.nix
index b82f64ea05f..de97ba3f7bb 100644
--- a/nixos/modules/virtualisation/containers.nix
+++ b/nixos/modules/virtualisation/containers.nix
@@ -43,7 +43,7 @@ in
'';
};
- enableOciSeccompBpfHook = mkOption {
+ ociSeccompBpfHook.enable = mkOption {
type = types.bool;
default = false;
description = "Enable the OCI seccomp BPF hook";
@@ -122,7 +122,7 @@ in
[network]
cni_plugin_dirs = ["${pkgs.cni-plugins}/bin/"]
- ${lib.optionalString (cfg.enableOciSeccompBpfHook == true) ''
+ ${lib.optionalString (cfg.ociSeccompBpfHook.enable == true) ''
[engine]
hooks_dir = [
"${config.boot.kernelPackages.oci-seccomp-bpf-hook}",
|
Signed-off-by: Sascha Grunert <sgrunert@suse.com>
Sure thing, fixed as suggested 👍 |
As it's now optional and using the system kernel I think it's fine to include in the next release. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
Motivation for this change
Add the OCI seccomp bpf hook per default to the contianers.conf file. The hook will result in a no-op if the annotation is not present.
Things done
sandbox
innix.conf
on non-NixOS linux)nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
./result/bin/
)nix path-info -S
before and after)cc @NixOS/podman