Aprendiendo eBPF para observabilidad, optimización y seguridad.
Publicado el: 13 de noviembre de 2025
8 min de lectura
Contenido
- 🧠 ¿Qué es eBPF?
- ⚙️ ¿Cómo funciona eBPF?
- 🧮 ¿Para qué se utiliza eBPF?
- 🚀 ¿Cómo empezar con eBPF?
- 🧑💻 Escribiendo programas eBPF sencillos con BCC
- ✨ Conclusión
- 📚 Bibliografía y recursos recomendados
🧠 ¿Qué es eBPF?
eBPF (Extended Berkeley Packet Filter) es una tecnología avanzada de Linux que permite la ejecución segura de programas en el espacio del kernel sin necesidad de modificar el código o cargar módulos; brindando una forma eficiente y flexible de monitorear, analizar y modificar el comportamiento del sistema operativo en tiempo real. eBPF se ha convertido en una herramienta esencial para la observabilidad, seguridad y optimización del rendimiento en sistemas Linux, aunque también es compatible con otras plataformas como Windows a través de proyectos como eBPF for Windows y para sistemas embebidos con proyectos como micro-BPF; aquí nos centraremos en su uso y funcionamiento en Linux.⚙️ ¿Cómo funciona eBPF?
Ésta tecnología permite a los desarrolladores escribir programas en un lenguaje de bajo nivel similar a C. Estos programas se compilan y se convierten a un bytecode eBPF que es verificado por el kernel de Linux para garantizar que sea seguro antes de ser cargado y ejecutado en el espacio del kernel. Los programas eBPF pueden adjuntarse a varios puntos de entrada en el kernel, como llamadas al sistema, eventos de red, todos los puntos donde se puede recoger información con perf, rastreo de funciones, y más; lo que permite una gran flexibilidad en su uso.🧮 ¿Para qué se utiliza eBPF?
Se utiliza para una variedad de propósitos, incluyendo:- Monitoreo: permite la recolección de métricas y eventos del sistema en tiempo real.
- Seguridad: facilita la implementación de políticas de seguridad y la detección de intrusiones.
- Optimización del rendimiento: ayuda a identificar cuellos de botella y mejorar la eficiencia del sistema.
- Redes: mejora la gestión del tráfico de red y la implementación de firewalls.
Existen muchos proyectos y herramientas que aprovechan y facilitan el uso de eBPF, algunos son:
- Cilium: una plataforma de redes y seguridad para contenedores que utiliza eBPF para proporcionar visibilidad y control de red.
- BCC (BPF Compiler Collection): un conjunto de herramientas y bibliotecas para crear programas eBPF de manera sencilla.
- bpftrace: una herramienta de trazado de alto nivel que facilita la escritura de scripts eBPF para monitoreo y depuración.
- libbpf: una biblioteca que proporciona una API para interactuar con eBPF desde aplicaciones de usuario.
🚀 ¿Cómo empezar con eBPF?
En éste artículo, usaremos comandos one-liners de eBPF para obtener información básica del sistema y escribiremos un programa simple usando la biblioteca BCC en Python. Asegúrate de tener un entorno Linux con soporte para eBPF (kernel 4.4 o superior) y las herramientas necesarias instaladas. Para empezar instalaremos BCC y las demás herramientas necesarias en una distribución basada en Debian/Ubuntu:sudo apt-get update
sudo apt-get install bpfcc-tools linux-headers-$(uname -r) libbpfcc-dev python3-bpfcc
Las herramientas de BCC incluyen varios scripts útiles que podemos usar directamente desde la línea de comandos. Por ejemplo, para monitorear los archivos abiertos en el sistema, con información sobre el proceso que los abrió y el nombre del archivo, podemos usar el siguiente comando:
sudo /usr/sbin/opensnoop-bpfcc
Mientras el comando está en ejecución, abre otro terminal y ejecuta el comando “ls” o abre archivos para ver cómo se registran en tiempo real. Para detener la ejecución y mirar la salida, presiona Ctrl + C en el primer terminal.

Salida del comando opensnoop-bpfcc mostrando procesos como code,ls y los archivos que están abriendo.
Este comando nos proporciona una visión en tiempo real de los archivos que se están abriendo en el sistema, en el caso del ejemplo, vemos procesos como code y ls y los archivos que están abriendo; ésta información es útil para monitorear la actividad del sistema y detectar comportamientos inusuales. En el repositorio de BCC, encontrarás scripts y one-liners de eBPF que puedes explorar para diferentes propósitos, como monitorear el uso de CPU, la actividad de red, entre otros.

Diagrama de herramientas de trazado disponibles en BCC.
🧑💻 Escribiendo programas eBPF sencillos con BCC
Ahora, vamos a escribir un programa eBPF simple que imprima: “Hola, mundo” cada que se crea un nuevo proceso usando la llamada al sistema sys_clone. Crea un archivo llamado hello_ebpf.py y agrega el siguiente código:#!/usr/bin/python
#
# This is a Hello World example that formats output as fields.
from bcc import BPF
from bcc.utils import printb
# define BPF program
prog = """
int hello(void *ctx) {
bpf_trace_printk("Hola, mundo!\\n");
return 0;
}
"""
# load BPF program
b = BPF(text=prog)
b.attach_kprobe(event=b.get_syscall_fnname("clone"), fn_name="hello")
# header
print("%-18s %-16s %-6s %s" % ("TIME(s)", "COMM", "PID", "MESSAGE"))
# format output
while 1:
try:
(task, pid, cpu, flags, ts, msg) = b.trace_fields()
except ValueError:
continue
except KeyboardInterrupt:
exit()
printb(b"%-18.9f %-16s %-6d %s" % (ts, task, pid, msg))
Guarda el archivo y ejecuta el script con permisos de superusuario:
sudo python3 hello_ebpf.py
Ahora, cada vez que se cree un nuevo proceso en el sistema, verás el mensaje “Hola, mundo!” en la salida de la terminal, junto con información sobre el proceso que lo generó. Puedes probar esto abriendo nuevas terminales y ejecutando comandos como “ls”, “cat”, etc. Para detener la ejecución, presiona Ctrl + C.

Salida del programa hello_ebpf.py mostrando “Hola, mundo!” cada que se crea un nuevo proceso.
El script utiliza BCC para definir un programa eBPF que se adjunta a la llamada al sistema clone, que es responsable de crear nuevos procesos. Cada vez que se llama a clone, el programa eBPF imprime el mensaje en el búfer de trazas del kernel, que luego es leído, formateado y presentado en la terminal por el script de Python.
⚠️ La función bpf_trace_printk() es simple pero tiene limitaciones (máximo 3 argumentos) y solo debe usarse para pruebas. Para herramientas de producción, se usa BPF Maps o perf buffers para una transferencia de datos eficiente entre el kernel y el espacio de usuario.
Volviendo a nuestro primer one-liner opensnoop-bpfcc, escribamos una versión simplificada en Python usando BCC. Crea un archivo llamado open_files.py y agrega el siguiente código:
#!/usr/bin/python
from bcc import BPF
prog = """
struct data_t {
u32 pid;
char comm[16];
char filename[256];
};
BPF_PERF_OUTPUT(events);
TRACEPOINT_PROBE(syscalls, sys_enter_openat) {
struct data_t data = {};
// Obtener PID y comando
u64 pid_tgid = bpf_get_current_pid_tgid();
data.pid = pid_tgid >> 32;
bpf_get_current_comm(&data.comm, sizeof(data.comm));
// Leer filename desde los argumentos del tracepoint
// args->filename contiene el puntero
bpf_probe_read_user_str(&data.filename, sizeof(data.filename), (void *)args->filename);
events.perf_submit(args, &data, sizeof(data));
return 0;
}
"""
b = BPF(text=prog)
print("%-16s %-6s %s" % ("PROCESO", "PID", "ARCHIVO"))
print("=" * 80)
def print_event(cpu, data, size):
event = b["events"].event(data)
comm = event.comm.decode('utf-8', 'replace')
filename = event.filename.decode('utf-8', 'replace').rstrip('\x00')
# Solo imprimir si hay un nombre de archivo válido
if filename and len(filename) > 0:
print("%-16s %-6d %s" % (comm, event.pid, filename))
b["events"].open_perf_buffer(print_event)
print("Capturando... Presiona Ctrl+C para salir\n")
try:
while 1:
b.perf_buffer_poll()
except KeyboardInterrupt:
print("\nFinalizando...")
Guarda el archivo y ejecútalo con permisos de superusuario:
sudo python3 open_files.py
Ahora, cada vez que un proceso abra un archivo, verás el nombre del proceso, su PID y el nombre del archivo en la terminal. Puedes verificar abriendo otra terminal y ejecutando comandos que abran archivos, como “cat”, “ls”, etc.

Salida del script open_files.py capturando archivos abiertos con información sobre el proceso que los abre.
En éste script usamos de nuevo la biblioteca BCC para cargar y ejecutar un programa eBPF que rastrea las llamadas al sistema de apertura de archivos mediante el tracepoint “syscalls:sys_enter_openat”.
Explicación breve del código:
-
Se define la estructura (data_t) para guardar el PID del proceso, el nombre del comando y el nombre del archivo abierto.
-
Se usa un tracepoint probe sobre sys_enter_openat que se activa cada vez que un proceso llama a la función openat para abrir un archivo.
-
En el probe, obtenemos el PID y el nombre del comando del proceso actual.
-
Luego, usamos bpf_probe_read_user_str para leer el nombre del archivo abierto.
-
Enviamos la información a espacio usuario a través de un buffer de eventos perf (events.perf_submit).
-
En Python, se imprime una cabecera y se define una función para recibir eventos desde el buffer perf y mostrar en consola el proceso, PID y archivo abierto.
-
Se ejecuta un loop que escucha eventos en tiempo real hasta que se interrumpe con Ctrl+C.