CoursesAdvanced Linux securityDetection engineering

Falco on bare hosts

The k8s runtime tool, minus the k8s.

Advanced12 min · lesson 12 of 17

Falco is the CNCF runtime security tool you met in the Kubernetes and container courses, and it works just as well on a bare Linux host — it taps kernel events (via eBPF) and matches them against behaviour rules in real time, alerting the instant something matches. On a host, that means detecting the exact attacker behaviours from the earlier lessons — a shell spawned by a service, a write under a binary directory, a sensitive file read, an outbound connection from a process that should only listen — as they happen, not on the next scheduled scan.

WHERE FALCO FITS: THREE LAYERS
State (point-in-time)
osquery
query & diff fleet state on a schedule
History (durable)
Audit pipeline
off-host record that survives the host
Live (real-time)
Falco
eBPF kernel events matched to rules
Fires the instant behavior matches
shell from a service, write to persistence path
Together they cover state, history, and live events; Falco's alerts feed the same off-host pipeline to be correlated and triaged.
falco rule
- rule: Shell spawned by a service account
desc: A shell was launched by a process that should never need one
condition: >
spawned_process and shell_procs
and proc.pname in (nginx, httpd, postgres, mysqld)
output: >
Service spawned a shell (parent=%proc.pname cmd=%proc.cmdline
user=%user.name)
priority: CRITICAL

Host rules, not just container rules

Falco ships with a ruleset aimed at containers and Kubernetes, but the same engine and rule language cover host concerns directly: writes to /etc/passwd or /etc/shadow, new files in /etc/cron.d, modifications to authorized_keys, loading a kernel module, execution from /tmp, a process reading many home directories’ SSH keys. You write rules keyed to the persistence and escalation techniques you studied, so the theory becomes live detection: the LD_PRELOAD file appearing, the SUID binary being created, the credential hunt running.

falco_rules.local.yaml
- rule: Persistence file modified
desc: A common persistence location was written
condition: >
(evt.type in (open,openat) and evt.is_open_write=true)
and (fd.name startswith /etc/cron or fd.name endswith authorized_keys
or fd.name = /etc/ld.so.preload)
output: "Persistence location written (file=%fd.name proc=%proc.cmdline user=%user.name)"
priority: CRITICAL

Where Falco fits

Falco is your real-time behavioural layer, complementing the others: osquery answers point-in-time and diff questions across the fleet, the audit pipeline provides the durable off-host record, and Falco fires immediately when a watched behaviour occurs. Together they cover state, history, and live events. Falco’s alerts feed the same pipeline — shipped off-host, correlated, and triaged — and its rules are the front line of turning "we know how attackers behave" into "we get paged when they do."

Tune before you deploy, or the alerts get muted
Falco’s default rules on a busy host are noisy — package managers, cron, admin sessions all trip generic rules — and a noisy detector gets its alerts ignored or silenced, which is worse than no detector. Override in a local rules file (never edit the shipped rules; they are overwritten on upgrade), key on behaviours attackers cannot cheaply avoid, add exceptions for your known-good processes, and route low-signal rules to a dashboard while paging only on the short, rehearsed list. A tuned Falco is a tripwire; an untuned one is muted within a week.