Todo sistema operativo cuenta con funcionalidad para almacenar logs del sistema, aplicaciones, dispositivos, etc. Los sistemas tipo *nix cuentan con el demonio syslog, encargado de recoger los logs y almacenarlos en el lugar indicado. El servicio syslog es tan potente que, además de realizar la tarea de logging local, permite almacenar logs de dispositivos remotos a través de un protocolo propio llamado del mismo nombre y que funciona sobre UDP y TCP. La mayoría de los sistemas operativos poseen facilidades para almacenar logs en un servidor remoto.
Centralizar los logs en un servidor facilita la tarea de análisis de logs a administradores y auditores, ya que deben acceder a sólo un repositorio.
La obvia desventaja es que si hackean el servidor de logs, pueden ver los logs de toda la red. Por ello es muy importante que el servidor de logging posea una buena configuración de seguridad. Igualmente, como se detallará al final del artículo, existen varias desventajas de seguridad adicionales al utilizar este esquema.
Los sistemas *nix modernos, utilizan una versión mejorada del antiguo syslog denominada rsyslog, más confiable que el anterior y con capacidades extendidas. La siguiente explicación muestra cómo armar un servidor de logging con rsyslog, que puede aplicarse a cualquier sistema *nix. Además se incluyen los comandos para habilitar el logging remoto en dispositivos Cisco.
Toda la configuración de rsyslog se realiza a través del archivo /etc/rsyslog.conf.
Servidor rsyslog
Para convertir el demonio rsyslog en un servidor de loggeo de red debe utilizarse el plugin imudp (si se desea utilizar UDP) y/o imtcp (para TCP). Estos plugins reemplazan la opción -r de syslog ya obsoleta. El port utilizado por defecto por este servicio es el 514 para ambos protocolos.
Las líneas que se deben agregar (o descomentar) en /etc/rsyslog.conf para habilitar el logging remoto son las siguientes:
$ModLoad imudp
$UDPServerRun 514
$ModLoad imtcp
$InputTCPServerRun 514
Para que la nueva configuración entre en vigencia, debe recargarse el demonio. Una manera de no cortar el logging de forma abrupta matando el proceso (clásico restart), lo mejor es enviar una señal HungUp:
killall -HUP rsyslogd
Con esto, cualquier dispositivo de red puede enviar sus logs al servidor recién configurado, y este los añadirá a los locales del servidor. Claro que lo mejor es no mezclar logs locales con logs remotos, por lo cual se pueden configurar distintas entradas en la configuración que redirijan estos logs a otros archivos.
Las reglas para separar logs se arman en base al facility y al nivel de criticidad que va de 0 (emergencias) a 7 (debugging). Las facilities permiten indicar el origen del mensaje, y existe un número fijo de ellas. Algunos demonios y procesos del sistema operativo tienen asignados valores de facilities (por ej: kern, mail, daemon, user, etc), y aquellos que no, deben utilizar alguna de las definidas como "uso local" (local0 a local7). El usuario puede utilizar las facilities local0 a local7 para sus logs, y estas son las que se suelen utilizar para separar logs de dispositivos remotos.
El formato de las reglas es:
<facility>.<criticidad> <archivo log destino (ej /var/log/syslog)>
Tanto el facility como la criticidad pueden ser asterisco (*), indicando que abarque todo. Por ejemplo, "kern.*" envía todos los logs del kernel al archivo especificado. En el caso de utilizar asterisco en el facility, es posible utilizar la prioridad none para indicar qué facilities no incluir. Por ejemplo, existe la siguiente regla default en la configuración de rsyslog:
*.*;auth,authpriv.none -/var/log/syslog
la cual hace que todo se envíe al archivo syslog. En esa misma regla se puede observar que se agregó auth,authpriv.none para evitar que los logs de auth y authpriv se almacenen en dicho archivo. A la regla anterior se puede agregar local4.none, para luego utilizar la facility local4 en dispositivos remotos y así separar esos logs de los locales:
*.*;auth,authpriv.none;local4.none -/var/log/syslog
Además de las reglas "facility.priority", se pueden armar reglas en base a filtros, basados en distintas propiedades como IP origen, mensaje, hostname, y varias más que se pueden ver en la
sección de propiedades del manual oficial de rsyslog.
Las reglas con filtros se arman de la siguiente manera:
:<propiedad>, <operación de comparación>, "valor" <archivo log destino (ej /var/log/syslog)>
donde la operación de comparación puede ser isempty, isequal, startswith, regex y eregex, como se puede observar en el
manual oficial, en la sección de filtros.
Esto permite, por ejemplo, separar los logs provenientes de la dirección IP 192.168.1.15 en un archivo propio para el host con la siguiente regla:
:fromhost-ip, isequal, "192.168.1.15" /var/log/remote/192.168.1.15.log
Una vez completadas las reglas, debe recargarse el demonio rsyslogd para que tome la nueva configuración.
Separación de logs
Conociendo las bases para la configuración del servidor, es posible armar una que reciba logs de diferentes fuentes y los separe en distintos archivos.
Dado que por defecto todo va a parar a syslog, lo mejor es eliminar las facilities local* de dicha configuración y después utilizarlas en los dispositovs de red. El primer paso es editar la regla correspondiente (en /etc/rsyslog.conf) para que quede como sigue:
*.*;auth,authpriv.none;\
local0.none;\
local1.none;\
local2.none;\
local3.none;\
local4.none;\
local5.none;\
local6.none;\
local7.none -/var/log/syslog
También hay que evitar que info, notice y warning terminen en /var/log/messages
*.=info;*.=notice;*.=warn;\
auth,authpriv.none;\
cron,daemon.none;\
mail,news.none;
local0.none;\
local1.none;\
local2.none;\
local3.none;\
local4.none;\
local5.none;\
local6.none;\
local7.none -/var/log/messages
y que los mensajes de debugging terminen en /var/log/debug
*.=debug;\
auth,authpriv.none;\
news.none;mail.none;
local0.none;\
local1.none;\
local2.none;\
local3.none;\
local4.none;\
local5.none;\
local6.none;\
local7.none -/var/log/debug
La separación se puede realizar de varias maneras, una es basándose en las facilities. Para ello, a cada tipo de dispositivo se asigna una facility de las "local use" y luego se arma la configuración en base a esto, de la siguiente manera:
local3.* /var/log/remote/firewalls.log
local4.* /var/log/remote/routers.log
local5.* /var/log/remote/APs.log
local6.* /var/log/remote/switches.log
Como se ve, se utiliza local3 para firewalls, loca4 para routers, local5 para access points y local6 para switches. A esta separación se la puede mejorar utilizando distintos archivos para diferentes prioridades, pero sigue siendo muy simple y no demasiado agradable para quien revisa los logs.
Una mejor forma de separar logs es colocar los logs de cada host en un archivo separado. En la sección anterior se mostró que es posible ver de qué dirección IP viene la información y armar un archivo en base a esto, pero es muy ineficiente colocar una regla por cada host. Una forma más simple de hacerlo es utilizar templates. Con un template es posible definir el formato del nombre del archivo log a partir de alguna
propiedad del mismo, como por ejemplo el hostname o IP. Para usar una propiedad es necesario colocarla entre signos de porcentaje "%".
La siguiente línea crea un template que luego se puede utilizar para especificar el nombre del archivo:
$template LogsRemotos,"/var/log/remote/%fromhost-ip%.log"
donde fromhost-ip especifica que se utilice la IP como nombre del archivo.
Para lograr que cada dispositivo loggee en un archivo separado, sólo debe agregarse lo siguiente:
:fromhost-ip, isequal, "127.0.0.1" ~
*.* -?LogsRemotos
y con ello rsyslog generará automáticamente los nombres de archivos y almacenará los mensajes en el lugar correcto. En la primer línea se descartan los logs locales, dado que los mismos se almacenan en otros archivos y no deseamos generar uno nuevo. El descarte se realiza utilizando caracter "~" en lugar de un nombre de archivo. El signo de pregunta "?" de la segunda línea indica que se utiliza un nombre de archivo dinámico, a partir del template LogsRemotos, y el guión "-" que no escriba en el archivo inmediatamente (buffering), para mejorar la performance.
Para no "ensuciar" el archivo de configuración global, es posible crear archivos dentro de /etc/rsyslog.d/ con las configuraciones deseadas. En el último ejemplo, sería posible tener un archivo denominado remote.conf con las líneas:
$template LogsRemotos,"/var/log/remote/%fromhost-ip%.log"
:fromhost-ip, isequal, "127.0.0.1" ~
*.* -?LogsRemotos
Configuracion en dispositivos Cisco con IOS
Todos los dispositivos Cisco poseen la capacidad de loggear en un servidor remoto a través de syslog. La configuración de los mismos es muy simple, sólo debe indicarse la dirección del servidor, el nivel de información a enviar y el facility a utilizar. Esto se lleva a cabo en el modo de configuración con privilegios de administrador, ejecutando los siguientes comandos (lo que se encuentra luego del // son comentarios):
(config)#logging on
(config)#logging host <IP syslog server>
(config)#logging trap informational // es el nivel de mensajes a loguear. Cada nivel incluye a todos los niveles inferiores (informational incluye error, critical, alerts, etc).
(config)#logging facility local5 // usar el facility local5 (local0... local7 son para códigos definidos por el usuario).
Configuración de clientes *nix
Lograr que un máquina que ejecuta algún sistema *nix loggee remotamente es muy simple. Sólo debe agregarse la línea mostrada a continuación en su archivo /etc/rsyslog.conf (o /etc/syslog.conf si no posee rsyslog):
*.* @<IP remota>
El @ indica que deben enviarse los mensajes a un host remoto en lugar de almacenarlos en un archivo local. Con un sólo @ rsyslog utiliza UDP como protocolo de transporte, y si se desea utilizar el más confiable TCP deben colocarse dos:
*.* @@<IP remota>
Restringir el acceso
El protocolo no posee un mecanismo de autenticación que restrinja qué dispositivo puede almacenar logs en el servidor, permitiendo que cualquiera pueda escribir en el mismo, con el riesgo de que un atacante genere un Denial of Service si el disco se llena o la cantidad de datos transmitida satura el ancho de banda.
Una forma de limitar el acceso es utilizando un firewall y rechazar toda conexión que no venga de una dirección de red autorizada. Esta mejora no es la panacea, dado que suplantar una dirección de red es muy simple, pero al menos es algo.
Conclusiones
rsyslog es un sistema muy flexible, simple y consolidado. El protocolo se encuentra en prácticamente todo dispositivo decente, por lo cual la compatibilidad está garantizada. Lo que se describió en este artículo muestra sólo una parte de la potencia de esta herramienta, por lo cual se recomienda una atenta lectura de su
manual oficial.
Probablemente su problema más grave es la pobre seguridad que provee. Entre algunos de los problemas más graves se encuentran:
- Posibilidad de DoS, como se explicó en la sección anterior.
- UDP es poco confiable: los paquetes se pueden perder y nadie se enteraría. syslog por TCP mejora este aspecto, pero no todos los dispositivos lo implementan.
- No hay autenticación, permitiendo que cualquiera envíe logs al servidor.
- No existe confidencialidad de los datos enviados.
- No hay integridad de los datos (alguien podría modificarlos en el camino - MITM)
Algunos de estos problemas pueden solucionarse si se utiliza IPSec en la capa inferior, pero no es una solución que forme parte del protocolo.
Referencias
-
rsyslog doc - rsyslog.conf configuration file
-
Syslog Configuration and /etc/syslog.conf
-
How To Set Up A Debian Linux Syslog Server
-
FreeBSD Handbook - 29.11 Remote Host Logging with syslogd
-
Catalyst 2950 - Configuring System Message Logging
-
Practical UNIX & Internet Security - 10.5 The UNIX System Log (syslog) Facility
-
Softpanorama - Centralised Syslog Server
-
PIX 501 Logging to Syslog Server