SYSLOG CENTRALIZADO CON DETECCION DE EVENTOS
Norberto Altalef
[email protected]
RedKlee Argentina
___________________________________________________________________
Alcances
Se describirá en el presente documento la implementación de un sistema de syslog centralizado con detección de eventos y generación de distintos tipos de alarmas. Todo el sistema está basado en herramientas Open Source. Se detallarán las herramientas utilizadas, así como detalles de su configuración y ejemplos reales de aplicación.Generalidades de un sistema de log.
Log es el registro de acciones y eventos que tienen lugar en un sistema. Los logs son el primer registro de la actividad en los sistemas y redes. Los logs de un sistema son una parte primaria de la seguridad y pueden ser usados en la detección de ataques e intrusiones, así como en el análisis de fallas de hardware y software. El programa syslog, es una interface que provee un framework standard para que tanto programas como el mismo sistema operativo puedan generar mensajes que peuden ser almacenados localmente o ser enviados a un host remoto. Originalmente escrito para Unix, se convirtió en un standard que se usa en muchos sistemas operativos y dispositivos de red. ¿ Cual es la utilidad de un sistema de syslog centralizado ? En un sistema de syslog centralizado, un server común recibe todos los mensajes de syslog de todos los sistemas de la red. Esto incluye logs de los servers Unix/linux/Windows etc, firewalls, y dispositivos de red (routers, switches, etc) Hay varias ventajas de un sistema de syslog centralizado • El syslog puede ser conectado en un segmento de red diferente protegido por un firewall para mantener más segura la información • Teniendo los mensajes de todos los equipos, puede hacerse una correlación de ataques o fallas en distintos puntos de una manera mucho más sencilla. Por ejemplo si en el syslog aparece un mensaje de desconexión de la interface de red de varios servers en el mismomomento, es lógico suponer una falla en el switch donde estos servers estan conectados. • Un usuario no deseado que haya ingresado en un server, no podrá alterar los mensajes que se hayan almacenado en el server central. • Se pueden generar alertas usando sistemas de monitoreo de logs. Sistema de monitoreo de logs El análisis de logs es una herramienta muy importante para mantener el control de servers y dispositivos de red. Sin embargo esta es una de las tareas que más tiempo consume y por consiguiente que menos se hace. Con la cantidad de mensajes informativos que se generan en un sistema de log, detectar en forma manual los mensajes de problemas es muy dificultoso y con mucha probabilidad de error. Esto se vé aumentado cuando se usa un sistema de syslog centralizado, donde la información proviene de varias fuentes distintas. Muchas soluciones de monitoreo se basan en sumarizar la información de archivos de log de dias previos. Esto es muy útil para la generación de estadísticas y análisis posterior a una falla o intrusión, pero no tanto para la resolución de problemas. Un administrador no puede actuar en forma proactiva, previamente a que el error ocurra. Muchas fallas o accesos no autorizados se ven precedidos por mensajes que de haber sido detectados, podrían haber permitido tomar acciones preventivas. Por ejemplo, un acceso no autorizado via ssh, puede haber estado precedido por una gran cantidad de intentos fallidos de acceso. Disponer una solución online de monitoreo, permite disponer de herramientas que pueden ayudar a prevenir problemas graves antes que ocurran. Detectar eventos en el momento que ocurren permite generar acciones en ese mismo instante y no luego de las consecuencias. Siguiendo con el ejemplo del acceso ssh, podría bloquearse el acceso ssh desde determinada
dirección IP despues de un número de intentos fallidos de acceso. Un concepto que aparece aquí es el de correlación de eventos. Un sistema automatizado de análisis de logs que pueda hacer una correlación de varios eventos simplifica y acelera el monitoreo de eventos consolidando alertas y mensajes de error en un mensaje más corto y fácil de entender. Una serie de operaciones están relacionadas con la correlación de eventos. Compresión toma varias apariciones del mismo evento y se examina la duplicación de información, se remueve las redundacias y se reporta como un único evento. De esta manera 1000 mensajes "route failed" se convierte en un único alerta que dice "route failed 1000 times" Recuento reporta un número específico de eventos similares como uno solo. Esto se diferencia de la compresión en que no solo cuenta en que sea el mismo evento, sino que se supere un determinado umbral para generar un reporte. Supresión asocia prioridades con alarmas y permite que el sistema suprima un alarma de prioridad más baja si ha ocurrido un evento de prioridad mayor. Generalización asocia alarmas con eventos de más alto nivel que son los que son reportados. Esto puede ser útil para por ejemplo para correlacionar eventos de múltiples discos de un array. No se necesita ver cada mensaje específico si se puede determinar que el array completo tiene problemas. Correlación basada en tiempo puede ser útil estableciendo causalidad. A menudo una información puede ser obtenida relacionando eventos que tienen una relación temporal específica. Ejemplos genéricos: • El Evento A está seguido del Evento B. • Este es el primer Evento A desde el Evento B reciente. • El Evento A sigue al Evento B dentro de los dos minutos. • El Evento A no fue observado dentro del Intervalo I.
Implementación
Se detallará a continuación la implementación real de un sistema de syslog centralizado junto con un sistema de monitoreo online de los logs. La instalación tuvo los siguientes requisitos: Concentrar los logs de un server que corre HPUX, un firewall que corre Linux y un sistema dedetección de intrusos (IDS) usando snort que corre en Linux. Los mensajes del sistema que corre HPUX eran provenientes del sistema operativo y de una aplicación específica. Debian generarse alarmas para determinados eventos. Se debía disponer de una manera de consultar los logs y realizar búsquedas en ellos. Para armar este sistema se tomaron en cuenta los siguientes aspectos:
Sistema operativo: se utilizó Debian GNU/Linux. La decisión estuvo basada en el conocimiento y experiencia con esta distribución, así como la reconocida estabilidad y facilidad de actualización. Sin embargo, la solución podría perfectamente adaptarse a otra distribución.
Syslog: si bien el daemon de syslog standard de Linux (syslogd) es adecuado para concentrar información de otros syslog, se decidió utilizar syslogng (syslognew generation) que es un reempazo directo de syslog.
El syslog original permite que los mensajes sean organizados basandose en los pares
priority/facility; syslogng agrega la posibilidad de filtrar basandose en el contenido de los mensajes usando expresiones regulares.
syslogng permite guardar los mensajes en un base de datos y tambien usar TCP en lugar de UDP para enviar los mensajes a otro server.
Base de datos: para facilitar las posteriores consultas se decidió almacenar los mensajes en una base de datos MySQL.
Consulta de logs: se usó como base un producto denominado phpsyslogng, que se modificó para tener más opciones de consulta..
Monitoreo de logs: se utilizó un producto llamado SEC (Simple Event Correlator). En el siguiente observan los componentes del sistema.
Algunos detalles de este esquema:
● Los hosts envian sus mensajes al server de syslog, a través del protocolo UDP. No se usó
TCP, porque se decidió no instalar syslogng en los servers HPUX.
● Se guarda la información de cada server en distintos archivos, para facilitar las reglas de SEC posteriores.
● En syslogng no se hace ningún filtrado y se guardan todos los mensajes.
● El proceso SEC está monitoreando en forma continua estos archivos generados por
syslogng.
● Existen dos bases de datos a las que SEC tiene acceso. Una base de datos de alarmas y una base de datos de logs. ● Estas bases de datos pueden ser consultadas desde formularios en forma interactiva o generando reportes estadísticos. ● En base a distintas reglas de SEC se toman distinto tipo de decisiones, con respecto a los mensajes que se leen de los archivos. Estas decisiones son: 1. Mensaje descartado. Los mensajes que son solo informativos, se descartan y no se almacenan en la base de datos. 2. Mensaje almacenado. Los mensajes que se consideran importantes se almacenan
en la base de datos de log 3. Alarma. Si hay un evento que genera alguna alarma, se guarda en la base de datos de alarmas. Además de esto, pueden generarse acciones adicionales, tales como enviar un mail o mostrar un mensaje en la consola de monitoreo. ● Se define una consola de monitoreo, que originalmente se basó en la incluída en php syslogng . En esta consola accesible desde un browser puede elegirse los mensajes de que server se muestran, así como las alarmas que se generan. Detalles de la implementación I syslogng
El paquete syslogng, puede instalarse usando aptget desde los repositorios de Debian. En otras distribuciones está tambien disponible, sino puede bajarse el códifo fuente desde www.balabit.com Toda la configuración se hace en el archivo /etc/syslogng/syslogng.conf La ruta que seguirá un mensaje se define con tres posibles secciones, que son source, destination y filtering rules. ● source: se define el origen de los mensajes (palabra clave: source) El formato es: source <sourcename> { sourcedriver params; sourcedriver params; ... };
donde sourcename es un identificador y sourcedriver es el método usado para recibir estos mensajes. Ejemplos: source kernel file("/proc/kmsg" log_prefix("kernel: ")); source net udp; El primer ejemplo indica que los mensajes del kernel se leen desde /proc/kmsg y que se les agrega un prefijo kernel: El segundo ejemplo indica que se habilita la recepción de mensajes a través de conexiones udp. ● destination: se define el destino de los mensajes (palabra clave: destination) El formato es:
destination <destname> { destdriver params; destdriver params; ... ; };
donde destname es un identificador y destdriver es el método usado para guardar los mensajes. Ejemplos: destination df_mail { file("/var/log/mail.log"); }; destination du_root { usertty("root"); }; El primer ejemplo se define para enviar los mensajes del sistema de mail al archivo /var/log/mail.log El segundo ejemplo se define para enviar mensajes a la tty donde esté conectado root. Estos son solo ejemplos. En ambos casos hay varias opciones adicionales. Consultar man (5) syslogng.conf, para ver las opciones completas. ● filtering rules: reglas de filtrado (palabra clave: filter) El formato es: filter <filtername> { expression; };
Donde filtername es el nombre del filtro y expression es una expersión booleana simple. Se puede usar "and", "or" y "not" para conectar las funciones incorporadas. Las funciones pueden ser: ○ facility (una lista separada por comas de nombres de facilities) ○ level (una lista separada por comas o un rango separado por ".." de nombres de priority) ○ program (una expresión regular para buscar coincidencias con nombres de programas) ○ host (una expresión regular para buscar coincidencias con nombres de host ○ match (una expresión regular que busca coincidencias en el mensaje de syuslog en si.
Sentencias log. Se pueden conectar origenes y destinos, usando sentencias log. El formato es: log { source S1; source S2; ... filter F1; filter F2; ... destination D1; destination D2; ... }; Donde Sx se refiere a uno de los orígenes de log declarados, Fx a uno de los filtros y Dx a uno de los destinos. Veamos un ejemplo:
Para loguear los mensajes que se reciben de un server que tiene como nombre amadeus y tiene un IDS (snort). 1 Definimos como origen los mensajes recibidos por udp source s_net { udp(); }; 2 Definimos como destino un archivo llamado /var/log/amadeus.ids.log Adicionalmente se cambia el formato standard de los mensajes, incluyendo el año destination d_amadeus.ids { file("/var/log/amadeus.ids.log"
template("$YEAR-$MONTH-$DAY $WEEKDAY $HOUR:$MIN:$SEC $HOST $FACILITY $PRIORITY $MSG\n")
template_escape(no) ); };
3 Creamos un filtro que seleccione los mensajes recibidos de este server. En este caso snort se configuró para enviar sus mensajes al facility local6.
filter f_amadeus.ids {
host(amadeus) and facility(local6); };
3 Por último generamos los mensajes de log
log {
source(s_net);
destination(d_amadeus.ids); }; 2 SEC SEC (Simple Event Corrrelator) es un script en Perl. Está escrito por Risto Vaarandi y su home están en http://www.estpak.ee/~risto/sec/. Está pensado para hacer un monitoreo de archivos de log en tiempo real y elegir eventos que se quieran reportar. En SEC se pueden definir y almacenar contextos, que son un juego arbitrario de hechos que describen un evento. Empecemos por un ejemplo básico, para entender el funcionamiento de SEC. Supongamos que queremos controlar los login de root. Cada vez que hay un login de root en un equipo el mensaje de syslog tiene el siguiente formato: Feb 1 11:54:48 192.168.22.1 sshd[20994]: [ID 800047 auth.info] Accepted publickey for root from 192.168.15.3 port 33890 ssh2
Creamos un archivo de configuración (que se llame root.conf) con el siguiente contenido:
type=Single ptype=RegExp pattern=(^.+\d+ \d+:\d+:\d+) (\d+\.\d+\.\d+\.\d+) sshd\[\d+\]: \[.+\] Accepted (.+) for root from (\d+\.\d+\.\d+\.\d+) desc=direct ssh root login on $2 from $4 (via $3) @ $1 action=add rootssh_$2 $0; report rootssh_$2 /usr/bin/mail s "Login de root en $2 desde $4" [email protected] Esto es un ejemplo de una regla de SEC.
La primer línea, type, define el tipo de regla, que en este caso es "Single", que le indica que queremos analizar ocurrencias únicas de un evento. La segunda línea, ptype, define como haremos la búsqueda de patrones. En este caso "RegExp" indica que se usarán expresiones regulares de Perl. La próxima linea, pattern, es una expresión regular que va a coincidir con los mensajes de log cuando hay un login de root. Se agrupan la fecha y hora, la IP de origen y la IP de destino. La siguiente linea, desc, es una descripción. Esta descripción identifica explicitamente cada ocurrencia (ver Reglas y operaciones de correlación de eventos)
La última línea, action, es la acción que se tomará. En este caso se agrega el mensaje completo (identificado como $0) a un contexto denominado rootssh_$2, donde $2 será la IP de origen. Finalmente, se envía un mail con el contenido del contexto. Para ejecutar SEC: sec detach conf=root.conf input=/var/log/messages detach, hace que SEC corra en background conf, indica el archivo de configuración que debe usarse input, especifica el archivo de donde deben leerse los mensajes. Ahora bien, supongamos que hay una tarea de cron que todos los días hace una conexión como root, para ejecutar un proceso y no queremos recibir un mail cada vez que se realiza esta conexión conocida. Lo que se necesita es agregar en el archivo de configuración la regla siguiente antes de la regla anterior. type=Suppress ptype=RegExp pattern=^.+\d+ \d+:\d+:\d+ \d+\.\d+\.\d+\.\d+ sshd\[\d+\]: \[.+\] Accepted .+ for root from 192.168.55.89
Enviando la señal SIGABRT al proceso SEC se le indica que relea el archivo de configuración y continue. Ahora las conexiones desde 192.168.55.89, no generarán mensajes de alerta. Siguiendo con ejemplos veamos, una regla de SEC para detectar posibles ataques por fuerza bruta en conexiones ssh. # # crear el contexto en la primera ocurrencia # type=SingleWithThreshold ptype=RegExp pattern=(^.+\d+ \d+:\d+:\d+) (\d+\.\d+\.\d+\.\d+) sshd\[\d+\]: \[.+\] Failed (.+) for (.*?) from (\d+\.\d+\.\d+\.\d+) desc=Posible ataque por fuerza bruta (ssh) usuario $4 en $2 desde $5 window=60 thresh=5 context=!SSH_BRUTE_FROM_$5 action=create SSH_BRUTE_FROM_$5 60 (report SSH_BRUTE_FROM_$5 /usr/bin/mail s "ataque por fuerza bruta ssh en $2 desde $5" [email protected]); add SSH_BRUTE_FROM_$5 Detectados 5 intentos fallidos de ssh en 60 seg;
add SSH_BRUTE_FROM_$5 $0 # # agregar eventos siguientes al contexto # type=Single ptype=RegExp pattern=(^.+\d+ \d+:\d+:\d+) (\d+\.\d+\.\d+\.\d+) sshd\[\d+\]: \[.+\] Failed (.+) for (.*?) from (\d+\.\d+\.\d+\.\d+) desc=Posible ataque por fuera bruta (ssh) usuario $4 en $2 desde $5 context=SSH_BRUTE_FROM_$5 action=add SSH_BRUTE_FROM_$5 "Evento adicional: $0"; set SSH_BRUTE_FROM_$5 30 Esto son en realidad dos reglas. La primera regla es otro de los tipos disponibles en SEC: SingleWithThershold. Se agregan dos opciones más a las que tenía Single, que son window y thresh.
window es el lapso durante el que esta regla debe estar monitoreando y thresh es el umbral para el número de eventos que es necesario que aparezcan dentro del lapso anterior para disparar la action de esta regla. En este caso la regla ejecutará la acción si hay 5 eventos de login fallido dentro de 60 seg. Se usa tambien la opción de contexto, que indica que la regla se dispara solo si el contexto no existe. La línea de action, crea el contexto ($5 representa la IP de origen) que expira en 60 seg. Una vez que expiró el contexto se envía un mail con una descripción y las lineas de log que fueron detectadas. La segunda regla agrega eventos adicionales al contexto y extiende su tiempo de vida por 30 seg, siempre que este exista. Si no existe no hace nada. La creación de estos contextos que son creados en forma dinámica, es una de las principales caracteristicas de SEC. Por ejemplo una impresora con un papel trabado, puede emitir una gran cantidad de mensajes de log y sería una molestia si se genera un mail por cada mensaje de log. En SEC podría crearse un contexto tal que "se ha visto un evento de papel trabado y ya se ha enviado un mail" de manera que la regla podría en el futuro suprimir el envío de los mails si el contexto existe. SEC incluye otros tipos de reglas. La descripción obtenida directamente del manual es: SingleWithScript buscar coincidencias en los eventos de entrada y ejecutar una acción dependiendo del status de un script externo SingleWithSuppress buscar coincidencias en los eventos de entrada y ejecutar una acción inmediatamente, pero ignorar las siguientes coincidencias durante los próximos t seg.
Pair buscar coincidencias en los eventos de entrada, ejecutar una acción inmediatamente e ignorar las siguientes coincidiencias, hasta que haya una coincidencia con otro evento distinto. En la coincidencia del segundo evento ejecutar otra acción. PairWithWindow buscar coincidencias en los eventos de entrada y esperar t seg para que aparezca otro evento. Si este evento no se observa dentro de un determinado intervalo se ejecuta una acción y si el evento aparece se ejecuta otra acción. SingleWith2Thresholds buscar coincidencias en los eventos de entrada durante t1 seg y si se supera un dado umbral, ejecutar una acción. Entonces empezar a contar las coincidencias de nuevo y si su número durante t2 seg es menor que un segundo umbral, ejecutar otra acción. Calendar ejecuta una acción en momentos específicos. Reglas y operaciones de correlación de eventos (extraído del manual de SEC) Pese a que cada operación de correlación de eventos se inicia por una regla de SEC, no hay una relación uno a uno entre reglas y operaciones de correlación de eventos, ya que una regla podría iniciar varias operaciones de correlación de eventos que corren simultaneamente. Para distinguir una operación de otra, SEC asigna una clave a cada operación que está compuesta por el nombre de archivo de configuración, el ID de la regla y la descripción del evento derivado del parámetro desc de cada regla, reemplazando cada variable con su valor. Uso de SEC en la implementación. Como se vió antes, en la implementación descripta guarda tanto los mensajes de syslog, como las alarmas en una base de datos MySQL. La interacción entre SEC y MySQL, se hace a través de un archivo de tipo FIFO (pipe). SEC puede escribir a un pipe y luego un proceso que está leyendo este pipe hace los insert correspondientes en la base de datos. Dentro de la base de datos se definieron las siguientes tablas: alarms: alarmas cod_alarms: códigos de alarmas. Se usan para los reportes logs: mensajes de syslog Estructura de la tabla alarms:
newmsg: se usa para saber si un mensaje ha sido leído o no en la consola de monitoreo screen_dest: define en cual de las zonas de la consola de monitoreo debe mostrarse el mensaje host: server que generó la alarma level: es un código que define la importancia de la alarma date y time: fecha y hora msg: texto del mensaje de alarma seq: indice Estructura de la tabla cod_alarms: cod: código de la alarma rep: indica si el tiop de alarma debe incluirse o no en los reportes des: descripción Estructura de la tabla logs: newmsg: se usa para saber si un mensaje ha sido leído o no en la consola de monitoreo screen_dest: define en cual de las zonas de la consola de monitoreo debe mostrarse el mensaje host: server que generó el mensaje facility: sistema que generó el mensaje (ver syslog) priority: nivel del mensaje (ver syslog) date y time: fecha y hora program: programa que generó el mensaje msg: texto del mensaje seq: indice
Estas estructuras se respetan tanto cuando SEC escribe al pipe, como cuando el proceso que lee del pipe hace los insert en la base de datos.
"Working with SEC The Simple Event Correlator" (http://sixshooter.v6.thrupoint.net/SEC examples/article.html). Veamos un ejemplo de una regla que hace un insert en una tabla: # Asignación de variables # Pipe # type=Single ptype=RegExp pattern=(SEC_STARTUP|SEC_RESTART|SEC_SOFTRESTART) desc=SEC Initialization_Pipe context=SEC_INTERNAL_EVENT action=assign %secdb_pipe /etc/sec/db/secdb.pipe # Generar alarma cuando se presentaron más de 100 mensajes # de cualquier tipo en 1 hora # IDS # type=SingleWithThreshold ptype=RegExp continue=TakeNext pattern=(.*) desc=xx eventos en yy minutos IDS window=3600 thresh=100 action=write %secdb_pipe ALR|1|5|amadeus|3|0003|%f|%h|Más de 100 mensajes en 1 hora IDS Poniendo detalle en la linea action, se observa que SEC vá a escribir al pipe definido en la variable %secdb_pipe, una serie de campos separados por "|"
El primer campo, no pertenece en realidad a ninguna tabla y es el que le indica al script dbinsert.pl, en que tabla debe hacer el insert. En este caso es ALR indicando que el insert debe hacerse en la tabla alarms. El resto son los campos de la tabla correspondiente. De la misma manera, para guardar un mensaje de syslog (generado en este caso por un programa de usuario): # Fallo al validar la clave # Mensaje en el log # # 20050527 Fri 10:10:41 gsahp local6 notice gam(ascprec.exe)[28045]: Fallo al validar clave;\ # login=001000025092 uid=740 euid=740 tty=/dev/pts/tBjrhost=pctuc12 user=tuc00g # Regla type=Single
ptype=RegExp pattern=(\S+)\s+\S+\s+(\S+)\s+gsahp\s+local6\s+(\S+)\s+gam\((\S+)\)\[\d+\]\:\s+Fallo al validar clave\;\s+(.*) desc=falla de clave sistema comercial action=write %secdb_pipe LOG|1|0|gsahp|local6|$3|$1|$2|$4|Fallo al validar clave $5 En este caso el primer campo es LOG, indicando que el insert debe hacerse en la tabla log. Con este esquema, aprovechando la gran potencia de SEC, puede armarse un sistema de monitoreo y alarmas tan complejo y sofisticado como se necesite. No se dispone de una interface gráfica de configuración, por lo que hay que dedicarle un poco de trabajo a armar las reglas. Sin embargo, las potencialidades son muchas. Para ver más ejemplos se recomienda ver la información de SEC, tanto las páginas del manual, como la FAQ y los ejemplos. Hay una colección de reglas en http://www.bleedingsnort.com/sec/. Tambien hay un execelente tutorial en http://www.cs.umb.edu/~rouilj/sec/ 3 Interface de usuario Una vez que los datos están almacenados en la base de datos es más sencillo, realizar consultas y reportes.
Para la aplicación se partió de phpsyslogng (http://www.vermeer.org/projects/phpsyslogng) pensado para hacer consultas en una base de datos creada directamente por syslogng y se adaptó al esquema descripto anteriormente.
Un ejemplo de un pantalla de consulta es:
En phpsyslogng tambien hay una opción para mostrar en tiempo real los mensajes que se ván generando:
Se muestra acá el resultado de una versión modificada donde dos ventanas con mensajes de syslog de hosts y una tercera con alarmas. En el momento de escribir este documento se está realizando una migración de esta interface a una desarrollada en AJAX. Este conjunto de programas, la mayoría usados sin modificación y puestos juntos a trabajar muestran una de las grandes posibilidades del software libre, que es la de lograr una solución completa a un problema, con muchisimas posiblidades de operación. Valga aclarar que este sistema está funcionando desde mediados del 2005, en una empresa de envergadura, monitoreando varios servers y firewall y se le están continuamente agregando funcionalidades y ha demostrado en más de una vez su utilidad. Norberto Altalef RedKlee Soluciones basadas en Software Libre www.redklee.com.ar [email protected] Sanchez de Bustamante 635 Buenos Aires Argentina Tel: 541148633074 / Cel: 54111550559853