Skip to content

About

Not the best implementation of falco on a linux workstation.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

12 Commits

Folders and files

Repository files navigation

falco-workstation-rules

Opinionated Falco rules and supporting configuration for a Linux developer workstation. Encodes ~3 months of false-positive tuning so a fresh Falco install is actually usable on a desktop instead of drowning you in alerts on day one.

Targets Lubuntu / XFCE / i3 with libvirt VMs, VS Code, Claude Code, and Google Chrome. Other desktop environments will need edits.


What it does

  • Custom CRITICAL detection for any process under the user's Claude Code install (including Bun worker threads and the VS Code extension subprocess) reading ~/.ssh/.
  • Custom WARNING detection for unauthorized reads of Claude Code's credentials, config, or settings files.
  • Targeted exceptions for the noisy upstream rules on a real workstation:
    • Write below root for virtiofsd / vring_worker (libvirt virtio-fs)
    • Write below etc for Chrome's daily cron rewriting /etc/default/google-chrome
    • Update Package Repository for Chrome's daily cron updating sources.list.d
    • Read sensitive file untrusted for i3lock, xfce4-screensaver, lightdm, pkexec, systemd-executor PAM access
    • Read ssh information for gnome-keyring-daemon and systemd-tmpfiles --clean
    • Set Setuid or Setgid bit for Chrome, VS Code, and dpkg postinst chmod
    • Modify binary dirs for VS Code package upgrades removing /usr/bin/code
    • Launch Suspicious Network Tool on Host for interactive dig and tcpdump
    • Unexpected UDP Traffic for Chrome, VS Code, opencode, Claude Code, dev tooling, fwupd, and APT
    • …and more (see comments in the rules template).
  • Exceptions are scoped by proc.exepath where possible to avoid trusting a renamed attacker binary that happens to share a process name.
  • Falcosidekick → Discord forwarding for warning+ priority alerts.
  • Falco webserver locked to 127.0.0.1.
  • logrotate config (weekly, 12 rotations, compressed) for /var/log/falco/alerts.json.

What it doesn't do

  • Not for containers or Kubernetes — workstation only.
  • Not for headless servers — assumes an X session, screen locker, GUI auth.
  • Not for GNOME/Wayland — written for XFCE/i3 specifically.
  • No per-file SPDX headers, no contributor model — internal use, not soliciting PRs.

Layout

.
├── LICENSE                                       Apache 2.0
├── NOTICE                                        attribution
├── README.md                                     this file
├── .gitignore
└── falco/
    ├── .env.example                              copy to .env, fill in
    ├── apply-rules.sh                            renders + validates + deploys
    ├── rules.d/
    │   ├── 00-trust.yaml.template                trustworthy_exe macro
    │   ├── 10-macro-overrides.yaml.template      upstream macro extensions
    │   ├── 20-claude-detection.yaml.template     custom Claude rules
    │   └── 30-rule-exceptions.yaml.template      upstream rule exceptions
    ├── falcosidekick.yaml.template               sidekick config (no secrets)
    ├── falcosidekick.service.d-override.conf     systemd drop-in for secrets
    ├── falco.workstation.yaml                    output field overrides
    ├── falco-alerts.logrotate                    log rotation
    ├── falco-healthcheck.sh                      periodic health check
    ├── falco-healthcheck.service                 oneshot systemd unit
    └── falco-healthcheck.timer                   runs health check every 6h

Trust gating

Every exception in rules.d/ is gated on the trustworthy_exe macro (proc.is_exe_from_memfd = false and proc.is_exe_upper_layer = false). A renamed-and-dropped attacker binary cannot ride into an allow-list entry just by sharing a process name with a trusted program: the kernel-tracked exec source has to be a regular on-disk file from the lower layer.

This is not a complete defense — an attacker who tampered with a binary at install time and waited will pass this check. Treat it as a tripwire against the trivial drop-and-exec bypass, not as an integrity guarantee.

Health check

falco-healthcheck.timer runs every 6 hours (and 5 min after boot) and verifies:

  • falco-modern-bpf.service is active
  • falcosidekick.service is active
  • /var/log/falco/alerts.json has been written to in the last 24h
  • Falco's HTTP healthz endpoint at 127.0.0.1:8765/healthz responds

On failure, it posts a single message to the configured Discord webhook and logs to journald. Designed to surface the day Falco silently dies.


Setup

Prerequisites:

  • Falco (tested against 0.43.x) installed and running as falco-modern-bpf.service.
  • Falcosidekick installed at /usr/local/bin/falcosidekick with a systemd service file.
  • envsubst (from gettext-base).
  • sudo access.

Steps:

cp falco/.env.example falco/.env
chmod 600 falco/.env
$EDITOR falco/.env       # fill in USERNAME, HOME_DIR, DISCORD_WEBHOOKURL
./falco/apply-rules.sh

apply-rules.sh:

  1. Loads .env (refuses to run if it's not mode 0600 or 0400).
  2. Renders the templates with envsubst to a tmpfs (whitelisted variables only — Falco's own %field.name syntax is untouched).
  3. Validates the rendered rules with falco --validate.
  4. Deploys to /etc/falco/, /etc/falcosidekick/, /etc/logrotate.d/.
  5. Reloads Falco via systemctl kill -s HUP.
  6. Restarts Falcosidekick.
  7. Verifies the deployed rules match the rendered source (drift check).

Re-run any time you edit the templates or .env.


Secrets

The Discord webhook URL is the only secret. It lives in .env (gitignored, mode 0600). At deploy time:

  • apply-rules.sh writes it to /etc/falco-secrets.env (mode 0600, root:root).
  • A systemd drop-in (/etc/systemd/system/falcosidekick.service.d/override.conf) loads that file as EnvironmentFile=.
  • Falcosidekick reads DISCORD_WEBHOOKURL from its environment.
  • The webhook never appears in /etc/falcosidekick/config.yaml or any file readable by non-root users.

If you fork this for a different sink (Slack, mattermost, etc.), the same pattern works — Falcosidekick reads almost every output's credentials from env vars.


Variables

Defined in .env (see .env.example):

Variable Description
USERNAME Linux user owning the home directory the rules protect
HOME_DIR Absolute home path; used in Claude/SSH detection rules
DISCORD_WEBHOOKURL Discord webhook URL — secret

Templated into the rules via envsubst. Other workstation assumptions (i3lock, xfce4-screensaver, lightdm, virtiofsd, libvirtd, fwupdmgr, etc.) are hardcoded in the rules template — fork and edit if your desktop differs.


License

Apache License 2.0 — see LICENSE and NOTICE.

About

Not the best implementation of falco on a linux workstation.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages