# Getting started developing Falco
Hello, Falconers!
Got interested in Falco and would like to contribute with your own ideas? Feeling stuck because you don't know where to start? No worries, we are here to help you!
Whether you want Falco to [monitor a new system call](https://falco.org/blog/falco-monitoring-new-syscalls/), add a brand new feature or solve a problem you ran into, you have to create a developing environment. This blog post tries to walk you through the process of setting up a new one so that you can feel comfortable and ready to start contributing!
First things first, Falco's source code lives in the [Falco organization](https://github.com/falcosecurity) on GitHub. The two repositories you should definitely take a look at are:
- [falcosecurity/libs](https://github.com/falcosecurity/libs), containing both the kernel module and the eBPF probe, and also libscap and libsinsp
- [falcosecurity/falco](https://github.com/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](https://falco.org/blog/falco-monitoring-new-syscalls/)! Now, let's try to go step by step, showing what is actually required to get started coding something.
### 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 coding, 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. This allows 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 carefulness because your code will run with full kernel power. 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](https://www.vagrantup.com/) extremely helpful. Basically, 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. Vagrant initializes virtual machines so that you can easily access them via SSH. This really helps in case you also want to try out [remote development](https://code.visualstudio.com/docs/remote/ssh), for instance with Visual Studio Code. This way, you will be able to seamlessly code, build and test on the Vagrant virtual machine! If you want to try this, first you will need to [download and install Vagrant](https://www.vagrantup.com/downloads) and a Vagrant VM provider. You may want to install VirtualBox, since Vagrant comes with support out of the box for it. You can follow the [Vagrant quickstart](https://learn.hashicorp.com/tutorials/vagrant/getting-started-index?in=vagrant/getting-started) to accomplish this. Once you are able to spawn VMs with Vagrant, feel free to choose a VM with the distribution you like for development from [Vagrant Cloud](https://app.vagrantup.com/boxes/search). 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
```
From now on, you can use the `vagrant ssh` command to log into the VM and start working. Unless you like writing code on old (but very powerful) tools like Vim, you may feel the need of using an IDE, as if you were developing on your local machine. To do so, you can download the `Remote - SSH` Visual Studio Code extension. The latter lets you use any remote machine with a SSH server as your development environment, including the VM you spawned with Vagrant. After installing the extension, all you have to do is:
```
$ cd ubuntu-vm
$ 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
```
You can copy the output of the last command and paste it in the `.ssh/config` file in your local home directory. Also, feel free to change the `Host default` line with something that helps you remembering that this is the VM that you use for developing Falco: something like `Host falco-dev` would be great! Then, go back to Visual Studio Code. You can 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!
### Build 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. Then, try to follow the steps in our [official Falco documentation](https://falco.org/docs/getting-started/source/). Some of the most useful `CMake` definitions you may want to use are:
- `-DUSE_BUNDLED_DEPS=ON` allows 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 to compile Falco with a local version of libs. If not specified, `CMake` will download the `libs` repository directly from GitHub. This option is extremely handy when you are implementing something that requires modification to both `falco` and `libs` 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 `-j` option of make to spawn multiple parallel jobs.
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 ./userspace/falco/falco FALCO_BPF_PROBE=driver/bpf/probe.o \
-c ../falco.yaml -r ../rules/falco_rules.yaml
```
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](https://github.com/falcosecurity/event-generator). This is yet another project from the Falco security organization, and it can be used to generate some suspicious actions on the system, triggering Falco rules. All you need to do is launching Falco from a terminal, and from another one issue the following command:
```
docker run -it --rm falcosecurity/event-generator run syscall
```
If everything works fine, you will see Falco alerting some malicious behaviours in the container.
You can also test Falco by using its own test-suite. The Falco test-suite uses the [Avocado Framework](https://avocado-framework.readthedocs.io/en/95.0/) to launch test. All you have to do is the following:
```
cd falco/test
bash 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](https://github.com/falcosecurity/falco/tree/master/test) 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 anything 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](https://falco.org/docs/rules/). Falco's rule syntax is very simple and you will be able to write rules down very soon. A rule is made up of:
- 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 monitoring for a new syscall. You would like to throw an alert every time a process executes it. You can 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](https://falco.org/docs/rules/supported-fields/) and [operators](https://falco.org/docs/rules/conditions/#operators).
### Conclusion
That's it, you are now all set to dig in the source code, hack around, and unleash your creativity! I can't wait to see some of your PRs and build something great together!
You can find us in the [Falco community](https://github.com/falcosecurity/community). Please feel free to reach out to us for any questions, suggestions, or even for a friendly chat!
If you would like to find out more about Falco:
* Get started in [Falco.org](http://falco.org/)
* Check out the [Falco project in GitHub](https://github.com/falcosecurity/falco).
* Get involved in the [Falco community](https://falco.org/community/).
* Meet the maintainers on the [Falco Slack](https://kubernetes.slack.com/?redir=%2Farchives%2FCMWH3EH32).
* Follow [@falco_org on Twitter](https://twitter.com/falco_org).