logo izquierdo de la pagina

CONTADORD - Counter daemon

logo de la pagina

Demonio contador

Demonio contador. Cuenta en una DB las lineas (keys) iguales que recibe de la "named pipe". Para hacer estadísticas "al vuelo".

La DB se mantiene en parte en memoria (cachés de sistema y programa) pero periódicamente o cuando se le ordena, la salva a disco.

Probado únicamente en Linux Debian Sarge, pero debe funcionar en cualquier distribución que disponga de Perl. En otros sistemas Unix, puede que no funcione el arranque "a posteriori", después del arrancado el cliente.

Prerequisitos

  • Unix (Linux)
  • Perl
  • BerkeleyDB (p.e. libdb4.4) y el módulo correspondiente para acceso desde Perl
    (Notar que el daemon podría prescindir de enlazar el hash con una DB: en realidad bastaría salvar los datos periódicamente en un fichero texto).
    En un Debian se instala todo con sólo ejecutar:
  apt-get install libberkeleydb-perl

Instalación/Configuración

  • Salvar el fichero apuntado por este enlace. Darle el nombre "contadord".
  • Editar si necesario. En las primeras líneas del programa se pueden configurar el lugar donde abre la FIFO de comunicación, el lugar donde mantiene la DB en disco y el periódo en segundos con que vuelca la DB a disco:
    $FIFO = '/var/run/clamav/contador.fifo';
    $FIDB = '/usr/local/etc/contador.db';
    $timeup=300; 

Lanzarlo

Simplemente, ejecutar:

    ./contadord

Uso

Una vez lanzado, escribir en la pipe una palabra y la contará.

Por ejemplo, cada vez que se ejecute

  echo prueba >/var/run/clamav/contador.fifo

sumará una unidad al contador "prueba", que ha creado con valor 0 la primera vez.

Se pueden sumar N unidades de golpe; por ejemplo para sumar 4 pruebas más:

  echo "prueba 4" >/var/run/clamav/contador.fifo

Para terminar el contadord, escribir en la FIFO "TERMINA" en mayúsculas:

  echo "TERMINA" >/var/run/clamav/contador.fifo

Para forzar a que vuelque a disco la DB que mantiene en memoria, escribir en la FIFO "SYNC" en mayúsculas:

  echo "SYNC" >/var/run/clamav/contador.fifo

Observar que, dada la naturaleza arbitraria de los nombres de las variables a contar, es perfectamente posible utilizar un único contadord para contabilizar múltiples y diferentes aplicaciones: basta con generar distintos espacios de nombres (p.e.: "antivirus.arranques", "miprograma.llamadas",...).

Ejemplo de llamada desde C:

En este ejemplo, se abre la fifo y se cuentan los arranques del programa cliente. Observar que la FIFO se abre con un no-block para que el programa cliente no se ralentize y pueda funcionar aunque no este el demonio.


int cfd= -1;

/*-------------------------------------------------------------------------*/
int abreContador(char *nombre)
{
  /* Se abre O_RDWR para poder lanzar contadordb LUEGO sin tener que 
   * rearrancar -solo en Linux- */
  int contafd=open(nombre,O_RDWR|O_NONBLOCK);
  if (contafd < 0 ) {
    if(use_syslog)
         syslog(LOG_ERR,"Can't open (%d) count fifo %s",errno,nombre); 
    perror("count FIFO open");
    }
  return contafd;
}

/*-------------------------------------------------------------------------*/
void cuenta(int contafd,char *tag, int n)
{
  char value[200];
  if (contafd <0) return;
  if (n==1) 
    snprintf(value,200,"%s\n",tag);
  else
    snprintf(value,200,"%s %d\n",tag,n);
  write(contafd,value,strlen(value));
}

/*-------------------------------------------------------------------------*/

#define FIFOCONTA "/var/run/clamav/contador.fifo"

       cfd=abreContador(FIFOCONTA);  /* CIUV abre la DB de contadores */
       cuenta(cfd,"arranques",1);


Visualización de los contadores y totalización de resultados

Los resultados se almacenan en la DB Berkeley mencionada. Un simple barrido de la misma proporciona la lista de resultados.

A continuación se muestran tres ejemplos escritos en Perl y shell, utilizados para el conteo de virus detectados por un Milter de Sendmail basado en el antivirus clamav.

Estos ejemplos son programas CGI-BIN, que generan una página HTML con el resultado. Para consultarlos desde un navegador basta instalarlos en un directorio de ejecutables de un servidor web (el cgi-bin de un Apache, p.e.). ¡Proteger con contraseña si los datos son confidenciales!.

  • EstadisticasClam vuelca en HTML el contenido de la DB, organizando los valores en base a la aplicación concreta.
  • EstadisticasClamCHECK script shell que genera un "checkpoint", es decir, una copia de la DB en un momento de tiempo dado, para luego llamar a:
  • EstadisticasClamDIFF que vuelca una diferencia entre los valores actuales y los almacenados durante el último checkpoint.

Una demostración del funcionamiento de estos cgi-bin se puede encontrar en EstadisticasClam y EstadisticasClamDIFF. Pulsando repetidamente se comprueba como se van actualizando los contadores.

Uso en clamav-milter

Actualmente contadord está siendo utilizado en la Universitat de València para llevar en tiempo real la estadística de los virus detectados por el antivirus clamav llamado desde un milter Sendmail. El milter utilizado es una versión modificada del clamav-milter estándar. Entre otras cosas, se le ha añadido la interfaz con contadord, tal como se describe a continuación:

  1. Insertar las funciones C del contadord indicadas más arriba, antes de la primera función del clamav-milter.
  2. Definir ESTADIS al principio del programa.
      #define ESTADIS
    
  3. Justo antes de entrar en el bucle principal del milter, abrir la FIFO al contadord:
      #ifdef ESTADIS        
         cfd=abreContador(FIFOCONTA);  /* CIUV abre la DB de contadores */
         cuenta(cfd,"arranques",1);
      #endif                        
    
         if (smfi_main() !=0) ...
    
    
  4. Al final de la función clamfi_eom, añadir las llamadas al contadord:
    (NOTA: estas modificaciones corresponden a una versión antigua del milter, la 0.70; es posible que versiones más modernas del milter la estructura de clamfi_eom sea distinta):
      #ifdef ESTADIS   
                 cuenta(cfd,virname,1);
                 cuenta(cfd,"virus",1);
                 switch (rc) { 
                   case SMFIS_CONTINUE: cuenta(cfd,"enviados",1); break;
                   case SMFIS_REJECT:  cuenta(cfd,"rechazados",1); break;
                   case SMFIS_DISCARD: cuenta(cfd,"descartados",1); break;
                   }
      #endif /* ESTADIS */                           
    
              /* FIN DE VIRUS HALLADO */
              }
    
      #ifdef ESTADIS                  
              cuenta(cfd,"mensajes",1); 
      #endif /* ESTADIS */                  
    
              clamfi_cleanup(ctx);
              return rc;
      } 
    
    

Licencia

El copyright es GNU.

No hay inconveniente en que se implemente y difunda, sobre todo si se mantiene una nota indicando el autor/centro original.

Autor:

  • © Héctor Rulot Segovia - Servicio de Informática Universitat de València - 2007
volver

© Hector Rulot, Universitat de Valencia. email Contact Mod: 13 octubre 2009 20:54  documentacion wiki traza de la pagina Editar