The Information Systems and Computer Applications examination covers material that is usually taught in an introductory college-level business information systems course.

Introducción a SystemTap

 

Al hilo de una antigua entrada de nuestro compañero Antonio Villalón acerca de Dtrace y Solaris, me propuse encontrar algo parecido para sistemas Linux. Dtrace te permitia recolectar información del sistema a muy bajo nivel para detectar anomalías en su funcionamiento y en algunos casos poder prevenir futuros problemas.

Tras un tiempo de búsqueda, y después de descartar varias opciones que no me parecían todo lo completas que deberían, me encontré con SystemTap, una maravillosa herramienta que nos permite monitorizar la actividad del kernel mediante scripts sin tener que compilar y reiniciar cada vez que se requiera ejecutar una prueba.

Es crítico para un administrador de sistemas tener un control total sobre que ocurre en el sistema y herramientas como SystemTap, que te permiten obtener datos precisos del funcionamiento del sistema son de gran ayuda. También aporta seguridad el hecho de poder tener controlado cualquier evento del sistema, ya no a nivel de aplicación, sino de kernel. Conocer qué procesos están abriendo cierto fichero, el consumo de red de cualquier proceso o la ejecución de X función dentro del kernel por Y proceso nos proporciona una ingente cantidad de información que puede resultar necesaria en caso de una detectar una intrusión.

Por el propósito que tiene, SystemTap no es sencillo. Aunque la base es fácil de comprender, su programación requiere conocimientos avanzados de los diferentes módulos del kernel de Linux, aparte de conocimientos de su propia sintaxis. Por suerte para nosotros, existe abundante documentación, y para facilitarnos la tarea y reducir la barrera de entrada existen ya multitud de scripts de ejemplo que nos permitirán ver su funcionamiento e imaginar las posibilidades que tiene SytemTap.

Su instalación es bastante sencilla. En una distribución Fedora basta con instarlo mediante Yum y luego usar un comando propio para que descargue e instale el paquete kernel-debug correspondiente a nuestra versión actual del kernel:

#yum install systemtap
#stap-prep

Como breve introducción, en SystemTap tenemos “events” y “handlers”. La construcción habitual en SystamTap suele ser la siguiente

#codigo#
probe event {statements}

En lo que respecta a los “events” existen dos tipos, síncronos y asíncronos. Un evento síncrono ocurre cuando cualquier proceso ejecuta una operación en el kernel. Como ejemplos de este tipo de eventos tenemos:

  • Entradas a syscalls.
  • Operaciones en el VFS (Virtual File System).
  • Entradas en funciones del kernel, por ejemplo “sys_open”.
  • Entradas en funciones de cierto modulo.
  • etc.

Los eventos asíncronos, por contra, son aquellos que no están ligados a ninguna instrucción particular en el código. Consisten principalmente en contadores y temporizadores.

Los “handlers” es la parte del código llamada cuando ocurre un “event”. Este código, una mezcla entre C y AWK, nos permite tratar la información del evento, almacenarla y en general, utilizar cualquier función disponible en cualquier lenguaje moderno (salida por pantalla, uso de vectores, funciones,…). Vamos a ver un ejemplo básico de “probe”, el cual almacenaremos en un fichero denominado probe.stp, y ejecutaremos con la orden stap probe.stp

####código####
probe syscall.open
{
printf ("%s(%d) open\n", execname(), pid())
}

En este ejemplo, cuando se realice cualquier llamada a la función open() el script escribirá por pantalla el nombre y el PID del proceso que ha ejecutado la llamada.

A partir de aquí, el asunto se puede complicar todo lo que queramos. Se pueden declarar funciones para factorizar el código, variables globales para compartir información entre handlers, timers, etc., y como con cualquier lenguaje nuevo hay que aprender la sintaxis. Por si esto no fuera suficiente, hay que conocer los eventos que podemos registrar en el kernel. Lo más recomendable para no desanimarnos es comenzar probando los scripts de prueba, ver como trabajan, y adaptarlos a nuestras necesidades, leyendo la documentación correspondiente en cada caso. En el wiki del proyecto encontrareis abundante información, y en Fedora, además, podemos instalar el paquete systemtap-testsuite el cual nos copiará en /usr/share/systemtap/testsuite/systemtap.examples/ multitud de ejemplos.

Por último, me gustaría compartir un script que me gustó mucho (está en el paquete de testsuite que hemos mencionado) y que nos permite conocer el consumo de red de cada proceso del sistema en tiempo real. Os invito a que lo reviséis, veáis como se programa un script un poco complejo y las posibilidades de la herramienta. El script tan sólo almacena en cada llamada a las funciones transmit y receive la información en vectores para luego, en función de un timer, mostrarla por pantalla. Aquí esta:

#! /usr/bin/env stap
global ifxmit, ifrecv
global ifmerged 

probe netdev.transmit
{
  ifxmit[pid(), dev_name, execname(), uid()] < << length
}

probe netdev.receive
{
  ifrecv[pid(), dev_name, execname(), uid()] <<< length
} 

function print_activity()
{
  printf("%5s %5s %-7s %7s %7s %7s %7s %-15s\n",
          "PID", "UID", "DEV", "XMIT_PK", "RECV_PK",
          "XMIT_KB", "RECV_KB", "COMMAND") 

  foreach ([pid, dev, exec, uid] in ifrecv) {
    ifmerged[pid, dev, exec, uid] += @count(ifrecv[pid,dev,exec,uid]);
  } 

  foreach ([pid, dev, exec, uid] in ifxmit) {
    ifmerged[pid, dev, exec, uid] += @count(ifxmit[pid,dev,exec,uid]);
  } 

  foreach ([pid, dev, exec, uid] in ifmerged-) {
     n_xmit = @count(ifxmit[pid, dev, exec, uid])
     n_recv = @count(ifrecv[pid, dev, exec, uid])
     printf("%5d %5d %-7s %7d %7d %7d %7d %-15s\n",
            pid, uid, dev, n_xmit, n_recv,
            n_xmit ? @sum(ifxmit[pid, dev, exec, uid])/1024 : 0,
            n_recv ? @sum(ifrecv[pid, dev, exec, uid])/1024 : 0,
            exec)
  } 

  print("\n") 

  delete ifxmit
  delete ifrecv
  delete ifmerged
} 

probe timer.ms(5000), end, error
{
  print_activity()
}

Comments are closed.