Vigilando los logs con logcheck (II)

Si después de leer mi primer post tienes interés en usar logcheck, en este intentaré explicar todo lo necesario para ello.

Instalación

El primer paso es instalar logcheck. En distribuciones basadas en Debian (sí, eso incluye Ubuntu) sólo necesitas ejecutar:

# apt-get install logcheck

y opcionalmente:

# apt-get install logcheck-database

En distribuciones RedHat/CentOS tendrás que añadir el repositorio EPEL, e instalar con:

# yum install logcheck

Configuración inicial

La configuración de logcheck se realiza en dos ficheros principales y unos directorios con reglas. El primer fichero que debemos revisar es /etc/logcheck/logcheck.logfiles. En él se incluyen los logs que serán procesados. En Debian vienen por defecto: /var/log/syslog y /var/log/auth.log. En RedHat sus equivalentes: /var/log/messages y /var/log/secure. Para empezar son buena elección y contienen el grueso de los logs de un sistema GNU/Linux. Si tenemos aplicaciones que tengan un log propio que queramos revisar, deberemos añadirlo a esta lista.

En el segundo fichero (logcheck.conf) hay dos opciones dignas de mención. REPORTLEVEL indica que directorio de reglas se usará. Por defecto viene “server”, que es una buena elección para empezar. Hay un nivel más exigente con el contenido de los logs, paranoid, y otro preparado para estaciones de trabajo/portátiles que generan muchos mensajes de aplicaciones de usuario, workstation.

SENDMAILTO indica la dirección a la que se enviarán los informes. En importante recalcar que el sistema debe tener un servidor de correo correctamente configurado. Ya sea por si mismo o a través de otro servidor (relay), el servidor tiene que ser capaz de enviarnos correo. Dicho esto, en SENDMAILTO podemos poner nuestra dirección de correo, o usar el /etc/aliases para reenviar el correo del usuario logcheck (valor inicial de la opción) a nuestro correo. Recomiendo en este punto probar a enviar un correo desde el shell de la máquina, ya sea al usuario logcheck (para probar que el alias funciona) o a nuestra dirección de correo.

Desde este momento, cada hora (según /etc/cron.d/logcheck) recibiremos un correo con todas las líneas de log que no le hayamos indicado como aceptables. Aquí es donde empieza realmente nuestro trabajo. Si dejamos REPORTLEVEL=”server” en el fichero de configuración, trabajaremos sobre todo en el directorio /etc/logcheck/ignore.d.server. En RedHat, o si instalamos el paquete logcheck-database, dicho directorio ya contendrá una serie de ficheros de reglas. Se trata de ficheros que contienen una regla, expresada usando Expresiones Regulares, por línea. Cuando una línea de log coincide con alguna regla de estos ficheros, la línea se omitirá del informe horario. Es decir, estas reglas definen las entradas de log que son normales, que no nos interesan, y que no queremos en el correo. De esta forma sólo cuando una línea de log no coincide con ninguna regla será enviada por correo.

Entrenando a logcheck

Una vez llegue el primer correo de logcheck, éste contendrá varias líneas. Pongamos como ejemplo éstas:

Mar 23 12:23:49 foobar sshd[14830]: pam_unix(sshd:auth): check pass; user unknown
Mar 23 12:23:51 foobar sshd[14830]: Failed password for invalid user csilla from 198.211.3.42 port 55188 ssh2

Excluir líneas

Lo primero que debemos decidir es que líneas no queremos volver a ver nunca. Aquellas que no ofrezcan ninguna información útil son un buen comienzo. La entrada de las 12:23:49 indica un fallo de autenticación en SSH. Pero ni indica la IP ni el usuario del intento fallido. Si tenemos un servidor SSH abierto a Internet (sin filtrar por firewall) tendremos decenas de mensajes como éste al día, y no nos aportarán nada.

Mi recomendación es que tus propias reglas estén en un fichero independiente (sin tocar las que vienen ya en el paquete). De esta forma facilitas la actualización del paquete y eres consciente de las reglas que añadiste tú. Yo sigo una nomenclatura sencilla: local-servicio. El prefijo indica que las reglas son propias (locales) y el sufijo servicio al que se refieren. En el ejemplo actual, crearíamos el fichero /etc/logcheck/ignore.d.server/local-ssh con la siguiente regla:

^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[0-9]+\]: pam_unix\(sshd:auth\): check pass; user unknown$

Para los que no sepan todavía sobre expresiones regulares esa línea no tendrá mucho sentido. No podemos hacer nada en logcheck sin expresiones regulares, así que tocará darlas un repaso. Algo importante que debemos hacer siempre después de añadir una regla, es probar que funciona. Es decir, que coincide con las líneas que esperamos. Para ello podemos usar el comando egrep o uno propio de logcheck: logcheck-test.

NOTA: -a indica que se busque en el fichero auth.log, -s en el syslog o podemos indicar el fichero deseado con -l NOMBRE_DE_FICHERO:

# logcheck-test -a '^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: pam_unix\(sshd:auth\): check pass; user unknown$'

Es lo mismo que:

# logcheck-test -l /var/log/auth.log '^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: pam_unix\(sshd:auth\): check pass; user unknown$'

O con egrep:
egrep '^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: pam_unix\(sshd:auth\): check pass; user unknown$' /var/log/auth.log

Si los comandos anteriores no devuelven líneas del log (y están allí) habremos cometido un error en la expresión regular y deberemos corregirlo antes de la ejecución periódica de logcheck, ya que de otra forma podría fallar la ejecución de éste. Y quedarnos sin saber que pasa en nuestra máquina.

Excluir líneas, después de haber tomado medidas

Otro caso diferente es la entrada de las 12:23:51 (también relacionada con un acceso no válido por SSH). En ella si tenemos información de la máquina remota. Aunque también tendremos decenas de estas líneas todos los días, antes de decidir ignorarlas tal vez hay que aprovechar su información. En este caso usando algún software como fail2ban, que añadirá una regla de firewall cuando una máquina remota se dedica a “bombardear” nuestro SSH en busca de un usuario y clave válidos. No digo que añadiendo una regla en logcheck  fail2ban deje de funcionar. Digo que antes de olvidarnos de por vida (indicando a logcheck que no nos interesa) de “una anomalía” procuremos tomar las medidas necesarias para paliarla.

Excluir con precisión

Mar 23 06:36:10 foobar nrpe[4975]: Host 192.99.10.71 is not allowed to talk to us!
Mar 23 11:42:19 foobar sshd[20137]: Connection closed by 91.121.65.176 [preauth]

En estos dos ejemplos vemos información de conexiones “irregulares” a dos servicios. En el primer caso se trata de una máquina no autorizada a hablar con el nagios. Al igual que comentaba en el punto anterior habría que ver si tomamos medidas adicionales (firewall, fail2ban) para evitarlo, y posteriormente ignorar ese tipo de mensajes con una regla en la que la dirección IP no sea relevante (por ejemplo en /etc/logcheck/ignore.d.server/local-nrpe):

^\w{3} [ :0-9]{11} [._[:alnum:]-]+ nrpe\[[0-9]+\]: Host [0-9.]+ is not allowed to talk to us.$

Sin embargo, la segunda línea se debe a una comprobación de Nagios sobre la disponibilidad del SSH de esta máquina. Otras líneas iguales, pero con diferente IP no tendrían por qué ser ignoradas. Así que afinamos más:

^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[0-9]+\]: Connection closed by 91.121.65.176 \[preauth\]$

También se puede dar el caso de líneas que sólo son aceptables a una hora determinada:

Mar 23 04:00:31 foobar kernel: [27011506.187248] EXT4-fs (dm-7): recovery complete

Un mensaje de “error” en un sistema de ficheros que está en un snapshot montado a la hora de hacer backup y que sólo debería aparecer entonces, la regla se limita a esa hora y ese dispositivo:

^\w{3}  ?[0-9]+ 04:00:[0-9]+ [._[:alnum:]-]+ kernel: \[[0-9.]+\] EXT4-fs \(dm-7\): recovery complete$

Resumen

logcheck es una herramienta simple y extremadamente útil, pero debemos usarla correctamente:

  • Asegúrate de que el correo puede salir correctamente de tu servidor y de actualizar la dirección de envío o usar el /etc/aliases.
  • Deja tus reglas en ficheros independientes a los que vienen de serie. Facilita actualización y localización de errores.
  • Prueba las reglas (con egrep o logcheck-test) antes de darlas por buenas. De otra forma podrías romper el funcionamiento de logcheck.
  • Procura tomar medidas (arreglar un error de configuración, cerrar el acceso a un servicio, monitorizar el rendimiento de un servidor) antes de ignorar un error/advertencia de por vida. Después de dejar de verlos no lo harás.
  • Sé preciso a la hora de ignorar errores. Una regla “demasiado generosa” (poco estricta) puede coincidir con líneas de log que no esperabas y perder esa información.

Y si tienes alguna otra sugerencia, no dudes en dejarla en los comentarios. 🙂

$ exit

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *