Aller au contenu

Falco Feuille de chaleur

- :material-content-copy: **[Copier sur le presse-papiers] (__LINK_0__)** - **[Télécharger PDF](__LINK_0__)**

Aperçu général

Falco est un outil de sécurité d'exécution open-source qui détecte les comportements inattendus des applications et les alertes sur les menaces à l'exécution. Il utilise les appels système pour sécuriser et surveiller un système, en analyseant les appels système Linux du noyau à l'exécution et en affirmant le flux contre un puissant moteur de règles.

Caractéristiques principales

  • Détection des menaces en temps réel: Surveillance en temps réel des appels système et des événements du noyau
  • ** Kubernetes Native**: Intégration profonde avec les environnements Kubernetes
  • Règles flexibles Moteur: Règles personnalisables pour la détection des menaces
  • ** Canaux de sortie multiples**: Alertes via syslog, fichiers, HTTP, gRPC, et plus encore
  • eBPF Support: sonde eBPF moderne pour une surveillance efficace du noyau
  • IntégrationCloud-Native: Intégration aux outils écosystémiques du CNCF

Installation

Installation binaire

# 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

Installation du gestionnaire de paquets

# 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
```_

### Installation du conteneur

```bash
# 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
```_

### Installation de Kubernetes

```bash
# 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

Installation eBPF

# Install with eBPF probe
falco --modern-bpf

# Install eBPF probe manually
falco-driver-loader bpf

# Verify eBPF probe
lsmod | grep falco

Utilisation de base

Courir 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

Options de ligne de commande

# 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

Fichiers de configuration

# /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

Règles et détection

Règles par défaut

# 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]

Règles douanières

# 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]

Règles d'audit de Kubernetes

# 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]

Configuration avancée

Canaux de sortie

# 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"

Analyse des performances

# 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

Règles et 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 Intégration

Configuration du casque

# 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]

Configuration de DaemonSet

# 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

Intégration CI/CD

Actions GitHub

# .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

Scripts d'automatisation

Traitement des événements Falco

#!/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 "$@"

Gestion des règles Falco

#!/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**:

{règle['condition']}


**Output**:

{règle['sortie']}


---

"""

        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()

Dépannage

Questions communes

# 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

Optimisation des performances

# 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

Analyse du journal

# 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

Meilleures pratiques

Développement des règles

  1. Conditions particulières: Écrire des conditions précises pour minimiser les faux positifs
  2. ** Sensibilisation au rendement** : tenir compte de l'impact des règles complexes sur le rendement
  3. Exceptions claires: Fournir des messages de sortie clairs et exploitables
  4. Tagging pour les promoteurs: Utiliser un marquage cohérent pour l'organisation des règles
  5. ** Tests réguliers**: Règles d'essai avec scénarios réalistes

Directives pour le déploiement

  1. Gradual Rollout: Déployer progressivement de nouvelles règles dans la production
  2. Surveillance: Surveiller la performance des règles et les faux taux positifs
  3. Documentation: tenir une documentation complète sur les règles
  4. Contrôle de la version: Utiliser le contrôle de version pour la gestion des règles
  5. ** Mises à jour régulières** : tenir les règles à jour avec les renseignements relatifs aux menaces

Considérations en matière de sécurité

  1. Least Privilege: Lancez Falco avec des privilèges minimum requis
  2. Sécuriser les sorties: Sécuriser les canaux et les paramètres de sortie
  3. **Protection des journaux de Falco
  4. ** Audits réguliers** : Règles d'audit et d'examen périodiques
  5. Réponse à l'incident: Intégrer les processus de réponse à l'incident

Cette feuille de triche Falco complète fournit tout ce qu'il faut pour la détection professionnelle des menaces d'exécution et la surveillance de la sécurité, de l'utilisation de base aux scénarios d'automatisation et d'intégration avancés.