How to setup Falco in Kubernetes Cluster to Detect Deep Kernel activities
Here in this article we will see how we can setup the kubernetes node for analysizing and alerting on the runtime activities related to Kernel API calls. We will be installing Falco on the Kubernetes node and launch a set up pods carrying out unusualy kernel activity and validate that these activities are getting logged in the system logs for further review and alerting purpose.
Test Environment
Fedora 36 server
Kubernetes Cluster (1 master + 1 worker node)
What is Falco
Falco is an open source runtime security tool originally built by Sysdiag. It is basically used to detect and alert on system call related to Kernel API. It has a set of default rules that check the kernel for unusual behavior such privileged container escalation, writing to sensitive files on the file system, unusual network connections and more.
Procedure
Step1: Install Falco on Worker Node
Here in this step we are going to setup the Falco runtime security tool RPM package repository to install it on Fedora OS node.
[admin@kubenode ~]$ sudo rpm --import https://falco.org/repo/falcosecurity-3672BA8F.asc
[admin@kubenode ~]$ sudo curl -s -o /etc/yum.repos.d/falcosecurity.repo https://falco.org/repo/falcosecurity-rpm.repo
[admin@kubenode ~]$ cat /etc/yum.repos.d/falcosecurity.repo
# falcosecurity-rpm - packages by falcosecurity
[falcosecurity-rpm]
name=falcosecurity-rpm
baseurl=https://download.falco.org/packages/rpm
gpgcheck=1
gpgkey=https://falco.org/repo/falcosecurity-3672BA8F.asc
repo_gpgcheck=0
enabled=1
Once the RPM package repository setup is completed, we can install Falco tool as shown below.
[admin@kubenode ~]$ sudo dnf install falco
Step2: Start Falco service
Let’s now start up the Falco systemd service as shown below.
[admin@kubenode ~]$ sudo systemctl start falco.service
[admin@kubenode ~]$ sudo systemctl status falco.service
[sudo] password for admin:
● falco.service - Falco: Container Native Runtime Security
Loaded: loaded (/usr/lib/systemd/system/falco.service; enabled; vendor preset: disabled)
Active: active (running) since Sat 2022-12-03 15:11:02 IST; 54s ago
Docs: https://falco.org/docs/
Main PID: 856 (falco)
Tasks: 13 (limit: 4685)
Memory: 32.4M
CPU: 9.022s
CGroup: /system.slice/falco.service
└─ 856 /usr/bin/falco --pidfile=/var/run/falco.pid
Step3: Verify Falco Configuration
Falco default configuration file is installed at the following location. This file basically contains details about the type of output setup and plugins that are active. It also contains the locations of all the falco rules file that are used by the falco rule engine for analyzing kernel activity violations.
[admin@kubenode falco]$ ls -ltr /etc/falco/falco.yaml
-rw-r--r--. 1 root root 15594 Nov 16 11:54 /etc/falco/falco.yaml
[admin@kubenode falco]$ grep -A 2 "syslog_output" /etc/falco/falco.yaml
syslog_output:
enabled: true
[admin@kubenode falco]$ grep -A 3 "rules_file" /etc/falco/falco.yaml
# The name "rules_file" is only for backwards compatibility.
# If the entry is a file, it will be read directly. If the entry is a directory,
# every file in that directory will be read, in alphabetical order.
#
--
rules_file:
- /etc/falco/falco_rules.yaml
- /etc/falco/falco_rules.local.yaml
- /etc/falco/rules.d
Step4: Verify Default Falco Rules
As shown in previous step, Falco rules are defined the same location as the Falco configuration files. The rules files that are by default included are as shown below and any custom rules file under rules.d folder.
[admin@kubenode falco]$ ls -ltr falco_rules.*
-rw-r--r--. 1 root root 140728 Oct 19 19:01 falco_rules.yaml
-rw-r--r--. 1 root root 3100 Nov 24 11:58 falco_rules.local.yaml
[admin@kubenode falco]$ ls -ltr rules.d/
Let’s try to look at one of the default rule as shown below.
[admin@kubenode falco]$ grep -A 5 "Write below etc" falco_rules.yaml
- rule: Write below etc
desc: an attempt to write to any file below /etc
condition: write_etc_common
output: "File below /etc opened for writing (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline pid=%proc.pid parent=%proc.pname pcmdline=%proc.pcmdline file=%fd.name program=%proc.name gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] container_id=%container.id image=%container.image.repository)"
priority: ERROR
tags: [filesystem, mitre_persistence]
Step5: Update the Default Falco Rule
This above rule basically provides a error message in the sysout logs when ever there is a write activity happening under the /etc configuration directory. Let’s try to update the default rules output logging message as shown below. We are going to copy the following rule section into “falco_rules.local.yaml” as shown below and update the output message.
[admin@kubenode falco]$ cat falco_rules.local.yaml
...
- rule: Write below etc
desc: an attempt to write to any file below /etc
condition: write_etc_common
output: "SUSPECIOUS FILE UNDER /etc WRITTEN!! (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline pid=%proc.pid parent=%proc.pname pcmdline=%proc.pcmdline file=%fd.name program=%proc.name gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] container_id=%container.id image=%container.image.repository)"
priority: ERROR
tags: [filesystem, mitre_persistence]
...
Once the rules file is updated, we need to make sure that the falco systemd service is restarted. Let’s restart the service now.
[admin@kubenode falco]$ sudo systemctl restart falco.service
Step6: Create a Pod that writes to /etc directory
[admin@kubemaster ~]$ alias k='kubectl'
[admin@kubemaster ~]$ export do='-o yaml --dry-run=client'
[admin@kubemaster ~]$ kubectl create ns falcotest
[admin@kubemaster ~]$ cat touchetc.yml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: touchetc
name: touchetc
namespace: falcotest
spec:
containers:
- command:
- sh
- -c
- touch /etc/trojan.exe; sleep 1d
image: busybox
name: touchetc
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
[admin@kubemaster ~]$ k create -f touchetc.yml
pod/nginx created
Step7: Validate the Sysout logs
Now that we have launched a container which write to /etc configuration directory, ideally this activity should be be logged in our sysout logs with the updated output message as shown below. Here we are going to check this logging using two different methods. They are using the falco status and journalctl.
[root@kubenode falco]# systemctl status falco.service
● falco.service - Falco: Container Native Runtime Security
Loaded: loaded (/usr/lib/systemd/system/falco.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2022-12-07 12:09:34 IST; 2min 17s ago
Docs: https://falco.org/docs/
Main PID: 7857 (falco)
Tasks: 12 (limit: 4685)
Memory: 29.3M
CPU: 3.615s
CGroup: /system.slice/falco.service
└─ 7857 /usr/bin/falco --pidfile=/var/run/falco.pid
Dec 07 12:09:35 kubenode.stack.com falco[7857]: Falco initialized with configuration file: /etc/falco/falco.yaml
Dec 07 12:09:35 kubenode.stack.com falco[7857]: Loading rules from file /etc/falco/falco_rules.yaml
Dec 07 12:09:35 kubenode.stack.com falco[7857]: Loading rules from file /etc/falco/falco_rules.local.yaml
Dec 07 12:09:35 kubenode.stack.com falco[7857]: The chosen syscall buffer dimension is: 8388608 bytes (8 MBs)
Dec 07 12:09:35 kubenode.stack.com falco[7857]: Starting health webserver with threadiness 8, listening on port 8765
Dec 07 12:09:35 kubenode.stack.com falco[7857]: Enabled event sources: syscall
Dec 07 12:09:35 kubenode.stack.com falco[7857]: Opening capture with Kernel module
Dec 07 12:11:11 kubenode.stack.com falco[7857]: 12:11:11.110045673: Error File below / or /root opened for writing (user=root user_loginuid=1000 command=less pid=7960 parent=systemctl file=>
Dec 07 12:11:16 kubenode.stack.com falco[7857]: 12:11:16.582514276: Error File below / or /root opened for writing (user=root user_loginuid=1000 command=less pid=7962 parent=systemctl file=>
Dec 07 12:11:48 kubenode.stack.com falco[7857]: 12:11:48.117445145: Error SUSPECIOUS FILE UNDER /etc WRITTEN!! (user=<NA> user_loginuid=-1 command=touch /etc/trojan.exe pid=8081 parent=sh p>
[root@kubenode falco]# journalctl -f -n -u falco | grep trojan
Dec 07 12:11:48 kubenode.stack.com falco[7857]: 12:11:48.117445145: Error SUSPECIOUS FILE UNDER /etc WRITTEN!! (user=<NA> user_loginuid=-1 command=touch /etc/trojan.exe pid=8081 parent=sh pcmdline=sh -c touch /etc/trojan.exe; sleep 1d file=/etc/trojan.exe program=touch gparent=<NA> ggparent=<NA> gggparent=<NA> container_id=3cfe86f47e41 image=<NA>)
You can also further update the logging output with specific fields to be written. For a complete list of fields that are supported by Falco refer Falco Supported Fields.
Hope you enjoyed reading this article. Thank you..
Leave a Reply
You must be logged in to post a comment.