Skip to content

Commit

Permalink
chore(content/docs): move modern BPF probe above classic BPF probe se…
Browse files Browse the repository at this point in the history
…ction.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>

Co-authored-by: Luca Guerra <luca@guerra.sh>
  • Loading branch information
FedeDP and LucaGuerra committed Jan 29, 2024
1 parent 5a95a1c commit 0ce23d4
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 70 deletions.
93 changes: 48 additions & 45 deletions content/en/docs/event-sources/kernel/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ Falco uses different instrumentations to analyze the system workload and pass se
There are several supported drivers:

- Kernel module *(default)*
- Classic eBPF probe
- Modern eBPF probe
- Classic eBPF probe

| | Kernel module | Classic eBPF probe | Modern eBPF probe |
| ----------- | ------------- | ------------------ | -------------------------------------------------------------------- |
Expand All @@ -30,49 +30,6 @@ To install the kernel module, please refer to the [installation](/docs/getting-s

The kernel module requires full privileges and cannot run with Linux capabilities

## Classic eBPF probe

The classic {{< glossary_tooltip text="eBPF probe" term_id="ebpf-probe" >}} is an alternative source to the one described above.

To install the eBPF probe, please refer to the [installation](/docs/getting-started/installation/#install-driver) page.

To enable the eBPF support in Falco set the `engine.kind` configuration key to `ebpf` and eventually customize `engine.ebpf.probe` to the path where the eBPF probe resides; the default path is the location used by `falcoctl driver` tool to install the eBPF probe.

### Least privileged mode

The minimal set of capabilities required by Falco to run the classic eBPF probe is the following:

- `CAP_SYS_ADMIN`
- `CAP_SYS_RESOURCE`
- `CAP_SYS_PTRACE`

Let's see them in detail:

- **CAP_SYS_RESOURCE**: Falco needs this capability to be able to call the `setrlimit` syscall. The `setrlimit` syscall is used together with the `RLIMIT_MEMLOCK` flag to change the amount of memory that can be _mlocked_ into RAM. The default value for this memory limit is very low, so even a very simple eBPF program would fail. The workaround is to increase the default value to something acceptable so eBPF maps can be correctly _mlocked_ in memory.
- **CAP_SYS_PTRACE**: Falco needs this capability because it accesses paths like `/proc/<pid>/environ`. From the userspace standpoint, the permission to do so is mapped to the `CAP_SYS_PTRACE` capability. For the curious reader, see [environ_open](https://elixir.bootlin.com/linux/latest/source/fs/proc/base.c#L937) implementation in the kernel.
- **CAP_SYS_ADMIN**: Falco needs this capability to load eBPF programs and maps, and to interact with the system using the `bpf` syscall.

This set of capabilities should work most of the time but under some conditions, it is possible to replace the `CAP_SYS_ADMIN` with two more granular capabilities: `CAP_SYS_BPF` and `CAP_SYS_PERFMON`.

The conditions to satisfy are the following:

1. A kernel version that supports these capabilities. The Linux Kernel version `5.8` is the first one that officially supports them but they could have been backported on older versions on some distributions.

2. An acceptable value of `kernel.perf_event_paranoid` config. Reading the [manual](https://linuxsecurity.expert/kb/sysctl/kernel_perf_event_paranoid/) it says that `perf_event_paranoid` influences only the behavior of unprivileged users, but under the hood, some distributions like Debian or Ubuntu introduce additional `perf_event_paranoid` levels. Consider [`Ubuntu`](https://kernel.ubuntu.com/git/ubuntu-stable/ubuntu-stable-jammy.git/tree/kernel/events/core.c#n11991) as an example:

```c
if (perf_paranoid_any() && !capable(CAP_SYS_ADMIN))
return -EACCES;

// where perf_paranoid_any is defined as:
static inline bool perf_paranoid_any(void) {
return sysctl_perf_event_paranoid > 2;
}
```

As you can notice, when your `kernel.perf_event_paranoid` is `>2` the capability `CAP_PERFMON` won't suffice, you would still need `CAP_SYS_ADMIN`.
So before disabling `CAP_SYS_ADMIN` check your `perf_event_paranoid` value with `sysctl kernel.perf_event_paranoid` and make sure their values are compatible with your distribution enforcement.

## Modern eBPF probe

The {{< glossary_tooltip text="modern probe" term_id="modern-ebpf-probe" >}} is an alternative driver for Falco. The main advantage it brings to the table is that it is embedded into Falco, which means that you don't have to download or build anything, if your kernel is recent enough Falco will automatically inject it!
Expand All @@ -97,13 +54,16 @@ sudo bpftool feature probe kernel | grep -q "program_type tracing is available"

### How to run it

The modern eBPF probe supports all the installation methods of other drivers:
To enable the modern eBPF support in Falco, just set the `engine.kind` configuration key to `modern_ebpf`. Nothing else will be needed since no external artifact is required for it to work.

It is supported in all the installation methods of other drivers:

* [Falco packages](/docs/getting-started/installation/#installation-with-dialog)
* [Falco binary](/docs/getting-started/running/#falco-binary)
* [Docker](/docs/getting-started/running/#modern-ebpf)
* [Helm chart](https://github.com/falcosecurity/charts/tree/master/charts/falco#daemonset)


### Useful resources

* [Modern BPF blog post](/blog/falco-modern-bpf/)
Expand All @@ -122,3 +82,46 @@ The minimal set of capabilities required by Falco to run the modern eBPF probe i
The mentioned capabilities require no further explanation since they were already discussed in detail in the classic eBPF probe section. This set of capabilities should always work since here there are no issues with `kernel.perf_event_paranoid`.

> **Please note**: we will try to do our best to keep this as the minimum required set but due to [some issues with CO-RE relocations](https://lore.kernel.org/bpf/CAGQdkDvYU_e=_NX+6DRkL_-TeH3p+QtsdZwHkmH0w3Fuzw0C4w@mail.gmail.com/T/#u) it is possible that this changes in the future.
## Classic eBPF probe

The classic {{< glossary_tooltip text="eBPF probe" term_id="ebpf-probe" >}} is an alternative source to the ones described above, leveraging greater compatibility than the modern BPF one, since it requires older kernel versions.

To install the eBPF probe, please refer to the [installation](/docs/getting-started/installation/#install-driver) page.

To enable the eBPF support in Falco set the `engine.kind` configuration key to `ebpf` and eventually customize `engine.ebpf.probe` to the path where the eBPF probe resides; the default path is the location used by `falcoctl driver` tool to install the eBPF probe.

### Least privileged mode

The minimal set of capabilities required by Falco to run the classic eBPF probe is the following:

- `CAP_SYS_ADMIN`
- `CAP_SYS_RESOURCE`
- `CAP_SYS_PTRACE`

Let's see them in detail:

- **CAP_SYS_RESOURCE**: Falco needs this capability to be able to call the `setrlimit` syscall. The `setrlimit` syscall is used together with the `RLIMIT_MEMLOCK` flag to change the amount of memory that can be _mlocked_ into RAM. The default value for this memory limit is very low, so even a very simple eBPF program would fail. The workaround is to increase the default value to something acceptable so eBPF maps can be correctly _mlocked_ in memory.
- **CAP_SYS_PTRACE**: Falco needs this capability because it accesses paths like `/proc/<pid>/environ`. From the userspace standpoint, the permission to do so is mapped to the `CAP_SYS_PTRACE` capability. For the curious reader, see [environ_open](https://elixir.bootlin.com/linux/latest/source/fs/proc/base.c#L937) implementation in the kernel.
- **CAP_SYS_ADMIN**: Falco needs this capability to load eBPF programs and maps, and to interact with the system using the `bpf` syscall.

This set of capabilities should work most of the time but under some conditions, it is possible to replace the `CAP_SYS_ADMIN` with two more granular capabilities: `CAP_SYS_BPF` and `CAP_SYS_PERFMON`.

The conditions to satisfy are the following:

1. A kernel version that supports these capabilities. The Linux Kernel version `5.8` is the first one that officially supports them but they could have been backported on older versions on some distributions.

2. An acceptable value of `kernel.perf_event_paranoid` config. Reading the [manual](https://linuxsecurity.expert/kb/sysctl/kernel_perf_event_paranoid/) it says that `perf_event_paranoid` influences only the behavior of unprivileged users, but under the hood, some distributions like Debian or Ubuntu introduce additional `perf_event_paranoid` levels. Consider [`Ubuntu`](https://kernel.ubuntu.com/git/ubuntu-stable/ubuntu-stable-jammy.git/tree/kernel/events/core.c#n11991) as an example:

```c
if (perf_paranoid_any() && !capable(CAP_SYS_ADMIN))
return -EACCES;

// where perf_paranoid_any is defined as:
static inline bool perf_paranoid_any(void) {
return sysctl_perf_event_paranoid > 2;
}
```

As you can notice, when your `kernel.perf_event_paranoid` is `>2` the capability `CAP_PERFMON` won't suffice, you would still need `CAP_SYS_ADMIN`.
So before disabling `CAP_SYS_ADMIN` check your `perf_event_paranoid` value with `sysctl kernel.perf_event_paranoid` and make sure their values are compatible with your distribution enforcement.
49 changes: 24 additions & 25 deletions content/en/docs/install-operate/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,42 +310,41 @@ In these steps, we are targeting a Debian-like system on `x86_64` architecture.
```

4. Use `falcoctl driver` tool to configure Falco and install the kernel module or the BPF probe. If you want to use other sources like the modern BPF probe or plugins you can skip this step.
{{% pageinfo color="info" %}}

{{% pageinfo color="info" %}}

To install the driver, write and execution permissions on the `/tmp` directory are required, since `falcoctl` will try to create and execute a script from there.

{{% /pageinfo %}}

```bash
# If you want to use the kernel module, configure Falco for it
falcoctl driver config --type kmod
# If you want to use the eBPF probe, configure Falco for it
falcoctl driver config --type ebpf
# Install the chosen driver
falcoctl driver install
```
To install the driver, write and execution permissions on the `/tmp` directory are required, since `falcoctl` will try to create and execute a script from there.

{{% /pageinfo %}}

```bash
# If you want to use the kernel module, configure Falco for it
falcoctl driver config --type kmod
# If you want to use the eBPF probe, configure Falco for it
falcoctl driver config --type ebpf
# Install the chosen driver
falcoctl driver install
```

By default, the `falcoctl driver install` command tries to download a prebuilt driver from [the official Falco download s3 bucket](https://download.falco.org/?prefix=driver/). If a driver is found then it is inserted into `${HOME}/.falco/`. Otherwise, the script tries to compile the driver locally, for this reason, you need the dependencies at step [3].
By default, the `falcoctl driver install` command tries to download a prebuilt driver from [the official Falco download s3 bucket](https://download.falco.org/?prefix=driver/). If a driver is found then it is inserted into `${HOME}/.falco/`. Otherwise, the script tries to compile the driver locally, for this reason, you need the dependencies at step [3].

You can use the env variable `FALCOCTL_DRIVER_REPOS` to override the default repository URL for prebuilt drivers. The URL must not have the trailing slash, i.e. `https://myhost.mydomain.com` or if the server has a subdirectories structure `https://myhost.mydomain.com/drivers`. The drivers must be hosted with the following structure:
You can use the env variable `FALCOCTL_DRIVER_REPOS` to override the default repository URL for prebuilt drivers. The URL must not have the trailing slash, i.e. `https://myhost.mydomain.com` or if the server has a subdirectories structure `https://myhost.mydomain.com/drivers`. The drivers must be hosted with the following structure:

```bash
/${driver_version}/${arch}/falco_${target}_${kernelrelease}_${kernelversion}.[ko|o]
```bash
/${driver_version}/${arch}/falco_${target}_${kernelrelease}_${kernelversion}.[ko|o]
```

where `ko` and `o` stand for Kernel module and `eBPF` probe respectively. This is an example:

```text
/7.0.0+driver/x86_64/falco_amazonlinux2022_5.10.75-82.359.amzn2022.x86_64_1.ko
```
```text
/7.0.0+driver/x86_64/falco_amazonlinux2022_5.10.75-82.359.amzn2022.x86_64_1.ko
```

> If you wish to print some debug info, you can use:
```bash
# If you want to use the kernel module, configure Falco for it
falcoctl driver printenv
```
```bash
# If you want to use the kernel module, configure Falco for it
falcoctl driver printenv
```

You are finally ready to [run the Falco binary](/docs/install-operate/running#falco-binary)!

Expand Down

0 comments on commit 0ce23d4

Please sign in to comment.