Join our Newsletter — 33% off our NHI Course
Home› Guides› eBPF Security Guide: Control Who Loads BPF and…
Guide Endpoint Security

eBPF Security Guide: Control Who Loads BPF and Detect Abuse

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 27 October 2026 13 min read
On this page

eBPF lets privileged code run inside the Linux kernel without a module, which is why the same technology powers modern EDR, observability and networking, and also a growing class of Linux rootkits. Most hosts and clusters give no thought to who may load BPF programs, which programs are loaded, or how to tell a legitimate agent from a malicious one. This guide covers the BPF privilege model (unprivileged BPF, CAP_BPF, CAP_PERFMON and CAP_SYS_ADMIN), how to treat eBPF based agents as privileged software, the artefacts to inventory and monitor, and a hardening baseline with kernel settings, lockdown and container controls. It is for Linux platform engineers, Kubernetes operators and detection engineers. Broader Linux detection is in the Linux Detection and Response Guide.

Key takeaways

  • Turn off unprivileged BPF. Set kernel.unprivileged_bpf_disabled to 1 (cannot be cleared until reboot) or 2 (admin can re-enable); the upstream default is 0 unless the kernel was built with BPF_UNPRIV_DEFAULT_OFF.
  • CAP_BPF is a kernel level privilege. Since Linux 5.8 it separates BPF from CAP_SYS_ADMIN, but any process holding it, or CAP_SYS_ADMIN, can load programs that observe or alter the whole host.
  • Detect at load time. Once a malicious program is running, tools such as ps and ss may lie. Audit the bpf() syscall and alert on unexpected program loads.
  • Know your legitimate programs. EDR, CNI plugins, service meshes and profilers all load BPF. An inventory of expected program types, names and owning processes is the baseline every alert depends on.
  • Classic BPF matters too. BPFDoor hides behind classic BPF socket filters attached with SO_ATTACH_FILTER; check sockets with ss -0pb, not only bpftool.

Who can load BPF: the privilege model

A BPF program is bytecode loaded through the bpf(2) syscall (BPF_PROG_LOAD), checked by the in-kernel verifier, compiled and attached to a hook: a kprobe or tracepoint, a network interface (XDP or TC), a socket, a cgroup, or an LSM hook. Programs share data with user space through maps and can be pinned in the BPF file system (/sys/fs/bpf) so they outlive the process that loaded them. The verifier checks memory safety and termination; it does not judge intent. A program that hides a file or rewrites syscall results can be perfectly verifier safe.

ControlValues and effectSource
kernel.unprivileged_bpf_disabled0: unprivileged bpf() allowed. 1: disabled, cannot be cleared on the running kernel. 2: disabled, admin can write 0 or 1 later. Default 0, or 2 with BPF_UNPRIV_DEFAULT_OFFKernel sysctl documentation
CAP_BPF (Linux 5.8+)"Employ privileged BPF operations"; added to separate BPF from CAP_SYS_ADMINcapabilities(7)
CAP_PERFMON (Linux 5.8+)Performance monitoring, perf_event_open, and BPF operations with performance implications (tracing)capabilities(7)
CAP_SYS_ADMINCan perform the same BPF operations as CAP_BPF; capabilities(7) prefers the narrower capabilitycapabilities(7)
kernel.perf_event_paranoidDefault 2: kernel profiling, CPU events and raw tracepoints need CAP_PERFMONKernel sysctl documentation
Kernel lockdownLockdown lists BPF and kprobes among blocked features and logs "Lockdown: X: Y is restricted"kernel_lockdown(7)
Container seccomp defaultDocker's default profile blocks bpf ("Deny loading potentially persistent BPF programs into kernel") and perf_event_openDocker seccomp documentation

Kernel build options also matter. Zscaler's analysis of eBPF malware recommends ensuring CONFIG_BPF_KPROBE_OVERRIDE is not set unless needed, because return value overrides let a program make a syscall fail on demand, for example to stop a tool that would reveal it. Appliance and container host kernels can often drop kprobes and BPF features they do not use.

Privileged access: treating BPF capabilities as admin rights

Because a BPF program can read kernel and process data across the host, a principal that can load one is effectively a kernel administrator for observation purposes, and with the right hooks and helpers, for enforcement too. The BPF LSM, documented in the kernel as a way for "privileged users" to implement system-wide MAC and audit policies, shows the power: a program attached to an LSM hook returns -EPERM and the operation is denied host wide.

  • Grant CAP_BPF and CAP_PERFMON, not CAP_SYS_ADMIN: where an agent supports it, run it with the narrow capabilities. See the Linux Capabilities Guide.
  • Remove BPF rights from interactive sessions: developers need bpftrace and bpftool on test hosts, not on production. Control their use through sudo rules with logging; see the sudo and sudoers Security Guide.
  • Containers: never give workload containers CAP_SYS_ADMIN, CAP_BPF or --privileged; keep the runtime default seccomp profile, which blocks bpf. A container that can load BPF can observe or interfere with every other container on the node (escape class risk, ATT&CK T1611). See the seccomp Guide.
  • Kubernetes: the DaemonSets that legitimately need BPF (CNI, runtime security, observability) should be few, named, in dedicated namespaces and allowed through an admission policy exception rather than by relaxing the policy for everyone. See the Kubernetes Admission Control Guide.

Decision guidance

EnvironmentRecommended postureTrade-off
General purpose servers with an EDR agentunprivileged_bpf_disabled=1; only the agent holds BPF capabilities; audit bpf()Developers lose ad hoc tracing in production; give them a break glass procedure
Kubernetes nodes with eBPF CNI or runtime securityUnprivileged BPF off; runtime default seccomp for workloads; admission exceptions for named DaemonSets onlyEvery new observability tool needs a reviewed exception
Fixed function appliances and high assurance hostsKernel lockdown, or kernels built without unneeded BPF and kprobe featuresSome EDR and performance tools will not run; confirm vendor support first
Developer and lab hostsUnprivileged BPF off, sudo access to bpftrace loggedMinor friction; keeps habits safe

eBPF tooling, agents and their credentials

The legitimate eBPF footprint on a modern host is large: EDR and runtime security sensors, Kubernetes CNI plugins and service meshes, continuous profilers, and network observability agents. Each runs as root or with BPF capabilities, receives updates from a vendor, and usually holds an enrolment token, API key or client certificate for its management service. That makes the agent a privileged non-human identity on every host it touches.

  • Supply chain: the agent's update channel can push new kernel side code to the whole estate. Require signed packages from a trusted repository, staged rollout rings and the ability to pin versions. See the Linux Package Signing and Repository Trust Guide.
  • Agent credentials: store enrolment tokens and API keys with file permissions limited to the agent account, rotate them, and scope them to the minimum the console allows. Treat a leaked sensor token as a high severity incident. See the Service Account Security Guide.
  • Tamper protection: an attacker with root can unload or blind a BPF based sensor. Monitor for the agent stopping, its programs disappearing and its heartbeat going quiet, as covered in the EDR Tampering and BYOVD Response Playbook.
  • Policy engines: tools that enforce with the BPF LSM are powerful but are a single point of failure. Test policies in audit mode and keep a documented rollback.

Logging and detection

Zscaler's eBPF malware analysis puts it bluntly: the best chance to detect eBPF malware is when it loads, because after installation the output of system tools may not be trustworthy. Datadog Security Labs' 2026 research on eBPF rootkits (naming families such as VoidLink and LinkPro) takes the same load time focus. Known techniques include hiding command traffic with XDP and TC programs (ebpfkit), hooking socket options to hide traffic from packet capture (Symbiote), and rewriting user space memory during syscalls (bad-bpf research). In ATT&CK v20 this behaviour maps to T1014 Rootkit, T1547.006 Kernel Modules and Extensions, and, for packet filter triggered backdoors, T1205.002 Socket Filters.

Artefacts to inventory and compare

ArtefactHow to inspectWhat looks wrong
Loaded programsbpftool prog (type, name, tag, load time, owning PIDs)Program types or names not in your baseline; programs loaded outside agent install windows
Program to process mappingbpftool perfkprobe or tracepoint programs owned by an unknown process
Pinned objectsList /sys/fs/bpfPinned programs or maps that no known agent owns
XDP and TC programsip link show dev <if>, tc filter show dev <if>XDP or TC programs on hosts that run no eBPF networking
Kprobes/sys/kernel/debug/kprobes/listProbes on syscalls used for file, process or network listing
Classic BPF socket filtersss -0pbPacket sockets with filters held by unexpected processes; Trend Micro uses this to find BPFDoor
Kernel logdmesg -k, journalWarnings for the bpf_probe_write_user helper; Lockdown denials
  • Syscall auditing: record every bpf() call that loads a program with an auditd rule on the bpf syscall, or use your EDR's BPF load event. Alert when the loading executable is not on the approved list. See the Linux Logging and auditd for Defenders Guide.
  • Helper warning: the kernel prints a warning when a program uses bpf_probe_write_user. Elastic ships a high severity rule matching that kernel message and maps it to T1547.006 and T1014; expect false positives only from debugging tools.
  • Configuration drift: alert if unprivileged_bpf_disabled drops to 0 or if a host that should be locked down reports none in /sys/kernel/security/lockdown.
  • Cross-check from outside the host: because a rootkit can filter local tools, compare network flow data from switches or cloud flow logs with what the host reports. BPFDoor's magic packet is processed in the kernel before host firewall rules, according to Trend Micro, so a host firewall alone does not stop activation.

Metrics

  • Unprivileged BPF disabled: percentage of Linux hosts with unprivileged_bpf_disabled of 1 or 2 (target 100%).
  • Unknown programs: count of loaded BPF programs not matched to an approved agent, per week (target zero after baselining).
  • BPF capable principals: number of services and containers holding CAP_BPF, CAP_PERFMON or CAP_SYS_ADMIN, trending down.
  • Load event coverage: share of hosts sending BPF load events to the SIEM.
  • Privileged workload exceptions: number of Kubernetes workloads allowed to load BPF, each with an owner.

Hardening baseline

Rollout plan

  1. Inventory: collect bpftool prog, bpftool perf, /sys/fs/bpf, ss -0pb and capability sets of running services from a representative sample of hosts and nodes. Map each program to its agent and vendor.
  2. Disable unprivileged BPF: set kernel.unprivileged_bpf_disabled=2 in /etc/sysctl.d/ first, so it can be reverted without a reboot if something breaks; move to 1 once a pilot ring shows no impact.
  3. Reduce capabilities: move agents from CAP_SYS_ADMIN to CAP_BPF plus CAP_PERFMON where the vendor supports it; remove BPF capabilities from everything else.
  4. Lock containers: enforce runtime default seccomp and forbid privileged Pods and added CAP_SYS_ADMIN or CAP_BPF outside named exceptions.
  5. Turn on load time detection: audit bpf(), ship kernel logs, and build the "unknown program" alert from the inventory.
  6. Consider lockdown and kernel options: on hosts that run no eBPF agent, evaluate lockdown and kernels without CONFIG_BPF_KPROBE_OVERRIDE. Test in a pilot ring first because lockdown also restricts other debugging features. Kernel settings are in the Linux Kernel Hardening and sysctl Guide.
  7. Rollback: keep a documented procedure to set the sysctl to 0 (only possible from value 2), to grant a capability temporarily, and to boot without lockdown, each needing a change record.

Framework mapping

FrameworkReferenceHow it applies
NIST SP 800-53 Rev. 5AC-6 Least Privilege; AC-6(10) Prohibit Non-privileged Users from Executing Privileged FunctionsUnprivileged BPF off; narrow capabilities for agents
NIST SP 800-53 Rev. 5CM-6 Configuration Settings; CM-7 Least Functionalitysysctl baseline; kernels without unneeded BPF and kprobe features
NIST SP 800-53 Rev. 5SI-4 System Monitoring; AU-12 Audit Record Generation; SI-7 Software, Firmware, and Information IntegrityBPF load auditing, program inventory, lockdown
NIST CSF 2.0PR.AA-05, PR.PS-01, DE.CM-09Enforced permissions, configuration management, runtime monitoring
CIS Controls v8.1Control 4 Secure Configuration; Control 8 Audit Log ManagementKernel settings baseline and load event logging
MITRE ATT&CK v20T1014 Rootkit; T1547.006 Kernel Modules and Extensions; T1205.002 Socket Filters; T1611 Escape to HostDetection content and threat model

Common misconfigurations

  • Unprivileged BPF left on: older images and custom kernels still default to 0. Unprivileged BPF has repeatedly been a route to kernel privilege escalation (ATT&CK T1068), which is why many distributions now turn it off.
  • Privileged observability containers everywhere: a profiler or log shipper deployed with privileged: true because it was easier than listing capabilities. Every such Pod can load BPF on the node.
  • No baseline of legitimate programs: without it, an unknown kprobe looks like any other agent's program, and investigators give up.
  • Trusting host tools during an incident: an eBPF rootkit can hide processes and connections from ps, ss and packet capture. Collect memory and external network evidence; see the Rootkits and Bootkits Guide.
  • Only looking for eBPF: BPFDoor, attributed by Trend Micro to Red Menshen and seen against telecoms operators, uses classic BPF socket filters that bpftool inventories can miss. Include ss -0pb in host checks.
  • Agent tokens in world readable files: the BPF sensor is protected but its enrolment token is not, letting an attacker register rogue sensors or query the console.

Practitioner checklist

  • Set kernel.unprivileged_bpf_disabled to 1 or 2 on every Linux host and alert on drift.
  • Inventory loaded BPF programs, pinned objects, XDP, TC and socket filters, and map each to an approved agent.
  • Run eBPF agents with CAP_BPF and CAP_PERFMON instead of CAP_SYS_ADMIN where supported.
  • Keep runtime default seccomp for containers and block privileged Pods outside named exceptions.
  • Audit bpf() program loads and alert on unknown loaders.
  • Alert on kernel warnings for bpf_probe_write_user and on Lockdown denials.
  • Evaluate lockdown and reduced kernel BPF features for hosts that run no eBPF tooling.
  • Protect and rotate eBPF agent enrolment tokens and API keys like other privileged machine credentials.
  • During incidents, validate host data against external network telemetry.

Standards and references

Related NHI Mgmt Group resources: Linux Detection and Response Guide · EDR Guide · Container Runtime Security Guide · Linux Capabilities Guide

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 27 October 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org