.cargo | Loading last commit info... | |
.github/workflows | ||
.vim | ||
.vscode | ||
examples | ||
guardity | ||
guardity-common | ||
guardity-ebpf | ||
xtask | ||
.gitignore | ||
Cargo.toml | ||
LICENSE | ||
README.md | ||
README.tpl |
guardity
Guardity 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 Guardity 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
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
Guardity's userspace part is licensed under Apache License, version 2.0.
eBPF programs inside guardity-ebpf directory are licensed under GNU General Public License, version 2.