Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ tasks:
validate-falco-rules:
desc: Validate custom Falco rules with the Falco binary via Docker
vars:
FALCO_IMAGE: '{{.FALCO_IMAGE | default "falcosecurity/falco:0.43.1"}}'
FALCO_IMAGE: '{{.FALCO_IMAGE | default "falcosecurity/falco:0.45.0"}}'
cmds:
- |
docker run --rm \
Expand Down Expand Up @@ -191,7 +191,7 @@ tasks:
- bash tools/oo-alerts.sh import

install-falco-system:
desc: Install Falco 0.43.1 system-wide to /usr/bin/falco and /etc/falco (requires sudo)
desc: Install Falco 0.45.0 system-wide to /usr/bin/falco and /etc/falco (requires sudo)
cmds:
- bash scripts/install-falco-system.sh

Expand Down
162 changes: 72 additions & 90 deletions docs/falco-host-install.md
Original file line number Diff line number Diff line change
@@ -1,139 +1,119 @@
# Falco Host Installation & LocalObserve Pipeline Integration

This guide documents the procedures for installing Falco 0.43.1 on Linux host systems, verifying package integrity, configuring kernel telemetry outputs, and integrating with the LocalObserve observability pipeline.
This guide documents the procedures for installing Falco 0.45.0 on Linux host systems, verifying package integrity, configuring kernel telemetry outputs, and integrating with the LocalObserve observability pipeline.

---

## 1. Overview & Distribution Discovery

Falco is a kernel runtime security tool that uses eBPF or a kernel module to monitor system call events. In LocalObserve, Falco acts as a host kernel telemetry generator alongside osquery.
Falco is a kernel runtime security tool that uses eBPF (modern_ebpf) or a kernel module to monitor system call events. In LocalObserve, Falco acts as a host kernel telemetry generator alongside osquery.

LocalObserve supports two deployment models:
1. **Host-Native Falco** (*Recommended for Linux endpoints*): Falco runs as a systemd service (`falco-modern-bpf.service`), writing events to `/var/log/falco/events.jsonl`, which is bind-mounted into the OpenTelemetry Collector container.
2. **Containerized Falco**: Pinned to `falcosecurity/falco:0.45.0`, opt-in via `--profile agents`.

> [!IMPORTANT]
> **Binary Package Source**: Official Falco Linux binary tarballs are distributed via `https://download.falco.org/packages/bin/` rather than directly on GitHub release pages (where assets are restricted to debug symbols and source packages).
> **Package Sources**: Official Falco Linux binary tarballs are distributed via `https://download.falco.org/packages/bin/`. Official Debian/Ubuntu APT packages are hosted at `https://download.falco.org/packages/deb`.

### Release Details
- **Version**: `0.43.1`
- **Version**: `0.45.0`
- **Architecture**: `x86_64`
- **Tarball URL**: `https://download.falco.org/packages/bin/x86_64/falco-0.43.1-x86_64.tar.gz`
- **Expected SHA256**: `c9dd114b19028f473f04860d89f841e879fa21d53e2b312123f5885934b58095`
- **Tarball URL**: `https://download.falco.org/packages/bin/x86_64/falco-0.45.0-x86_64.tar.gz`
- **Expected SHA256**: `6c8c591089db4ccf815c1761be28109b46f2c14d462a8414abcdd282249aeefe`

---

## 2. Integrity Verification & Extraction
## 2. Installation Methods

### Method A: Official APT Repository (Recommended on Ubuntu / Debian)

Before installing or running Falco, always verify the SHA256 checksum of the downloaded archive.
On modern Ubuntu (22.04 LTS / 24.04 LTS):

```bash
# 1. Download official archive
mkdir -p /tmp/falco-install
cd /tmp/falco-install
curl -SLO https://download.falco.org/packages/bin/x86_64/falco-0.43.1-x86_64.tar.gz
# 1. Trust Falco signing key
curl -fsSL https://falco.org/repo/falcosecurity-packages.asc | \
sudo gpg --dearmor -o /usr/share/keyrings/falco-archive-keyring.gpg

# 2. Verify SHA256 checksum
echo "c9dd114b19028f473f04860d89f841e879fa21d53e2b312123f5885934b58095 falco-0.43.1-x86_64.tar.gz" | sha256sum --check -
# 2. Configure Falco APT repository
echo "deb [signed-by=/usr/share/keyrings/falco-archive-keyring.gpg] https://download.falco.org/packages/deb stable main" | \
sudo tee /etc/apt/sources.list.d/falcosecurity.list

# 3. Extract contents
tar -xzf falco-0.43.1-x86_64.tar.gz
# 3. Update and install falco
sudo apt update
sudo apt install -y falco
```

---

## 3. User-Local Installation (Development & Testing)

For non-root development or testing environments where `sudo` access is restricted, install Falco into user-local directory structures (`~/.local` and `~/.config`).

### Step-by-Step User-Local Setup

After installing via APT, run the LocalObserve output and permission wiring script:
```bash
# Create local directory paths
mkdir -p ~/.local/bin ~/.config/falco

# Copy executable binary
cp falco-0.43.1-x86_64/usr/bin/falco ~/.local/bin/

# Copy default rules & configuration templates
cp -r falco-0.43.1-x86_64/etc/falco/* ~/.config/falco/

# Verify binary execution & version
~/.local/bin/falco --version
sudo bash scripts/install-falco-system.sh --config-only
```

### Validating Rules & Configuration
### Method B: Binary Tarball Installation

To validate rules or test syntax using user-local configuration files:
Before installing or running Falco from tarball, verify the SHA256 checksum:

```bash
~/.local/bin/falco -c falco-config.yaml -r ~/.config/falco/falco_rules.yaml --list rules
```

---
# 1. Download official archive
mkdir -p /tmp/falco-install
cd /tmp/falco-install
curl -SLO https://download.falco.org/packages/bin/x86_64/falco-0.45.0-x86_64.tar.gz

## 4. System-Wide Installation (Production Host Deployment)
# 2. Verify SHA256 checksum
echo "6c8c591089db4ccf815c1761be28109b46f2c14d462a8414abcdd282249aeefe falco-0.45.0-x86_64.tar.gz" | sha256sum --check -

For production Linux endpoints requiring continuous system call monitoring via systemd and eBPF:
# 3. Extract contents
tar -xzf falco-0.45.0-x86_64.tar.gz

```bash
# 1. Move binary to system path
sudo cp falco-0.43.1-x86_64/usr/bin/falco /usr/bin/falco
# 4. Install binary and rules to system paths
sudo cp falco-0.45.0-x86_64/usr/bin/falco /usr/bin/falco
sudo chmod 755 /usr/bin/falco

# 2. Install system configuration & rules
sudo mkdir -p /etc/falco /var/log/falco
sudo cp -r falco-0.43.1-x86_64/etc/falco/* /etc/falco/
sudo cp -r falco-0.45.0-x86_64/etc/falco/* /etc/falco/

# 3. Configure modern_ebpf engine in /etc/falco/falco.yaml
sudo sed -i 's/kind: .*/kind: modern_ebpf/' /etc/falco/falco.yaml
# 5. Wire output configuration and permissions
sudo bash scripts/install-falco-system.sh --config-only
```

# 4. Enable JSON file output for LocalObserve ingestion
sudo cat << 'EOF' | sudo tee /etc/falco/config.d/localobserve-output.yaml
json_output: true
file_output:
enabled: true
filename: /var/log/falco/events.jsonl
EOF
---

# 5. Verify system configuration
falco --list rules
```
## 3. Host Systemd & Permission Integration

### Systemd Service Configuration
### The UMask & Permission Requirement

Create `/etc/systemd/system/falco.service`:
By default, upstream Falco systemd units (`falco-modern-bpf.service` / `falco.service`) specify `UMask=0077`. This causes `/var/log/falco/events.jsonl` to be created with `0600` (root-only) permissions.

```ini
[Unit]
Description=Falco Kernel Security Telemetry Collector
Documentation=https://falco.org/docs/
After=network.target
The OpenTelemetry Collector container runs unprivileged as UID `10001:10001`. If `/var/log/falco/events.jsonl` is `0600`, the collector logs `permission denied` and cannot ingest detections.

The `scripts/install-falco-system.sh` script automatically applies a systemd drop-in override:
`/etc/systemd/system/falco-modern-bpf.service.d/localobserve-umask.conf`:
```ini
[Service]
Type=simple
ExecStart=/usr/bin/falco -c /etc/falco/falco.yaml
Restart=on-failure
RestartSec=5s
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
UMask=0022
```

Enable and start the service:
This guarantees that `events.jsonl` is created with mode `0644` (world-readable), enabling seamless collector ingestion.

```bash
sudo systemctl daemon-reload
sudo systemctl enable --now falco
### LocalObserve Output Configuration

The script places `/etc/falco/config.d/localobserve-output.yaml`:
```yaml
json_output: true
priority: warning
file_output:
enabled: true
filename: /var/log/falco/events.jsonl
```

---

## 5. LocalObserve Pipeline Integration
## 4. LocalObserve Pipeline Integration

Falco events flow through the LocalObserve security pipeline as follows:

```
┌──────────────────┐ JSON Lines ┌──────────────────────┐ OTTL / OTLP ┌──────────────────┐
│ Falco Daemon │ ─────────────────> │ OTel Collector │ ─────────────────> │ OpenObserve │
│ (host/container)│ .data/falco/ │ (filelog receiver) │ │ Stream: falco │
│ (host/container)│ /var/log/falco/ │ (filelog receiver) │ │ Stream: falco │
└──────────────────┘ events.jsonl └──────────────────────┘ └──────────────────┘
│
│ Rule Matching
Expand All @@ -144,16 +124,18 @@ Falco events flow through the LocalObserve security pipeline as follows:
└──────────────────────┘ └──────────────────┘
```

1. **Log Location**: Falco writes structured JSON security events to `./.data/falco/events.jsonl`.
2. **OTel Collector Ingestion**: The OTel Collector `filelog/falco` receiver tails this file, parses JSON attributes, and assigns `log_type: falco`.
1. **Log Location**: Falco writes structured JSON security events to `/var/log/falco/events.jsonl` on the host (bind-mounted into the collector container at `/var/log/falco-host`).
2. **OTel Collector Ingestion**: The OTel Collector `file_log/falco` receiver tails this file, parses JSON attributes, and assigns resource attributes (`log.source: falco-file`, `service.name: falco`).
3. **Pipeline Mapping**: `rules/sigma/pipelines/localobserve_pipeline.yaml` maps Falco's `output_fields.proc.cmdline` and process fields to Sigma standard schema names.
4. **rsigma Detection & Alerts**: rsigma ingests process/kernel events, evaluates active Sigma rules (such as `rules/sigma/active_rules/suspicious_unshare.yaml`), and issues HTTP POST webhooks to the `alert-receiver` service upon detection.
4. **rsigma Detection & Alerts**: rsigma ingests process/kernel events, evaluates active Sigma rules, and issues HTTP POST webhooks to the `alert-receiver` service upon detection.

---

## 6. Verification Checklist
## 5. Verification Checklist

- [x] Falco binary verified with SHA256 (`c9dd114b19028f473f04860d89f841e879fa21d53e2b312123f5885934b58095`).
- [x] `--version` returns `0.43.1`.
- [x] Config schema validation succeeds with `falco -c falco-config.yaml`.
- [x] Integration tests pass with `uv run pytest --run-stack tests/test_rsigma_alerts.py`.
- [x] Falco binary verified with version `0.45.0`.
- [x] Service running via modern eBPF: `systemctl status falco-modern-bpf.service`.
- [x] Systemd UMask drop-in applied: `/etc/systemd/system/falco-modern-bpf.service.d/localobserve-umask.conf`.
- [x] Log file permissions verified: `-rw-r--r-- 1 root root ... /var/log/falco/events.jsonl`.
- [x] Collector tailing confirmed: OpenTelemetry Collector logs `"Started watching file /var/log/falco-host/events.jsonl"`.
- [x] End-to-end detection verified: running `cat /etc/shadow` creates a `Read sensitive file untrusted` event appearing in OpenObserve's `falco` stream.
45 changes: 35 additions & 10 deletions scripts/install-falco-system.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
# install-falco-system.sh — System-wide installation script for Falco 0.43.1
# install-falco-system.sh — System-wide installation and wiring script for Falco 0.45.0
#
# Modes:
# (no args) — full tarball install (binary + configs + drop-in)
Expand All @@ -9,13 +9,37 @@
# Usage: sudo bash scripts/install-falco-system.sh --config-only
set -euo pipefail

TARBALL="/tmp/falco-install/falco-0.43.1-x86_64.tar.gz"
EXPECTED_SHA="c9dd114b19028f473f04860d89f841e879fa21d53e2b312123f5885934b58095"
FALCO_VERSION="0.45.0"
TARBALL="/tmp/falco-install/falco-${FALCO_VERSION}-x86_64.tar.gz"
EXPECTED_SHA="6c8c591089db4ccf815c1761be28109b46f2c14d462a8414abcdd282249aeefe"

FALCO_OUTPUT_DIR="/var/log/falco"
FALCO_CONFIG_DROPIN="/etc/falco/config.d/localobserve-output.yaml"
FALCO_SERVICES=(falco-modern-bpf falco)

write_systemd_dropin() {
# Upstream systemd units default to UMask=0077, creating events.jsonl
# with 0600 permissions. The unprivileged OpenTelemetry Collector (UID 10001)
# tails this file via bind mount and gets permission denied unless
# permissions are readable. UMask=0022 allows 0644 creation.
local svc
for svc in "${FALCO_SERVICES[@]}"; do
local dropin_dir="/etc/systemd/system/${svc}.service.d"
sudo mkdir -p "$dropin_dir"
sudo tee "${dropin_dir}/localobserve-umask.conf" > /dev/null << 'EOF'
[Service]
UMask=0022
EOF
done
sudo chmod 755 "$FALCO_OUTPUT_DIR" 2>/dev/null || true
if [ -f "${FALCO_OUTPUT_DIR}/events.jsonl" ]; then
sudo chmod 644 "${FALCO_OUTPUT_DIR}/events.jsonl" 2>/dev/null || true
fi
if command -v systemctl >/dev/null 2>&1; then
sudo systemctl daemon-reload 2>/dev/null || true
fi
}

write_localobserve_output_config() {
# Distro falco.yaml defaults (json_output: false, priority: debug,
# file_output disabled) combined with systemd StandardOutput=null mean
Expand All @@ -33,12 +57,13 @@ file_output:
enabled: true
filename: /var/log/falco/events.jsonl
EOF
write_systemd_dropin
}

restart_falco() {
local svc
for svc in "${FALCO_SERVICES[@]}"; do
if systemctl list-unit-files 2>/dev/null | grep -q "^${svc}\.service"; then
if command -v systemctl >/dev/null 2>&1 && (systemctl cat "${svc}.service" >/dev/null 2>&1 || systemctl list-unit-files --no-pager 2>/dev/null | grep -q "^${svc}\.service"); then
sudo systemctl restart "$svc"
echo "[+] Restarted ${svc}; host Falco now writes JSON to ${FALCO_OUTPUT_DIR}/events.jsonl"
return 0
Expand All @@ -63,9 +88,9 @@ if [ "${1:-}" = "--config-only" ]; then
fi

if [ ! -f "$TARBALL" ]; then
echo "[*] Downloading Falco 0.43.1..."
echo "[*] Downloading Falco ${FALCO_VERSION}..."
mkdir -p /tmp/falco-install
curl -SL -o "$TARBALL" https://download.falco.org/packages/bin/x86_64/falco-0.43.1-x86_64.tar.gz
curl -SL -o "$TARBALL" "https://download.falco.org/packages/bin/x86_64/falco-${FALCO_VERSION}-x86_64.tar.gz"
fi

echo "[*] Verifying SHA256 integrity..."
Expand All @@ -75,17 +100,17 @@ echo "[*] Extracting..."
tar -xzf "$TARBALL" -C /tmp/falco-install

echo "[*] Installing binary and configurations to system paths (requires sudo)..."
sudo cp /tmp/falco-install/falco-0.43.1-x86_64/usr/bin/falco /usr/bin/falco
sudo cp "/tmp/falco-install/falco-${FALCO_VERSION}-x86_64/usr/bin/falco" /usr/bin/falco
sudo chmod 755 /usr/bin/falco

sudo mkdir -p /etc/falco /var/log/falco
sudo cp -r /tmp/falco-install/falco-0.43.1-x86_64/etc/falco/* /etc/falco/
sudo cp -r "/tmp/falco-install/falco-${FALCO_VERSION}-x86_64/etc/falco/"* /etc/falco/

# Enable modern_ebpf engine
sudo sed -i 's/kind: .*/kind: modern_ebpf/' /etc/falco/falco.yaml 2>/dev/null || true

# Enable JSON file output for LocalObserve ingestion
# Enable JSON file output and systemd drop-in permissions for LocalObserve ingestion
write_localobserve_output_config

echo "[+] Falco 0.43.1 installed system-wide successfully!"
echo "[+] Falco ${FALCO_VERSION} installed system-wide successfully!"
/usr/bin/falco --version || true
15 changes: 13 additions & 2 deletions tests/test_falco_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def test_falco_config_disables_unused_syslog_output(falco_config: dict) -> None:
def test_falco_custom_rules_validate_with_docker() -> None:
"""Run falco --list rules in Docker to validate our custom rules parse.

Uses the same falco version as docker-compose (0.43.1). The falco binary
Uses the same falco version as docker-compose (0.45.0). The falco binary
prints rule names to stdout and deprecation warnings to stderr; we only
require exit code 0 (no parse errors).
"""
Expand All @@ -83,7 +83,7 @@ def test_falco_custom_rules_validate_with_docker() -> None:
"docker", "run", "--rm",
"-v", f"{rules_file}:/rules/custom.yaml:ro",
"--entrypoint", "/usr/bin/falco",
"falcosecurity/falco:0.43.1",
"falcosecurity/falco:0.45.0",
"-r", "/rules/custom.yaml",
"--list", "rules",
],
Expand All @@ -97,3 +97,14 @@ def test_falco_custom_rules_validate_with_docker() -> None:
f"Falco rule validation failed (exit {result.returncode}):\n"
f"stderr: {result.stderr[:500]}"
)


def test_falco_install_system_script_configures_umask_and_output() -> None:
"""scripts/install-falco-system.sh must configure UMask=0022 and JSON output."""
script_path = REPO_ROOT / "scripts" / "install-falco-system.sh"
content = script_path.read_text(encoding="utf-8")

assert "UMask=0022" in content
assert "localobserve-umask.conf" in content
assert "json_output: true" in content
assert "0.45.0" in content
Loading