Projects STRLCPY ebpfguard Files
🤬
.cargo Loading last commit info...
.github/workflows
.vim
.vscode
ebpfguard
ebpfguard-common
ebpfguard-ebpf
examples
xtask
.gitignore
Cargo.toml
LICENSE
README.md
README.tpl
README.md

Workflow Status

ebpfguard

Ebpfguard is a library for managing Linux security policies. It is based on LSM hooks, but without necessity to write any kernel modules or eBPF programs directly. It allows to write policies in Rust (or YAML) in user space.

It's based on eBPF and Aya library, but takes away the need to use them directly.

Prerequisites

First, you need to have a Linux kernel:

  • with BTF support
  • with BPF LSM support (kernels >= 5.7)

You can check if your kernel has BTF support by checking whether file /sys/kernel/btf/vmlinux exists. You can also check the kernel configuration:

$ zgrep CONFIG_DEBUG_INFO_BTF /proc/config.gz
CONFIG_DEBUG_INFO_BTF=y

Next, you need to check if your kernel has BPF LSM support:

$ cat /sys/kernel/security/lsm
lockdown,capability,selinux,bpf

If the output doesn't contain bpf, you need to enable BPF LSM by adding lsm=[...],bpf to your kernel config parameters. That can be achieved by executing the following script.

Then you need the Rust stable and nightly toolchains installed on your system, as well as bpf-linker. You can install these by following these instructions.

LSM hooks

LSM hooks supported by Ebpfguard are:

Examples

Defining single policies

file_open

The file_open example shows how to define a policy for file_open LSM hook as Rust code. It denies the given binary (or all processes, if none defined) from opening the given directory.

To try it out, let's create a directory and a file inside it:

$ mkdir /tmp/test
$ echo "foo" > /tmp/test/test

Then run our example policy program with:

$ RUST_LOG=info cargo xtask run --example file_open -- --path-to-deny /tmp/test

When trying to access that directory and file, you should see that these operations are denied:

$ ls /tmp/test/
ls: cannot open directory '/tmp/test/': Operation not permitted
$ cat /tmp/test/test
cat: /tmp/test/test: Operation not permitted

The policy application should show logs like:

[2023-04-22T20:51:01Z INFO  file_open] file_open: pid=3001 subject=980333 path=9632
[2023-04-22T20:51:03Z INFO  file_open] file_open: pid=3010 subject=980298 path=9633

mount

The mount example shows how to define a policy for sb_mount, sb_remount and sb_umount LSM hooks as Rust code. It denies the mount operations for all processes except for the optionally given one.

To try it out, let's create two directories:

$ mkdir /tmp/test1
$ mkdir /tmp/test2

Then run our example policy program, first without providing any binary to allow mount for (so it's denied for all processes):

$ RUST_LOG=info cargo xtask run --example mount

Let's try to bind mount the first directory to the second one. It should fail with the following error:

sudo mount --bind /tmp/test1 /tmp/test2
mount: /tmp/test2: permission denied.
       dmesg(1) may have more information after failed mount system call.

And the policy program should show a log like:

[2023-04-23T21:02:58Z INFO  mount] sb_mount: pid=17363 subject=678150

Now let's try to allow mount operations for the mount binary:

$ RUST_LOG=info cargo xtask run --example mount -- --allow /usr/bin/mount

And try to bind mount the first directory to the second one again. It should succeed this time:

$ sudo mount --bind /tmp/test1 /tmp/test2
$ mount | grep test
tmpfs on /tmp/test2 type tmpfs (rw,nosuid,nodev,seclabel,nr_inodes=1048576,inode64)

task_fix_setuid

The task_fix_setuid example shows how to define a policy for task_fix_setuid LSM hook as Rust code. It denies the setuid operation for all processes except for the optionally given one.

To try it out, run our example policy program, first without providing any binary to allow setuid for (so it's denied for all processes):

$ RUST_LOG=info cargo xtask run --example task_fix_setuid

Then try to use sudo. It should fail with the following error:

sudo -i
sudo: PERM_ROOT: setresuid(0, -1, -1): Operation not permitted
sudo: error initializing audit plugin sudoers_audit

And the policy program should show log like:

[2023-04-23T15:15:00Z INFO  task_fix_setuid] file_open: pid=25604 subject=674642 old_uid=1000 old_gid=1000 new_uid=0 new_gid=1000

Now, let's try to allow setuid for a specific binary. Let's use sudo:

$ RUST_LOG=info cargo xtask run --example task_fix_setuid -- --allow /usr/bin/sudo

Then try to use sudo again. It should work this time:

$ sudo -i
# whoami
root

Daemon with CLI and YAML engine

Run the daemon with:

$ RUST_LOG=info cargo xtask run --example daemon

Then manage the policies using the CLI:

$ cargo xtask run --example cli -- --help

You can apply policies from the example YAML file:

$ cargo xtask run --example cli -- policy add --path examples/cli/policy.yaml

License

Ebpfguard's userspace part is licensed under Apache License, version 2.0.

eBPF programs inside ebpfguard-ebpf directory are licensed under GNU General Public License, version 2.

Please wait...
Page is in error, reload to recover