Monitorización en serio. Teoría

vie, 07 dic 2012 by Foron

Os ahorro tener que leer todo el post para llegar a esta conclusión: El título es un poco sensacionalista, lo sé. Sigamos.

Uno de los aspectos más consolidados en lo que a la administración de sistemas se refiere es la monitorización. No hay infraestructura razonablemente seria que no tenga un ciento de monitores de carga de CPU, memoria consumida, tráfico de red, conexiones abiertas, .... Y junto a estos tenemos otros monitores, algo más avanzados, que por ejemplo revisan si una sesión POP3 se establece correctamente, usando para ello un usuario/contraseña preestablecidos; o que un una página PHP contiene cierto texto, para lo que se hacen X consultas, también predefinidas, en una base de datos.

Básicamente, esto es lo que hay; aquí nos quedamos la mayoría. Pero, ¿Es suficiente?

Sigamos con un ejemplo más concreto:

Vamos a suponer a partir de ahora que somos los responsables de los servidores IMAP de alguna de las empresas más grandes del sector del correo electrónico, y que por lo tanto tenemos millones de usuarios para los que poder acceder a su correo es, obviamente, fundamental.

Con el gráfico de conexiones establecidas en la mano, sabemos que el patrón más habitual es el siguiente:

Grafico base

Vemos que tenemos pocas conexiones abiertas durante la madrugada, y que el número va subiendo en la medida en que empieza la jornada laboral, con un pequeño descenso en las horas habituales de comida. Para este ejemplo nos quedamos con esto, aunque en condiciones normales se deberían tener en cuenta fines de semana, vacaciones, ....

La línea roja indica el umbral de alerta del monitor. Ya sabéis: el móvil suena cada vez que la línea verde supere a la roja. Aunque lo normal es que también tuviéramos un umbral de aviso amarillo y otro para cuando las conexiones fueran demasiado bajas, por ahora nos sirve esta versión simplificada.

Y llega el día en el que las conexiones establecidas contra nuestros servidores muestran lo siguiente:

Grafico con alertas

Qué fácil parece todo cuando vemos el gráfico! Lamentablemente, cuando somos responsables de unos cuantos cientos de gráficos, que por supuesto no estamos vigilando constantemente, solo vamos a tener constancia de ese pico de las 10 a.m., que además podría ser perfectamente un pequeño aumento puntual de carga inocuo para el servicio.

Por supuesto, ni nos hemos enterado del ataque por fuerza bruta de las 04:00 a.m. que probablemente haya conseguido "adivinar" decenas de contraseñas de usuarios, ya disponibles para el "spameo" generalizado; o de ese problema de media tarde, que quizá sí haya supuesto una perdida de servicio para muchos usuarios. Pero la cosa es todavía peor, porque resulta que nuestro sistema de validación de cuentas se "volvió loco" justo antes de esa bajada de tráfico y empezó a aceptar logins, independientemente de la validez de la contraseña.

¿Cuántos sistemas de monitorización habéis visto capaces de detectar estas situaciones? Llevadlo a otros entornos: ¿Cuantos sistemas de monitorización concéis capaces de detectar que una tienda online en realidad está cobrando 10 euros menos en algunos pedidos? ¿O un motor de búsqueda que da resultados erróneos periódicamente?

¿Qué hacemos entonces? ¿Tiramos todos los monitores que tenemos a la basura? Obviamenente, no. Es evidente que un servidor con una carga de CPU alta necesita atención.

Sin embargo, lo que sí debemos cambiar es el punto de vista sobre el que gira la monitorización, de tal manera que en lugar de orientarla hacia el aspecto estrictamente operacional, lo hagamos teniendo en cuenta el propio servicio que estamos vigilando, que no deja de ser, en definitiva, lo único que aporta valor. Dicho de otra forma, lo que importa no es que la máquina reviente, sino que el acceso de los clientes falle o sea más lento. Puede parecer un cambio sutil, pero no lo es.

Acercándonos otra vez a la faceta técnica, esto significa que deberíamos prestar más atención a los siguientes aspectos:

  1. La monitorización debe centrarse en las aplicaciones, y no en el hardware, la red o las máquinas. (Lo que veníamos diciendo sobre la percepción del servicio que tienen los usuarios).
  2. La monitorización puede ser importante como mecanismo para buscar mejoras y optimaciones para el servicio.
  3. Desde el punto de vista de los sistemas, esto significa que la monitorización debe interactuar mucho más con las aplicaciones.
  4. Parámetros como la latencia o el tiempo de respuesta de una aplicación deben cobrar más importancia.
  5. Detectar las anomalías debe ser uno de los objetivos a conseguir. Dicho de otra forma, si nuestro sistema gana una conexión nueva de media a la semana, y si este lunes tenemos 10, el que la semana siguiente veamos 20 debe alertarnos.
  6. No se puede monitorizar lo que no se puede medir.
  7. Por si no ha quedado claro, sólo se puede monitorizar lo que se puede medir.
  8. Revisar el estado de las aplicaciones hace que algunos de los chequeos "tradicionales" dejen de ser necesarios, con lo que se simplifica la monitorización.
  9. Los monitores tradicionales siguen siendo útiles para detectar un buen número de problemas, incluidos los relacionados con la escalabilidad de las plataformas.

Pero, ¿Cómo llevamos esto a la práctica?

En líneas generales, necesitamos trabajar mucho más contra los logs que generan los servicios. Si somos los desarrolladores de nuestras aplicaciones (una web por ejemplo), queda en nuestra mano definir y loguear la información que consideramos importante. Si, por el contrario, estamos usando una aplicación de un tercero (el servidor POP/IMAP Dovecot, por citar uno), nos resultará más difícil incluir un logueo específico, pero siempre podremos buscar la información que nos puede aportar visibilidad extra del entorno. En este caso concreto, por ejemplo, el número de intentos de conexión con credenciales inválidas o el ratio logins/logoouts son métricas que nos podrían ayudar en un momento dado, por citar dos.

En cuanto al software que podemos usar para la monitorización, tenemos decenas de buenas alternativas que podemos usar. Las hay más visuales, algunas están pensadas para entornos muy grandes, otras usan backends especializados (Cassandra por ejemplo), .... Queda a nuestra elección.

En lo que sí están de acuerdo la mayoría de aplicaciones es en la forma de detectar anomalías, sobre todo porque todas las que yo conozco se basan en este estupendo documento, que a la postre sirvió para la implementación en RRDTool. Siempre podéis diseñaros vuestro sistema, quizá usando R y su paquete forecast, pero esto está muy lejos del objetivo de este post.

En unos días describiré con más detalle una pequeña implementación de ejemplo sobre un servicio IMAP (Dovecot).

read more

Monitorización orientada a host con OSSEC I

sáb, 01 nov 2008 by Foron

En el mundo del software libre hay multitud de proyectos que, debido a su calidad, han terminado siendo comprados por empresas para ser usados como parte de sus soluciones comerciales. Dos ejemplos son sguil y ossec.

En la próxima serie de dos posts voy a comentar muy por encima lo principal de ossec.

Ossec es un proyecto relacionado con la seguridad informática, y particularmente con lo que se suele llamar HIDS. Dicho de otra forma, y simplificando mucho, se trata de una aplicación que monitoriza una máquina, y que detecta las anomalías que puedan producirse en el sistema. Para hacer esto usa sobre todo una herramienta para la detección de rootkits, otra para revisar la integridad de ficheros y ejecutables del sistema, y por último un potente sistema para analizar logs.

En cuanto a la arquitectura del sistema, usa básicamente un modelo de servidor/agentes, con lo que tendremos una máquina (servidor) encargada de recibir y actuar en base a la información que reciba de los agentes que, en definitiva, son las máquinas que están siendo monitorizadas. La forma de actuar del servidor es, por una parte, enviando noficaciones, y por otro lado, si así se configura, generando reglas firewall que se ejecutarán en los propios agentes.

Este primer post sólo va a describir la instalación de ossec. Dejamos para posts posteriores la configuración.

La instalación de ossec es muy sencilla. Es suficiente con ejecutar el típico install.sh del fichero de instalación que se puede descargar desde la web.

  sh install.sh

Una vez seleccionamos el idioma de instalación empieza el tema.

  1- What kind of installation do you want (server, agent, local or help)? server
    - Server installation chosen.
  2- Setting up the installation environment.
    - Choose where to install the OSSEC HIDS [/var/ossec]:  /usr/local/ossec-1.6
       - Installation will be made at  /usr/local/ossec-1.6 .
  3- Configuring the OSSEC HIDS.
    3.1- Do you want e-mail notification? (y/n) [y]:
     - What's your e-mail address? zzz@yyyyyyy.net
     - We found your SMTP server as: mail.yyyyyyy.net.
     - Do you want to use it? (y/n) [y]:
     --- Using SMTP server:  mail.yyyyyyy.net.
    3.2- Do you want to run the integrity check daemon? (y/n) [y]:
     - Running syscheck (integrity check daemon).
    3.3- Do you want to run the rootkit detection engine? (y/n) [y]:
     - Running rootcheck (rootkit detection).
    3.4- Active response allows you to execute a specific
         command based on the events received. For example,
         you can block an IP address or disable access for
         a specific user.
         More information at:
         http://www.ossec.net/en/manual.html#active-response
     - Do you want to enable active response? (y/n) [y]: n
       - Active response disabled.
    3.5- Do you want to enable remote syslog (port 514 udp)? (y/n) [y]:
     - Remote syslog enabled.
    3.6- Setting the configuration to analyze the following logs:
      -- /var/log/messages
      -- /var/log/auth.log
      -- /var/log/syslog
      -- /var/log/vsftpd.log
      -- /var/log/mail.info
      -- /var/log/dpkg.log
      -- /var/log/snort/alert (snort-full file)
      -- /var/log/apache2/error.log (apache log)
      -- /var/log/apache2/access.log (apache log)

     - If you want to monitor any other file, just change
       the ossec.conf and add a new localfile entry.
       Any questions about the configuration can be answered
       by visiting us online at http://www.ossec.net .

     --- Press ENTER to continue ---

A partir de aquí empieza a compilar los distintos componenetes. He elegido una instalación para el servidor que recibirá los eventos, y he activado tanto la detección de rootkits como la revisión de integridad, pero he dejado sin activar la respuesta activa, que básicamente se trata de añadir entradas a hosts.deny y reglas de firewall.

El syslog remoto lo vamos a usar para recibir mensajes desde los agentes.

Por cierto, mientras escribía estas líneas el sistema se ha terminado de compilar:

  - System is Debian (Ubuntu or derivative).
  - Init script modified to start OSSEC HIDS during boot.
  - Configuration finished properly.
  - To start OSSEC HIDS:
                 /usr/local/ossec-1.6/bin/ossec-control start
  - To stop OSSEC HIDS:
                 /usr/local/ossec-1.6/bin/ossec-control stop
  - The configuration can be viewed or modified at /usr/local/ossec-1.6/etc/ossec.conf
      Thanks for using the OSSEC HIDS.
      If you have any question, suggestion or if you find any bug,
      contact us at contact@ossec.net or using our public maillist at
      ossec-list@ossec.net
      ( http://www.ossec.net/main/support/ ).
      More information can be found at http://www.ossec.net
  ---  Press ENTER to finish (maybe more information below). ---

A partir de aquí, por un lado tendremos que configurar ossec (ossec.conf), y después tendremos que ir añadiendo los agentes con la utilidad /usr/local/ossec-1.6/bin/manage_agents.

Vamos a arrancar el servidor y a añadir un par de agentes, uno en linux y otro en windows. Bueno, el agente windows no lo voy a documentar aquí. Tiene un instalador gráfico que se descarga desde la web, y los pasos son muy similares.

  /usr/local/ossec-1.6/bin/ossec-control start
  Starting OSSEC HIDS v1.6 (by Third Brigade, Inc.)...
  Started ossec-maild...
  Started ossec-execd...
  Started ossec-analysisd...
  Started ossec-logcollector...
  Started ossec-remoted...
  Started ossec-syscheckd...
  Started ossec-monitord...
  Completed.

  # ps aux | grep osse
  ossecm    5579  0.0  0.0   2076   528 ?        S    17:45   0:00 /usr/local/ossec-1.6/bin/ossec-maild
  ossec     5587  0.0  0.1   2664  1312 ?        S    17:45   0:00 /usr/local/ossec-1.6/bin/ossec-analysisd
  root      5591  0.0  0.0   1796   468 ?        S    17:45   0:00 /usr/local/ossec-1.6/bin/ossec-logcollector
  root      5603  2.5  0.0   1944   512 ?        D    17:45   0:04 /usr/local/ossec-1.6/bin/ossec-syscheckd
  ossec     5607  0.0  0.0   1980   480 ?        S    17:45   0:00 /usr/local/ossec-1.6/bin/ossec-monitord
  ossecm    5610  0.0  0.0   2076   300 ?        S    17:45   0:00 /usr/local/ossec-1.6/bin/ossec-maild

  # ./manage_agents
  ***********************************************
  * OSSEC HIDS v1.6 Agent manager.  *
  * The following options are available:  *
  ***********************************************
     (A)dd an agent (A).
     (E)xtract key for an agent (E).
     (L)ist already added agents (L).
     (R)emove an agent (R).
     (Q)uit.
  Choose your action: A,E,L,R or Q: A

  - Adding a new agent (use '\q' to return to the main menu).
    Please provide the following:
      * A name for the new agent: agente1
      * The IP Address of the new agent: 172.17.0.131
      * An ID for the new agent[001]:
  Agent information:
      ID:001
      Name:agente1
      IP Address:172.17.0.131
  Confirm adding it?(y/n): y
  Agent added.

  # ./manage_agents

  ***********************************************
  * OSSEC HIDS v1.6 Agent manager.  *
  * The following options are available:  *
  ***********************************************
     (A)dd an agent (A).
     (E)xtract key for an agent (E).
     (L)ist already added agents (L).
     (R)emove an agent (R).
     (Q)uit.
  Choose your action: A,E,L,R or Q: E

  Available agents:
     ID: 001, Name: agente1, IP: 172.17.0.131
  Provide the ID of the agent to extract the key (or '\q' to quit): 001
  Agent key information for '001' is:
  XDAxIGZuMTMxIDE5Mi4xNjguMTXuMTMxIDZzY2IzZjg1Y2JmYjVmOaBhMWM0MWRkMTNjMWQ4OWY4MZMyMjkyYTRiOTk5YjJlZ4U5MjRm5zU0ZGE1N2I3NTk=

  ** Press ENTER to return to the main menu.

Y ya está. Ahora sólo queda instalar el agente en el servidor a monitorizar. La clave se usa para la comunicación agente/servidor.

  # ./install.sh
  ...
  1- What kind of installation do you want (server, agent, local or help)? agent
    - Agent(client) installation chosen.
  2- Setting up the installation environment.
    - Choose where to install the OSSEC HIDS [/var/ossec]: /usr/local/ossec-1.6
      - Installation will be made at  /usr/local/ossec-1.6 .
  3- Configuring the OSSEC HIDS.
    3.1- What's the IP Address of the OSSEC HIDS server?: 172.17.0.1
      - Adding Server IP 172.17.0.1
    3.2- Do you want to run the integrity check daemon? (y/n) [y]:
      - Running syscheck (integrity check daemon).
    3.3- Do you want to run the rootkit detection engine? (y/n) [y]:
      - Running rootcheck (rootkit detection).
    3.4 - Do you want to enable active response? (y/n) [y]: n
      - Active response disabled.
    3.5- Setting the configuration to analyze the following logs:
      -- /var/log/messages
      -- /var/log/auth.log
      -- /var/log/syslog
      -- /var/log/mail.info
      -- /var/log/dpkg.log
    - If you want to monitor any other file, just change
      the ossec.conf and add a new localfile entry.
      Any questions about the configuration can be answered
      by visiting us online at http://www.ossec.net .
  --- Press ENTER to continue ---

Y ahora copiamos la clave pública que antes hemos sacado del servidor:

  ./bin/manage_agents

  ***********************************************
  * OSSEC HIDS v1.6 Agent manager.  *
  * The following options are available:  *
  ***********************************************
     (I)mport key from the server (I).
     (Q)uit.
  Choose your action: I or Q: I
  * Provide the Key generated by the server.
  * The best approach is to cut and paste it.
  *** OBS: Do not include spaces or new lines.
  Paste it here (or '\q' to quit): XDAxIGZuMTMxIDE5Mi4xNjguMTXuMTMxIDZzY2IzZjg1Y2JmYjVmOaBhMWM0MWRkMTNjMWQ4OWY4MZMyMjkyYTRiOTk5YjJlZ4U5MjRm5zU0ZGE1N2I3NTk=
  Agent information:
     ID:001
     Name:agente1
     IP Address:172.17.0.131
  Confirm adding it?(y/n): y
  Added.
  ** Press ENTER to return to the main menu.

Arrancamos el agente... y ya está.

  /usr/local/ossec-1.6/bin/ossec-control start

Y no hay nada más que hacer para tener lo básico de ossec. Por supuesto, todo es muy configurable, y ampliable en base a lo que cada uno necesite.

Desde otra máquina, me intento conectar digamos que 10 veces usando ssh con usuarios invalidos..... sorpresa, recibo este correo.

  OSSEC HIDS Notification.
  2008 Sep 21 22:30:40

  Received From: (agente1) 172.17.0.131->/var/log/auth.log
  Rule: 5712 fired (level 10) -> "SSHD brute force trying to get access to the system."
  Portion of the log(s):

  Sep 21 19:06:32 fn131 sshd[5990]: Invalid user aaaaab from 172.17.0.2
  Sep 21 19:06:26 fn131 sshd[5986]: Failed password for invalid user aaaaa from 172.17.0.2 port 39010 ssh2
  Sep 21 19:06:23 fn131 sshd[5986]: Failed password for invalid user aaaaa from 172.17.0.2 port 39010 ssh2
  Sep 21 19:06:21 fn131 sshd[5986]: Failed none for invalid user aaaaa from 172.17.0.2 port 39010 ssh2
  Sep 21 19:06:21 fn131 sshd[5986]: Invalid user aaaaa from 172.17.0.2
  Sep 21 19:06:09 fn131 sshd[5984]: Failed password for invalid user aaaah from 172.17.0.2 port 39009 ssh2
  Sep 21 19:06:06 fn131 sshd[5984]: Failed none for invalid user aaaah from 172.17.0.2 port 39009 ssh2

Algunos ejemplos con distintos tipos de eventos:

  OSSEC HIDS Notification.
  2008 Oct 09 21:29:03

  Received From: servidor->syscheck
  Rule: 550 fired (level 7) -> "Integrity checksum changed."
  Portion of the log(s):

  Integrity checksum changed for: '/etc/dovecot/dovecot.conf'
  Size changed from '45438' to '45460'
  Old md5sum was: 'bd5c81584dad9725045ec0e52eb0c15c'
  New md5sum is : '439061951cdeb975c21d37b4cc5f8649'
  Old sha1sum was: '8d7ade9a74b9e8ff4d6758c14bdb070ccb15b198'
  New sha1sum is : '8e7d34ba6328a1e5d38645972b369e700f7d05b2'
   --END OF NOTIFICATION

  OSSEC HIDS Notification.
  2008 Oct 07 18:29:00

  Received From: servidor->/var/log/dpkg.log
  Rule: 2902 fired (level 7) -> "New dpkg (Debian Package) installed."
  Portion of the log(s):

  2008-10-07 18:29:00 status installed unzip 5.52-12
   --END OF NOTIFICATION

  OSSEC HIDS Notification.
  2008 Oct 05 17:42:23

  Received From: agente1->/var/log/messages
  Rule: 5104 fired (level 8 ) -> "Interface entered in promiscuous(sniffing) mode."
  Portion of the log(s):

  Oct  5 17:42:21 nurn kernel: device lo entered promiscuous mode
   --END OF NOTIFICATION

En el próximo post veremos un poco sobre la configuración de todas estas reglas.

read more

Monitorización orientada a host con OSSEC II

jue, 13 nov 2008 by Foron

En mi primer post sobre ossec he mostrado los pasos para hacer una instalación básica y completamente estándar de ossec. En este post vamos a ver lo que hay por debajo del software.

Ossec usa tres componentes: un detector de rootkits, una herramienta para revisar la integridad del sistema, y el analizador de logs. Todas ellas se configuran en el fichero ossec.conf.

Este fichero de configuración tiene una estructura muy clara, en formato xml, en el que se definen varios bloques.

En este post sólo voy a dar algunas ideas básicas sobre el formato con el que se definen las reglas que describen los eventos detectables en los logs.

Tanto el chequeo de integridad como el detector de rootkits se configuran de una forma muy similar, así que lo dejaré para que quien quiera se pelee con ello.

En ossec.conf se definen los logs que se quieren monitorizar dentro de secciones "localfile". Un ejemplo:

  <localfile>
    <log_format>syslog</log_format>
    <location>/var/log/auth.log</location>
  </localfile>

En este caso se dice que queremos vigilar auth.log, del tipo syslog. Existen varios formatos definidos, como apache o snort-full, por citar dos ejemplos. Syslog se usa en los casos en los que se loguea un único evento por linea. Sort-full, por poner otro ejemplo, está adaptado al tipo de log que deja snort cuando usa el formato de salida full.

Una vez definidos los formatos, empezamos a hablar de reglas. El primer paso es que ossec detecte qué tipo de entrada de log es. Para esto se usan los decoders (decoder.xml) Veamos un ejemplo.

  <decoder name="sshd">
  <program_name>^sshd</program_name>
  </decoder>

Este decoder "se activa" cuando la entrada de log es generada por el programa sshd (sshd[5493] en el siguiente ejemplo):

  Feb  3 19:22:33 server sshd[5493]: Accepted publickey for prueba from 192.168.10.2 port 50560 ssh2

Pero, a pesar de la importancia de esta sencilla regla (después veremos por qué), necesitamos extender el decoder para que sea útil.

  <decoder name="ssh-failed">
  <parent>sshd</parent>
  <prematch>^Failed \S+ </prematch>
    <regex offset="after_prematch">^for (\S+) from (\S+) port \d+ \w+$</regex>
    <order>user, srcip</order>
  </decoder>

Gracias a la primera y simple regla "sshd" nos aseguramos que ossec sólo va a analizar la entrada de log contra esta segunda regla, mucho más compleja, si dicho log está relacionado con ssh. Esto es una gran mejora en el rendimiento del sistema.

Sin entrar en explicaciones detalladas, esta regla se cumple con este tipo de log:

  Jul 26 22:06:10 server sshd[3727]: Failed password for prueba from 192.168.10.2 port 50519 ssh2

Y además crea dos "variables"; una con el usuario que ha intentado conectarse y otra con la IP origen.

Teniendo estos datos ya podemos empezar con las reglas "de verdad". Veamos algo del fichero sshd_rules.xml

  <rule id="5700" level="0" noalert="1">
    <decoded_as>sshd</decoded_as>
    <description>SSHD messages grouped.</description>
  </rule>

  <rule id="5716" level="5">
    <if_sid>5700</if_sid>
    <match>^Failed|^error: PAM: Authentication</match>
    <description>SSHD authentication failed.</description>
    <group>authentication_failed,</group>
  </rule>

De manera similar a los decoders, se define una primera regla básica para ssh, que ayudará a ossec en no tener que analizar reglas de apache (por ejmplo) en logs de ssh.

La segunda regla (5716) generará una alerta de nivel 5 cuando haya un intento de login erroneo. Pero también se pueden crear reglas compuestas que activarán alertas de mayor nivel si hay x intentos fallidos desde una misma IP

  <rule id="5720" level="10" frequency="6">
    <if_matched_sid>5716</if_matched_sid>
    <same_source_ip />
    <description>Multiple SSHD authentication failures.</description>
    <group>authentication_failures,</group>
  </rule>

Gracias al formato xml es muy sencillo añadir nuevas reglas. También se pueden enviar correos con las alertas a cuentas de correo diferentes en base, por ejemplo, al agente que ha generado la alerta o al nivel de la misma.

En el tercer y último post de la serie vamos a integrar ossec con psad.

read more

Monitorización orientada a host con OSSEC III

dom, 16 nov 2008 by Foron

En este último post de la serie vamos a ver, como siempre muy por encima, la funcionalidad "active response" que ofrece ossec. En definitiva, se trata de ser capaces de ejecutar un script cuando se activa un evento. Esto normalmente se usa para añadir reglas en firewalls, para añadir reglas tcp wrapper o para bloquear usuarios, pero en el fondo se puede hacer cualquier cosa que se pueda escribir en un programa. Por ejemplo, si una de las máquinas monitorizadas es un servidor de correo se podría añadir una IP que generase una alerta a una lista de acceso, o a una base de datos RBL. O también se podrían añadir reglas de modsecurity en un servidor web.

Para el ejemplo de este post, digamos que como administradores ya estamos usando psad para crear reglas en nuestro firewall. Digamos, además, que sólo queremos que sea psad el responsable de las reglas dinámicas en el cortafuegos.

Infraestructura ossec

Rootkits, accesos no permitidos, .... No parece necesario justificar la necesidad de tener el firewall monitorizado, ¿Verdad?

Nuestro objetivo es crear reglas para psad desde ossec. Primero definimos el comando en ossec.conf para poder usarlo más adelante en la configuración de la respuesta activa.

  <command>
    <name>psad</name>
    <executable>psad.sh</executable>
    <expect>user,srcip</expect>
  </command>

El script "psad.sh" (que guardaremos en $ossec_instalacion/active-response/bin con permisos de ejecución) tiene el siguiente contenido:

  #!/bin/bash
  # Anyade una regla de psad usando la IP origen. Tambien pasamos el usuario, pero no lo vamos a usar.
  # Entrada: user, srcip
  # Salida: Nada. Ejecuta una regla psad
  ACCION=$1
  USUARIO=$2
  IP=$3

  psad -fw-block-ip $IP

Ahora sólo queda configurar la respuesta activa en ossec.conf.

  <active-response>
    <disabled>no</disabled>
    <command>psad</command>
    <location>defined-agent</location>
    <agent_id>001</agent_id>
    <level>10</level>
    <rules_group>authentication_failures</rules_group>
  </active-response>

Estamos diciendo que vamos a ejecutar en el agente 001 (el firewall) el comando psad cuando ocurra un evento de nivel 10 y del grupo authentication_failures (por ejemplo la regla 5720).

Veamos si funciona bien intentando loguearnos varias veces desde una máquina (después de haber recargado la configuración de ossec). Este es el resultado

  Nov  9 00:50:03 firewall psad: added iptables auto-block against 192.168.10.133 for 3600 seconds

  Chain PSAD_BLOCK (1 references)
  target     prot opt source               destination
  DROP       all  --  192.168.10.133       0.0.0.0/0

Como siempre, y para aquellos que quieran profundizar más, recomiendo el libro http://www.elsevierdirect.com/product.jsp?isbn=9781597492409.

read more

Port Knocking sin complicaciones

mié, 06 nov 2013 by Foron

(Así, pecando de básico desde el principio)

Históricamente, desde el punto de vista de la seguridad, los servidores han venido teniendo dos tipos de puertos:

  • Los que tienen que estar siempre abiertos: Los puertos HTTP o HTTPS de un servidor web, sin ir más lejos.
  • Los que sólo tienen que estar abiertos para unas IPs determinadas: SSH, por ejemplo.

La configuración, en ambos casos, siempre ha sido razonablemente sencilla; al menos si asumimos que, a menudo, el rango de IPs con acceso a esos puertos restringidos era conocido (oficinas, etc).

Con el tiempo, sobre los firewalls y todas sus variantes se han añadido otra serie de medidas "complementarias", que muchos no considerarán parte de la seguridad informática "de verdad", pero que han demostrado ser útiles si se usan adecuadamente y como parte de una solución más global. Me refiero, por ejemplo, al uso de librerías como TCPWrappers o de geolocalización, a los propios mecanismos de cada aplicación, o al uso de puertos no estándar para los servicios (los sandboxes por aplicación basados en la virtualización, Selinux y todo este tipo de medidas quedan fuera de este post).

Sin embargo, en la actualidad nos encontramos ante un problema añadido que no hemos tenido hasta la fecha: Las IPs origen que se tienen que conectar a esos servicios restringidos ya no son "tan estáticas" como antes. ¿Cómo abro el acceso SSH a un móvil? ¿Y el webmail corporativo? ¿Y el acceso IMAP?

Muchos diréis que nada como una buena VPN para solucionar este problemilla; y tendréis razón, claro. Ahora bien, el mundo de las redes privadas, por si sólo, tiene otra serie de problemas que no vamos a tratar aquí: ¿Qué tecnología VPN usamos? ¿Qué aplicación cliente? ¿A qué IPs permitimos establecer la conexión? ¿Dónde terminamos la red? ¿Qué acceso tiene un usuario de VPN una vez ha pasado ese terminador? En fin, lo dicho, todo un mundo.

En este post casi voy a limitarme a citar una herramienta más que usar a la hora de securizar un servidor: El Port Knocking. Ojo, se trata de un mecanismo adicional, y no de la solución definitiva a los problemas; pero sí es cierto que viene a ayudar con el problema del dinamismo actual de los orígenes.

El concepto general es realmente sencillo. El firewall del servidor mantiene bloqueado el puerto al que se quiere acceder, y sólo se habilita a través del envío de una secuencia determinada de paquetes. Las opciones son múltiples, y van desde simples SYN, en orden, a n puertos, hasta combinaciones más elaboradas, en las que se activan otros flags en las cabeceras.

A partir de esta idea básica, han ido apareciendo otras mejoras que vamos a ver en un minuto.

Port Knocking básico

La versión más sencilla del "protocolo" se basa, como vengo diciendo, en mandar una secuencia concreta de paquetes a varios puertos. Para su implementación en el lado del servidor, tenemos tres opciones. La primera requiere instalar software (knockd por ejemplo), y las otras dos usan únicamente iptables.

Si optáis por la vía de knockd, os tendréis que descargar el software (obviamente). Según la distribución que uséis, esto será más o menos fácil, así que no me voy a meter con la instalación.

[options]
  logfile = /var/log/knockd.log

[IMAPon]
  sequence    = 6030,6026,6031
  seq_timeout = 5
  command     = /sbin/iptables -I INPUT 2 -s %IP% -p tcp --dport 993 -j ACCEPT
  tcpflags    = syn

[IMAPoff]
  sequence    = 6040,6036,6041
  seq_timeout = 5
  command     = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 993 -j ACCEPT
  tcpflags    = syn

Esta es una configuración tipo, en mi caso de "/etc/knockd.conf". Como podéis suponer, cuando alguien envíe tres paquetes SYN a los puertos 6030,6026 y 6031, en ese orden, se ejecutará el comando definido en "command". En este ejemplo, es una simple regla iptables que permite que desde la IP origen se pueda conectar al puerto IMAP (IMAPon). Como la aplicación da la opción de lanzar más secuencias, se puede crear otra para eliminar la regla (IMAPoff).

Y poco más. En vuestro caso, tendréis que adaptar la regla iptables a vuestra configuración, o incluso podríais lanzar scripts más complejos, que por ejemplo manden un correo o alerta cada vez que se active el acceso.

Esta es la forma más simple de implementar el Port Knocking. Tiene fallos, como por ejemplo que un cambio de IP en el móvil supondría que la IP antigua tendría acceso permanente (o hasta eliminarla a mano), pero creo que son fáciles de solucionar (el match "recent" de iptables por ejemplo ofrece alternativas). Vosotros deberéis decidir si esto os sirve, o si necesitáis algo más elaborado.

La segunda forma de implementar esta versión original de Port Knocking es a través de iptables, sin software adicional. El proceso está muy bien documentado en el siempre magnífico wiki de archlinux, así que podéis seguir desde allí si optáis por esta vía.

Y para terminar, si queréis una alternativa específica de iptables, hay un módulo en xtables addons pensado para hacer Port Knocking. Se llama xt_pknock, y permite hacer cosas como esta (entre otras que veremos más adelante):

  iptables -A INPUT -p tcp -m pknock --knockports 4002,4001,4004 --strict --name IMAP --time 10 --autoclose 60 --dport 993 -j ACCEPT

El problema es que, hasta la fecha, os va a costar encontrar un kernel que traiga el módulo compilado, así que lo tendríais que hacer vosotros.

Port Knocking con autenticación

Aunque obligar a que el origen conozca la secuencia concreta que enviar al servidor sea útil, no es menos cierto que tiene margen de mejora. La más obvia va en el sentido de verificar que la conexión procede realmente desde un usuario autenticado.

Sobre esta idea, Michael Rash (autor, entre otros, de psad) implementó una mejora del Port Knocking sobre el concepto de Single Packet Authorization (SPA): fwknop. El objetivo es el mismo (abrir un puerto a través de iptables si usamos Linux), pero usando para ello un único paquete UDP con unos datos determinados. De esta manera, se evitan los problemas generados a partir del envío de múltiples paquetes (llegar desordenados, bloqueo por IDS, ...) y, además, da la opción de cifrar el payload con un algoritmo que también ofrezca autenticación. Podéis ver el listado de features y las ventajas de esta implementación en la propia web de fwknop.

La instalación de fwknopd es muy sencilla. De hecho, está disponible en muchas distribuciones. Como no podía ser de otra forma, tener muchas más funcionalidades también hace que la configuración sea algo más complicada que en el caso de knockd, aunque sigue siendo manejable.

Este es el momento en el que debería escribir algunas notas y ejemplos de configuración pero, la verdad, visto que en la web ya hay un buen tutorial, prefiero no alargar mucho más el post. Si tenéis alguna duda, escribid un comentario e intentaré resolverla. Tened en cuenta que fwknop es un proyecto "vivo", y que por lo tanto va mejorando con cada release. Las últimas versiones (a partir de la 2.5), por ejemplo, incluyen soporte para HMAC + SHA, de tal manera que se puede combinar con AES o GnuPG para mejorar la autenticación. Yo personalmente no he usado esta versión, así que no puedo comentar nada sobre esta nueva funcionalidad.

Una instalación tipo de fwknop, al menos en versiones anteriores a a la 2.5, usa dos ficheros de configuración. Cada parámetro está muy bien documentado, así que lo mejor es ir siguiendo los comentarios que veréis en fwknopd.conf y en access.conf. El primero se usa para definir si queremos poner el interfaz en modo promiscuo, el puerto en el que escucharemos los paquetes y, sobre todo, las cadenas de iptables que usaremos para incluir las reglas. Access.conf se usa para la parte más directamente relacionada con el acceso; empezando por todo lo relacionado con las claves de cifrado, y siguiendo con el contenido que puede ir en cada paquete, desde usuarios autorizados a puertos para los que se puede pedir acceso, pasando por un mecanismo de control de la IP origen desde la que se genera la solicitud.

Por último, y dejando a un lado fwknop, el módulo de Netfilter del que os he hablado antes, xt_pknock, también ofrece una versión de Port Knocking que ofrece SPA, de tal manera que se pueden escribir cosas como estas:

  ...
  iptables -A INPUT -p udp -m state --state NEW -m pknock --knockports 2000 --name IMAP --opensecret your_opensecret --closesecret your_closesecret -j DROP
  iptables -A INPUT -p tcp -m state --state NEW -m pknock --checkip --name IMAP -m tcp --dport 143 -j ACCEPT
  ...

Aún así, como os he dicho, este módulo todavía no es "demasiado fácil" de usar y, en todo caso, es más simple que lo que ofrece fwknop.

Clientes

La pregunta es: ¿Cómo se genera la secuencia que abre la puerta?

Si usamos la versión básica de Port Knocking, no hay ningún problema. Podemos usar la aplicación cliente del software (knock), o podemos usar nmap, nping, netcat, o cualquier otra aplicación que permita mandar paquetes con el flag SYN activo a un puerto concreto. Para móviles, también hay variedad; en android, por ejemplo, una búsqueda de "port knocking" da al menos dos aplicaciones gratuitas (y que funcionan, al menos en mi teléfono y tablet).

Si optamos por la versión con SPA, también tenemos aplicaciones para todo tipo de dispositivos y clientes, aunque en este caso tendremos que tirar, probablemente, por las aplicaciones creadas específicamente para fwknop. Yo personalmente no he probado las versiones para móvil, así que poco puedo aportar. En el tutorial tenéis los enlaces y sus limitaciones (sobre todo relacionadas con el uso de HMAC). Por supuesto, si estáis en Linux, no tendréis problema para usar el propio software cliente que trae fwknop.

Notas

No pretendo empezar una discusión sobre si el Port Knocking es útil o no, o de si entra dentro de lo llamado "Security through obscurity"; pero sí tengo claro que es una herramienta más, y que es perfectamente "usable" en muchos entornos. Ahora bien, aunque podamos estar de acuerdo en que el Port Knocking básico es algo limitado, la implementación de fwknop sí que es, indudablemente, mucho más completa desde el punto de vista de la seguridad informática.

read more