Abstrayendo WebSockets SSL

Ahora que la W3C y el IETF están cerrando la normalización de toda la implementación de websockets, no cabe duda de que el futuro RFC6455 está siendo cada vez más utilizado en multitud de plataformas donde la experiencia de usuario es un plus más sobre su oferta de servicios.

El protocolo implementado ya en todos los navegadores permite unas nuevas líneas de comunicación cliente-servidor bidireccionales que desde el punto de vista de la seguridad se deben tener en cuenta. Además, desde la administración de sistemas (que es lo que toco), sí existe la responsabilidad de diseñar una buena arquitectura que ayude a la seguridad de todo el conjunto aunque al final uno queda a merced del buen código del propio desarrollo.

Mirando desde el lado del cliente ya existen en la red ciertos documentos (véase Shekyan Toukharian – Hacking Websocket Slides) de cómo cualquier ejecución no autorizada sobre protocolos embebidos en el navegador, como puede ser javascript, pueden lanzar comunicaciones que vayan por estos canales bidireccionales que proporciona los websockets en background. Todo ello sin el conocimiento del usuario.

Por otro lado, desde el punto de vista del servidor, la perspectiva puede ser otra.

Como la comunicación entre el cliente (navegador) y el servidor es necesariamente directa para mantener esos canales, ciertas instalaciones acaban exponiendo sus servidores sobre los que se soportan los websockets. Realmente esto no sería mayor problema si se realizase correctamente pero sí que lo puede ser cuando dicha exposición, para permitir la comunicación, conlleva que el backend quede alcanzado desde fuera para que los navegadores, y desde ese momento todo Internet, puedan acceder a él.

Los inconvenientes son dos muy claros:

  • No es posible la aplicación eficiente de reglas cuando son los navegadores de móviles, navegadores de portátiles y n-mil dispositivos de internet los que tienen que acceder al server vía websockets.
  • Multitud de servidores necesitan de extensiones no instaladas en los ISPs para su uso.

La conclusión de estos inconvenientes es que en ocasiones se opta por la exposición directa del backend como ya comentábamos (o la no implementación de websockets, con la renuncia evidente a sus características). Sin embargo, hay multitud de LB (loadbalancers) que SÍ soportan websockets: haproxy, nginx desde hace poquillo, varnish…. y también los hay que hasta la fecha usaban implementaciones más controvertidas: apache con mod_pywebsocket, que no obstante, no es de todos los gustos.

Realmente hay cientos de arquitecturas pero para hoy vamos a elegir como ejemplo Nginx con Node.js y Sockect.io.

Las implementaciones de Socket.io son sencillas. Es autocontenido y el trabajo con sockets del propio Socket.io permite que se pueda optar por un acceso directo contra el puerto del Node.js. No obstante, si el despliegue de Node.js lo hacemos desde el backend (por un tema de intercomunicación y escalabilidad) exponemos un servicio que tal vez no era necesario. La alternativa tal vez podría ser optar por “encapsular”, y por tanto abstraer el acceso al Node.js a través de un segundo dominio y gracias a un nginx por ejemplo.

Nginx nos permite también una exquisita creación de hilos en caso de picos y nos proporciona un buen nivel de abstracción para websockets desde su versión 1.3.x (que no recomiendo porque anda con algún importante bug de seguridad). Así que nos metemos en la 1.4.1 ya que las versiones anteriores no soportan estas comunicaciones.

El proceso es sencillo. Únicamente vamos a necesitar un nombre de dominio adicional a nuestra config (si ya hubiera una). Esto nos permite de forma muy sencilla desmarcarnos del resto de funciones que esté realizando nginx (web, vídeo, etc etc) y usar la funcionalidad de websockets únicamente para ese nombre de dominio (servers en nginx).

Tenemos que crear un upstream para el control de los backends y creamos sock.midominio.es

Al final la implementación sería algo como:

upstream websockets_nodejs {
        server backend:9090;
}

server {
        listen       80;
        server_name  sock.midominio.es;
        root   /usr/local/app/sock/app/webroot;
        keepalive_timeout  512;

        location / {
                proxy_pass  http://websockets_nodejs;
                proxy_redirect off;
                proxy_http_version 1.1;
                proxy_set_header        Host            $http_host;
                proxy_set_header        X-Real-IP       $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header        Upgrade $http_upgrade;
                proxy_set_header        Connection "upgrade";
        }
}

Varias anotaciones:

  • server backend:9090: backend es un nombre de /etc/hosts y 9090 es el puerto por defecto donde se levanta nodejs.
  • keepalive_timeout: mejor corto que largo por tema de recursos pero si el código no es capaz de controlar la conexión es posible indicar un número superior para evitar algunos comportamientos anómalos.
  • El resto de líneas son de manual. Únicamente faltaría indicar en nuestro desarrollo como acceder al server que gestiona los websockets indicando nuestro nuevo dominio y si, todo por el puerto 80.

Con esto acabamos de incorporar un nivel de abstracción más sobre nuestra arquitectura delegando al buen hacer de nginx el control y gestión de las conexiones contra el backend Node.js+Socket.io.

Evidentemente es posible configurarlo sobre SSL sin problemas:

upstream websockets_nodejs {
        server backend:9090;
}

server {
        listen       443;
        server_name  sckts.midominio.es;
        root   /usr/local/app/sock/app/webroot;
        index index.php;
        keepalive_timeout  512;

        ssl                  on;
        ssl_certificate      /etc/nginx/server.crt;
        ssl_certificate_key  /etc/nginx/server.key;

        ssl_session_timeout  5m;

        ssl_protocols  SSLv2 SSLv3 TLSv1;
        ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
        ssl_prefer_server_ciphers   on;

        location / {
                proxy_pass  http://websockets_nodejs;
                proxy_redirect off;
                proxy_http_version 1.1;
                proxy_set_header        Host            $http_host;
                proxy_set_header        X-Real-IP       $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header        Upgrade $http_upgrade;
                proxy_set_header        Connection "upgrade";
        }
}

Ahora en la configuración de vuestro desarrollo deberéis conectar sobre https.
En nuestro entorno de pruebas ha ido de maravilla aunque siempre habrá alguien que podrá apuntar más datos interesantes sobre estas arquitecturas. En ese caso, bienvenido sea.

Fundamentos sobre certificados digitales (III): Cadena de confianza

Siguiendo en la línea de los anteriores posts (Fundamentos sobre certificados digitales, primera y segunda parte), continuamos hablando de firma y certificación digital. En este caso, y a mi ver, siguiendo un orden lógico para la explicación, en la entrada de hoy nos centraremos en la cadena de confianza.

Como ya se comentó en entradas anteriores de este hilo, de cara a emplear o validar un certificado o firma digital, uno de los puntos más importantes es la confiabilidad del mismo, ya que, como se comentó, cualquiera puede generar una clave asimétrica e incluir los campos que desee en el certificado. De nuevo en base a este hecho surge la necesidad de la existencia de Autoridades de Certificación (CA), quienes se encargan de emitir certificados confiables y reconocidos. Pero, ¿como sabemos que el certificado que tenemos entre las manos ha sido emitido por una de estas entidades?

Aunque se comentará en próximas entradas el formato X.509 como estándar de generación de certificados digitales, es importante destacar que, como es natural, dicho formato contiene campos para introducir los datos del emisor (issuer). Es obvio que estos campos nos pueden parecer útiles para este fin; pero del mismo modo que el resto de campos del certificado pueden ser fijados al gusto de quien lo genere, por lo que en absoluto suponen una garantía de procedencia y autenticidad del certificado digital.

Para cubrir estas necesidades surge el modelo de cadena de confianza. Este modelo establece una relación entre certificados que permite asegurar, sin duda alguna, que dicho certificado ha sido emitido por una Autoridad de Certificación. Veamos en primer lugar como se implementa este modelo.

Como algunos habrán adelantado, la solución más obvia será firmar el certificado emitido con un certificado que “represente” a la CA. De este modo, si el certificado que firma es confiable, tenemos total certeza de que el certificado ha sido emitido por una CA, y por tanto quien lo emplea debería ser quien dice ser (siempre y cuando no se vulnere su clave privada, en la próxima entrada veremos de qué mecanismos se vale la CA para revocar y validar certificados, así como cómo dispone esta información al alcance de los usuarios finales de los mismos). Todo esto parece que suena bien, sin embargo, nos sigue dejando en el mismo punto del que partimos, ¿cómo sé que el certificado que firma el anterior es válido?

En el modelo de cadena de confianza jerárquico, las Autoridades de Certificación disponen de un certificado conocido como Certificado Raíz (Root CA), y como su nombre indica es el certificado que validará todos y cada uno de los certificados emitidos por la CA; sin embargo, este certificado no es el que firmará los certificados de suscriptor (o certificados finales), sino se empleará únicamente para firmar los denominados Certificados Subordinados (Sub-CA), y estos últimos firmarán los certificados de suscriptor (o finales). Se muestra un diagrama ejemplo del modelo jerárquico para ilustrar el funcionamiento de la cadena de confianza de certificados:

Es importante destacar que, en general, las Autoridades de Certificación emiten los certificados intermedios orientados a generar certificados de suscriptor en base a distintas tipologías, usos o unidades de negocio (por ejemplo certificados de persona física, persona jurídica, SSL, firma de código, etc.).

Sin embargo, el principal motivo de tomar esta decisión es proteger al máximo Certificado Raíz de la jerarquía. En base a los conceptos explicados en entradas anteriores, si un tercero consiguiera la clave privada de un Certificado Raíz, se comprometerían todos y cada uno de los certificados emitidos con la misma (es más sería capaz de emitir certificados en nombre de la CA). Visto de este modo, cobra sentido que los certificados finales no estén firmados con esta clave; además que en base a éste modelo jerárquico, un certificado de suscriptor firmado por el raíz no sería de suscriptor sino subordinado, con todo lo que conllevaría dar esa clave a un usuario. Este hecho propicia que se considere normalmente la clave privada del certificado raíz como la información de mayor valor y más crítica de la CA. Debido a ello, es habitual que la clave privada del certificado raíz se encuentre offline, en un dispositivo de seguridad cifrado y con medidas de alta seguridad (que también se comentarán en próximas entradas).

De cara a la validación del certificado firmado tanto por el certificado raíz como su subordinado, la CA mantiene online todas las claves públicas de su jerarquía; aunque habitualmente se suelen adjuntar al certificado de suscriptor (como se muestra en el ejemplo posterior). De modo que para validar un certificado de un suscriptor, se deberá comprobar la firma para toda la cadena de confianza de la CA emisora, quedando así clara la procedencia del mismo.

Por último, y siguiendo con la línea de ejemplos planteada en entradas anteriores, se muestra la información de la cadena de confianza del certificado SSL de www.bankia.es, que en este caso ha sido generado por VeriSign, Inc. (autoridad de certificación propiedad de Symantec).

Como se puede observar en la imagen, se describe la jerarquía de certificados de VeriSign que ha generado este certificado se suscriptor. Lo detallamos a continuación:

  • Certificado Raíz: VeriSign Class 3 Public Primary Certification Authority
  • Certificado Subordinado: VeriSign Class 3 Extended Validation SSL SGC CA
  • Certificado de Suscriptor: www.bankia.es

El proceso de validación lo suelen realizar de forma automática los navegadores web, de modo que aunque el certificado no estuviera auto firmado (self signed), si detectara una incoherencia en la cadena de certificación consideraría el certificado no confiable y avisaría al usuario como se detalló en la entrada Fundamentos sobre Certificados Digitales (II).

A modo de curiosidad, dejo unos cuantos enlaces que os ayudarán a ver un ejemplo práctico de jerarquía de certificados, concretamente la de Verisign (Symantec):

Dejo también una entrada referente al escándalo de TURKTRUST, en el que por error se firmaron dos certificados de suscriptor directamente con el certificado raíz, lo que tuvo consecuencias desastrosas: http://www.securitybydefault.com/2013/01/algunas-reflexiones-sobre-el-ultimo-ca.html

Gracias de nuevo por leernos y como siempre quedo a la espera de vuestros comentarios.

He leído y acepto los términos y condiciones de uso

Una de las mayores mentiras del siglo XXI. El que siempre haya aceptado los términos de uso tras una lectura detallada, siendo plenamente consciente de lo que aceptaba, que levante la mano.

Prácticamente a diario, instalamos aplicaciones en nuestros PCs y smartphones, nos registramos en redes sociales o servicios diversos. Todos estos proveedores de aplicaciones y servicios se cuidan mucho sus espaldas, y no se arriesgan a dejar resquicios legales.

Y nosotros, como usuarios, aceptamos sin saber lo que estamos aceptando. Principalmente, yo diría que por dos razones:

1. Como ya se comentó hace (mucho) tiempo en este mismo blog, o lo tomas o lo dejas. Si quieres hacer uso del servicio, no tienes más remedio que aceptar las condiciones que establezcan.
2. Vivimos estresados. Y no tenemos tiempo que perder leyendo un galimatías, frecuentemente en inglés, que nos va a aclarar poco o nada a qué nos estamos comprometiendo exactamente

Como todos, soy de esas personas que al llegar al paso de aceptar los términos y condiciones y ver ese scroll que parece ser infinito voy directamente a la famosa casilla y afirmo estar de acuerdo con algo que no he leído.

Pero ahora que estoy rodeada de gente que sabe de seguridad y se preocupa por la privacidad, estoy empezando a plantearme cosas a las que antes no les daba tanta importancia.

Así que como usuaria asidua de Google y sus servicios, me he propuesto leer y analizar las condiciones que acepté en su día y que se aplican en unos servicios que utilizo a diario.

Lo primero que me ha llamado la atención es que el lenguaje utilizado no es tan incomprensible y rebuscado como me esperaba. En la mayoría de los puntos, queda bastante claro a qué hacen referencia y qué cabe esperar al respecto. De otros servicios no puedo hablar, pero al menos en este caso, descubrir que se pueden leer y entender sin ser licenciado en Derecho invalida el punto 2 que he mencionado antes.

Algunos puntos que considero merece la pena remarcar:

Tu contenido en nuestros Servicios

Algunos de nuestros servicios te permiten enviar contenido. Si lo haces, seguirás siendo el titular de los derechos de propiedad intelectual que tengas sobre ese contenido. En pocas palabras, lo que te pertenece, tuyo es.

Al subir contenido o al enviarlo por otros medios a nuestros Servicios, concedes a Google (y a sus colaboradores) una licencia mundial para usar, alojar, almacenar, reproducir, modificar, crear obras derivadas (por ejemplo, las que resulten de la traducción, la adaptación u otros cambios que realicemos para que tu contenido se adapte mejor a nuestros Servicios), comunicar, publicar, ejecutar o mostrar públicamente y distribuir dicho contenido. Google usará los derechos que le confiere esta licencia únicamente con el fin de proporcionar, promocionar y mejorar los Servicios y de desarrollar servicios nuevos. Esta licencia seguirá vigente incluso cuando dejes de usar nuestros Servicios (por ejemplo, en el caso de una ficha de empresa que hayas añadido a Google Maps). Algunos Servicios te permiten acceder al contenido que hayas proporcionado y eliminarlo.

El principio suena muy bien, dejan muy claro que lo tuyo es tuyo. Pero luego resulta que estás autorizando a Google (y sus colaboradores, que no he conseguido determinar quiénes son) a usar, reproducir, crear obras derivadas etc. Y seguirán teniendo derecho a hacerlo incluso si tú dejas de usar sus servicios.

Cómo modificar y cancelar nuestros Servicios

Google cambia y mejora sus Servicios constantemente. Por ello, es posible que añadamos o eliminemos algunas funciones o características, o que suspendamos o cancelemos un Servicio por completo.
Puedes dejar de usar los Servicios en cualquier momento, aunque lamentaríamos que así fuera. De igual modo, Google puede dejar de proporcionarte los Servicios o añadir o crear nuevas limitaciones en cualquier momento.

Consideramos que eres el propietario de tus datos y que es importante preservar tu acceso a los mismos. Si interrumpimos un Servicio, en los casos en los que sea razonable, te informaremos con suficiente antelación y te permitiremos extraer la información del Servicio.

No deja de ser curioso que, en cualquier momento y sin justificación previa puedan modificar o cancelar los servicios que ofrecen. Hay quien dice que, siendo gratis no te puedes quejar ante posibles cambios o cierres de servicios (claro que no es gratis, ya que pagas con tus datos). Pero eso no ha evitado por ejemplo el revuelo provocado por el cierre de Google Reader. Al menos parece que han cumplido la parte de avisar con antelación y permitirte extraer la información.

Acerca de estas condiciones

Google puede modificar estas condiciones o las condiciones adicionales que se apliquen a un Servicio para, por ejemplo, reflejar cambios legislativos o en los Servicios. Te recomendamos que consultes las condiciones de forma periódica. Google publicará avisos relacionados con las modificaciones de estas condiciones en esta página. Asimismo, publicará avisos relacionados con las modificaciones que se hagan en las condiciones adicionales del Servicio correspondiente. Las modificaciones no se aplicarán con carácter retroactivo y entrarán en vigor en un plazo no inferior a 14 días a partir de la fecha de su publicación. No obstante, las modificaciones que afecten a nuevas funciones de un Servicio o los cambios que se hagan por cuestiones legales entrarán en vigor de forma inmediata. Si no aceptas las condiciones modificadas de un Servicio, deberás dejar de usar dicho Servicio.

Para acabar, el salvavidas definitivo: todos los usuarios hemos aceptado que los términos aceptados pueden ser modificados unilateralmente (muy importante el “por ejemplo” de la segunda línea: se mencionan dos posibles motivos de cambio, pero no todas las razones que pueden alegar para modificar las condiciones). Y aceptamos que debemos ser nosotros quienes revisemos cada cierto tiempo las condiciones para detectar posibles cambios. Me gustaría conocer una estadística del número de usuarios que sigue esta recomendación… Pero lo hagamos o no, hemos aceptado estas condiciones y ellos tienen la sartén por el mango.

He de reconocer que la lectura no ha sido tan terrible como esperaba, y que no me quedo con la sensación de haber vendido mi alma a Google a cambio del uso de sus servicios. Pero varios de los puntos de las condiciones de servicio de Google remiten a la política de privacidad, a la que también he echado un vistazo y he encontrado bastantes cosas reseñables, pero ese análisis lo dejaremos para otra ocasión, por no extendernos demasiado.

Casualmente, mientras estaba terminando de redactar esta entrada, muy satisfecha por haberme leído los términos y la política de privacidad, me encuentro con esta noticia sobre “algo” llamado PRISM que me genera nuevas inquietudes. ¿Son conscientes o no las empresas del acceso que los gobiernos tienen a la información que manejan? Si los gobiernos pueden acceder a ella sin consentimiento de las empresas ¿para qué sirve tanta política de privacidad, tantos términos de uso y tantas condiciones a aceptar?

Y lo más importante: ¿qué podemos hacer nosotros, como usuarios de a pie, para proteger nuestra información y nuestros datos?

En el ojo de la tormenta

Viviendo en la era digital no hay duda de que la información es un recurso muy valioso, y como mencionaba mi compañera María Ángeles en su entrada, el que tiene la información tiene el poder, pero ser capaz de sintetizarla y inferir nuevas evidencias o predicciones a partir de esta en un tiempo razonable es también muy importante.

Cada día se almacenan enormes cantidades de información, por lo que sistemas gestores de bases de datos relacionales están dando paso al fenómeno big data, que cada vez despierta más interés y expectativas en las organizaciones. De hecho, muchas empresas están abriendo nuevas líneas de negocio, creando plataformas SaaS que se dedican exclusivamente a analizar cantidades titánicas de información e identificar aquella que podría tener un valor importante para las decisiones estratégicas de muchas corporaciones.

Para aquellos que todavía no están familiarizados con el término, se trata de la nueva generación de tecnologías para el acceso, procesamiento, análisis y visualización de enormes volúmenes de datos. Entre estas surge toda una tipología de bases de datos NoSQL y plataformas de procesamiento big data, sistemas robustos que ofrecen elevadas capacidades de escalabilidad, baja latencia, y un esquema libre de modelo para el almacenamiento flexible de datos. Así, tenemos familias para el almacenamiento de datos en forma de clave-valor (key-value), orientados a colecciones, columnas, persistencia de estructuras de datos en forma de grafos, etc. Uno de ellos es Storm (el lector precavido ya puede estar intuyendo de donde proviene la inspiración para el título de esta entrada).

Storm es el sistema distribuido para el procesamiento de flujo de datos, actualmente propiedad de Twitter, aunque originalmente fue desarrollado por la compañía Blacktype. Fiable y tolerante a fallos, garantiza que cada mensaje inyectado en el flujo se procesará de forma completa. A diferencia de otras plataformas de procesamiento de datos como Hadoop o Cascading, Storm realiza el procesamiento del flujo de datos en tiempo real. El componente encargado de llevar a cabo ese procesamiento se llama topología. A su vez, ésta está formada por varias abstracciones que explicaremos más adelante. Cuando la carga computacional se incrementa de forma considerable se hace trivial aumentar el paralelismo de la topología para que se ejecute en varios procesos distribuidos en multitud de máquinas físicas. Si se produce un fallo durante el procesamiento, Storm se encargará de reasignar el trabajo a las tareas, además de garantizar que no habrá pérdida de ningún mensaje gracias a la naturaleza transaccional de las topologías. Otra de las ventajas de Storm, es que permite la ejecución de consultas distribuidas (DRPC) paralelizables al vuelo, ideal para los escenarios donde es necesario lanzar queries intensas u otras operaciones exigentes.

Es usado por multitud de organizaciones tales como Groupon, Alibaba, The Weather Channel, y como no, Twitter. Podemos ver la lista completa de empresas y proyectos que usan Storm. No tenemos que olvidarnos de mencionar que se trata de una plataforma open source, y aunque está desarrollada en una combinación de Clojure y Java, Storm es completamente agnóstico de lenguaje, por lo que nada nos limita a crear las topologías en otros lenguajes de programación.

El cluster de Storm está compuesto por dos tipos de nodos:

  • Nodo maestro, es el nodo principal donde se ejecuta el demonio llamado Nimbus, encargado de asignar tareas a los nodos worker, monitorizar posibles fallos, distribuir el código a lo largo del cluster, etc.
  • Nodos worker alojan el demonio llamado Supervisor que ejecuta la porción de la topología entre varios procesos que incluso puedan estar ejecutándose en múltiples máquinas.

La coordinación y el estado de ejecución entre los nodos se mantiene en ZooKeeper, o bien se persiste en disco duro cuando se ejecuta en modo local, y es precisamente esto lo que hace que Storm sea tan robusto y estable.

Las topologías se ejecutan continuamente hasta que se solicite explícitamente su terminación. Éstas están formadas por dos tipos de componentes que se agrupan en un grafo. Unos llamados spouts representan la fuente de entrada de flujo de datos en el sistema y generan listas de tuplas. Los spouts pueden inyectar datos en la topología bien consumiendo mensajes de las colas de los sistemas de mensajería, consultando la API de terceros vía REST, leyendo registros desde la base de datos, o cualquier otra fuente que se nos ocurra. Los bolts consumen las tuplas emitidas por spouts u otros bolts, para aplicar cualquier tipo de transformación o lógica específica al flujo de datos, ya sea filtrado, agrupaciones, funciones, agregaciones, etc. En el siguiente diagrama podemos ver la estructura simplificada del cluster de Storm.

Para dar un enfoque pragmático e ilustrar las capacidades de Storm, vamos a desarrollar una sencilla aplicación para procesar datos obtenidos desde las redes sociales. Usaremos el API de Facebook, para recuperar los estados que han ido publicando nuestros amigos y los mandaremos a una cola RabbitMQ. A continuación desarrollaremos los componentes de la topología – uno se encargará de consumir los mensajes de la cola y generar tuplas con el estado y el publicador (spout), y el resto aplicarán las transformaciones correspondientes para separar cada estado en palabras, contar las ocurrencias de las mismas y mostrar el top 20 de palabras más utilizadas en los estados de nuestros amigos en tiempo real. En la imagen podemos ver el grafo de spouts y bolts que forman nuestra topología.

El código completo de la aplicación se encuentra en el repositorio github, por lo que no vamos a entrar en detalles de implementación. Tan solo mencionaremos que los spouts deben implementar la interfaz IRichSpout y los bolts la interfaz IRichBolt. Los métodos importantes de los spouts, son nextTuple donde se obtiene el flujo de datos y se generan las tuplas, y el par ack / fail para confirmar o bien señalizar el fallo en el procesamiento de la tupla. Esto es importante, ya que la emisión de una tupla por un spout puede desencadenar la generación de muchas tuplas en otros componentes, por lo tanto se considera que un mensaje se ha completado satisfactoriamente cuando se procesa correctamente el árbol de tuplas generadas.

A la hora de ensamblar la topología podemos especificar las preferencias de paralelismo, tanto el número de tareas como el número de procesos workers. El último argumento del constructor de los componentes especifica el paralelismo. TopologyBuilder nos permite construir la topología que más tarde se desplegará en el cluster:

TopologyBuilder topologyBuilder = new TopologyBuilder();
topologyBuilder.setSpout("status-emitter", new AmqpStatusEmitterSpout() );
topologyBuilder.setBolt("status-splitter", new StatusSplittingBolt())
        .shuffleGrouping("status-emitter");
topologyBuilder.setBolt("status-segmentator", new StatusSegmentatorBolt(), 
        5).fieldsGrouping("status-splitter", new Fields("word"));

StatusSegmentatorBolt se ejecutará de forma paralela entre 5 hilos de ejecución.

A raíz de todo lo que hemos dicho, podemos concluir que Storm es una plataforma prometedora y gracias a su modelo de programación sencillo, la curva de aprendizaje del mismo es corta y no tendremos que preocuparnos por detalles de sincronización, paralelismo o mantenimiento del estado y coherencia en el procesamiento de los mensajes.

Estrategia de Seguridad Nacional 2013. Ciberseguridad.

Esta semana ha sido noticia la aprobación de la Estrategia de Seguridad Nacional 2013 la cual constituye la articulación fundamental de la Seguridad Nacional como Política de Estado, esto es, contiene directrices con el fin de reasignar todos los recursos disponibles del Estado de manera eficiente para la preservación de la Seguridad Nacional.

Si ya en la versión del 2011 el ciberespacio cobraba importancia como un nuevo ámbito en el que nuestro país se enfrenta ante amenazas y riesgos:

[…] cada vez una mayor parte de nuestra actividad se desarrolla en el ciberespacio, donde las amenazas pueden ocasionar graves daños e incluso podrían paralizar la actividad de un país. Los ciberataques más comunes tienen fines comerciales, pero también estamos expuestos a agresiones por parte de grupos criminales, terroristas u otros, incluso de Estados. Las nuevas tecnologías de información y comunicación ofrecen nuevos y más sofisticados medios para el espionaje y la contrainteligencia. Mejorar la seguridad en el ciberespacio pasa por fortalecer la legislación […]

[Read more…]

BotTrack: Tracking Botnets using NetFlow and PageRank

La semana pasada una compañera me hizo llegar una serie de papers de la Universidad de Luxemburgo. Entre ellos me llamó la atención uno cuyo título era el de esta misma entrada: BotTrack: Tracking Botnets using NetFlow and PageRank. Para el que no lo conozca, Netflow es un protocolo desarrollado por Cisco Systems que permite a routers y switches, principalmente, enviar los flujos de comunicación de red hacia otro dispositivo que se le conocerá como colector y donde se podrá hacer un análisis de la información.

La investigación, realizada por Jérôme François, Shaonan Wang, Radu State, y Thomas Engel, en su documento intenta mostrarnos cómo detectar botnets P2P utilizando NetFlow y una extensión del algoritmo PageRank utilizado por Google.

El documento nos cuenta las arquitecturas habituales de botnets y la evolución que están sufriendo hacia arquitecturas distribuidas, para aumentar la escalabilidad principalmente. Para detectar estas nuevas arquitecturas, proponen lo siguiente:

Tal y como explican, en primer lugar se dispone de un colector netflow (por ejemplo la herramienta ntop con el plugin de netflow) que recoge los flujos de routers, honeypots, etc. Con estos flujos se hace un grafo de relación entre hosts. Este grafo es analizado por un módulo que implementa una versión del algoritmo PageRank de Google que según el autor es un algoritmo apropiado para analizar los enlaces de comunicación entre los hosts en redes grandes. Como resultado de procesar el grafo con estos algoritmos se obtienen dos valores, el hub rank (Partiendo de los nodos origen tráfico hacia los nodos destino) y el authority rank (Partiendo de los nodos destino tráfico hacia los orígenes), que tienen en cuenta la dirección del tráfico para calcularlos. La puntuación de cada nodo será mayor dependiendo de la cantidad de conexiones que tenga con otros nodos y de la calidad de esas conexiones. Por ejemplo, el nodo que es un honeypot distribuirá mayor peso a los nodos con los que está relacionado, y se considerará por tanto una conexión importante (mayor peso), ya que la probabilidad de que un nodo relacionado con él forme parte de una botnet es muy alta.

Partiendo del hub rank y authority rank de cada nodo el módulo de cluster agrupará con el objetivo de identificar nodos con un rol similar dentro de la red. El ejemplo que ponen en el documento es el cálculo de hub rank y authority rank para el protocolo kademlia, para hosts normales y para bots, de manera que se vea la distribución de los valores y sea posible comparar. En este caso se ve cómo ha identificado dos clusters de bots principales:

Es posible por tanto obtener unos rangos de valores que permitan identificar una botnet utilizando un protocolo p2p según lo que nos cuentan en este estudio. Os recomiendo su lectura dado que puede aportaros ideas para la explotación del tráfico NetFlow para la detección de botnets p2p.

Presentamos tiké

Security Art Work comenzó hace poco más de seis años por iniciativa del que escribe estas palabras, lo que hace que le tenga un especial cariño. Como sabrán, una de las políticas no escritas de Security Art Work siempre ha sido la ausencia de publicidad propia o ajena; Security Art Work fue creado para compartir conocimiento, no como una plataforma para hacer publicidad.

Sin embargo, una vez al año —como mucho— utilizamos el blog como escaparate de algún hecho destacado relacionado con S2 Grupo, tras lo cual volvemos a la programación habitual. Hoy es uno de esos días, con una especial particularidad que ahora mismo entenderán.

Hace aproximadamente un año, comencé a trabajar en una herramienta que mejorase la implantación y mantenimiento de un SGSI y diese respuesta a diversos problemas a los que en el pasado me he tenido que enfrentar. Esta idea inicial creció y con esfuerzo ha acabado convirtiéndose en una realidad, lo que nos lleva de nuevo hasta el día de hoy. Me siento especialmente orgulloso de presentar tiké® en público: la herramienta de S2 Grupo para la gestión de referentes normativos y legales. No sólo por mi papel en su nacimiento o como responsable funcional, sino sobre todo por todo el trabajo que nos ha costado llegar hasta aquí y que no me cabe duda de que ha valido la pena.

No voy a entrar a detallar las funcionalidades de tiké®, que pueden consultar en la página web del producto. Pero sí que me gustaría comentar los pilares sobre los que descansa la aplicación, que soporta actualmente LOPD y SGSI, pero cuyo ámbito ya estamos ampliando al Esquema Nacional de Seguridad, la norma ISO 9001, la Ley de Protección de Infraestructuras Críticas y la norma ISO 22301 (continuidad de negocio):

  • Gestión integral. Algunos de los principales problemas que encontramos en muchas organizaciones que desean adaptarse a la LOPD o implantar un SGSI son la ausencia de herramientas para abordar determinados aspectos requeridos por el referente en cuestión, la falta de mecanismos de control sobre las iniciativas o la ausencia de trazabilidad al utilizar documentos ofimáticos. Para hacer frente a esto tiké® presenta un modelo integral en el que a través de una única herramienta es posible gestionar y llevar un control de todos los elementos necesarios: proyectos, tareas, catálogo de puestos, indicadores, sistema documental, suministradores, etc., con total trazabilidad de las modificaciones realizadas por cualquier usuario.
  • [Read more…]

Seguridad lógica: Pues yo prefiero el libro

Ya sé que es un poco tarde, pero hoy he visto El Hobbit. Y sí, la película me ha resultado entretenida, he visto la recreación de un libro divertido en la pequeña pantalla que alguien se ha encargado de transformar en un guión de tres horas para la primera parte de una trilogía. Perdónenme los fanáticos de Tolkien, pero yo jamás pude imaginar que un libro como El Hobbit diese para una trilogía de tres horas cada película.

Y esa misma sensación es la que muchas veces me he encontrado en mi experiencia profesional cuando he tenido que abordar proyectos de seguridad que únicamente tienen en cuenta la fase de la auditoría lógica.

[Read more…]

¿Es demasiado complicada la seguridad “informática”? (Sí)

Algunos años trabajando en una empresa de seguridad física me han provocado una cierta deformación profesional, pero ya antes me sorprendía la inocencia de las personas y empresas. Por ejemplo:

  • Los que se anotan el PIN de la tarjeta en la propia tarjeta.
  • Los que se anotan todas las contraseñas (o usan la misma para todo) en el mismo sitio.
  • Los que cuando entran a casa solo cierran de golpe y no le dan, aunque sea una vuelta a la llave.
  • Los que dicen en el bar, a voces, que se van de vacaciones quince días.
  • Los compañeros que en las empresas contestan al teléfono (a alguien que no conocen), ¿fulanito?, no estará hasta el mes que viene, se ha ido al Caribe.
  • Los que dejan la llave de seguridad puesta en la grúa.

Todo es opinable, pero creo que estas actitudes son debidas a la falta de cultura de la seguridad. ¿Cuáles son las posibles razones?

[Read more…]

Programación segura

A la hora de hablar de seguridad informática a todos nos viene a la cabeza codificar información, supervisar la red, usar cortafuegos, etc… Sin embargo, solemos olvidar que nuestro sistema puede verse afectado por atacantes que se aprovechan de nuestro propio descuido. Me estoy refiriendo principalmente al código que creamos en las aplicaciones que luego vamos a tener visibles, como es el caso de las aplicaciones web.

Programar sin tener en cuenta unos mínimos estándares de calidad en cuanto a seguridad se refiere, puede ser tan desastroso como descargarse archivos desconocidos sin ser revisados por un antivirus. No hay más que pensar en el siguiente caso:
Supongamos que programamos una aplicación web de un banco que permite obtener los datos de una cuenta corriente a partir del identificador de la cuenta corriente (http://www.bancoChachi.com/aplic/vistaCuenta?id=XXXX). Si no tenemos malicia, lo normal sería programar la recogida de los datos de entrada de la siguiente manera:

String query = "SELECT * FROM cuentas WHERE idCliente='" + request.getParameter("id") +"'";.

Escrito así no parece que haya ningún problema. La consulta está bien formada y no hay nada incorrecto. Pero ¿qué pasa si se accede a la aplicación de esta manera?:

http://www.bancoChachi.com/aplic/vistaCuenta?id=’ or ‘1’=’1

Por si el lector aún no lo ha detectado, al realizar la sustitución nos encontramos con que la condición se cumple siempre, ya que ’1=1’ es cierto. Le estaríamos permitiendo a un atacante la posibilidad de acceder a todas las cuentas corrientes del banco.

Como este caso podemos encontrar cientos. Puede ser abrumador pensar en todos nuestros posibles errores o en la imaginación de un usuario malintencionado (los maleantes siempre van con un paso por delante de la policía). Pero por fortuna existen organizaciones que se dedican a detectar este tipo de problemas y ponerlos al alcance de todos. Una de estas organizaciones es The Open Web Application Security Project (OWASP), organización sin ánimo de lucro formada por voluntarios que se dedican a investigar posibles problemas de seguridad en la programación. Como actividad más relevante, la OWASP publica todos los años un top10 con los problemas más detectados durante los últimos meses, y por fortuna tiene voluntarios y páginas en muchos países (incluida España). Además la OWASP tiene publicadas una serie de metodologías a seguir para evaluar y mejorar la seguridad en nuestras infraestructuras y aplicaciones web.

Para no extendernos mucho más en este post, os dejamos con el último top10 publicado:

1. Inyección de código.
2. Gestión de las sesiones.
3. XSS (Cross site scripting).
4. Referencias a objetos inseguras.
5. Desactualización de componentes o partes de nuestro sistema.
6. Exposición de datos sensibles.
7. Pérdida de control de acceso.
8. CSRF (Cross site request forgery).
9. Uso de componentes con vulnerabilidades conocidas.
10. Redirecciones inválidas.

Se puede ver la lista completa en la página web de OWASP.