# Falco - Runtime Security Monitoring

Comprehensive guide to cloud-native runtime security with Falco for detecting anomalous behavior and threats in real-time.

## Overview

**Container**: `falcosecurity/falco-no-driver:latest`
**Category**: Runtime Security
**Port**: N/A (daemon)

Falco is a cloud-native runtime security tool that detects anomalous activity in applications using system call monitoring.

## Quick Start

```bash
# Start Falco
docker-compose up -d falco

# View alerts
docker logs -f falco

# Check Falco status
docker exec falco falco --version

# Validate rules
docker exec falco falco --validate /etc/falco/rules.d/
```

## Detection Capabilities

| Category | Examples |
|----------|----------|
| Container Escape | Privileged container access |
| File Access | Reading /etc/shadow, /etc/passwd |
| Process Execution | Shell spawned in container |
| Network Activity | Unexpected outbound connections |
| Package Management | apt/yum running in container |
| Credential Access | AWS credential file access |
| Persistence | Crontab modifications |
| Kubernetes | Unauthorized API access |

## Default Rules

Falco includes rules for common threats:

- Shell in container
- Writing to /etc
- Reading sensitive files
- Unexpected network connections
- Package management in containers
- Privileged container started
- Container drift (new binaries)
- Kubernetes audit events

## Rule Components

| Component | Description | Example |
|-----------|-------------|---------|
| `rule` | Rule name | "Shell in Container" |
| `desc` | Description | Human-readable explanation |
| `condition` | Detection logic | `spawned_process and container` |
| `output` | Alert message | With placeholders |
| `priority` | Severity | EMERGENCY to DEBUG |
| `tags` | Categories | [container, shell] |
| `enabled` | Rule active | true/false |

## Custom Rules

### Shell Detection

```yaml
# /falco-rules/shell-detection.yaml
- rule: Shell Spawned in Container
  desc: Detect shell execution in container
  condition: >
    spawned_process and
    container and
    shell_procs
  output: >
    Shell spawned in container
    (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline
     container_id=%container.id container_name=%container.name
     image=%container.image.repository)
  priority: WARNING
  tags: [container, shell, mitre_execution]
```

### Sensitive File Access

```yaml
- rule: Read Sensitive File
  desc: Detect reads to sensitive files
  condition: >
    open_read and
    (fd.name startswith /etc/shadow or
     fd.name startswith /etc/passwd or
     fd.name contains /aws/credentials or
     fd.name contains .ssh/id_rsa)
  output: >
    Sensitive file read
    (user=%user.name file=%fd.name command=%proc.cmdline
     container=%container.name)
  priority: CRITICAL
  tags: [file, credentials, mitre_credential_access]
```

### Unexpected Outbound Connections

```yaml
- rule: Unexpected Outbound Connection
  desc: Detect outbound connections from containers
  condition: >
    outbound and
    container and
    not (fd.sip.name in (allowed_outbound_hosts)) and
    not (proc.name in (allowed_network_procs))
  output: >
    Unexpected outbound connection
    (user=%user.name command=%proc.cmdline connection=%fd.name
     container=%container.name)
  priority: WARNING
  tags: [network, mitre_command_and_control]
```

### Package Manager Detection

```yaml
- rule: Package Management in Container
  desc: Detect package manager execution
  condition: >
    spawned_process and
    container and
    (proc.name in (apt, apt-get, yum, dnf, apk, pip, pip3, npm, gem))
  output: >
    Package manager executed in container
    (user=%user.name command=%proc.cmdline container=%container.name
     image=%container.image.repository)
  priority: ERROR
  tags: [container, package, mitre_execution]
```

### Kubernetes Specific

```yaml
- rule: K8s ServiceAccount Token Access
  desc: Detect access to service account token
  condition: >
    open_read and
    fd.name startswith /var/run/secrets/kubernetes.io/serviceaccount
  output: >
    Service account token accessed
    (user=%user.name file=%fd.name command=%proc.cmdline
     container=%container.name pod=%k8s.pod.name)
  priority: NOTICE
  tags: [k8s, credential, mitre_credential_access]
```

## Macros and Lists

### Reusable Macros

```yaml
# Common macros
- macro: container
  condition: container.id != host

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

- macro: shell_procs
  condition: proc.name in (shell_binaries)

- macro: open_read
  condition: evt.type in (open, openat) and evt.dir = < and fd.typechar = f

- macro: outbound
  condition: >
    (evt.type in (connect) and evt.dir = <) and
    (fd.typechar = 4 or fd.typechar = 6) and
    fd.ip != "0.0.0.0"
```

### Reusable Lists

```yaml
# Common lists
- list: shell_binaries
  items: [bash, sh, zsh, ksh, csh, tcsh, dash]

- list: allowed_outbound_hosts
  items: [api.github.com, registry.npmjs.org, pypi.org]

- list: allowed_network_procs
  items: [curl, wget, apt, apt-get, yum, pip]

- list: sensitive_mount_dirs
  items: [/proc, /var/run/docker.sock, /var/run/crio]
```

## Alert Priorities

| Priority | Value | Use Case |
|----------|-------|----------|
| EMERGENCY | 0 | System unusable |
| ALERT | 1 | Immediate action required |
| CRITICAL | 2 | Critical conditions |
| ERROR | 3 | Error conditions |
| WARNING | 4 | Warning conditions |
| NOTICE | 5 | Normal but significant |
| INFO | 6 | Informational |
| DEBUG | 7 | Debug messages |

## Output Configuration

```yaml
# falco.yaml
json_output: true
json_include_output_property: true
json_include_tags_property: true

stdout_output:
  enabled: true

file_output:
  enabled: true
  keep_alive: false
  filename: /var/log/falco/events.json

http_output:
  enabled: true
  url: http://allure:5050/api/falco

grpc_output:
  enabled: true
  keep_alive_time_ms: 10000
```

## CLI Commands

```bash
# Test rules syntax
docker exec falco falco --validate /etc/falco/rules.d/

# List available fields
docker exec falco falco --list

# Run with specific rules file
docker exec falco falco -r /etc/falco/rules.d/custom-rules.yaml

# Dry run (check rules, don't monitor)
docker exec falco falco --dry-run

# Run with increased verbosity
docker exec falco falco -v

# Print all rules
docker exec falco falco --list-rules
```

## Alert Examples

### JSON Alert

```json
{
  "output": "Shell spawned in container (user=root command=bash container=myapp)",
  "priority": "Warning",
  "rule": "Shell Spawned in Container",
  "time": "2024-01-15T10:30:00.000000000Z",
  "output_fields": {
    "user.name": "root",
    "proc.cmdline": "bash",
    "container.name": "myapp",
    "container.id": "abc123",
    "container.image.repository": "nginx"
  },
  "tags": ["container", "shell", "mitre_execution"]
}
```

### Formatted Output

```
2024-01-15T10:30:00.000000000+00:00: Warning Shell spawned in container (user=root user_loginuid=-1 command=bash container_id=abc123 container_name=myapp image=nginx)
```

## Kubernetes Integration

### DaemonSet Deployment

```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
        securityContext:
          privileged: true
        volumeMounts:
        - mountPath: /host/var/run/docker.sock
          name: docker-socket
        - mountPath: /host/dev
          name: dev-fs
        - mountPath: /host/proc
          name: proc-fs
          readOnly: true
        - mountPath: /etc/falco
          name: config
      volumes:
      - name: docker-socket
        hostPath:
          path: /var/run/docker.sock
      - name: dev-fs
        hostPath:
          path: /dev
      - name: proc-fs
        hostPath:
          path: /proc
      - name: config
        configMap:
          name: falco-config
```

### Falco with Kubernetes Audit

```yaml
# Enable K8s audit logging
- rule: K8s Secret Access
  desc: Detect access to Kubernetes secrets
  condition: >
    ka.verb in (get, list) and
    ka.target.resource = secrets
  output: >
    K8s secret accessed
    (user=%ka.user.name verb=%ka.verb secret=%ka.target.name
     namespace=%ka.target.namespace)
  priority: NOTICE
  tags: [k8s, secrets]
  source: k8s_audit
```

## CI/CD Integration

### Security Testing with Falco

```bash
#!/bin/bash
# security-test.sh

# Start application
docker-compose up -d app

# Start Falco monitoring
docker-compose up -d falco

# Run security tests (intentionally trigger alerts)
npm run security-tests

# Wait for Falco to process events
sleep 10

# Check for Falco alerts
ALERTS=$(docker logs falco 2>&1 | grep -c "Warning\|Error\|Critical")

if [ "$ALERTS" -gt 0 ]; then
  echo "Security alerts detected!"
  docker logs falco 2>&1 | grep "Warning\|Error\|Critical"
  exit 1
fi

echo "No security alerts"
```

### GitHub Actions

```yaml
name: Runtime Security
on: [push]

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

      - name: Start Falco
        run: |
          docker run -d --name falco \
            --privileged \
            -v /var/run/docker.sock:/var/run/docker.sock \
            -v ${PWD}/falco-rules:/etc/falco/rules.d \
            falcosecurity/falco:latest

      - name: Start Application
        run: docker-compose up -d app

      - name: Run Security Tests
        run: npm run test:security

      - name: Check Falco Alerts
        run: |
          CRITICAL=$(docker logs falco 2>&1 | grep -c "Critical")
          if [ "$CRITICAL" -gt 0 ]; then
            echo "Critical security events detected!"
            docker logs falco
            exit 1
          fi

      - name: Export Falco Events
        if: always()
        run: docker logs falco > falco-events.log

      - name: Upload Events
        if: always()
        uses: actions/upload-artifact@v3
        with:
          name: falco-events
          path: falco-events.log
```

## Falco Sidekick Integration

Forward alerts to external systems:

```yaml
# falcosidekick config
config:
  slack:
    webhookurl: "https://hooks.slack.com/services/xxx"
    outputformat: "all"
    minimumpriority: "warning"

  elasticsearch:
    hostport: "http://elasticsearch:9200"
    index: "falco"
    type: "_doc"

  webhook:
    address: "http://defectdojo:8083/api/v2/import-scan/"
    customHeaders:
      Authorization: "Token xxx"
```

## Best Practices

1. **Start with defaults** - Use built-in rules first
2. **Tune gradually** - Add custom rules incrementally
3. **Minimize noise** - Filter false positives with macros
4. **Use tags** - Categorize rules for filtering
5. **Test in staging** - Validate rules before production
6. **Forward alerts** - Send to SIEM/logging system
7. **Create runbooks** - Document response procedures
8. **Monitor resources** - Watch Falco CPU/memory usage

## Integration with Stack

- Runtime complement to Semgrep/Trivy static scans
- Alerts feed into DefectDojo for tracking
- Monitor during Toxiproxy chaos testing
- Validate security posture during E2E tests
- JSON output for Allure reporting
- Correlate with Checkov IaC findings

## Troubleshooting

### Common Issues

**Issue**: High CPU usage
```bash
# Reduce rule scope
# Increase sampling rate
# Disable verbose rules
```

**Issue**: Missing events
```bash
# Check Falco has required privileges
docker exec falco falco --support

# Verify syscall driver loaded
docker exec falco falco --info
```

**Issue**: Too many alerts
```bash
# Add to allowlist
- list: allowed_processes
  items: [your_app, allowed_binary]

# Increase priority threshold
priority: ERROR  # Instead of WARNING
```
