Docker Runtime Security: Detecting Threats with Falco and eBPF

Move beyond image scanning. Learn how to detect container breakouts, crypto miners, and suspicious exec calls in real-time using Falco, eBPF, and runtime security policies.

Y
Yash Pritwani
12 min read read

Docker Runtime Security: Detecting Threats with Falco and eBPF

Image scanning catches known vulnerabilities before deployment. But what about the threats that happen after the container is running? The crypto miner that gets dropped via a compromised dependency. The reverse shell spawned through a deserialization exploit. The container breakout that escalates to host access.

These are runtime threats, and your Trivy scan will not catch them. You need eyes inside the running container — in real-time.

Why Image Scanning Is Not Enough

Image scanning (Trivy, Grype, Snyk Container) is essential but limited:

  • It finds known CVEs in installed packages. It cannot detect zero-days.
  • It runs before deployment. Anything that happens after the container starts is invisible.
  • It does not detect behavioral anomalies — a web server spawning a shell, a database process downloading a binary, or a container writing to /etc/passwd.
  • The recent Trivy supply chain attack (March 2026) showed that even the scanning tools themselves can be compromised.

Runtime security fills this gap by monitoring container behavior and flagging deviations from expected patterns.

Understanding eBPF: The Foundation

eBPF (extended Berkeley Packet Filter) is a Linux kernel technology that lets you run sandboxed programs inside the kernel without modifying kernel source code or loading kernel modules.

For container security, this means:

  • System call monitoring — every exec, open, connect, write made by any process inside any container
  • Network observation — every connection established, every packet sent
  • File access tracking — every file read, written, or modified
  • Near-zero overhead — eBPF programs run in kernel space, avoiding the context switches of userspace monitoring

Traditional approaches (ptrace, audit subsystem) add significant overhead. eBPF gives you the same visibility at a fraction of the cost.

Falco: Runtime Threat Detection

Falco (CNCF graduated project) is the standard for container runtime security. It uses a rules engine to detect suspicious behavior based on system call patterns.

Get more insights on Security

Join 2,000+ engineers who get our weekly deep-dives. No spam, unsubscribe anytime.

Installing Falco

# Using Docker (for Docker-based setups)
docker run -d --name falco \
  --privileged \
  -v /var/run/docker.sock:/host/var/run/docker.sock \
  -v /dev:/host/dev \
  -v /proc:/host/proc:ro \
  -v /etc:/host/etc:ro \
  falcosecurity/falco:latest

# Using eBPF driver (preferred — no kernel module needed)
docker run -d --name falco \
  --privileged \
  -e FALCO_BPF_PROBE="" \
  -v /var/run/docker.sock:/host/var/run/docker.sock \
  -v /proc:/host/proc:ro \
  falcosecurity/falco:latest

How Falco Rules Work

Falco rules define what normal behavior looks like and alert on deviations:

# Detect shell spawned inside a container
- rule: Terminal Shell in Container
  desc: A shell was used as the entrypoint/exec for a container
  condition: >
    spawned_process and
    container and
    shell_procs and
    proc.pname exists and
    not proc.pname in (shell_binaries)
  output: >
    Shell spawned in container
    (user=%user.name container=%container.name
    shell=%proc.name parent=%proc.pname
    cmdline=%proc.cmdline image=%container.image.repository)
  priority: WARNING
  tags: [container, shell, mitre_execution]

# Detect outbound connections from unexpected containers
- rule: Unexpected Outbound Connection
  desc: Container making outbound connection that is not whitelisted
  condition: >
    outbound and
    container and
    not fd.sip in (allowed_outbound_ips) and
    not container.image.repository in (proxy_containers)
  output: >
    Unexpected outbound connection
    (container=%container.name image=%container.image.repository
    connection=%fd.name)
  priority: NOTICE
  tags: [container, network, mitre_exfiltration]

Built-in Detection Rules

Falco ships with rules for the most common container threats:

Threat Detection Method
Container breakout Detect writes to sensitive host paths (/etc/shadow, /proc/sysrq-trigger)
Crypto mining Detect connections to known mining pools, unusual CPU-intensive processes
Reverse shell Detect shell processes with network connections
Privilege escalation Detect setuid/setgid calls, writes to /etc/passwd
Data exfiltration Detect unexpected outbound connections from data-tier containers
Suspicious exec Detect kubectl exec or docker exec into production containers
Package manager in runtime Detect apt-get, yum, apk running in a container (should only happen at build time)

Building a Runtime Security Stack

Layer 1: Falco for Detection

Falco watches everything. Configure it to send alerts to your monitoring stack:

# falco.yaml
json_output: true
json_include_output_property: true

http_output:
  enabled: true
  url: http://alertmanager:9093/api/v1/alerts

stdout_output:
  enabled: true

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

Layer 2: Custom Rules for Your Stack

Generic rules catch generic threats. Write rules specific to your applications:

# Your web server should never spawn child processes
- rule: Web Server Spawned Process
  desc: Nginx or Node.js container spawned an unexpected child process
  condition: >
    spawned_process and
    container and
    container.image.repository in (nginx, node-app, api-server) and
    not proc.name in (nginx, node, npm, sh)
  output: >
    Unexpected process in web container
    (proc=%proc.name parent=%proc.pname container=%container.name
    cmdline=%proc.cmdline)
  priority: ERROR

# Database containers should only connect to specific IPs
- rule: Database Unexpected Network
  desc: PostgreSQL container connecting to non-whitelisted IP
  condition: >
    outbound and
    container and
    container.image.repository contains "postgres" and
    not fd.sip in ("10.0.0.0/8")
  output: >
    PostgreSQL container connecting to unexpected IP
    (container=%container.name dest=%fd.sip)
  priority: CRITICAL

Layer 3: Enforcement with Seccomp and AppArmor

Detection tells you about threats. Enforcement prevents them:

{
  "defaultAction": "SCMP_ACT_ERRNO",
  "architectures": ["SCMP_ARCH_X86_64"],
  "syscalls": [
    {
      "names": ["read", "write", "open", "close", "stat",
               "fstat", "mmap", "mprotect", "munmap",
               "brk", "ioctl", "access", "pipe", "select",
               "sched_yield", "clone", "execve", "exit",
               "wait4", "kill", "uname", "fcntl", "flock",
               "fsync", "ftruncate", "getdents", "getcwd",
               "chdir", "rename", "mkdir", "rmdir", "link",
               "unlink", "readlink", "chmod", "chown",
               "lseek", "getpid", "socket", "connect",
               "accept", "sendto", "recvfrom", "bind",
               "listen", "epoll_create", "epoll_ctl",
               "epoll_wait", "futex", "set_tid_address",
               "set_robust_list", "clock_gettime", "getuid",
               "getgid", "geteuid", "getegid"],
      "action": "SCMP_ACT_ALLOW"
    }
  ]
}

Apply per-container:

services:
  api:
    image: my-api:latest
    security_opt:
      - seccomp:/path/to/profile.json
      - apparmor:docker-custom
    read_only: true
    tmpfs:
      - /tmp

Real-World Detection Examples

Detecting a Crypto Miner

A compromised npm dependency drops a crypto miner. Falco sees:

WARNING: Unexpected process in container
  proc=xmrig parent=node container=api-server
  cmdline=xmrig --pool stratum+tcp://pool.minexmr.com:4444

CRITICAL: Outbound connection to mining pool
  container=api-server dest=213.32.29.78:4444

Two alerts fire simultaneously — process anomaly and network anomaly. Your runbook says: isolate the container, capture the image for forensics, redeploy from a known-good image.

Detecting a Container Breakout Attempt

Free Resource

Infrastructure Security Audit Template

The exact audit template we use with clients: 60+ checks across network, identity, secrets management, and compliance.

Get the Template

An attacker exploits a vulnerability to write to the host filesystem:

CRITICAL: Write to sensitive host path
  proc=bash container=web-app
  file=/host/etc/crontab

CRITICAL: Container exec with host PID namespace
  proc=nsenter container=web-app
  cmdline=nsenter --target 1 --mount --uts --ipc --net --pid

Falco catches both the file write and the namespace escape attempt. With enforcement (read-only filesystem, seccomp profile blocking nsenter), the attack would be prevented, not just detected.

Integrating with Your Monitoring Stack

Falco generates events. You need to route them to where your team will actually see them:

# Prometheus metrics from Falco
- job_name: falco
  static_configs:
    - targets: ['falco-exporter:9376']

# Alert rules
groups:
  - name: falco-alerts
    rules:
      - alert: FalcoHighSeverity
        expr: falco_events{priority="Critical"} > 0
        for: 0m
        labels:
          severity: critical
        annotations:
          summary: "Critical Falco event detected"
          description: "{{ $labels.rule }}"

Route critical alerts to PagerDuty/Ntfy/Slack. Route warnings to a dashboard. Route notices to a log for weekly review.

The Minimum Viable Runtime Security Setup

You do not need all of this on day one. Start with:

  1. Deploy Falco with default rules (catches the obvious threats)
  2. Enable JSON logging to a file (for forensics)
  3. Write 3-5 custom rules for your specific containers (what processes should they run? What connections should they make?)
  4. Add seccomp profiles to your most exposed containers (web servers, API gateways)
  5. Set up one alert channel (Slack, Ntfy, or email) for critical-priority events

Then iterate: review Falco events weekly, tune rules to reduce false positives, add enforcement gradually.

The Bottom Line

Image scanning is the locked door. Runtime security is the security camera. You need both.

Falco with eBPF gives you real-time visibility into every container on your host with minimal overhead. Combined with seccomp profiles and AppArmor, you can detect AND prevent the threats that image scanning misses.

The tools are free, open-source, and battle-tested. The only cost is the time to write rules that match your actual workload. Start with the defaults, customize as you learn your baseline, and build enforcement gradually. Your containers are running right now — the question is whether you know what they are doing.

#docker#container-security#falco#ebpf#runtime-security#devsecops#threat-detection

Related Service

Security & Compliance

Zero-trust architecture, compliance automation, and incident response planning.

Need help with security?

TechSaaS provides expert consulting and managed services for cloud infrastructure, DevOps, and AI/ML operations.

We Will Build You a Demo Site — For Free

Like it? Pay us. Do not like it? Walk away, zero complaints. You will spend way less than hiring developers or any agency.

47+ companies trusted us
99.99% uptime
< 48hr response

No spam. No contracts. Just a free demo.