Archivo

Archivo del autor

Cloudbleed

Domingo, 26 febrero 2017, 17:00 Deja un comentario

pexels-photo-306198

Cloudbleed es el último incidente de seguridad en la red que presumiblemente puede tener un gran impacto por la información sensible desvelada, tanto en cantidad como en sensibilidad. El fallo fue descubierto el 17 de febrero por Tavis Ormandy, ingeniero de Google que lo reportó a Cloudflare. Cloudflare lo resolvió de manera muy rápida (en menos de una hora cortando los servicios afectados y corrigiéndolos en 7 horas), pero ya ha admitido que el error es posible que existiese desde septiembre de 2016, y lo que es peor, parece ser que ha sido explotado de manera masiva del 13 al 18 de febrero. El problema se hace mayor si se tiene en cuenta que los robots de crawling de los buscadores han estado recuperando y cacheando esta información durante todo este tiempo.

Cloudflare es una compañía de seguridad y servicios para internet, que se ha especializado en lo que se denominan CDN (Content Delivery Networks) enfocados en la seguridad y protección de dominios o servicios de terceros contra ataques, como por ejemplo DoS. Entre las compañías que parece se encuentran afectadas están Uber, OKCupid o Fitbit, entre otras; y sin que se tenga todavía certeza del alcance de los servicios afectados.

El origen del problema se encuentra en el código de los servidores que hacen de proxy inverso con los que Cloudflare realiza toda la actividad de entrega y distribución de los contenidos. Cloudflare no solo se limita a distribuir el contenido, hace transformaciones de manera online como valor añadido o mejoras de seguridad, eficiencia o customización. Existe un componente que adapta o modifica las páginas HTML antes de servirlo. En este código no se comprobaba correctamente si se sobrepasaban los límites de un buffer de memoria al escribir (buffer overrun o buffer overflow), lo que provocaba que la información sensible fuese a las regiones de memoria adyacentes, pero de otros servicios.

Esta información puede contener contraseñas (en claro), cookies e identificadores de sesión, conversaciones de servicios de mensajería… aún cuando los servicios fuesen sobre conexiones seguras, para que nos hagamos una idea del impacto del fallo. Cloudflare ya se ha adelantado a confirmar que las claves SSL privadas (las que autentican a los servicios en la red) no se han visto comprometidas al servirse con un servicio de Nginx no afectado.

Las recomendaciones de los expertos es aprovechar la situación para cambiar y utilizar mejores claves en todos nuestros servicios, en especial aquellos que utilizan los servicios de Cloudflare, y hacer uso siempre que se ofrezca de la autenticación en dos pasos.

Puedes encontrar más información aquí o en el artículo que la propia Cloudflare publicó explicando con todo detalle los aspectos técnicos (un ejercicio de honestidad y detalle de agradecer, asumiendo toda la responsabilidad del error, exculpando a terceros y agradeciendo la ayuda de otros, como el equipo de Project Zero de Google que descubrió y comunicó la vulnerabilidad).

Anuncios
Categorías:Seguridad, Web

Consejos y buenas prácticas en la gestión de errores: recopilación y comunicación de información

Martes, 31 enero 2017, 10:53 Deja un comentario

Error

Los errores ocurren y son parte de la fase de servicio del ciclo de vida de toda aplicación. No hay ni que verlos de manera trágica, pues son las singularidades propias de la explotación de la aplicación, ni con excesiva indulgencia, porque son una medida clave de la calidad del servicio que estamos dando.

Pero lo que sí es relevante es que, desde el primer momento de la incidencia, tengamos información suficiente para disparar todos lo mecanismos de análisis y resolución del error. Es necesario que tengamos una recolección de datos automática y eficaz; y esa eficacia sobre todo va a depender, dado lo variado e impredecible de los errores, de lo completos que sean esos datos.

Más importante que la información recopilada para el análisis del problema, es la información y mensajes transmitidos al usuario de la aplicación que sufre el error. Factores como la usabilidad, funcionalidad, gestión del riesgo reputacional o la propia operativa de gestión de incidencias dependen fundamentalmente de este aspecto.

El proceso completo  de identificación, clasificación, investigación, resolución y cierre (pasos de la gestión de incidencias según ITIL) es especialmente elaborado y largo como para poder cubrirlo en una sola entrada. Esta entrada pretende solo abordar la primera etapa o paso en la gestión de las incidencias (Identification and Logging según ITIL), y en parte sólo, entrando más en aspectos prácticos que en los formalismos del proceso. El objetivo es cubrir cómo se identifica el incidente, cómo se informa de él y cómo se recopila información que sea útil para su resolución.

La dualidad de actores: usuario y operador

Cuando se produce el incidente hay dos actores interesados o relacionados: por un lado el usuario que no puede resolver de manera normal la operativa, y por otro, el equipo de soporte o de resolución de incidencias que tiene que darle una solución.

Ambos actores necesitan información muy distinta. Por un lado, el usuario no necesita información técnica de qué lo que ha pasado; de hecho, por motivos de seguridad se debería evitar que se revelase o fuese deducible. Por el otro, el soporte debe tener información detallada relativa a la incidencia, pero con un acceso muy limitado y controlado a la propia transacción, si esta tuviese información sensible o confidencial.

Afortunadamente, los canales por lo que se envía la información suelen ser distintos y solo tenemos que tener cuidado en recopilar toda la información necesaria a ambos y mostrar a cada uno la que le corresponde.

No conozco referencias relativas a este asunto, por lo que me he permitido llamar a una la visión del usuario, y a la otra la visión del técnico.

La visión del usuario

Cuando ocurre un error en la aplicación no hay que perder de vista lo más importante: que el usuario estaba intentando hacer algo que podría ser valioso o importante para él. Por eso la visión del usuario (sobre todo cuando estemos hablando de una actividad crítica, relevante o de valor para el usuario o cuando el nivel de calidad de servicio así lo exija) tiene que centrarse en trasmitir muy claramente:

  • ¿Qué ha pasado con la operación que estaba haciendo? ¿En qué situación se ha quedado? ¿Qué consecuencias puede tener?
  • ¿Qué puedo hacer ahora? ¿Cuáles son los pasos a seguir ahora que estamos en una situación anómala (o no) desde el punto de vista de la experiencia de usuario?

Por otro lado, las formas y el contenido en el que se comunica la información del error y de la situación al usuario es especialmente relevante para la usabilidad de la aplicación. Al ser, el error, una situación excepcional, a veces descuidamos esta usabilidad; pero es justamente esa excepcionalidad, la que nos obliga a tener especial cuidado en los mensajes y cómo se los transmitimos a los usuarios, así como el guiado para que puedan encauzar la operativa. Una buena opción es considerar los errores, al igual que las excepciones en el código, como vías de escape del flujo normal de navegación de la aplicación y considerarlas en su diseño. De esta manera ayudaremos a que en caso de error la aplicación esté en un estado y posición estables y conocidos (la pantalla de error “tal” dentro del proceso funcional “tal”) y que sea más usable (el usuario puede utilizar los mismos criterios y flujos de navegación que en el resto de la aplicación).

Información relativa a la operación del usuario

Ya sea escribir un mail, hacer una transferencia o confirmar el pago del carrito de la compra; el usuario está haciendo una operación o transacción importante para él y lo primero de lo que tiene que informarse al usuario es de qué ha pasado con lo que estaba haciendo. Por eso en la información del error que se muestra al usuario se deberían tener en consideración los siguientes puntos:

  • Si la transacción se ha finalizado correctamente: ¿se llegó a enviar el mail? ¿se efectúo la transferencia? ¿se ha cobrado en la tarjeta la compra?; o si por el contrario se canceló la operación: el mail no se envió y la transferencia y el pago no se hicieron efectivos
  • En cualquier caso, si existe operativa de soporte o ticketing, debe definirse un identificador único que permita al usuario poder identificar su caso. Aunque esa identificación pueda y deba llevarse de manera interna por el procedimiento de soporte, en mi opinión, debe ser comunicada al usuario por motivos de transparencia
  • Si la operación no es recuperable, es muy importante indicar al usuario qué va a pasar con la información que ha introducido. Por ejemplo: no he podido finalizar mi compra pero he introducido información sensible como es mi dirección o mi tarjeta. En este caso es conveniente:
    • Informar al usuario de qué información va a almacenarse y de cuál se va a eliminar
    • Indicar qué criterios se utilizarán para gestionarla. Como puede ser el almacenar dicha información por 30 días por si es necesaria para el equipo de soporte, por ejemplo
    • Si estamos obligados por imperativo legal o de cualquier otro tipo a mantenerla, no está de más mencionar estas exigencias u obligaciones
    • Informar al usuario de cómo puede verificar y eliminar esos datos. Desde su perfil o poniéndose en contacto con nosotros, por ejemplo

Pasos a tomar y opciones de resolución

Ahora que el usuario tiene ya una idea clara de qué ha pasado con su operación, es necesario indicarle cómo puede completar dicha operación

  • Si no quedó claro o no se pudo verificar el estado en que quedó la operación, debemos informar al usuario de cómo puede verificar la operación o dónde o con quién puede ponerse en contacto, como puede ser el equipo de soporte
  • Si tenemos cierta certeza de que el fallo es transitorio, podemos invitar a reintentar la operación al usuario pasado un tiempo o cuando podamos contrastar que el problema ha remitido
  • Si es posible continuar la operación o recuperarla en un punto en concreto, debemos indicar al usuario cómo y cuándo (más tarde por mail, por ejemplo) hacerlo; facilitando lo máximo posible este reintento y evitando todo lo posible la repetición de pasos ya realizados. Este punto es importante por varios motivos estratégicos:
    • Porque mejoramos el servicio y funcionalidad ofrecida al usuario y con ello la percepción que tiene de nuestro producto y reducimos el daño reputacional del error
    • Porque evitamos el tedioso proceso de repetir toda la transacción mejorando la experiencia de usuario
    • Porque reducimos el impacto del fallo o caída de servicio habilitando el que de los servicios perdidos algunos se puedan recuperar
    • Porque evitamos que parte de los usuarios afectados migren a la competencia buscando el mismo servicio
  • En la medida de lo posible debe ser parte del flujo normal de navegación y seguir los mismos criterios de navegación, forma y contenido de la información que en el resto de la aplicación. Esto transmite la sensación de ser un situación controlada al usuario, con lo que se limita la pérdida reputacional y se atenúa la sensación de gravedad; además de facilitar el guiado para la resolución del problema.

La visión del técnico

Los mecanismos de log pueden ser de gran ayuda, y son el referente normal en estos casos; pero para que puedan ser manejables desde el punto de vista operativo, suelen ser muy poco detallados. Lo singular e infrecuente del error nos permite que la recolección de información de incidencias pueda ser mucho más exhaustiva, elaborada y detallada. Esta información de mucho más volumen, pero de menor frecuencia.

Es muy importante recordar que esta información es altamente sensible y que su divulgación podría desvelar vulnerabilidades y patrones de ataque. De hecho, una parte fundamental que precede a los ataques informáticos, es el análisis de estas vulnerabilidades. El forzar situaciones de error puede permitir, si no se controla con cuidado, que se pueda obtener información muy sensible y relevante, vulnerabilidad, para luego poder ser explotada.

El siguiente es un checklist de información que puede ser útil recopilar para la visión del técnico:

  • Entorno
    • Hora y fecha
    • Posición geográfica, en especial en entornos móviles o distribuidos
    • Conectividad, también cobra especial importancia en entornos móviles
    • Host o instancia de máquina, para entornos distribuidos
    • Servicio o contenedor de la aplicación
    • Hebra o proceso del sistema operativo
    • Paths y parámetros de configuración del servicio
    • Cliente
      • Navegador, a través de las cabeceras HTTP o recopilando esa información desde la ejecución de código en el mismo navegador
      • Dispositivo, sea un móvil, equipo informático clásico, smartwatch, sistema empotrado…
      • Periféricos de los que hagamos uso
  • Usuario
    • Parametrizacion o personalización del usuario
    • Idioma, zona horaria y configuración regional
    • Credenciales, roles y autorizaciones
  • Transacción
    • Tipo de operación
    • Parámetros de la operación
    • Estado actual de la transacción
  • Aplicación
    • Componente software en el que se produjo el error o salida del flujo normal de ejecución
    • Stack trace de ejecución con los parámetros en el flujo de llamada
    • Variables de estado, de sesión, de ejecución, volcados de memoria, registros del micro…

Hay que tener especial cuidado cuando la información recabada sea relativa a sistemas que no son de nuestra propiedad y que lo puedan ser del usuario, como por ejemplo: la información del propio equipo del usuario, de su móvil o la obtenida relativa al navegador. En este caso, es ético y recomendable informar al usuario de qué información se obtiene de una manera explícita y concreta (aunque sin ser apabullante con detalles). Mejor si le permitimos, incluso, decidir si quiere compartirla con nosotros o no.

Referencias

La foto de cabecera ha sido tomada de https://www.flickr.com/photos/sissou/8432968631 y se está usando bajo licencia CC.

Licencia Creative Commons
Esta entrada de Juan Francisco Adame Lorite está publicada bajo una licencia Creative Commons Atribución-CompartirIgual 3.0 Unported.
Categorías:Arquitectura, Desarrollo, UI Etiquetas:

Apache Kafka

Miércoles, 15 julio 2015, 20:31 Deja un comentario

kafka_logo

Apache Kafka es un sistema de procesado de mensajes. Los mensajes se publican por los productores (producers) en colas denominadas topics  y se consumen de la cola por los consumidores (consumers) suscritos a dicha cola. Es una solución al problema de los productores-consumidores concurrentes. En este problema existen uno o más actores (productores) que generan los mensajes que son procesados por uno o más actores (consumidores) de manera concurrente.

El sistema de encolado y procesado de mensajes es distribuido y particionado en diferentes instancias denominadas brokers que conforman el clúster de Kafka. Dentro del clúster, en cada broker, cada topic o cola está dividida en particiones en las que los mensajes se almacenan de manera secuencial. Las particiones de un topic permiten:

  • Distribuir la carga de trabajo entre diferentes brokers y consumidores
  • Tener tolerancia a errores de los brokers, al poder tener replicadas la misma partición en brokers distintos (aunque solo una es la activa, pueden tomar el sitio de la activa si ésta cae)

Apache Kafka Diagram

El productor es quien encola los mensajes en cada partición, que mantiene estos mensajes de manera secuencial y ordenada. Es el propio productor quien decide en qué partición específica del topic se almacena el mensaje. De esta manera el balanceado de los mensajes en las diferentes particiones queda en manos del productor, no del clúster, que puede basarse en criterios de balanceado de carga o de lógica de negocio.

El modo en que se distribuyen los mensajes a los consumidores es también bastante flexible. Los consumidores se agrupan en grupos de consumidores. El clúster distribuye los mensajes de cada partición a un único consumidor del grupo, pero si hubiese más de un grupo de consumidores lo haría para cada grupo. De esta manera nos encontramos en un cola clásica con la carga balanceada entre varios consumidores si solo hay un grupo, y en un modelo de suscripción si tuviésemos más de un grupo.

Apache Kafka Distribution

El único modo de garantizar que los mensajes se consumen en el orden en que se crean es teniendo una única partición por topic y un solo consumidor por grupo. El único modo de garantizar que los mensajes se consumen una sola vez es teniendo un único grupo de consumidores.

El consumidor de cada partición es el que decide el orden en que se procesan los mensajes y los mensajes que se procesan. El consumidor tiene libertad para moverse en la partición accediendo a los mensajes de manera indexada (offset desde comienzo) y en sentido y con el criterio que quiera, y es quién lleva constancia de si han sido consumidos o no.  Esto permite que la política o lógica de procesado de mensajes sea mucho más flexible que la cola tradicional, permitiendo el reprocesado de mensajes, el procesado en cualquier orden o el consumo de mensajes en la misma partición por diferentes consumidores (si están en distintos grupos).

Los mensajes se mantienen en la partición, con independencia de si han sido consumidos o no, durante el tiempo indicado por la política de retención de mensajes. No hay borrado de los mensajes. Esto se debe a una decisión de diseño muy eficiente, puesto que el acceso al disco secundario es siempre secuencial y no aleatorio, con las ventajas de rendimiento que supone.

Mi opinión es que Apache Kafka es un solución muy versátil y sencilla para consumir o transformar elementos de información que se generan a un ritmo no constante o mantenido, sino poissoniano, como son eventos, mensajes, peticiones… Siguiendo la documentación, que por cierto es muy buena y completa, los ejemplos de aplicación más comunes son como sistema de mensajería tradicional, monitor de actividad web o monitor de métrica de operaciones, agregador de log, gestor de eventos, procesador de streams de datos…

apache-logo

Apache ZooKeeper

Jueves, 23 abril 2015, 23:50 Deja un comentario

zookeeper

Apache ZooKeeper es un servicio de datos en estructura de árbol. El servicio es centralizado, replicado, de alta disponibilidad y escalable; y garantiza la integridad en accesos concurrentes y el orden de modificación de los datos de manera secuencial. El sistema está formado por un conjunto distribuido de instancias denominado quorum que sirven la misma información.

El servicio es centralizado porque solo una de las instancias en ejecución hace las veces de instancia maestra, es la única que puede modificar los datos y que los replica al resto de las instancias. Esto garantiza el orden de los cambios, la atomicidad transaccional y la integridad concurrente de la información. Cuando la instancia maestra cae, el algoritmo de elección de líder, decide qué instancia es la nueva instancia maestra. El acceso de lectura, sin embargo, puede hacerse a cualquiera de las instancias levantadas del sistema. Esto por un lado garantiza la disponibilidad, al poder cualquier nodo convertirse en líder, y el rendimiento y la escabilidad, al permitir poder añadir todas las instancias que queramos al quorum para repartir la carga. Este diseño lo hace más adecuado para situaciones en que la lectura de datos es mucho más habitual que la escritura (al menos 1:10 según la documentación).

El servicio es rápido porque los datos se encuentran en memoria de cada instancia y solo se replican a disco para garantizar su persistencia. También es muy sencillo, tanto en el modo en que almacena la información; como en el modo en que se accede a la misma, con un conjunto de operaciones que son muy básicas y reducidas en número.

La forma en que se estructuran, organizan y acceden los conjuntos de datos es en estructura de árbol. Muy parecido a lo que sería un sistema de ficheros clásico pero siendo todos los nodos iguales, sin que haya distinción entre directorios y ficheros: todos los nodos son accesibles, pueden contener datos y pueden tener nodos hijos. Cada nodo puede contener cualquier tipo de información ya que el acceso es binario, pero el sistema está diseñado para que sean de un tamaño moderado, unos pocos kilobytes como mucho.

Los clientes tienen configuradas una o varias de las instancias del quorum, que no tienen por qué ser todas los integrantes, y que son los que se encargan de presentar al cliente al líder en ese momento.

Los usos más habituales de este servicio es como repositorio de información de configuración y nombres, o para proveer mecanismos de sincronización (lock, mutex,…) para soluciones distribuidas.

Un ejemplo de uso que me parece muy apropiado puede ser como repositorio de configuración de un conjunto de componentes muy numeroso, por ejemplo los sistemas de red de una gran organización o los diferentes servicios de una granja de servidores. Cada nodo hoja de la estructura de árbol puede ser un sistema o servicio y la información que contiene su configuración o estado. Los nodos rama nos permiten organizar, agrupar y clasificar los sistemas o servicios de la manera más adecuada para la organización. La configuración de todos los sistemas o servicios se gestiona de manera centralizada (solo hay una configuración aún estando replicada), la solución es muy escalable y tiene alta disponibilidad (levantando más instancias podemos servir a más clientes) y es también deslocalizable (al permitir desplegar instancias en diferentes lugares buscando la idoneidad específica para cada cliente).

Es también común verla como mecanismo de sincronización o como monitor de soluciones distribuidas como en Druid, por ejemplo.

apache-logo

Docker

Martes, 24 marzo 2015, 13:16 Deja un comentario

Docker

Docker es una plataforma para la virtualización de entornos a nivel de aplicación o software base en lugar de sistema operativo o máquina virtual. Docker permite definir las diferentes unidades de despliegue de la solución software, con sus componentes distribuidos y sus límites de interconexión con otras unidades, para permitir su despliegue apilado de tal manera que representen las diferentes capas de las soluciones.

La idea es que, en lugar de crear una máquina virtual completa para cada entorno con sus recursos virtuales y sistema operativo, sea el propio sistema operativo el que aísle y compartimente la ejecución de cada entorno, denominado container. El propio sistema operativo crea un entorno de ejecución aislado a nivel de sistema de ficheros, de red, de seguridad y ejecución; de tal manera que los diferentes entornos, aún ejecutando en el mismo sistema operativo, están aislados entre ellos o solo compartiendo aquellas partes que se deseen.

Docker para implementar su funcionalidad se basa en dos características del kernel de Linux, cgroups y namespaces, que permiten establecer criterios de prioridad de CPU, limitación de memoria o de operaciones de I/O o control de facturación en el primer caso; o aislar procesos, entornos de red, usuarios, sistemas de ficheros entre los diferentes entornos en el segundo.

Cada entorno en Docker en ejecución es un container, que se corresponde con el despliegue de una imagen, que contiene la definición del entorno, sus límites, puntos de interconexión con terceros y componentes software. Los containers pueden apilarse de tal manera que cada uno represente una capa de la solución final. La combinación apilada de containers se produce mediante la definición de los puntos de interconexión de los container, como pueden ser puertos de red, y la sobreposición de los sistemas de ficheros uno sobre otro, mediante UnionFS.

La posibilidad de dividir los diferentes componentes distribuidos y capas del aplicativo en diferentes containers apilables supone una gran ventaja tanto para desarrolladores como para técnicos de explotación. Por un lado las dependencias se resuelven dentro de los propios container de la solución por lo que dentro de un mismo sistema no hay incompatibilidades entre versiones y dependencias. Por otro, el proceso de despligue se modulariza y la nivelación de entornos de integración y productivos es mucho más sencilla, al basarse en el despliegue secuencial de estas unidades.

Las imágenes que se despliegan como containers pueden registrarse en directorios públicos o privados (dentro del ámbito de la organización) con Docker Hub. El servicio en la nube que registra, almacena, distribuye y da soporte social y colaborativo a la tarea de gestión de las diferentes imágenes. Este es el servicio que monetiza toda la idea. Secundo la opinión de D’Oh de que puede ser una excelente alternativa o mecanismo en el que basarse las futuras tiendas de aplicaciones o sistemas de paquetes de los sistemas operativos.

Aunque la tecnología está basada en características propias de Linux, existen versiones portadas a Windows o iOS, pero con un componente adicional de virtualización para dar soporte a estas funcionalidades de compartimentación que no existen, al menos de manera idéntica, en estos sistemas. Las plataformas de virtualización en la nube Amazon EC2 y Google Cloud también soportan de manera nativa Docker.

Categorías:Arquitectura, Píldoras, Sistemas Etiquetas:

“Best and bad practices” del desarrollo software

Lunes, 9 marzo 2015, 14:23 Deja un comentario
Categorías:Desarrollo

gRPC y Proto 3

Domingo, 8 marzo 2015, 1:24 Deja un comentario

Google hace público el protocolo o mecanismo RPC que utiliza en alguno de sus sistemas, gRPC:

https://github.com/grpc/grpc-common

Para el envío de mensajes utiliza el protocolo Protocols Buffers en su versión 3:

https://github.com/google/protobuf

Google asegura que son ligeras, rápidas y muy eficientes en cuanto al consumo de recursos. La verdad es que los ejemplos aparentan que es muy sencillo integrarlo.

Ambas opciones son multilenguaje/multiframework soportando C++, Java, Python, Go y Ruby entre otros (incluyendo la posibilidad de invocarse entre plataformas distintas). Pero sobre todo me llama la atención la opción de Android, porque hace tiempo buscando soluciones para RPC en este entorno no encontré ni muchas opciones, ni muy buenas.

Categorías:Desarrollo, Píldoras Etiquetas:
A %d blogueros les gusta esto: