Falco and Tetragon are the two leading open-source runtime security tools built on eBPF. They observe syscalls, network activity, and process behavior at the kernel level, then evaluate that telemetry against detection policies. Falco came out of Sysdig and is a CNCF graduated project oriented around alerting on policy violations. Tetragon comes from Isovalent (the Cilium team) and emphasizes deep observability and in-kernel enforcement. They serve overlapping but distinct purposes, and running them together gives you both broad rule-based alerting and targeted policy enforcement. This guide deploys both on a single RamNode VPS for host-level runtime security.
Sizing, Kernel Requirements, and Prerequisites
eBPF is a kernel feature, and the version of the kernel matters more than RAM here. Confirm what you have:
uname -rYou want 5.10 or later for Falco's modern eBPF probe, and 5.10 or later for Tetragon. Ubuntu 24.04 LTS ships with 6.8, which is ideal. Ubuntu 22.04 ships with 5.15, which works for both. Anything older needs a HWE kernel or an upgrade.
Plan the following on RamNode:
- 2 GB RAM minimum for a host-only deployment
- 2 vCPU minimum
- 20 GB disk; eBPF tooling itself is small but you need room for logs
- Ubuntu 24.04 LTS
The eBPF overhead is generally low (single-digit percent CPU under normal load), but a noisy ruleset on a busy host can spike. Plan to tune.
Initial Setup
Update the base system:
apt update && apt -y full-upgrade
apt -y install ufw curl gnupg2 software-properties-common dkms build-essentialInstall kernel headers, which Falco needs for some probe modes:
apt -y install linux-headers-$(uname -r)Configure the firewall. Neither tool requires inbound ports unless you expose their gRPC or metrics endpoints externally, which you should not:
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
ufw --force enableInstalling Falco
The Falcosecurity project maintains an apt repository. Add it and install:
curl -fsSL https://falco.org/repo/falcosecurity-packages.asc \
| gpg --dearmor -o /usr/share/keyrings/falco-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/falco-archive-keyring.gpg] \
https://download.falco.org/packages/deb stable main" \
| tee /etc/apt/sources.list.d/falcosecurity.list
apt update
apt -y install falcoThe installer will prompt for the driver type. Choose modern-bpf if you are on a 5.8+ kernel (which you should be on 24.04). The modern eBPF probe is the recommended path and does not require kernel module compilation or BCC.
If you accidentally selected a different driver during the prompt, you can change it later:
falcoctl driver config --type modern_ebpfStart Falco and confirm it is running:
systemctl enable --now falco-modern-bpf
systemctl status falco-modern-bpfNote the unit name reflects the driver. If you selected the kernel module driver, the unit is falco-kmod instead.
Falco Rule Configuration
Falco ships with a default ruleset at /etc/falco/falco_rules.yaml. Do not edit that file directly; it gets overwritten on package upgrade. Local overrides and additions go in /etc/falco/falco_rules.local.yaml.
The default rules catch a lot of useful behavior: writes to sensitive paths, shell spawned by web servers, container escape patterns, and so on. For a non-Kubernetes host, disable the container-specific rules to cut noise:
/etc/falco/falco_rules.local.yaml:
- macro: container
condition: (container.id != host)
override:
condition: replace
- rule: Disallowed SSH Connection
desc: Detect any new SSH connection to a host other than those in an allowed group
condition: >
inbound_outbound and ssh_port and not allowed_ssh_hosts
output: >
Disallowed SSH Connection (command=%proc.cmdline connection=%fd.name
user=%user.name container_id=%container.id image=%container.image.repository)
priority: NOTICE
tags: [network]
- list: allowed_ssh_hosts
items: [your.bastion.ip.here]Reload Falco after rule changes:
systemctl reload falco-modern-bpfValidate that the rule loaded:
falco --validate /etc/falco/falco_rules.local.yamlFalco Output Configuration
By default, Falco writes alerts to syslog and stdout. For production, you want at least one structured sink. Edit /etc/falco/falco.yaml:
json_output: true
json_include_output_property: true
json_include_tags_property: true
log_level: info
stdout_output:
enabled: true
file_output:
enabled: true
keep_alive: false
filename: /var/log/falco/events.json
http_output:
enabled: true
url: https://your-siem.example.org/falco
user_agent: "falco/0.39"
insecure: false
ca_cert: /etc/ssl/certs/ca-certificates.crt
echo: falseCreate the log directory and restart:
mkdir -p /var/log/falco
systemctl restart falco-modern-bpfFor Slack or webhook alerting without writing a custom sink, deploy falcosidekick. It is a small Go service that takes Falco's gRPC output and fans it out to dozens of destinations. Install via apt from the same repo:
apt -y install falcosidekickConfigure /etc/falco/falcosidekick.yaml with your destination of choice (Slack, PagerDuty, OpenObserve, Loki, and so on). Falcosidekick documentation lists the per-destination config keys.
Installing Tetragon
Tetragon ships as a static binary and a systemd unit. The official install path is via tarball:
TETRAGON_VERSION=v1.4.1
cd /tmp
curl -LO "https://github.com/cilium/tetragon/releases/download/${TETRAGON_VERSION}/tetragon-${TETRAGON_VERSION}-amd64.tar.gz"
tar -xzf "tetragon-${TETRAGON_VERSION}-amd64.tar.gz"
cd "tetragon-${TETRAGON_VERSION}-amd64"
./install.shThe installer drops the binary at /usr/local/bin/tetragon, the CLI at /usr/local/bin/tetra, default policies at /etc/tetragon/, and a systemd unit. Start the service:
systemctl enable --now tetragon
systemctl status tetragonVerify Tetragon is producing events:
tetra getevents -o compactOpen another shell on the VPS and run something benign like ls /etc. You should see the process exec event appear in the tetra output stream within a second.
Writing TracingPolicies for Tetragon
Tetragon's detection logic lives in TracingPolicy custom resources. On a non-Kubernetes host, these are YAML files in /etc/tetragon/tetragon.conf.d/ or loaded via the CLI. A useful starter policy that catches suspicious binary execution from world-writable directories:
/etc/tetragon/tetragon.conf.d/exec-from-tmp.yaml:
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
name: "exec-from-tmp"
spec:
kprobes:
- call: "security_bprm_check"
syscall: false
args:
- index: 0
type: "linux_binprm"
selectors:
- matchArgs:
- index: 0
operator: "Prefix"
values:
- "/tmp/"
- "/var/tmp/"
- "/dev/shm/"
matchActions:
- action: PostReload Tetragon to pick up the policy:
systemctl restart tetragonTest by copying a binary to /tmp and running it:
cp /bin/ls /tmp/testbin && /tmp/testbin
tetra getevents -o compact | headYou should see the exec event flagged.
How Falco and Tetragon Complement Each Other
The natural question is whether you need both. The answer for most production deployments is yes, for these reasons:
Falco has a mature, community-maintained ruleset that covers the common attack patterns out of the box. The rules are written in a high-level DSL, the alerts are easy to triage, and the ecosystem (Falcosidekick, response actions, third-party integrations) is broad.
Tetragon has lower overhead for high-volume event collection, supports in-kernel filtering and enforcement (it can kill a process from kernel space, not just alert on it), and produces more granular event data including full argument capture for tracked syscalls. The policy language is lower-level, which is more work but gives you more precision.
Running both, Falco handles the breadth (default detection coverage) and Tetragon handles the depth (targeted high-fidelity policies for the highest-value detections, plus enforcement where appropriate).
Performance Tuning
Both tools have low default overhead, but a noisy ruleset can change that. Monitor both:
systemctl status falco-modern-bpf
systemctl status tetragon
ps -p $(pgrep -x falco) -o pcpu,pmem,rss
ps -p $(pgrep -x tetragon) -o pcpu,pmem,rssFalco exposes metrics on a Prometheus endpoint. Enable in /etc/falco/falco.yaml:
metrics:
enabled: true
interval: 1h
output_rule: true
rules_counters_enabled: true
resource_utilization_enabled: true
webserver:
enabled: true
listen_port: 8765
ssl_enabled: false
threadiness: 0
prometheus_metrics_enabled: trueTetragon exposes Prometheus metrics by default at port 2112. Scrape both from your existing Prometheus.
The key metrics to alert on:
- Falco
falco_n_dropsrising (eBPF buffer overflows) - Falco rule evaluation latency on hot rules
- Tetragon
tetragon_msg_op_totalrate spikes - CPU and RSS of both daemons
Log Shipping
Falco's JSON output and Tetragon's event stream both need to leave the host to be useful for forensic timelines. Tetragon supports a built-in JSON file exporter; enable it in /etc/tetragon/tetragon.yaml:
export-filename: /var/log/tetragon/tetragon.log
export-file-perm: "600"
export-file-max-size-mb: 100
export-file-max-backups: 5
export-file-compress: trueRestart Tetragon. Then use Vector, Filebeat, or Fluent Bit to ship both Falco's /var/log/falco/events.json and Tetragon's /var/log/tetragon/tetragon.log to your SIEM. A Vector source block for both:
sources:
falco:
type: file
include: [/var/log/falco/events.json]
read_from: end
tetragon:
type: file
include: [/var/log/tetragon/tetragon.log]
read_from: endOperational Hygiene
Both tools touch the kernel and both will keep running through a graceful upgrade, but kernel upgrades require driver compatibility checks. After any kernel upgrade:
falco --version
tetragon --version
systemctl status falco-modern-bpf tetragonThe modern_bpf driver and Tetragon's eBPF programs are CO-RE (compile once, run everywhere), so they survive most kernel upgrades. If you are on the kernel module driver for Falco, you need to rebuild after every kernel change.
Set up alerts for:
- Either service in failed state
- Driver load failure on boot (check journalctl for both units)
- Event drop counters non-zero
- Rule file syntax errors after edits (validate before reload)
What to Read Next
The natural progressions from here are detection engineering (writing custom Falco rules and Tetragon TracingPolicies for your specific threat model), response automation (using Falcosidekick to drive automated containment via webhook actions), and SOC integration (correlating runtime alerts with network telemetry from Suricata/Zeek and threat intel from MISP). Each of those is a substantial topic in its own right.
