(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.


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 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

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