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:
- Insertar las funciones C del contadord indicadas más arriba, antes
de la primera función del clamav-milter.
- Definir ESTADIS al principio del programa.
#define ESTADIS
- 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) ...
- 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