Monitorización usando eBPF y bpftrace en Ubuntu 25

QUÉ VAMOS A CONSTRUIR

  • Preparación del servidor Ubuntu 25 con las cabeceras exactas del kernel para compilar en vivo.
  • Creación y ejecución de sondas de lectura/escritura de disco para cazar latencias ocultas.
  • Rastreo de conexiones de red TCP entrantes saltándonos el ruido de las herramientas clásicas de espacio de usuario.

Vamos a configurar las herramientas de trazabilidad a bajo nivel en tu servidor. Lo primero que se suele romper aquí es la paciencia cuando los monitores tradicionales fallan. Estás mirando el comando top, ves que el procesador está relajado, no hay consumo excesivo de RAM, pero la base de datos responde peor que conectarse vía módem de 56k.

#Requisitos Previos

Para que esto levante, necesitamos un entorno controlado. Si tu servidor colapsa por mala configuración de red en medio de esto, vas a necesitar acceso de consola fuera de banda.

  • Una instalación limpia o en uso de Ubuntu 25 (Noble/Oracular o equivalente, con kernel 6.8 o superior).
  • Acceso root absoluto o un usuario con privilegios de sudo completos. No intentes esto con permisos restringidos.
  • Conexión estable a los repositorios oficiales de Ubuntu para descargar repos de compilación asimétrica.

¡CUIDADO!

Cuidado con lanzar sondas de red demasiado amplias (como atrapar cada paquete IPv4) en un entorno de producción que sirva miles de peticiones. Podrías consumir toda la CPU en la propia recolección de datos y hacer tambalear el servicio. Iremos paso a paso aplicando filtros.

#El Entorno / Setup Inicial

El error más común es arrancar sin las cabeceras del núcleo. Necesitamos emparejar compuertas. eBPF compila tu script, lo valida mediante el verificador estricto del sistema y lo inyecta.

Actualizar paquetes e instalar dependencias base en terminal:

bash
sudo apt update
# Requerimos clang como backend LLVM para compilar y libbpf
sudo apt install -y bpfcc-tools linux-headers-$(uname -r) bpftrace

La salida esperada de este comando será el clásico volcado de instalación de apt. Asegúrate de verificar que el paquete linux-headers descargado coincide exactamente con la salida de tu comando uname -r.

#Paso a Paso

#Paso 1: Tu primera sonda de disco con bpftrace

Vamos a cazar el proceso que está saturando el almacenamiento físico. Construiremos un one-liner (un comando de una sola línea) que enganche un rastreador en el evento interno que se dispara al solicitar un bloque de E/S.

Ejecutar directamente en tu línea de comandos como usuario root:

bash
sudo bpftrace -e 'tracepoint:block:block_rq_issue { printf("PID: %d command: %s intentando acceso a IO\n", pid, comm); }'
# El flag -e le indica al intérprete que lea el código a continuación
# tracepoint:block... es el evento estático dentro del kernel
# Usamos PID y COMM integrados en el entorno de bpftrace

La salida esperada debe ser una lista de líneas parpadeando por tu pantalla, avisando de qué software (por ejemplo systemd-journald o postgres) está triturando los cilindros virtuales de tu disco. Al cabo de 5 segundos, aprieta CTRL+C.

#Paso 2: Monitorización de red silenciosa

Si la red sufre micro-cortes, tcpdump genera pcap gigantes de gigabytes. Vamos a pedirle al corazón del sistema operativo que cuente cuántas conexiones recibe cada aplicación, directamente desde el socket de red interno, ignorando la payload para salvar procesamiento.

Crear un archivo temporal para el script más complejo en /tmp/net.bt:

bash
cat << 'EOF' > /tmp/net.bt
#include <linux/net.h>

kprobe:inet_csk_accept
{
    // Capturamos el inicio de una conexión entrante TCP
    @conexiones[comm] = count();
}

interval:s:5
{
    // Cada 5 segundos, arrojamos el recuento a la consola y limpiamos
    print(@conexiones);
    clear(@conexiones);
}
EOF

Disparar el archivo creado:

bash
sudo bpftrace /tmp/net.bt

Esto te indicará qué demonios en tu máquina están lidiando con el aluvión, consolidado cada cinco segundos. Alguien debe procesar el tráfico; si ves un servicio no autorizado sumando números ahí, tienes un problema grave de permisos.

NOTA TÉCNICA

Hemos usado un kprobe en lugar de un tracepoint. Los tracepoints son APIs estables que sobreviven entre actualizaciones de Ubuntu. Los kprobes son pinchazos directos al nombre de una función de C dentro del código fuente de Linux (en este caso inet_csk_accept). Si cambias de versión mayor del núcleo, el nombre de la función podría haberse modificado.

#Validación: Cómo saber que no hemos roto nada

La maravilla de esta tecnología es que las instrucciones corren en una caja de arena restrictiva. Para confirmar que el entorno sigue limpio tras detener nuestros scripts (usando un simple interrupción de teclado), verificaremos que los módulos precompilados de sistema se encuentran desenganchados.

Listar los programas eBPF activos en memoria:

bash
sudo bpftool prog show
# Deberías ver una salida mínima con programas de red nativos (como cilium si lo usas, 
# o hooks de systemd). Si no ves rastros de tu script 'net.bt', el ring buffer se ha liberado.

Otra comprobación sencilla es revisar tu disco. Lanza una carga arbitraria ejecutando dd if=/dev/zero of=/tmp/test_dd bs=1M count=500. Si dejaste el script de I/O encendido en otro terminal, captarás el evento de dd escribiendo basura. Cierra el monitor para regresar a la normalidad.

#Troubleshooting Frecuente

Este es el paso donde demasiada gente tira la toalla. Repasemos los dos muros contra los que te vas a estrellar con mayor seguridad:

  1. Error «Missing kernel headers»: Como comenté antes, actualizar el kernel pero no reiniciar deja al servidor corriendo un núcleo obsoleto en memoria mientras las cabeceras instaladas corresponden a la nueva versión que yace en frío en el disco. La solución es drástica: sudo reboot si las versiones no encajan.
  2. Tu script salta con «Permission denied»: Acabas de intentar lanzar bpftrace desde tu cuenta estándar protegida, asumiendo que te lo dejaría correr por ser inofensivo. El parche de seguridad inamovible requiere ser administrador legítimo. Invoca el superusuario.

TIP PRO

Puedes limitar la duración de las sondas desde la propia línea de comandos exportando un simple timeout, o usar herramientas preempaquetadas como execsnoop-bpfcc. Esta herramienta captura todo lo que el sistema arranca internamente sin usar un shell visible. Inestimable para auditorías exprés.

#Plan de Rollback / Limpieza

Imagina que quieres retroceder y desinstalar absolutamente todos los paquetes de monitoreo introducidos porque necesitas que tu entorno base de producción quede inmaculado (o porque quieres ahorrar los pocos MB que pesan las utilidades).

Para barrer las herramientas, mata las posibles ejecuciones zombis perdidas y desmonta el ecosistema instalado con apt.

Limpieza de la máquina:

bash
# Matamos cualquier instancia zombi de nuestro compilador justo a tiempo
sudo pkill -9 -f bpftrace || true 

# Purgamos la suite dejando fuera la parte básica del propio sistema
sudo apt purge --autoremove -y bpfcc-tools bpftrace

Una vez ejecutado, el servidor volverá a su quietud original. Cero dependencias colgadas, cero compiladores consumiendo inodos. Es el tipo de rescate rápido por si las cosas se ponen inciertas en auditoría.

A partir de aquí, el siguiente paso evolutivo natural es sacar estas métricas que hemos escupido directamente en terminal y mandarlas estructuradas vía agentes de Prometheus o similares para un dashboard permanente en tus nodos corporativos.

Qué quieres analizar hoy Comando Clandestino / Sonda Mágica
Nuevos procesos (Execsnoop) execsnoop-bpfcc
Apertura de archivos ocultos opensnoop-bpfcc
Recuento de bloqueos I/O bpftrace -e 'tracepoint:block:block_rq_issue { @ = count(); }'
Desenganchar procesos de pánico sudo pkill -9 bpftrace
Revisar si quedan sondas activas sudo bpftool prog show