Aller au contenu

Fiche de référence Falco

Vue d’ensemble

Falco est un outil open-source de sécurité runtime qui détecte les comportements inattendus des applications et alerte sur les menaces en temps réel. Il utilise les appels système pour sécuriser et surveiller un système, en analysant les appels système Linux du noyau à l’exécution et en confrontant le flux à un moteur de règles puissant.

Fonctionnalités principales

  • Détection de menaces en temps réel : Surveillance en temps réel des appels système et des événements du noyau
  • Natif Kubernetes : Intégration profonde avec les environnements Kubernetes
  • Moteur de règles flexible : Règles personnalisables pour la détection de menaces
  • Plusieurs canaux de sortie : Alertes via syslog, fichiers, HTTP, gRPC, et plus encore
  • Support eBPF : Sonde eBPF moderne pour une surveillance du noyau efficace
  • Intégration Cloud-Native : Intégration avec les outils de l’écosystème CNCF

Would you like me to continue translating the subsequent sections?```bash

Download and install Falco

curl -s https://falco.org/repo/falcosecurity-3672BA8F.asc | apt-key add - echo “deb https://download.falco.org/packages/deb stable main” | tee -a /etc/apt/sources.list.d/falcosecurity.list apt-get update -y apt-get install -y falco

Start Falco service

systemctl enable falco systemctl start falco


### Package Manager Installation

```bash
# Ubuntu/Debian
curl -s https://falco.org/repo/falcosecurity-3672BA8F.asc | apt-key add -
echo "deb https://download.falco.org/packages/deb stable main" | tee -a /etc/apt/sources.list.d/falcosecurity.list
apt-get update
apt-get install falco

# RHEL/CentOS/Fedora
rpm --import https://falco.org/repo/falcosecurity-3672BA8F.asc
curl -s -o /etc/yum.repos.d/falcosecurity.repo https://falco.org/repo/falcosecurity-rpm.repo
yum install falco

# Arch Linux
yay -S falco

# macOS (Homebrew)
brew install falco

Container Installation

# Pull Falco image
docker pull falcosecurity/falco:latest

# Run Falco in container
docker run --rm -i -t \
    --privileged \
    -v /var/run/docker.sock:/host/var/run/docker.sock \
    -v /dev:/host/dev \
    -v /proc:/host/proc:ro \
    -v /boot:/host/boot:ro \
    -v /lib/modules:/host/lib/modules:ro \
    -v /usr:/host/usr:ro \
    -v /etc:/host/etc:ro \
    falcosecurity/falco:latest

Kubernetes Installation

# Install via Helm
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm repo update
helm install falco falcosecurity/falco

# Install via kubectl
kubectl apply -f https://raw.githubusercontent.com/falcosecurity/falco/master/deploy/kubernetes/falco-daemonset-configmap.yaml

# Verify installation
kubectl get pods -l app=falco
kubectl logs -l app=falco

eBPF Installation

# Install with eBPF probe
falco --modern-bpf

# Install eBPF probe manually
falco-driver-loader bpf

# Verify eBPF probe
lsmod | grep falco

Basic Usage

Running Falco

# Run Falco with default configuration
falco

# Run with specific configuration file
falco -c /etc/falco/falco.yaml

# Run with custom rules
falco -r /path/to/custom_rules.yaml

# Run in daemon mode
falco -d

# Run with specific output format
falco --json-output

Command Line Options

# Verbose output
falco -v

# Very verbose output
falco -vv

# Disable specific rule tags
falco -T filesystem,network

# Enable specific rule tags only
falco -t container,k8s_audit

# Dry run (validate configuration)
falco --dry-run

# Print supported fields
falco --list

# Print version information
falco --version

Configuration Files

# /etc/falco/falco.yaml
rules_file:
  - /etc/falco/falco_rules.yaml
  - /etc/falco/falco_rules.local.yaml
  - /etc/falco/k8s_audit_rules.yaml

time_format_iso_8601: false
json_output: false
json_include_output_property: true
json_include_tags_property: true

log_stderr: true
log_syslog: true
log_level: info

priority: debug

buffered_outputs: false
outputs:
  rate: 1
  max_burst: 1000

syslog_output:
  enabled: true

file_output:
  enabled: false
  keep_alive: false
  filename: ./events.txt

stdout_output:
  enabled: true

webserver:
  enabled: true
  listen_port: 8765
  k8s_healthz_endpoint: /healthz
  ssl_enabled: false

grpc:
  enabled: false
  bind_address: "0.0.0.0:5060"
  threadiness: 8

grpc_output:
  enabled: false

Rules and Detection

Default Rules

# Container rules
- rule: Terminal shell in container
  desc: A shell was used as the entrypoint/exec point into a container with an attached terminal.
  condition: >
    spawned_process and container
    and shell_procs and proc.tty != 0
    and container_entrypoint
  output: >
    A shell was spawned in a container with an attached terminal (user=%user.name %container.info
    shell=%proc.name parent=%proc.pname cmdline=%proc.cmdline terminal=%proc.tty container_id=%container.id image=%container.image.repository)
  priority: NOTICE
  tags: [container, shell, mitre_execution]

- rule: File below /etc opened for writing
  desc: an attempt to write to any file below /etc
  condition: open_write and fd.typechar='f' and fd.name startswith /etc
  output: "File below /etc opened for writing (user=%user.name command=%proc.cmdline file=%fd.name parent=%proc.pname pcmdline=%proc.pcmdline gparent=%proc.aname[2])"
  priority: ERROR
  tags: [filesystem, mitre_persistence]

Custom Rules

# custom_rules.yaml
- rule: Detect cryptocurrency mining
  desc: Detect cryptocurrency mining activities
  condition: >
    spawned_process and
    (proc.name in (xmrig, cpuminer, ccminer, cgminer, bfgminer) or
     proc.cmdline contains "stratum+tcp" or
     proc.cmdline contains "mining.pool" or
     proc.cmdline contains "--donate-level")
  output: >
    Cryptocurrency mining detected (user=%user.name command=%proc.cmdline
    container=%container.info image=%container.image.repository)
  priority: CRITICAL
  tags: [cryptocurrency, mining, malware]

- rule: Suspicious network activity
  desc: Detect suspicious network connections
  condition: >
    inbound_outbound and
    (fd.rip in (suspicious_ips) or
     fd.rport in (4444, 5555, 6666, 7777, 8888, 9999) or
     fd.rip startswith "10.0.0" and fd.rport = 22)
  output: >
    Suspicious network activity detected (user=%user.name command=%proc.cmdline
    connection=%fd.rip:%fd.rport direction=%evt.type container=%container.info)
  priority: WARNING
  tags: [network, suspicious]

- rule: Privilege escalation attempt
  desc: Detect privilege escalation attempts
  condition: >
    spawned_process and
    (proc.name in (sudo, su, pkexec, doas) or
     proc.cmdline contains "chmod +s" or
     proc.cmdline contains "setuid" or
     proc.cmdline contains "setgid")
  output: >
    Privilege escalation attempt detected (user=%user.name command=%proc.cmdline
    parent=%proc.pname container=%container.info)
  priority: HIGH
  tags: [privilege_escalation, mitre_privilege_escalation]

Kubernetes Audit Rules

# k8s_audit_rules.yaml
- rule: K8s Secret Created
  desc: Detect any attempt to create a secret
  condition: ka and secret and kcreate
  output: K8s Secret Created (user=%ka.user.name verb=%ka.verb name=%ka.target.name reason=%ka.reason)
  priority: INFO
  source: k8s_audit
  tags: [k8s]

- rule: K8s Secret Deleted
  desc: Detect any attempt to delete a secret
  condition: ka and secret and kdelete
  output: K8s Secret Deleted (user=%ka.user.name verb=%ka.verb name=%ka.target.name reason=%ka.reason)
  priority: WARNING
  source: k8s_audit
  tags: [k8s]

- rule: K8s ConfigMap Modified
  desc: Detect any attempt to modify a configmap
  condition: ka and configmap and kmodify
  output: K8s ConfigMap Modified (user=%ka.user.name verb=%ka.verb name=%ka.target.name reason=%ka.reason)
  priority: WARNING
  source: k8s_audit
  tags: [k8s]

Advanced Configuration

Output Channels

# HTTP Output
http_output:
  enabled: true
  url: "http://webhook.example.com/falco"
  user_agent: "falcosecurity/falco"

# gRPC Output
grpc_output:
  enabled: true
  address: "grpc-server:5060"
  tls: true
  cert: "/etc/ssl/certs/client.crt"
  key: "/etc/ssl/private/client.key"
  ca: "/etc/ssl/certs/ca.crt"

# Program Output
program_output:
  enabled: true
  keep_alive: false
  program: "jq '{text: .output}' | curl -d @- -X POST https://hooks.slack.com/services/XXX"

Performance Tuning

# Performance configuration
syscall_event_drops:
  actions:
    - log
    - alert
  rate: 0.03333
  max_burst: 10

syscall_event_timeouts:
  max_consecutives: 1000

metadata_download:
  max_mb: 100
  chunk_wait_us: 1000
  watch_freq_sec: 1

base_syscalls:
  custom_set: []
  repair: false

Rule Conditions and Macros

# Macros for reusable conditions
- macro: container
  condition: container.id != host

- macro: spawned_process
  condition: evt.type = execve and evt.dir = <

- macro: shell_procs
  condition: proc.name in (bash, csh, ksh, sh, tcsh, zsh, dash)

- macro: sensitive_files
  condition: >
    fd.name startswith /etc or
    fd.name startswith /root/.ssh or
    fd.name startswith /home/*/.ssh

# Lists for grouping values
- list: shell_binaries
  items: [bash, csh, ksh, sh, tcsh, zsh, dash]

- list: package_mgmt_binaries
  items: [dpkg, apt, apt-get, yum, rpm, dnf, zypper]

- list: network_tools
  items: [nc, ncat, netcat, nmap, dig, nslookup, host]

Kubernetes Integration

Helm Configuration

# values.yaml for Helm chart
falco:
  rules_file:
    - /etc/falco/falco_rules.yaml
    - /etc/falco/falco_rules.local.yaml
    - /etc/falco/k8s_audit_rules.yaml
  
  json_output: true
  json_include_output_property: true
  
  grpc:
    enabled: true
    bind_address: "0.0.0.0:5060"
  
  grpc_output:
    enabled: true

  webserver:
    enabled: true
    listen_port: 8765

resources:
  limits:
    cpu: 1000m
    memory: 1024Mi
  requests:
    cpu: 100m
    memory: 512Mi

nodeSelector:
  kubernetes.io/os: linux

tolerations:
  - effect: NoSchedule
    key: node-role.kubernetes.io/master
  - effect: NoSchedule
    key: node-role.kubernetes.io/control-plane

serviceAccount:
  create: true
  name: falco

rbac:
  create: true

customRules:
  custom_rules.yaml: |-
    - rule: Detect kubectl usage
      desc: Detect kubectl command execution
      condition: spawned_process and proc.name = kubectl
      output: kubectl command executed (user=%user.name command=%proc.cmdline)
      priority: INFO
      tags: [k8s, kubectl]

DaemonSet Configuration

# falco-daemonset.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: falco
  namespace: falco
spec:
  selector:
    matchLabels:
      app: falco
  template:
    metadata:
      labels:
        app: falco
    spec:
      serviceAccountName: falco
      hostNetwork: true
      hostPID: true
      containers:
      - name: falco
        image: falcosecurity/falco:latest
        args:
          - /usr/bin/falco
          - --cri=/run/containerd/containerd.sock
          - --k8s-api
          - --k8s-api-cert=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
          - --k8s-api-token=/var/run/secrets/kubernetes.io/serviceaccount/token
        securityContext:
          privileged: true
        volumeMounts:
        - mountPath: /host/var/run/docker.sock
          name: docker-socket
        - mountPath: /host/run/containerd/containerd.sock
          name: containerd-socket
        - mountPath: /host/dev
          name: dev-fs
        - mountPath: /host/proc
          name: proc-fs
          readOnly: true
        - mountPath: /host/boot
          name: boot-fs
          readOnly: true
        - mountPath: /host/lib/modules
          name: lib-modules
        - mountPath: /host/usr
          name: usr-fs
          readOnly: true
        - mountPath: /host/etc
          name: etc-fs
          readOnly: true
        - mountPath: /etc/falco
          name: falco-config
      volumes:
      - name: docker-socket
        hostPath:
          path: /var/run/docker.sock
      - name: containerd-socket
        hostPath:
          path: /run/containerd/containerd.sock
      - name: dev-fs
        hostPath:
          path: /dev
      - name: proc-fs
        hostPath:
          path: /proc
      - name: boot-fs
        hostPath:
          path: /boot
      - name: lib-modules
        hostPath:
          path: /lib/modules
      - name: usr-fs
        hostPath:
          path: /usr
      - name: etc-fs
        hostPath:
          path: /etc
      - name: falco-config
        configMap:
          name: falco-config

CI/CD Integration

GitHub Actions

# .github/workflows/falco.yml
name: Falco Security Monitoring

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  falco-rules-test:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout code
      uses: actions/checkout@v3

    - name: Install Falco
      run: |
        curl -s https://falco.org/repo/falcosecurity-3672BA8F.asc | sudo apt-key add -
        echo "deb https://download.falco.org/packages/deb stable main" | sudo tee -a /etc/apt/sources.list.d/falcosecurity.list
        sudo apt-get update
        sudo apt-get install -y falco

    - name: Validate Falco rules
      run: |
        sudo falco --dry-run -r rules/custom_rules.yaml

    - name: Test Falco rules
      run: |
        # Start Falco in background
        sudo falco -r rules/custom_rules.yaml --json-output > falco-events.json &
        FALCO_PID=$!
        
        # Run test scenarios
        sleep 5
        
        # Test 1: Shell in container
        docker run --rm alpine sh -c "echo 'test'"
        
        # Test 2: File modification
        sudo touch /etc/test-file
        
        # Wait and stop Falco
        sleep 10
        sudo kill $FALCO_PID
        
        # Check for expected events
        if grep -q "A shell was spawned in a container" falco-events.json; then
          echo "✅ Container shell detection working"
        else
          echo "❌ Container shell detection failed"
          exit 1
        fi

    - name: Upload Falco events
      uses: actions/upload-artifact@v3
      with:
        name: falco-events
        path: falco-events.json

  falco-k8s-deploy:
    runs-on: ubuntu-latest
    needs: falco-rules-test
    if: github.ref == 'refs/heads/main'
    steps:
    - name: Checkout code
      uses: actions/checkout@v3

    - name: Setup kubectl
      uses: azure/setup-kubectl@v3
      with:
        version: 'latest'

    - name: Configure kubectl
      run: |
        echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > kubeconfig
        export KUBECONFIG=kubeconfig

    - name: Deploy Falco to Kubernetes
      run: |
        kubectl create namespace falco --dry-run=client -o yaml | kubectl apply -f -
        kubectl apply -f k8s/falco-configmap.yaml
        kubectl apply -f k8s/falco-daemonset.yaml

    - name: Verify Falco deployment
      run: |
        kubectl rollout status daemonset/falco -n falco --timeout=300s
        kubectl get pods -n falco -l app=falco

GitLab CI

# .gitlab-ci.yml
stages:
  - validate
  - test
  - deploy

falco-validate:
  stage: validate
  image: falcosecurity/falco:latest
  script:
    - falco --dry-run -r rules/custom_rules.yaml
  only:
    - main
    - merge_requests

falco-test:
  stage: test
  image: docker:latest
  services:
    - docker:dind
  before_script:
    - apk add --no-cache curl
    - curl -s https://falco.org/repo/falcosecurity-3672BA8F.asc | apt-key add -
    - echo "deb https://download.falco.org/packages/deb stable main" | tee -a /etc/apt/sources.list.d/falcosecurity.list
    - apt-get update && apt-get install -y falco
  script:
    - falco -r rules/custom_rules.yaml --json-output > falco-events.json &
    - FALCO_PID=$!
    - sleep 5
    - docker run --rm alpine sh -c "echo 'test'"
    - sleep 10
    - kill $FALCO_PID
    - grep -q "A shell was spawned in a container" falco-events.json
  artifacts:
    paths:
      - falco-events.json
    expire_in: 1 week
  only:
    - main
    - merge_requests

falco-deploy:
  stage: deploy
  image: bitnami/kubectl:latest
  script:
    - kubectl create namespace falco --dry-run=client -o yaml | kubectl apply -f -
    - kubectl apply -f k8s/
    - kubectl rollout status daemonset/falco -n falco --timeout=300s
  only:
    - main

Automation Scripts

Falco Event Processing

#!/bin/bash
# falco-event-processor.sh

set -e

# Configuration
FALCO_EVENTS_FILE="${FALCO_EVENTS_FILE:-/var/log/falco/events.json}"
PROCESSED_EVENTS_DIR="${PROCESSED_EVENTS_DIR:-/var/log/falco/processed}"
ALERT_WEBHOOK_URL="${ALERT_WEBHOOK_URL:-}"
SLACK_WEBHOOK_URL="${SLACK_WEBHOOK_URL:-}"

# Create processed events directory
mkdir -p "$PROCESSED_EVENTS_DIR"

# Function to process Falco events
process_events() {
    echo "Processing Falco events from $FALCO_EVENTS_FILE..."
    
    # Read new events (since last processing)
    local last_processed_file="$PROCESSED_EVENTS_DIR/last_processed.timestamp"
    local last_processed_time="0"
    
    if [ -f "$last_processed_file" ]; then
        last_processed_time=$(cat "$last_processed_file")
    fi
    
    # Process events newer than last processed time
    while IFS= read -r line; do
        if [ -n "$line" ]; then
            process_single_event "$line"
        fi
    done < <(jq -r --arg timestamp "$last_processed_time" '
        select(.time > $timestamp) | @json
    ' "$FALCO_EVENTS_FILE" 2>/dev/null || echo "")
    
    # Update last processed timestamp
    date +%s > "$last_processed_file"
}

# Function to process a single event
process_single_event() {
    local event_json="$1"
    
    # Parse event details
    local priority=$(echo "$event_json" | jq -r '.priority // "INFO"')
    local rule=$(echo "$event_json" | jq -r '.rule // "Unknown"')
    local output=$(echo "$event_json" | jq -r '.output // "No output"')
    local time=$(echo "$event_json" | jq -r '.time // "Unknown"')
    local tags=$(echo "$event_json" | jq -r '.tags[]? // empty' | tr '\n' ',' | sed 's/,$//')
    
    echo "Processing event: $rule (Priority: $priority)"
    
    # Save event to processed directory
    local event_file="$PROCESSED_EVENTS_DIR/event_$(date +%s%N).json"
    echo "$event_json" > "$event_file"
    
    # Handle based on priority
    case "$priority" in
        "CRITICAL"|"ERROR")
            handle_critical_event "$event_json"
            ;;
        "WARNING")
            handle_warning_event "$event_json"
            ;;
        "NOTICE"|"INFO")
            handle_info_event "$event_json"
            ;;
    esac
}

# Function to handle critical events
handle_critical_event() {
    local event_json="$1"
    local rule=$(echo "$event_json" | jq -r '.rule')
    local output=$(echo "$event_json" | jq -r '.output')
    
    echo "🚨 CRITICAL EVENT: $rule"
    echo "Details: $output"
    
    # Send immediate alerts
    send_slack_alert "🚨 CRITICAL Falco Alert" "$rule: $output" "danger"
    send_webhook_alert "$event_json"
    
    # Log to syslog
    logger -p local0.crit "Falco Critical: $rule - $output"
}

# Function to handle warning events
handle_warning_event() {
    local event_json="$1"
    local rule=$(echo "$event_json" | jq -r '.rule')
    local output=$(echo "$event_json" | jq -r '.output')
    
    echo "⚠️ WARNING EVENT: $rule"
    echo "Details: $output"
    
    # Send warning alerts
    send_slack_alert "⚠️ WARNING Falco Alert" "$rule: $output" "warning"
    
    # Log to syslog
    logger -p local0.warning "Falco Warning: $rule - $output"
}

# Function to handle info events
handle_info_event() {
    local event_json="$1"
    local rule=$(echo "$event_json" | jq -r '.rule')
    
    echo "ℹ️ INFO EVENT: $rule"
    
    # Log to syslog
    logger -p local0.info "Falco Info: $rule"
}

# Function to send Slack alerts
send_slack_alert() {
    local title="$1"
    local message="$2"
    local color="$3"
    
    if [ -n "$SLACK_WEBHOOK_URL" ]; then
        curl -X POST -H 'Content-type: application/json' \
            --data "{
                \"attachments\": [{
                    \"color\": \"$color\",
                    \"title\": \"$title\",
                    \"text\": \"$message\",
                    \"footer\": \"Falco Security Monitor\",
                    \"ts\": $(date +%s)
                }]
            }" \
            "$SLACK_WEBHOOK_URL" &
    fi
}

# Function to send webhook alerts
send_webhook_alert() {
    local event_json="$1"
    
    if [ -n "$ALERT_WEBHOOK_URL" ]; then
        curl -X POST -H 'Content-type: application/json' \
            --data "$event_json" \
            "$ALERT_WEBHOOK_URL" &
    fi
}

# Function to generate summary report
generate_summary_report() {
    echo "Generating Falco events summary..."
    
    local report_file="$PROCESSED_EVENTS_DIR/summary_$(date +%Y%m%d).json"
    
    # Count events by priority
    local critical_count=$(find "$PROCESSED_EVENTS_DIR" -name "event_*.json" -exec jq -r '.priority' {} \; | grep -c "CRITICAL" || echo "0")
    local error_count=$(find "$PROCESSED_EVENTS_DIR" -name "event_*.json" -exec jq -r '.priority' {} \; | grep -c "ERROR" || echo "0")
    local warning_count=$(find "$PROCESSED_EVENTS_DIR" -name "event_*.json" -exec jq -r '.priority' {} \; | grep -c "WARNING" || echo "0")
    local info_count=$(find "$PROCESSED_EVENTS_DIR" -name "event_*.json" -exec jq -r '.priority' {} \; | grep -c -E "NOTICE|INFO" || echo "0")
    
    # Generate summary
    cat > "$report_file" << EOF
{
  "date": "$(date -I)",
  "summary": {
    "critical": $critical_count,
    "error": $error_count,
    "warning": $warning_count,
    "info": $info_count,
    "total": $((critical_count + error_count + warning_count + info_count))
  },
  "top_rules": $(find "$PROCESSED_EVENTS_DIR" -name "event_*.json" -exec jq -r '.rule' {} \; | sort | uniq -c | sort -nr | head -10 | jq -R 'split(" ") | {count: .[0], rule: .[1:] | join(" ")}' | jq -s .)
}
EOF
    
    echo "Summary report generated: $report_file"
    
    # Print summary to console
    echo "=== Daily Falco Events Summary ==="
    echo "Critical: $critical_count"
    echo "Error: $error_count"
    echo "Warning: $warning_count"
    echo "Info: $info_count"
    echo "Total: $((critical_count + error_count + warning_count + info_count))"
}

# Function to cleanup old events
cleanup_old_events() {
    local retention_days="${RETENTION_DAYS:-30}"
    
    echo "Cleaning up events older than $retention_days days..."
    
    find "$PROCESSED_EVENTS_DIR" -name "event_*.json" -mtime +$retention_days -delete
    find "$PROCESSED_EVENTS_DIR" -name "summary_*.json" -mtime +$retention_days -delete
    
    echo "Cleanup completed"
}

# Main execution
main() {
    case "${1:-process}" in
        "process")
            process_events
            ;;
        "summary")
            generate_summary_report
            ;;
        "cleanup")
            cleanup_old_events
            ;;
        "monitor")
            # Continuous monitoring mode
            while true; do
                process_events
                sleep 60
            done
            ;;
        *)
            echo "Usage: $0 {process|summary|cleanup|monitor}"
            exit 1
            ;;
    esac
}

main "$@"

Falco Rules Management

#!/usr/bin/env python3
# falco-rules-manager.py

import yaml
import json
import sys
import os
import subprocess
from pathlib import Path
from datetime import datetime

class FalcoRulesManager:
    def __init__(self, rules_dir="rules", config_file="/etc/falco/falco.yaml"):
        self.rules_dir = Path(rules_dir)
        self.config_file = Path(config_file)
        self.falco_binary = "falco"
    
    def validate_rules(self):
        """Validate Falco rules syntax"""
        print("Validating Falco rules...")
        
        success = True
        for rules_file in self.rules_dir.glob("**/*.yaml"):
            try:
                # Validate YAML syntax
                with open(rules_file) as f:
                    yaml.safe_load(f)
                
                # Validate with Falco
                result = subprocess.run([
                    self.falco_binary, "--dry-run", "-r", str(rules_file)
                ], capture_output=True, text=True)
                
                if result.returncode != 0:
                    print(f"❌ Validation failed for {rules_file}: {result.stderr}")
                    success = False
                else:
                    print(f"✅ {rules_file} validated successfully")
                    
            except yaml.YAMLError as e:
                print(f"❌ YAML syntax error in {rules_file}: {e}")
                success = False
            except Exception as e:
                print(f"❌ Error validating {rules_file}: {e}")
                success = False
        
        return success
    
    def generate_rules_documentation(self):
        """Generate documentation for Falco rules"""
        print("Generating rules documentation...")
        
        all_rules = []
        all_macros = []
        all_lists = []
        
        for rules_file in self.rules_dir.glob("**/*.yaml"):
            try:
                with open(rules_file) as f:
                    data = yaml.safe_load(f)
                
                if not isinstance(data, list):
                    continue
                
                for item in data:
                    if 'rule' in item:
                        all_rules.append({
                            'file': str(rules_file),
                            'rule': item['rule'],
                            'desc': item.get('desc', 'No description'),
                            'condition': item.get('condition', ''),
                            'output': item.get('output', ''),
                            'priority': item.get('priority', 'INFO'),
                            'tags': item.get('tags', [])
                        })
                    elif 'macro' in item:
                        all_macros.append({
                            'file': str(rules_file),
                            'macro': item['macro'],
                            'condition': item.get('condition', '')
                        })
                    elif 'list' in item:
                        all_lists.append({
                            'file': str(rules_file),
                            'list': item['list'],
                            'items': item.get('items', [])
                        })
                        
            except Exception as e:
                print(f"❌ Error processing {rules_file}: {e}")
        
        # Generate markdown documentation
        doc_content = self._generate_markdown_doc(all_rules, all_macros, all_lists)
        
        doc_file = self.rules_dir / "RULES_DOCUMENTATION.md"
        with open(doc_file, 'w') as f:
            f.write(doc_content)
        
        print(f"✅ Documentation generated: {doc_file}")
        
        # Generate JSON summary
        summary = {
            'generated_at': datetime.now().isoformat(),
            'total_rules': len(all_rules),
            'total_macros': len(all_macros),
            'total_lists': len(all_lists),
            'rules_by_priority': self._count_by_priority(all_rules),
            'rules_by_tag': self._count_by_tags(all_rules)
        }
        
        summary_file = self.rules_dir / "rules_summary.json"
        with open(summary_file, 'w') as f:
            json.dump(summary, f, indent=2)
        
        print(f"✅ Summary generated: {summary_file}")
    
    def _generate_markdown_doc(self, rules, macros, lists):
        """Generate markdown documentation"""
        content = f"""# Falco Rules Documentation

Generated on: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}

## Summary

- **Total Rules**: {len(rules)}
- **Total Macros**: {len(macros)}
- **Total Lists**: {len(lists)}

## Rules

"""
        
        # Sort rules by priority
        priority_order = ['CRITICAL', 'ERROR', 'WARNING', 'NOTICE', 'INFO']
        rules_sorted = sorted(rules, key=lambda x: priority_order.index(x['priority']) if x['priority'] in priority_order else 999)
        
        for rule in rules_sorted:
            content += f"""### {rule['rule']}

**Priority**: {rule['priority']}  
**File**: `{rule['file']}`  
**Tags**: {', '.join(rule['tags']) if rule['tags'] else 'None'}

**Description**: {rule['desc']}

**Condition**:

{rule[‘condition’]}


**Output**:

{rule[‘output’]}


---

"""
        
        content += "\n## Macros\n\n"
        for macro in macros:
            content += f"""### {macro['macro']}

**File**: `{macro['file']}`

**Condition**:

{macro[‘condition’]}


---

"""
        
        content += "\n## Lists\n\n"
        for lst in lists:
            content += f"""### {lst['list']}

**File**: `{lst['file']}`

**Items**: {', '.join(lst['items']) if lst['items'] else 'None'}

---

"""
        
        return content
    
    def _count_by_priority(self, rules):
        """Count rules by priority"""
        counts = {}
        for rule in rules:
            priority = rule['priority']
            counts[priority] = counts.get(priority, 0) + 1
        return counts
    
    def _count_by_tags(self, rules):
        """Count rules by tags"""
        counts = {}
        for rule in rules:
            for tag in rule['tags']:
                counts[tag] = counts.get(tag, 0) + 1
        return counts
    
    def test_rules(self):
        """Test Falco rules with sample events"""
        print("Testing Falco rules...")
        
        # Create test scenarios
        test_scenarios = [
            {
                'name': 'Container shell test',
                'command': 'docker run --rm alpine sh -c "echo test"',
                'expected_rules': ['Terminal shell in container']
            },
            {
                'name': 'File modification test',
                'command': 'touch /tmp/test-file && rm /tmp/test-file',
                'expected_rules': []
            }
        ]
        
        for scenario in test_scenarios:
            print(f"Running test: {scenario['name']}")
            
            # Start Falco in background
            falco_process = subprocess.Popen([
                self.falco_binary, "-r", str(self.rules_dir / "*.yaml"),
                "--json-output"
            ], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
            
            # Wait a moment for Falco to start
            import time
            time.sleep(2)
            
            # Run test command
            subprocess.run(scenario['command'], shell=True, capture_output=True)
            
            # Wait for events
            time.sleep(3)
            
            # Stop Falco
            falco_process.terminate()
            stdout, stderr = falco_process.communicate(timeout=5)
            
            # Check for expected events
            events = []
            for line in stdout.split('\n'):
                if line.strip():
                    try:
                        event = json.loads(line)
                        events.append(event)
                    except json.JSONDecodeError:
                        continue
            
            print(f"  Captured {len(events)} events")
            
            # Validate expected rules
            triggered_rules = [event.get('rule', '') for event in events]
            for expected_rule in scenario['expected_rules']:
                if expected_rule in triggered_rules:
                    print(f"  ✅ Expected rule triggered: {expected_rule}")
                else:
                    print(f"  ❌ Expected rule not triggered: {expected_rule}")
    
    def deploy_rules(self, target="local"):
        """Deploy rules to target environment"""
        print(f"Deploying rules to {target}...")
        
        if target == "local":
            # Copy rules to local Falco configuration
            import shutil
            for rules_file in self.rules_dir.glob("*.yaml"):
                dest = Path("/etc/falco") / rules_file.name
                shutil.copy2(rules_file, dest)
                print(f"✅ Deployed {rules_file} to {dest}")
            
            # Restart Falco service
            subprocess.run(["systemctl", "restart", "falco"], check=True)
            print("✅ Falco service restarted")
            
        elif target == "kubernetes":
            # Deploy to Kubernetes via ConfigMap
            subprocess.run([
                "kubectl", "create", "configmap", "falco-rules",
                f"--from-file={self.rules_dir}",
                "--dry-run=client", "-o", "yaml"
            ], check=True)
            
            subprocess.run([
                "kubectl", "apply", "-f", "-"
            ], input=subprocess.run([
                "kubectl", "create", "configmap", "falco-rules",
                f"--from-file={self.rules_dir}",
                "--dry-run=client", "-o", "yaml"
            ], capture_output=True, text=True).stdout, text=True, check=True)
            
            # Restart Falco DaemonSet
            subprocess.run([
                "kubectl", "rollout", "restart", "daemonset/falco", "-n", "falco"
            ], check=True)
            
            print("✅ Rules deployed to Kubernetes")
        
        else:
            print(f"❌ Unknown target: {target}")
            return False
        
        return True

def main():
    import argparse
    
    parser = argparse.ArgumentParser(description='Falco Rules Manager')
    parser.add_argument('action', choices=['validate', 'document', 'test', 'deploy'],
                       help='Action to perform')
    parser.add_argument('--rules-dir', default='rules',
                       help='Directory containing Falco rules')
    parser.add_argument('--target', default='local',
                       help='Deployment target (local, kubernetes)')
    
    args = parser.parse_args()
    
    manager = FalcoRulesManager(args.rules_dir)
    
    if args.action == 'validate':
        success = manager.validate_rules()
        sys.exit(0 if success else 1)
    elif args.action == 'document':
        manager.generate_rules_documentation()
    elif args.action == 'test':
        manager.test_rules()
    elif args.action == 'deploy':
        success = manager.deploy_rules(args.target)
        sys.exit(0 if success else 1)

if __name__ == "__main__":
    main()

Troubleshooting

Common Issues

# Driver loading issues
falco-driver-loader

# Check driver status
lsmod | grep falco

# eBPF probe issues
falco --modern-bpf --dry-run

# Permission issues
sudo falco

# Configuration validation
falco --dry-run -c /etc/falco/falco.yaml

# Verbose debugging
falco -vv

Performance Optimization

# Reduce syscall overhead
falco --modern-bpf

# Optimize buffer sizes
falco -o syscall_event_drops.rate=0.1

# Disable unnecessary rules
falco -T filesystem,network

# Monitor performance
falco --stats-interval 30

Log Analysis

# Check Falco logs
journalctl -u falco -f

# Parse JSON events
tail -f /var/log/falco/events.json | jq '.rule, .output'

# Count events by priority
jq -r '.priority' /var/log/falco/events.json | sort | uniq -c

# Filter by rule
jq 'select(.rule == "Terminal shell in container")' /var/log/falco/events.json

Best Practices

Rule Development

  1. Specific Conditions: Write precise rule conditions to minimize false positives
  2. Performance Awareness: Consider performance impact of complex rules
  3. Clear Outputs: Provide clear, actionable output messages
  4. Proper Tagging: Use consistent tagging for rule organization
  5. Regular Testing: Test rules with realistic scenarios

Deployment Guidelines

  1. Gradual Rollout: Deploy new rules gradually in production
  2. Monitoring: Monitor rule performance and false positive rates
  3. Documentation: Maintain comprehensive rule documentation
  4. Version Control: Use version control for rule management
  5. Regular Updates: Keep rules updated with threat intelligence

Security Considerations

  1. Least Privilege: Run Falco with minimal required privileges
  2. Secure Outputs: Secure output channels and endpoints
  3. Log Protection: Protect Falco logs from tampering
  4. Regular Audits: Regularly audit and review rules
  5. Incident Response: Integrate with incident response workflows

This comprehensive Falco cheatsheet provides everything needed for professional runtime threat detection and security monitoring, from basic usage to advanced automation and integration scenarios.