Hello, Falcoers!
Interested in Falco and want to contribute your ideas? Feeling stuck because you don't know where to start? No worries, we are here to help!
Whether you want Falco to monitor a new system call, add a brand new feature, or solve a problem you ran into, you have to create a development environment. This blog post will walk you through the process of setting up a new one so that you can feel comfortable and ready to contribute!
Now, let's go step by step, showing what is required to get started hacking on Falco. We hope this table of contents will facilitate the use of this post as a future reference.
Setting up the environment
A peculiarity of the Falco project is that you may need to write some kernel-level code. An important consideration to make, even before starting to code, is that the eBPF probe and the kernel module should provide exactly the same features.
For this reason, when developing something on the eBPF probe, you should implement the same functionality on the kernel module and vice versa, with the intent of preserving feature parity across the two drivers.
Writing code at the kernel-level is not an easy task. In particular, the kernel module requires extra care because your code will run with full kernel privileges. Any little mistake may result in a kernel panic, crashing the system.
On the other hand, eBPF programs are much safer than the kernel module, but sometimes you may need to fight against the verifier on different kernel versions.
For these reasons, some of us find using Vagrant extremely helpful. Vagrant is a tool that allows you to easily spawn virtual machines, so that you can test your code against multiple kernel versions and Linux distributions without causing any harm to your system.
Creating a dedicated VM
If you have never used Vagrant before, you first need to download and install Vagrant and a Vagrant VM provider. You may want to install VirtualBox since Vagrant comes with out-of-the-box support. You can follow the Vagrant quickstart to accomplish this.
Once you can spawn VMs with Vagrant, choose a box from Vagrant Cloud containing your favorite distribution for development.
For instance, if you want to launch a Ubuntu Focal Fossa machine, you can issue the following commands:
$ mkdir ubuntu-vm && cd ubuntu-vm
$ vagrant init ubuntu/focal64
$ vagrant up
Vagrant initializes virtual machines so that you can easily access them via SSH. This helps in case you also want to try out remote development, for instance with Visual Studio Code. This way, you will be able to seamlessly code, build, and test on the Vagrant virtual machine!
From now on, the command vagrant ssh
will log you into the VM and you could start working right away. However, unless you prefer writing code on older (but very powerful) tools like Vim, you may feel the need to use an IDE, as if you were developing on your local machine.
To do so, we will show you how to extend Visual Studio Code capabilities by downloading the Remote - SSH
extension. This extension lets you use any remote machine that allows SSH access as your development environment. This includes the VM you just spawned with Vagrant.
After installing the extension, from inside the Vagrant VM directory, retrieve the SSH configuration:
$ vagrant ssh-config
Host default
HostName 127.0.0.1
User vagrant
Port 2222
UserKnownHostsFile /dev/null
StrictHostKeyChecking no
PasswordAuthentication no
IdentityFile /Users/lorenzo.susini/vagrant/official-ubuntu/.vagrant/machines/default/virtualbox/private_key
IdentitiesOnly yes
LogLevel FATAL
Copy the output of the last command and paste it into the .ssh/config
file in your local home directory. Also, we recommend changing the Host default
line with something that helps you remember that this is the VM you use for developing Falco. Something like Host falco-dev
would work.
Then, go back to Visual Studio Code. Press Control + P
(or Command + P
on MacOS) and type > Remote-SSH: Connect to Host
. Press Enter and you will see the falco-dev
entry in the UI to connect to the VM.
Your development environment is now up and running. You can open remote folders and projects, and use all the functionalities of Visual Studio Code!
Discovering the Falco code
Now, it's time to have some fun. Falco's source code lives in the Falco organization on GitHub. The two repositories you should take a look at are:
- falcosecurity/libs, containing both the kernel module and the eBPF probe, and also libscap and libsinsp.
- falcosecurity/falco, including the rule engine, rules, and support for any kind of output, such as standard output, file output, gRPC, and more. If you're not yet familiar with the overall Falco architecture, you can go into detail by reading the previous blog post.
Building Falco from scratch
Most of the time, the main starting point for developing something is building it from scratch. You can fork falco
and libs
, and clone them into your development machine. Forking the repositories first is recommended if you want to later push the changes and save your work.
Then, try to follow the steps in our official Falco documentation. Some of the most useful CMake
definitions you may want to use are:
-
-DUSE_BUNDLED_DEPS=ON
allows you to download and compile all the needed Falco dependencies. This also helps to build Falco independently of the libraries installed in your system. The build process will run trouble-free using this option, although it will be a little bit slower. -
-DFALCOSECURITY_LIBS_SOURCE_DIR=/path/to/local/libs
allows you to compile Falco with a local version of libs. If not specified,CMake
will download thelibs
repository directly from GitHub. This option is extremely handy when you are implementing something that requires modification to bothfalco
andlibs
repositories so that you can easily test what you coded. -
-DBUILD_BPF=ON
allows compilation of the eBPF probe, crucial when developing something on the eBPF driver. -
-DCMAKE_BUILD_TYPE=Debug
is helpful when you want to debug something. Debug information is printed out and assertions are enabled. The complete sequence of commands you may want to run is:
$ mkdir build && cd build
$ cmake -DUSE_BUNDLED_DEPS=ON \
-DFALCOSECURITY_LIBS_SOURCE_DIR=/path/to/local/libs \
-DBUILD_BPF=ON \
-DCMAKE_BUILD_TYPE=Debug ..
$ make
Also, note that you can use the
-jxxx
option of make to spawn multiple parallel jobs, wherexxx
is the number of jobs.
Testing your build
Now that you have successfully compiled Falco, try to run it. The default driver is the kernel module. To use it, assuming that you are in the build directory, just type:
$ sudo insmod driver/falco.ko
$ sudo ./userspace/falco/falco -c ../falco.yaml \
-r ../rules/falco_rules.yaml
To start Falco with the eBPF driver instead, you need to set the FALCO_BPF_PROBE
environment variable, like this:
$ sudo FALCO_BPF_PROBE=driver/bpf/probe.o ./userspace/falco/falco \
-c ../falco.yaml -r ../rules/falco_rules.yaml
Falco Event-Generator
Now that you built Falco, you may wonder if everything works as expected. A quick and dirty way of testing Falco is using the event-generator.
This is yet another project from the Falcosecurity organization, and it can be used to generate some suspicious actions on the system, therefore, triggering some Falco rules.
All you need to do is to start two terminals. You will launch Falco from one of them and leave it running. From the second terminal, launch the event generator using the following command:
docker run -it --rm falcosecurity/event-generator run syscall
If everything works fine, in the first terminal you opened you will see Falco alerting of some malicious behaviors from the container we started in the second one.
Falco Test Suite
You can also test Falco by using its own test-suite. The Falco test-suite uses the Avocado Framework to launch tests.
All you have to do is the following:
$ cd falco/test
$ ./run_regression_tests.sh -p -v
$ virtualenv venv
$ source venv/bin/activate
$ pip install -r requirements.txt
$ BUILD_DIR="../build" avocado run --mux-yaml falco_traces.yaml \
--job-results-dir /tmp/job-results -- falco_test.py
$ deactivate
The run_regression_tests.sh
script downloads and prepares trace files needed for testing. Falco can consume these files containing some recorded system activity that must trigger rules.
If you want, you can also refer to the documentation to launch other kinds of tests, such as rule engine and k8s audit logs tests, just to name a few.
You can relaunch these tests whenever you add something to the codebase, just to make sure nothing got broken after you played around with it.
You are now ready to put your hands on Falco!
Writing your own test rules
At this point, let's say you have introduced a new syscall. A possible way to effectively test it is to write a custom rule. You can dig deeper on how to write rules by reading the related section in the official documentation.
Falco's rule syntax is very simple and you will be able to write rules down very soon. A rule is made of:
field name | field description |
---|---|
rule name | a short unique name for the rule |
description | a longer description of what the rule detects |
condition | a filtering expression that is applied against events to see if they match the rule |
output | a message that should be produced if a matching event occurs |
priority | severity associated with the rule |
To give you a little taste of writing rules, let's assume you have followed the aforementioned post where we added support for a new syscall. You would like to throw an alert every time a process executes it.
You could create a rule.yaml
file having this as content:
- rule: My test rule
desc: Detects any process executing openat2 and prints its name and pid
condition: evt.type = openat2
output: openat2 executed by (process name: %proc.name, pid: %proc.pid)
priority: NOTICE
Then, you can use the -r
option to tell Falco to use this rule file. Of course, you can create much more complex and meaningful rules using many different fields and operators.
Conclusion
You have learned how to set up a development environment with the help of Vagrant and Visual Studio Code, and how to build and run tests on Falco. You are now all set to dig into the source code, hack around, and unleash your creativity! We can't wait to see some of your PRs and build something great together!
You can find us in the Falco community. Please feel free to reach out to us for any questions, suggestions, or just a friendly chat!
If you would like to find out more about Falco:
- Get started in Falco.org
- Check out the Falco project in GitHub.
- Get involved in the Falco community.
- Meet the maintainers on the Falco Slack.
- Follow @falco_org on Twitter.
Top comments (0)