 Hello everybody and welcome. The goal of this maintenance track is to look at one of the main interesting part of FALCO. FALCO is a CNCF incubated project that aims to provide cloud-native runtime security. In this talk we will see an introduction to FALCO. A demo about how to create custom FALCO rules? Me having fun with ASCII art. But first, a bit of history. FALCO was created as an open source project by Cystig in 2016. It was donated to the CNCF in 2018. About a year later, the CNCF promoted FALCO to the incubation level. FALCO has been the first ever runtime security project to be promoted to the CNCF incubation level. Before we start with the presentation, let's introduce myself. My name is Leonardo Grasso and I am an open source software engineer at Cystig and a FALCO maintainer. My daily job is to code FALCO, improve and evolve it and work with the community. I'm also the creator of the Prometheus Matrix Esporter for FALCO Output Events and I love to contribute to other FALCO related projects too. In general, I love to contribute to open source projects. By the way, you can find me on GitHub, Twitter, but also in the FALCO channel on the Kubernetes Slack. Among other things, I love to present the fantastic work the maintainers and the whole community continuously do to make FALCO better. So, EIM, let's start explaining what FALCO is. In short, FALCO is a cloud native runtime security tool that makes it easy to consume kernel events and reach those events with useful information. When an application, when every application is going to need to communicate with another application or access the network or, for example, use the file system and so on, in general, every time an application needs to access the kernel functionality, the application will use a system call. I'm talking about the system call because the system call is the fundamental interface between an application and the Linux kernel. So, it is also a real source of proof for what is happening in a system. So, FALCO passes the content of those system calls at runtime, read them, and what argument were passed to them. Then, FALCO reaches those events with information that came from other sources. Since FALCO focuses on the cloud native stack, it can, for example, fetch information from the container runtime layer and from Kubernetes. FALCO also comes with a rich rule set of security rules built explicitly for Kubernetes Linux and the cloud native stack. Those rules are asserted at runtime, and when a rule is violated in a system, FALCO will alert the user of the violation. That's basically what FALCO does. Why FALCO? Change is a fundamental part of cloud native. It is also part of deploying software and it's part of the infrastructure. Everything changes. But sometimes unexpected things happen and we have to respond to that accurately, especially when an expected event can affect security. So, for this reason, FALCO give us a set of eyes to protect our system against unknown or unwanted behavior. It can also detect zero-day vulnerabilities, CVs, anomalies and treats. FALCO is about detection, but you can think of it as a utility that enable prevention tool. For example, with FALCO, you could also uncover future security policies or create a mechanism that take action during a security violation. But how can FALCO do that? Let's see how FALCO works. Well, to understand how FALCO works, one of the first things to know is how it gets events from the system, specifically how it instruments the Linux kernel to receive system call. The FALCO process runs in the user space in the same place where your application running to. However, it also has a concept of the inputs that we usually call driver. These drivers run at the kernel level to instrument the system, so in this way they allow to intercept and understand what is happening at the kernel level and bring that up into the user space where FALCO, that run as a demon, can continually assert that information against a set of rules. Basically, these drivers act as producer, producer of those events that are consumed by FALCO's inputs. FALCO, for this reason, comes with a set of drivers by default, one of which is implemented as a kernel module and another one that uses the EBPF technology. Each of those has pros and cons, but both provide the same functionality. For example, you can use the kernel module that is very efficient, but maybe you cannot install everywhere. You cannot install it everywhere. On the other hand, an EBPF probe has some advantage. It can program the kernel without risking to break it, for example, but it requires a newer kernel. Finally, it works to mention that a new kind of driver has recently been introduced. It's a P-trace-based producer that we call PDIG, which can run in the user space only, but is lower than other drivers. Anyway, it is still beneficial since it's the only possible solution in some environments, like some managed Kubernetes cluster or in places where you cannot install the kernel module, either the EBPF probes. So, we are saying that FALCO uses the kernel of the operating system as a source of truth and takes this information, but there is more. It also reaches them with metadata coming from other layers of the cloud. For example, you can see in the slide from the container runtime and Kubernetes. Think like the container image name, the pod name, the namespace, the service labels, annotation and all these kind of stuff are consumed by FALCO to offer a view of the system that is much accurate as possible with regards, of course, to your application and your deployment. That is very important because when doing runtime and learning runtime protection of your infrastructure, you are typically much more interested in what service or what deployment is showing a strange behavior rather than just getting a container ID or something like that is not easy to link. Last but not least, it is also important to know that drivers are not the only input supported by FALCO. For example, it already supports the Kubernetes audit logging as an event source and in future maybe other inputs may be added. Now, we got an overview of how FALCO gets security events as input. We can take a look at its architecture. Well, from a high level point of view, FALCO architecture seems to be relatively simple. We can see on the right in the slide there are inputs which are also which also include information enrichment as I was saying before. That's an essential part of the input mechanism. At runtime, all that information gets collected and merged together in the security event which in the end arrives at the FALCO engine that we see in the middle. The engine continues to match events against the conditions specified by the rules we provide. When information is violated, the engine triggers an alert and delivers it through the output channels. Now, since we will discuss rules in depth later in this presentation let's put it aside for a moment and move on to the output channels. FALCO provides some output channels. We can see the standard output, the syslog, the file output, basically it can write events to a file. The program output it can pass FALCO can pass the alerts to the standard output of a program. And there is the HTTP output. For example you can use the HTTP output to integrate with a webbook or you can use other tool like FALCO SideKick. By the way, another open source project under the FALCO Security GitHub organization. With FALCO SideKick you can forward alerts to Slack Teams Elastic Search, for example and many other destinations. Finally, there is also GRPC output. You can enable GRPC and connect to the FALCO exporter, for example. That's again another open source project under the FALCO Security GitHub organization and I am the creator of it. With FALCO exporter you can export metrics to Prometheus, for example. There is more. There are SDKs for Golang, Rust and Python. By using them you can consume FALCO outputs directly from your application. Essentially, there is a bunch of ways to consume FALCO outputs. We have learned that we can monitor syscall and other things and get useful information on the one hand. On the other hand, when our time session fails we can send alerts with those pieces of information wherever we want. Whatever we want. But that's kind of useless if you don't have rules that make use of that. So let's see what rules are and how use them. A rule tells FALCO which security policy we want to observe and the information we want to receive if the policy has been violated. Basically, a rule mainly defines two things. The conditions under which another should be emitted and the message that should be output when a matching event occurs. Some rule examples. First of all, rules make use of specific of a specific syntax to express filtering condition. That syntax aims to be as lean and as and as simple as possible. But at the same time it allows you to create sophisticated stuff. In the first example we set the condition to detect when a shell is running a container. As you can see, the condition says container ID is different than host name. These mean that we are inside a container. And there is a process called bash. In this way it is evaluated at runtime to detect when someone is using a bash inside the container. Next, another example. Write below binary dir. In this rule we are using a macro that we'll see later. So the macro open write and the second part of the condition are basically saying a write operation in one of these directories. Then container namespace change. This rule detects a container trying to escape its namespace. But at the same time it excludes processes that we know are allowed to that. For example, Docker. Of course, condition can become more and more sophisticated. As you can see in the last example. It depends on how we use all information provided by inputs. For this reason FALCO came which are each set of security rules specifically built for Kubernetes. Linux and the cloud network stack those rules are created and maintained by the community and you can use all of them or just those you need. Moreover you can customize those rules depending on your needs. But also, more important you can easily create your own. So, what's better than a demo to see how to create rules? Let's see FALCO in action. By the way FALCO is really straightforward to install. So, I wanna show you how I install it on my laptop. You can find all the details on our documentation at falco.org. In my case, I'm gonna use the binary package. I downloaded the package and struct it and copy everything to my root file system. One more thing since I used the binary package I also have to install the driver manually and the package provide a script for that which is FALCO driver loader. It is now building and installing the FALCO kernel module via DKMS. This script is also included in the installation script of the Debian package or the RPM package that we provide as other installation methods. So, if you use this package you don't need to do that manually. Same thing if you use the package that we provide too. OK. Done. Now that FALCO has been installed let's see if it works. OK. FALCO started and it loaded its default configuration file which is I see that it also started to detect some activity that my browser is doing right now but this is not the goal of this demo. So, to test if it works properly I am gonna run a simple command that will create a file inside the bin directory and this should trigger a rule that's included into the default rule set of FALCO. OK. FALCO, as we expected emitted an alert with the command I typed before so in less than few minutes we have FALCO installed up and running. Awesome. OK. Now I wanna show you how to create a custom rule. This is an empty FALCO rules files. Basically a rules file is a demo file that can contain several types of elements. It can contain rules that we see below. It can also contain macros that basically rule condition snippets that can be reused inside rules or even other macros. Finally, it can also contain lists. List are collection of items that can be used in rules macros or even in other lists. The only difference is that list cannot contain filters. Now, before moving forward I wanna explain you what I'm gonna use in this rule. I wanna detect if my webcam is being used by some program. Exactly. I want to know if some program is using my webcam. In Linux, a webcam is a video device that is mapped to a file. For example, slash dev, slash video 0. And we know that a program has to call a system call to open any file. So, we are going to detect when some process opens a video device file. So, let me fill this rule. First thing, we need a name. This name will uniquely identify the rule into the pack rule engine but also in output. Let's say video device open it. We also need a longer description that explain what the rules detect. So, the text that a video device was opened. And now, the most important part the filtering expression. This expression is needed to filter those events that match our rules. Parco provides a language for that. It's a very simple language but at the same time it's very powerful. Since we need to select those events that are opening a file, so that are calling an open sys call we can write event type equal to open. But I know that this is not the only sys call that open a file. I know there is another one that's very similar that is open that add it to type equal an at. Sorry, it should be or open at. The syntax is basically a chain of boolean expressions. There are operators, moreover we can also use the information received from the inputs. Now, this condition is not enough because we are just saying select all those events which are using a sys call open or a sys call open at. We also need to specify which file descriptor is used by these sys calls and we can do that because among other information we also receive the values that are passed as argument to those sys call so let me add some parentheses and add file descriptor name equal to slash video 0. In this way we are saying select that are opening a file and the file is slash dev slash video 0 but we can further improve this because in this way now we are just selecting only one video device we can add more than one so let me change this operator with another operator provided by the syntax that see that is start with and remove the 0 in this way we are selecting all those files that starts with that video 0 and in this way we should select all video device that we have in our system and with this relative simple condition we have archived the goal of my example let's move on on the message the output message is also very important we can write something inside the example for example a video device was opened but we can also use place order to include all those useful information related to this event all those information that we think are relevant for this rule for example for sure I want to know the device name that was used when was used by the program that triggered this alert so I can write that equal in this way the falcon giant will replace this with the actual file name but we can do more for example I can add the command that generated the event and for that I can use proc.command line but we can do even more for example if I want to know if the event was generated inside the container or not I can add this container equal to container ID in this way if the event was generated inside the container I will get the container ID otherwise I will see just host that means it was not generated inside container alright and finally we have to assign a priority to our rule let's say that if someone opened my webcam it's critical okay alright I believe it's time to test the rule I've created right now so let's do that okay I'm gonna alko with the dashR option to specify the rule file I want to be loaded and now there are several ways to test this rule but to be honest since I knew this demo could be a bit boring I adopted for the funnest one at least I hope so and here we go okay the alert was emitted and you can see me in maski art and now you can see me dancing okay let's stop this I think it's enough and return to serious things alko send as few alerts maybe because the command I used was called two times and we can see that the priority was critical the message is a video device was opened and we also have all other useful information like the device name, the command and so on that's it well we are about to finish and I hope you enjoyed this talk before closing I'd like to give you some useful resources here you can find our website and our GitHub organization and also other project I mentioned in this talk finally I would like to invite you to join our fantastic community you can find us at the Falco channel on the Kubernetes lock and by the way feel free to contact me thank you čau