Documentación útil

sáb, 25 feb 2012 by Foron

La verdad, a estas alturas todavía no conozco a demasiada gente a la que le guste documentar. Es más, cuanto más técnico es uno, menos gusta.

Cada uno tendrá sus motivos, pero en mi caso, saber que nadie lee los documentos internos de instalaciones, actualizaciones, etc, que he escrito no me termina de hacer gracia.

Veamos el entorno en el que suelen moverse este tipo de documentos:

  • Son manuales que describen la instalación de servidores y aplicaciones, y que suelen guardarse en formato doc, pdf o similares en sistemas de gestión documental.
  • Su lógica es que un nuevo empleado pueda revisar el documento y que le sirva como referencia de la infraestructura.
  • Describen la instalación, paso a paso, de un servidor, por ejemplo de correo electrónico, las aplicaciones que ejecuta, ficheros de configuración, ....
  • Pretenden estar siempre actualizadas.

¿Cuál es el problema?

Según lo veo yo, y al igual que pasa con tantos otros "deberes" del trabajo (partes de actividad, gestión de procesos, ...), rompen completamente el flujo de trabajo del empleado: Para documentar, o para rellenar un parte de actividad, uno tiene que dejar lo que está haciendo, abrir libreoffice, buscar la plantilla, escribir texto, .... viene trabajo urgente, se aparca el documento, se retoma a los dos días, no se recuerda lo que se ha escrito, se repasa, ... otra vez trabajo prioritario, se vuelve a dejar el documento, ....

Y con las actualizaciones es todavía peor. No sé yo si mucha gente actualiza sus documentos cuando cambia algo de sus servidores (algo presumible en sistemas "vivos"), pero supone volver a dejar la rutina del trabajo, abrir el documento, buscar lo que hay que cambiar, redactar las modificaciones, repasar el documento, corregirlo, ....

Los wikis, que también se usan a menudo, tampoco están exentos de estos problemas: No siempre es fácil ir al navegador, buscar un documento que se escribió hace tiempo, modificarlo, ver referencias, mantenerlo al día, ....

Y para colmo, ¿Necesita esta documentación un nuevo empleado? Debemos suponer que alguien que va a trabajar con servidores de correo electrónico sabe como se instalan y lo que significa cada opción de configuración ¿Verdad?.

Con estos antecedentes, aquí van los mandamientos de forondarena.net para el trabajo de documentación:

  1. Por supuesto, hay que documentar todo aquello que no sea interno: Manuales para clientes y proveedores, documentos específicos para grupos de soporte y atención al cliente, ....
  2. Volviendo al trabajo interno de un departamento, sólo se documenta la definición del producto, quizá en forma de plan de proyecto, con su alcance, su público objetivo, lo que se pretende conseguir con él, .... En fin, estas cosas. Se pueden añadir detalles técnicos, pero más estructurales, de infraestructura, entorno tecnológico, ....
  3. Sólo hay una forma de garantizar que una instalación va a estar siempre bien documentada: Integrando la documentación en la rutina del trabajo. Dicho de otra forma, y concretando con un ejemplo, usando Puppet o similares en las instalaciones (y actualizaciones), y aprovechando su capacidad para auto-documentarse. Si alguien toca algo a mano, Puppet lo sobrescribe. Documentación actualizada, siempre.
  4. Si por algún motivo no se puede usar un sistema de gestión centralizada, al menos debe usarse software de control de versiones, ya sea git, subversion, cvs, o el que sea.
  5. La documentación más concreta, más detallada, de ficheros de configuración y scripts, como por ejemplo el motivo por el que se bloqueó una red en la configuración de apache, o la incidencia por la que se decidió aumentar el tamaño máximo de un mensaje en Postfix, deben estar al alcance del técnico, a ser posible sin tener que mover la vista de la terminal.

Y es este último punto el que me interesa en este post.

No, escribir comentarios en los mismos ficheros de configuración no es una opción, salvo para cosas puntuales. Además, una cosa es que queramos poder acceder rápido a la documentación, y otra que no podamos, en algún momento, pasarla a otros formatos, como html, con enlaces entre documentos, o pdf.

Entonces,.... Pues sí, sorpresa, ¡man!, el de toda la vida, y algunas aplicaciones construidas a su alrededor permiten hacer estas cosas, y mucho más.

Escribiendo páginas de manual

No, no voy a hablar sobre groff, ni mandoc, ni nada similar. Vamos a simplificar esto, aunque no haya nada complicado en groff, que conste. El objetivo es escribir documentación rápido, y no caer en los mismos errores que intentamos evitar.

A partir de ahora, sólo voy a escribir un pequeño resumen de este post del excelente blog dailyjs. Muy recomendable.

Por un lado, necesitamos un formato sencillo en el que escribir la documentación, y por otro, algún tipo de aplicación con la que convertir este texto en páginas compatibles con man, html, pdf, o lo que necesitemos.

Entre las opciones para el formato, la elección es markdown (que por cierto es interpretado por Github), y en cuanto a la aplicación que permite su conversión a otros formatos, tenemos varias alternativas, como ronn, o su versión para node.js ronnjs; pero en este post de ejemplo vamos a usar mantastic.herokuapp.com, que es una aplicación de Heroku que hace todo el trabajo por nosotros.

Pasemos a un ejemplo:

Tenemos un servidor de correo Postfix, con su correspondiente main.cf. Este fichero se sincroniza a través de Puppet, y se ha ido modificando en función de bugs, mejoras, incidencias de clientes y similares a lo largo de los meses.

En markdown, podríamos escribir algo como esto (que por cierto, se explica solo):

 main.cf(5) -- Configuración principal de Postfix
 ================================================

  ## SYNOPSIS

  `main.cf` - Fichero de configuración principal de Postfix.

  ## DESCRIPTION

  El fichero `main.cf` define gran parte de los cambios sobre la instalación base que se hacen a Postfix. Por lo tanto, cualquier cambio que se realice en este fichero debe ser probado en servidores de pre producción.


  `main.cf` es gestionado por `puppet(1)`. Los cambios que se apliquen directamente sobre este fichero serán sobreescritos.


  En la siguiente lista se encuentran las modificaciones más significativas que se han ido aplicando al fichero:

  * `message_size_limit`=20000:
       Se aplicó este límite de 20000 bytes a la configuración bla bla bla.

  * `dovecot_destination_recipient_limit`=1:
       Opción más segura para controlar las entregas locales bla bla bla. El transport dovecot se define en `master.cf(5)`

  * `smtpd_client_restrictions`=check_client_access cdb:/etc/postfix/clientes.out:
       Se define el fichero `clientes.out(5)`, como parte del grupo de restricciones en fase cliente, para rechazar aquellos clientes que no cumplan las normas de uso de la plataforma.

  ## INCIDENCIAS

  [1234](http://bugtrack.example.com/?id=1234) - Cliente x con problemas de envío.
  [5678](http://bugtrack.example.com/?id=5678) - Cliente z que envía miles de mensajes spam.

  ## HISTORY

  2012-02-20, Versión inicial.

  ## AUTHOR

  2012, Forondarena.net postmaster

  ## COPYRIGHT

  Forondarena.net

  ## SEE ALSO

  `puppet(1)`, `master.cf(5)`, `clientes.out(5)`

Si guardamos este fichero como "main.cf.5.md", y lo pasamos por la aplicación de Heroku, obtendremos una página de manual perfectamente formateada:

  curl -F page=@main.cf.5.md http://mantastic.herokuapp.com > main.cf.5

Si por el contrario optáis por usar una instalación local de ronn, o de ronnjs, se podría generar, además de lo anterior, una serie de páginas html enlazadas entre sí, tipo wiki, aunque para eso quizá habría que trabajar algo más el markdown.

Conclusión

Tal y como he venido diciendo, una buena documentación tiene tres niveles:

  1. Documentación general, de alto nivel, o externa. Puede ser un doc, pdf, etc.
  2. Documentación sobre instalaciones de máquinas, actualizaciones de software, etc. Muy dinámica y difícil de mantener si no se integra completamente en el día a día del trabajo. Los sistemas de configuración centralizados son la clave.
  3. Documentación detallada sobre scripts y ficheros concretos. No conozco muchos entornos en los que se tengan realmente bien documentados todos los scripts y ficheros de configuración. Algunos son capaces de incluir comentarios inline, pero esto no siempre es suficiente, y se corre el riesgo de terminar con ficheros de configuración demasiado "densos". Sólo pueden documentarse correctamente a través de aplicaciones muy sencillas y directas.

Notas

El fichero en markdown y su correspondiente página de manual están disponibles en Github.

Una vez más, el impulso definitivo para publicar esto se debe al post de dailyjs que he referenciado anteriormente.

Dejo como ejercicio el uso de ronn o ronnjs en línea de comandos, la generación de páginas html, la gestión centralizada, o incluso montar un servidor de páginas de manual (pista: tcpserver/tcpclient, netcat, socat, ...).

read more

Enrutamiento para dummies

jue, 27 sep 2012 by Foron

Si hay algo sobre lo que no hubiese querido escribir nunca en este blog es sobre el enrutamiento básico en Linux. Hace 10 años quizá hubiese sido más interesante, pero no ahora. Aún así, en este mundo del botón y del siguiente siguiente no tengo nada claro que la gente sepa exactamente lo que hay debajo de un "route -n", así que vamos a ello. Eso sí, para dummies. De hecho, me voy a pasar de básico, con lo que escribiré cosas que en condiciones normales merecerían una discusión. En fin.

Empezamos con el viejo comando "route -n", tan simple como siempre:

  # route -n
  Kernel IP routing table
  Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
  0.0.0.0         10.213.208.1    0.0.0.0         UG    0      0        0 eth0
  10.213.208.0    0.0.0.0         255.255.240.0   U     0      0        0 eth0
  192.168.10.0    0.0.0.0         255.255.255.0   U     0      0        0 eth1
  192.168.11.0    0.0.0.0         255.255.255.0   U     0      0        0 eth1

Lo normal cuando usamos la combinación route/ifconfig en la mayoría de las distribuciones, una puerta de enlace, una red para llegar a esa puerta de enlace a través de un dispositivo, y luego, en este caso, nuestras redes locales.

¿No hay nada más?

Pues sí, hay mucho más, claro. Esto no es más que una mínima porción de la tabla de enrutamiento de vuestro kernel favorito. Vamos a verlo pasando a la utilidad "ip", la pobre, que lleva tanto tiempo existiendo, pero que tan poco se usa (solo comparable al uso eterno de los aliases de IPs, pero esta es otra historia).

  # ip route ls
  default via 10.213.208.1 dev eth0
  10.213.208.0/20 dev eth0  proto kernel  scope link  src 10.213.218.162
  192.168.10.0/24 dev eth1  proto kernel  scope link  src 192.168.10.1
  192.168.11.0/24 dev eth1  proto kernel  scope link  src 192.168.11.1

¿Todo este rollo para ver lo mismo con un formato diferente?

Sí, porque estamos viendo, una vez más, solo una parte de la tabla de enrutamiento. ¡Hola "ip rule"!

  # ip rule ls
  0:      from all lookup local
  32766:  from all lookup main
  32767:  from all lookup default

Y ahora, sorpresa:

  # ip route ls table default
  _vacio_
  # ip route ls table main
  default via 10.213.208.1 dev eth0
  10.213.208.0/20 dev eth0  proto kernel  scope link  src 10.213.218.162
  192.168.10.0/24 dev eth1  proto kernel  scope link  src 192.168.10.1
  192.168.11.0/24 dev eth1  proto kernel  scope link  src 192.168.11.1
  # ip route ls table local
  broadcast 10.213.208.0 dev eth0  proto kernel  scope link  src 10.213.218.162
  local 10.213.218.162 dev eth0  proto kernel  scope host  src 10.213.218.162
  broadcast 10.213.223.255 dev eth0  proto kernel  scope link  src 10.213.218.162
  broadcast 127.0.0.0 dev lo  proto kernel  scope link  src 127.0.0.1
  local 127.0.0.0/8 dev lo  proto kernel  scope host  src 127.0.0.1
  local 127.0.0.1 dev lo  proto kernel  scope host  src 127.0.0.1
  broadcast 127.255.255.255 dev lo  proto kernel  scope link  src 127.0.0.1
  broadcast 192.168.10.0 dev eth1  proto kernel  scope link  src 192.168.10.1
  local 192.168.10.1 dev eth1  proto kernel  scope host  src 192.168.10.1
  broadcast 192.168.10.255 dev eth1  proto kernel  scope link  src 192.168.10.1
  broadcast 192.168.11.0 dev eth1  proto kernel  scope link  src 192.168.11.1
  local 192.168.11.1 dev eth1  proto kernel  scope host  src 192.168.11.1
  broadcast 192.168.11.255 dev eth1  proto kernel  scope link  src 192.168.11.1

Vaya sorpresa... Lo que vemos con un "route -n" es en realidad la tabla "main", que además, por ese 32766, parece tener menos prioridad que esa tabla "local" tan curiosa. Fácil de leer, ¿Verdad? Los broadcast los conocemos todos pero, ¿Y las rutas de tipo local? Sacado literalmente del manual (Sí, todo esto está en el manual de ip route!!!): "the destinations are assigned to this host. The packets are looped back and delivered locally". Y con esto hemos terminado, solo nos queda saber que "proto kernel" es la configuración más normal si no usamos software de enrutamiento (quagga, por ejemplo), y que "scope link" es para rutas broadcast y unicast mientras que "scope host" es para las locales.

Revisad los manuales de "ip rule" e "ip route", por favor, y entended cada entrada de estas tablas y reglas.

Ya que estamos, vamos a jugar un poco con todo esto que hemos visto, aunque seguimos en "modo sencillo" y no nos vamos a complicar demasiado. Solo unas ideas.

Nota: No hagáis caso a las IPs que uso a partir de aquí. Intentaré mantenerlas coherentes, pero me las estoy inventando sobre la marcha.

Tenemos reglas en "ip rule", tenemos tablas de enrutamiento, ... ¿Apostamos a que todo esto es modificable/configurable? ¡Por supuesto!

Vamos a vuestra distribución Debian favorita, y busquemos el fichero "/etc/iproute2/rt_tables"

  # cat /etc/iproute2/rt_tables
  #
  # reserved values
  #
  255     local
  254     main
  253     default
  0       unspec
  #
  # local
  #
  #1      inr.ruhep

  1001 proveedor1
  1002 proveedor2

No, en vuestros ficheros no van a estar las líneas "proveedor1" y "proveedor2". Las he añadido yo, alegremente. Donde estoy escribiendo este post no hay múltiples lineas de acceso a Internet, pero me voy a inventar, como ejemplo, que en mi equipo hay dos ADSL de proveedores diferentes. Uno me ha asignado la IP 192.0.2.33/24, con puerta de enlace 192.0.2.1, y el segundo 198.51.100.33/24, con gateway 198.51.100.1.

Como ya sabemos todo sobre enrutamiento, queremos mandar a los comerciales a través del primer proveedor, y a los técnicos a través del segundo. Supongamos que los comerciales están todos en la subred "172.16.0.0/24", y los técnicos en "172.16.1.0/24".

¡Juguemos con ip rule!

  # ip rule add from 172.16.0.0/24 table proveedor1
  # ip rule add from 172.16.1.0/24 table proveedor2
  # ip rule ls
  0:      from all lookup local
  32764:  from 172.16.1.0/24 lookup proveedor2
  32765:  from 172.16.0.0/24 lookup proveedor1
  32766:  from all lookup main
  32767:  from all lookup default

Efectivamente, hemos separado el tráfico en dos tablas, por ahora vacías. Es el turno de ip route:

  # ip route add 172.16.0.0/16 dev eth0 src 172.16.0.1 table proveedor1
  # ip route add 192.0.2.0/24 dev eth1 src 192.0.2.33 table proveedor1
  # ip route add default via 192.0.2.1 table proveedor1

  # ip route add 172.16.0.0/16 dev eth0 src 172.16.0.1 table proveedor2
  # ip route add 198.51.100.0/24 dev eth2 src 198.51.100.33 table proveedor2
  # ip route add default via 198.51.100.1 table proveedor2

¿Veis lo que hemos hecho? Hemos asignado dos puertas de enlace por defecto diferentes, en base al origen, por lo que todo lo que venga desde 172.16.0.0/24 irá por 192.0.2.1, y lo originado en 172.16.1.0/24 por 198.51.100.1. Por si fuera poco, el tráfico que no entre en ninguna de estas dos subredes accederá a la tabla main (from all lookup main), y con ello usará la puerta de enlace por defecto de toda la vida, esa que pensábamos que era única.

Y ya está, aquí lo dejo, aunque debo recordaros que esto no es una guía tipo copy/paste, ni remotamente.

Notas:

  • Como no podía ser de otra forma, el direccionamiento interno de este post no puede salir directamente a Internet. Hay que hacer SNAT (o el masquerade de toda la vida) en iptables. Lo normal es que conntrack haga magia y sepa dónde mandar vuestro tráfico, pero también es posible que se tenga que jugar más a fondo con ello.
  • Las entradas que añaden rutas a las tablas están simplificadas. Sería deseable completarlas, por ejemplo para evitar avisos de ICMP sobre mejores rutas si quisiésemos mandar tráfico entre redes. Lo dicho, no es más que un ejemplo.
  • En función de las configuraciones, interfaces, firewalls, ... puede ser posible que se tenga que cambiar algún parámetro de kernel, como por ejemplo, lo relacionado con rp_filter (Google es vuestro amigo). Por supuesto, ni que decir ip_forward.
  • Una vez más, esto es un mínimo ejemplo de lo mucho que se puede hacer. Las reglas, sin ir más lejos, pueden definirse por IP origen, destino, o incluso por marca de firewall, con lo que las posibilidades son enormes.
  • Os recomiendo completar lo visto en este post con todo lo que hay alrededor del enrutamiento en un kernel normal, con soporte Netfilter. Pista.
read more

Firewalls proactivos con psad

sáb, 06 sep 2008 by Foron

En este post voy a documentar un uso alternativo que se puede dar a psad, un interesante software pensado para la detección de escaneos de puertos, que fue creado como parte de bastille linux en el 1999.

El problema:

Tenemos un firewall que gestiona una red digamos que de servidores web y smtp, para los que evidentemente tenemos acceso libre por los puertos 25 y 80, pero que reciben multitud de ataques de todo tipo. Las propias aplicaciones tienen sus mecanismos de seguridad, pero al final siempre añadimos muchas de las IPs que generan los ataques en el firewall perimetral. Claro, al final tenemos cientos de IPs en los firewalls que somos incapaces de mantener, y que no hacen más que complicar su gestión. Para colmo, la mayoría de esas IP sólo lo intentan durante unos pocos minutos.

Una solución:

Queremos un sistema con el que podamos añadir IPs al firewall, y que expiren, si así lo decidimos, en un cierto plazo de tiempo. Vamos a utilizar psad para esto, que además, al mismo precio, nos sirve para detectar escaneos de puertos. En este primer post sobre todo escribiré sobre lo básico de psad, que en el próximo iremos adaptando al problema.

Vamos a ir instalando. Una opción es descargar el sofware y usar su propio instalador desde cipherdyne.org/psad/, pero en este caso voy a usar el software ya precompilado para Debian. Por cierto, más que recomendable dar una vuelta por cipherdyne.org y ver el software que hay disponible.

  aptitude install -R psad

No quiero que installe bastille, de ahí que use -R. Psad es una aplicación que en su mayoría está programada en perl, así que dependiendo de lo que cada uno tenga en su sistema instalará más o menos librerías.

Una instalación por defecto de psad lee los datos que a través de syslog se pasan a la tubería /var/lib/psad/psadfifo (un pipe de los de toda la vida), con lo que lo primero es hacer que kern.info se mande a dicho pipe, con algo tan sencillo como añadir a syslog.conf:

  kern.info       |/var/lib/psad/psadfifo

Después de reiniciar syslog, ya está todo practicamente listo ....

Configuración:

Dependiendo de la forma de instalación y de la distribución que usemos, seguramente las rutas, nombres de pipes y alguna otra opción podrían ser diferentes, con lo que lo descrito aquí es más conceptual que algo con lo que se pueda hacer copy/paste.

Como psad es un software que sobre todo lee logs, es fundamental que nuestro firewall loguee lo que queremos tratar, que puede ser sólo lo del propio cortafuegos, o también lo que otras máquinas puedan enviarle. En definitiva, que aquí está la clave del invento.

Como referencia, hay que tener en cuenta que psad mira que en las líneas de logs que recibe existan las cadenas IN= y OUT=, con lo que asume que son de iptables. Esto nos será útil posteriormente.

Toda la configuración se hace en /etc/psad/psad.conf. En el directorio /etc/psad hay muchos otros ficheros, algunos los trataré en este post, pero otro no. Hay que tener en cuenta que psad es un software que hace más cosas que lo que voy a describir aquí.

La configuración es muy sencilla de leer y muy documentada, "se explica sola", así que sólo voy a comentar lo más útil para hacerse una idea.

Las dos siguientes variables definen las redes locales y las que no lo son, muy al estilo snort.

  HOME_NET                    192.168.10.0/24, 172.16.0.0/16; # un ejemplo
  EXTERNAL_NET                any;

Estas redes se definen porque psad usa las reglas de snort para detectar tráfico sospechoso, aunque las usa en cierta medida de forma diferente. Por ejemplo, para psad todo el tráfico que loguea está destinado a lo que para snort sería HOME_NET.

Las siguientes variables definen los niveles de peligro. Desde el punto de vista de escaneo de puertos, estos niveles definen el número de paquetes recibidos. Desde el punto de vista de otro tipo de actividad maliciosa, estos niveles se definen según el tipo de ataque o si la IP origen es conocida por anteriores bloqueos.

  DANGER_LEVEL1               5;    ### Number of packets.
  DANGER_LEVEL2               15;
  DANGER_LEVEL3               150;
  DANGER_LEVEL4               1500;
  DANGER_LEVEL5               10000;

Con la siguiente línea hacemos que Psad no sea sólo algo pasivo, sino que añada reglas a nuestro firewall.

  ENABLE_AUTO_IDS             Y;

Digamos que queremos bloquear IPs a partir del nivel 3:

  AUTO_IDS_DANGER_LEVEL       3;

Y que queremos que los bloqueos duren 600 segundos

  AUTO_BLOCK_TIMEOUT          600;

Por supuesto, usamos iptables:

  IPTABLES_BLOCK_METHOD       Y;

La siguiente variable define la/s cadenas en las que queremos que se añadan reglas de bloqueo. Su sintaxis es: Target,Direction,Table,From_chain,Jump_rule_position,To_chain,Rule_position.

Por ejemplo:

  IPT_AUTO_CHAIN1             DROP, src, nat, PREROUTING, 1, PSAD_BLOCK, 1;

Lo más interesante aqui es que DROPeamos con reglas añadidas a la tabla nat y la cadena PSAD_BLOCK. Se pueden añadir IPT_AUTO_CHAINn reglas. No hace falta decir que debemos haber creado anteriormente la cadena PSAD_BLOCK

Psad puede incluso ejecutar scripts externos. La IP origen se pasa a estos scripts en la variable SRCIP.

  ENABLE_EXT_SCRIPT_EXEC      N;

Hay muchas opciones a configurar. Como he dicho antes aquí no hay más que unas cuantas para dar una idea de lo que se puede hacer.

Otro fichero interesante es el /etc/psad/auto_dl, en el que podemos configurar listas blancas y negras de IPs. Por ejemplo:

  127.0.0.1       0;
  10.111.21.23    5   tcp/22;

Con estas dos reglas permitimos todo lo que venga desde 127.0.0.1 y damos un danger_level de 5 a todo lo que venga de 10.111.21.23 y sea tráfico ssh.

Otro fichero interesante es /etc/psad/signatures, que incluye unas 200 firmas de snort, pero ligeramente modificadas para poder pasar información a psad. Por ejemplo:

  alert icmp $EXTERNAL_NET any -> $HOME_NET any (msg:"ICMP PING undefined code"; icode:>0; itype:8; classtype:misc-activity; sid:365; psad_id:100195; psad_dl:2;)

Es una definición de regla relacionada con icmp, y que tiene un identificador en psad de 100195 y que asigna un danger_level de 2.

Ahora sólo quedaría arrancar psad, con:

  /etc/init.d/psad start

Pruebas de funcionamiento:

Veamos lo que pasa cuando alguien nos hace un escaneo de puertos. Como nota, tengo un danger_level (DL) de 3 a partir del cual se añaden reglas de bloqueo.

  Sep  6 21:48:05  psad: src: 87.218.x.y signature match: "MISC MS Terminal Server communication attempt" (sid: 100077) tcp port: 3389
  Sep  6 21:48:05  psad: src: 87.218.x.y signature match: "MISC Microsoft PPTP communication attempt" (sid: 100082) tcp port: 1723
  Sep  6 21:48:05  psad: scan detected: 87.218.x.y -> 83.213.x.y tcp: [21-6347] flags: SYN tcp pkts: 130 DL: 2
  Sep  6 21:48:11  psad: src: 87.218.x.y signature match: "BACKDOOR DoomJuice file upload attempt" (sid: 2375) tcp port: 3141
  Sep  6 21:48:11  psad: src: 87.218.x.y signature match: "DOS Real Audio Server communication attempt" (sid: 100112) tcp port: 7070
  Sep  6 21:48:11  psad: src: 87.218.x.y signature match: "BACKDOOR Subseven DEFCON8 2.1 connection Attempt" (sid: 107) tcp port: 16959
  Sep  6 21:48:11  psad: scan detected: 87.218.x.y -> 83.213.x.y tcp: [2-32770] flags: SYN tcp pkts: 214 DL: 3
  Sep  6 21:48:11  psad: added iptables auto-block against 87.218.x.y for 600 seconds
  Sep  6 21:48:16  psad: scan detected: 87.218.x.y -> 83.213.x.y tcp: [104-13722] flags: SYN tcp pkts: 30 DL: 3

Donde 87.218.x.y es la IP origen del escaneo y 83.213.x.y el destino.

En el firewall:

  # iptables -L PSAD_BLOCK -n -t nat
  Chain PSAD_BLOCK (1 references)
  target     prot opt source               destination
  DROP       all  --  87.218.x.y       0.0.0.0/0

Y a los 600 segundos, se vacia.

  Sep  6 21:58:13 psad: removed iptables auto-block against 87.218.x.y
  # iptables -L PSAD_BLOCK -n -t nat
  Chain PSAD_BLOCK (1 references)
  target     prot opt source               destination

Lo que he hecho hasta ahora es lo básico de psad. En el próximo post seguiré con alguna otra cosilla interesante.

Para el que quiera buscar más información, nada como el libro linux firewalls. Un libro realmente excelente de una editorial que merece la pena.

read more

Firewalls proactivos con psad II

dom, 07 sep 2008 by Foron

En el anterior post hemos visto lo más básico de psad. De hecho, he resumido alguna cosa tanto que los que ya conozcan el software pueden decir que no he sido todo lo riguroso que debiera. Un ejemplo, la parte relacionada con las variables IPT_AUTO_CHAINn. Mi objetivo, más que ser completamente riguroso, era dar una visión global del software.

En fin, dicho esto, vamos a ver alguna otra cosilla que se puede hacer con psad.

Recordemos el problema. Queremos poder añadir a nuestro firewall perimetral reglas que con el tiempo vayan expirando sin tener que estar encima. Queremos, además, que estas reglas se añadan en base a decisiones que tomen los servidores web o smtp en base a sus propios mecanismos, quitando al firewall perimetral la responsabilidad del análisis del tráfico del nivel de aplicación.

Hay varias formas de hacerlo. Lo más fácil es usar el propio comando psad. Por ejemplo:

  # psad -fw-block-ip 10.0.5.98
  [+] Writing 10.0.5.98 to socket; psad will add the IP
      within 5 seconds.

Es tan sencillo como esto. Veamos el resultado:

  # psad --fw-list
  [+] Listing chains from IPT_AUTO_CHAIN keywords...

  Chain PSAD_BLOCK (1 references)
   pkts bytes target     prot opt in     out     source               destination
       0     0 DROP       all  --  *      *       10.0.5.98            0.0.0.0/0

Para quitar esta IP es suficiente con esperar los 600 segundos configurados, o bien ejecutar:

  # psad --fw-rm-block-ip 10.0.5.98
  [+] Writing 10.0.5.98 to socket; psad will remove the IP
      within 5 seconds.

  # psad --fw-list
  [+] Listing chains from IPT_AUTO_CHAIN keywords...

  Chain PSAD_BLOCK (1 references)
   pkts bytes target     prot opt in     out     source               destination

A partir de aquí, seguro que a cada uno se le ocurren cinco formas de hacer que un servidor genere los comandos para que el firewall añada las reglas.

La forma en la que cada administrador gestiona lo que puede hacer con psad es particular de cada infraestructura, pero sin duda, una combinación de psad, fwsnort y otras técnicas como el port knocking añaden funcionalidades muy interesantes que en muchos casos ni siquera el software/hardware de pago ofrecen.

read more

Gestión de logs con Solandra I

mar, 02 ago 2011 by Foron

Allá por el 2008, Rackspace(Mailtrust) publicaba algunos datos sobre la forma en la que había ido evolucionado su sistema de gestión de logs de la infraestructura de correo electrónico, y que por aquel entonces ya superaba holgadamente los 100GB de crecimiento diario. Junto a este documento, en una de las referencias bibliográficas sobre Hadoop, esta misma empresa explicaba, con algo de detalle técnico, la forma en la que habían implementado su sistema, basado sobre todo en Hadoop y Lucene+Solr.

Aunque Hadoop siga siendo una solución magnífica para la gestión de logs en el contexto del Software Libre (siempre hablando de volúmenes de datos realmente muy grandes), en esta serie de posts vamos a ver cómo podemos llevar la idea de Rackspace a la práctica usando otro tipo de tecnología, y más concretamente, Cassandra.

En realidad, como mis tres lectores no quieren posts demasiado largos, en lugar de entrar en los detalles de lo que sería una implementación más o menos "casera", vamos a usar una de las aplicaciones que Datastax (una empresa que da servicios comerciales para Cassandra) está potenciando como parte de su ecosistema alrededor de Cassandra, y que se llama Solandra.

El problema

Repasemos, simplificando un poco, la evolución de Rackspace:

  1. En una primera fase, los logs se almacenan en máquinas individuales. Cuando hay alguna incidencia, algún técnico tiene que entrar a hacer un grep. Si el negocio va bien, llegará un momento en el que el tiempo perdido haciendo estas búsquedas será, por lo menos, "crispante".
  2. En la segunda fase, los logs pasan a gestionarse a través de un syslog centralizado. En realidad, esta no es más que una versión algo mejorada de la primera evolución, pero al menos facilita el trabajo. En cualquier caso, en el fondo se sigue perdiendo mucho tiempo en la búsqueda manual en logs.
  3. La solución más natural en este punto es volcar los datos a una base de datos, y con ello a algún tipo de interfaz web. Dejaremos a un lado el desarrollo del frontend y de los scripts que cargan los datos en la bbdd (que pueden no ser en absoluto triviales, en función de la complejidad de la plataforma).

Hasta aquí, vale, todo es razonablemente sencillo. Sin embargo, cuando se gestionan digamos que 25 millones de mensajes al día, y cuando se quieren mantener 2 años de información (es un decir), nos encontramos con un problema.

¿Cómo se soluciona?

Aquí ya cada uno toma decisiones en función de su capacidad, su presupuesto, los perfiles que tiene disponibles, .... En algunos casos, mantener 30 días en base de datos (lo que genera la mayoría de incidentes), puede ser suficiente. En otros casos, se trabaja con los mecanismos que ofrecen las bases de datos para escalar (el framework Gizzard de Twitter es un estupendo ejemplo, aunque no hablemos de logs). Y por último, algunos pasan a otras soluciones, ya sean de pago o libres. En el caso de Rackspace, por ejemplo, su opción fue Hadoop y Lucene+Solr.

Una vez más, cada una de estas opciones puede ser "la mejor" en función del entorno en el que se desarrolle. Pero claro, si quiero seguir con este post tengo que optar por la tercera alternativa, obviamente :) .

Vamos por partes:

  1. Queremos almacenar un volumen de datos muy significativo. Para unos pocos GB todo esto no tiene demasiado sentido.
  2. Queremos que lo único necesario para aumentar la capacidad sea añadir nuevo hardware. Nada más. Ni cambios en la programación, ni cambios en la arquitectura.
  3. Queremos poder hacer consultas complejas sobre estos logs, en base a origen, destino, rangos de fechas, .... Por ejemplo, sería estupendo poder consultar todo el spam enviado a cuentas tipo info@ en toda la plataforma en un periodo de tiempo concreto.
  4. Aunque el tiempo real no es un requerimiento, es preferible poder hacer estas consultas y recibir los resultados al momento, en una misma sesión de navegador.

Para conseguir los puntos 1 y 2 Hadoop es una solución estupenda. Para 3 y 4 es necesario más trabajo. El acceso "casi inmediato" a los datos se conseguiría con alternativas como HBase, tan de moda ahora que Facebook ha empezado a usarlo. Además, siempre disponemos de Pig y Hive para simplificar las consultas. Ahora bien, de una u otra manera, con Hadoop es bastante probable que tengamos que programar bastante código.

La otra alternativa viene de la mano de Cassandra. Una vez más, los puntos 1 y 2 son inmediatos con esta tecnología. Al igual que con Hadoop, 3 y 4 no lo son; pero gracias a la aplicación llamada Solandra, que no deja de ser un Solr que guarda sus índices en Cassandra, podemos conseguir la capacidad de búsqueda de Lucene, el interfaz tipo REST que ofrece Solr, y la escalabilidad de Cassandra. Todo en uno.

El post se ha alargado un poco. Dejamos la parte práctica para el segundo (y último) mensaje de esta serie.

read more