jueves, diciembre 31, 2015

¡Feliz año 2016!

Disfrutad en compañía de vuestra gente

No es oro todo lo que reluce,
ni toda la gente errante anda perdida;
a las raíces profundas no llega la escarcha,
el viejo vigoroso no se marchita.
De las cenizas subirá un fuego,
y una luz asomará en las sombras;
el descoronado será de nuevo rey,
forjarán otra vez la espada rota.

martes, diciembre 29, 2015

Baterías de litio en aviones

Multitud de aparatos electrónicos usan hoy en día baterías de ión de litio: Teléfonos inteligentes, cámaras fotográficas, tabletas o portátiles. Estas compactas baterías son capaces de almacenar en poco volumen una gran cantidad de energía. Por eso, cuando una batería de este tipo se daña debido a un golpe o un fallo en la circuitería de carga puede provocar un incendio grave y complicado de apagar. No digamos ya, si dicho incendio se produce dentro de un avión las consecuencias que puede tener. Por eso, las aerolíneas recomiendan que cualquier dispositivo que utilice una batería de este tipo nunca vaya en la bodega de carga del avión sino en el equipaje de mano, para poder actual rápidamente en caso de problemas.

Hoy en el The Aviation Herald han publicado el incidente ocurrido en un A321 de Air Berlin cuando una batería de respaldo empezó a arder: La tripulación tuvo que apagar la batería descargando un extintor, enfriarla y colocarla en una caja metálica ... mientras el avión se desviaba al aeropuerto más cercano.

Puede parecer una tontería, pero hay algunas compañías de carga aérea que se niegan a transportar cargas de baterías de este tipo. Hay sospechas que incendio de del vuelo UPS Flight 6 estuvo relacionado con la carga de baterías de ion de litio que transportaba.

martes, diciembre 22, 2015

Hackeando la PS4 (enlaces)

Ayer dando un repaso a Reddit.programming me encontré con una serie de artículos que describen como usar un fallo de seguridad en webkit, el núcleo del navegador web que usa la Playstation 4, junto con la técnica de ROP poder ejecutar código no firmado dentro de la Playstation 4:

El autor de los artículos ha realizado toda este análisis en una Playstation 4 con una versión antigua del firmware 1.7x. Actualmente, puede que algunos de los agujeros de seguridad que se han usado no funcionen. Sin embargo, es una lectura amena y muy bien explicada para aquellos a los que nos gusta la ingniería inversa.

martes, diciembre 15, 2015

nstat: Estadisticas de red en Linux

Todos los sistemas que implementan la pila de protocolos TCP/IP suelen tener unos contadores internos que almacenan estadísticas sobre el funcionamiento de la pila de procotolos: Paquetes recibidos, conexiones TCP abiertas, paquetes UDP, etc. Normalmente, esas estadísticas son las necesarias para poder implementar la MIB II que necesitan los agentes SNMP. A esta información se puede acceder desde Linux de manera sencilla con el comando nstat. Este comando forma parte del paquete iproute2 que debe estar instalado para poder hacer uso del mismo. Cuando se ejecuta nos muestra los valores de los contadores SNMP del kernel y de las interfaces de red.

root@menzoberrazan:~# nstat
#kernel
IpInReceives                    152295             0.0
IpForwDatagrams                 147066             0.0
IpInDelivers                    5228               0.0
IpOutRequests                   160352             0.0
IpFragFails                     1                  0.0
IcmpInErrors                    421                0.0
...

He cortado la salida del comando. Hay que tener en cuenta que:

  • Se muestran la diferencia entre ejecuciones del comando. Si se quiere saber los valores totales hay que usar la opción -a
  • No se muestra aquellos contadores cuyo valor es cero. Si se quieren mostrar hay que usar la opción -z
  • Si se quiere resetear esos contadorews usar la opción -r
  • Para que los datos estén en formato json y se pueda procesar por otras utilidades (como jq), cabe la posibilidad de usar la opción -j.
  • Si sólo queremos actualizar los acumulados y no imprimir resultados -n

Esta utilidad es de utilidad para ver cual es el rendimiento de nuestra pila TCP/IP y si hay errores. Por ejemplo los contadores UdpInErrors nos podría dar una pista de paquetes UDP que estamos recibiendo y que el sistema no está aceptando por carga o porque estamos bajo un situación de denegación de servicios. UdpRcvbufErrors nos puede indicar que el sistema está saturando la pila TCP/IP a mayor velocidad que la que esta puede procesar el tráfico entrante.

lunes, diciembre 14, 2015

La gran apuesta (The Big short), la película.

Hace algún tiempo escribí una pequeña reseña de la Gran Apuesta, el magnífico libro de Michael Lewis en el cual relata algunos de los mecanimos que llevaron a la crisis subprime en EEUU. Hace unos días me enteré que el libro se ha llevado al cine. Con guión de Adam McKay y Charles Randolph, dirigida por Adam McKay y protagonizada por Christian Bale, Steve Carell, Ryan Gosling y Brad Pitt, en Enero del 2016 tendremos en el cine La Gran Apuesta. Si es la mitad de buena que el libro de Lewis, será una gran película. Aquí os dejo el trailer.

sábado, diciembre 12, 2015

ElasticSearch: Algunos conceptos básicos

Estas últimas semanas estoy trabajando con el buscador Elasticsearch. Quiero recopilar algunas notas de los conceptos, terminología y uso básico del mismo.

Elasticsearch es un motor de almacenamiento y búsqueda de documentos en formato JSON. Estos documentos se organizan índices de acuerdo a nuestros requerimientos. Los índices internamente se dividen en shards los cuales pueden residir en diferentes nodos. Un esquema sencillo de esta relación es el siguiente:

La primera decisión importante cuando se despliega un proyecto sobre Elasticsearch es decidir cual va a ser el número de shards que va a tener cada uno de los índices que usemos. Esta es una de la primeras preguntas que nos debemos hacer. El número de shards determina como podemos distribuir el índice entre los diferentes nodos que forman el cluster. Además, cada shard es un índice de Lucene que ocupa los correspondientes recursos en el sistema. Además está el inconveniente de que no se puede cambiar los shards de un índice sin reindexar de nuevo todos los datos y es un parámetro fundamental a la hora de evaluar el rendimiento del cluster y los problemas de escalado que pudiera haber. Como todo, el número que se use es un conjunto de compromisos entre nuestra escalabidad y rendimiento

Otro concepto importante a la hora de manejar los índices de elasticsearch son aquellos shards que son réplicas. Estás se usan para implementar la redundacia a fallos. Si un nodo que tiene un shard primario cae, la réplica pasa a ser el shard primario y así el cluster puede seguir funcionando.

Los shards, tanto primarios como réplicas se distribuyen entre los diferenes nodos del cluster que forman Elasticsearch para conseguir un escalado horizontal entre varias máquinas. Un cluster lo forman varios nodos que tienen el mismo nombre. Éste se fija en el fichero de configuración elasticsearch.yml con la propiedad cluster.name:. En la arquitectura de Elasticsearch un nodo siempre es el master encargado de la gestión de los índices y coordinación de los diferentes nodos. Las peticiones de indexado y búsqueda que reciben los nodos son rutadas de manera adecuada a donde están los datos.

Para interactuar con Elasticsearch lo más sencillo es usar su interfaz REST que por defecto escucha en el puerto 9200 de la máquina donde se está ejectuando Elasticsearch. Es muy fácil usar software como curl para realizar dichas peticiones. Aparte del verbo http (GET, PUT, POST, DELETE) la información que necesita Elasticsearch viaja en el cuerpo de las peticiones codificado en formato JSON. La mayoría de las respuestas que da el servidor de Elasticsearch son también en este formato. Existe otro método para interactuar con el cluster de Elasticsearch y es el llamado API de transporte, donde el sistema cliente simula ser otro nodo del cluster. Hay multitud de librerías que encapsulan este acceso al servidor como Python Elasticsearch Client para Python. Para algunas cosas que hago en Python he usado bastante Requests montando las peticiones directamente.

Intereactuar con el API rest es bastante sencillo. Por ejemplo, esta simple petición nos devuelve un JSON con las propiedades del server. A continuación unos ejemplos de como crear un índice, introducir datos, devolverlos y borrar el índice.

baldurgate:~ terron$curl -XGET http://localhost:9200
{
  "name" : "Krang",
  "cluster_name" : "avos",
  "version" : {
    "number" : "2.0.0",
    "build_hash" : "de54438d6af8f9340d50c5c786151783ce7d6be5",
    "build_timestamp" : "2015-10-22T08:09:48Z",
    "build_snapshot" : false,
    "lucene_version" : "5.2.1"
  },
  "tagline" : "You Know, for Search"
}

Crear un índice y ver las propiedades del índice es muy sencillo. Se añade el parámetro pretty para que nos devuelva el JSON formateado para que su lectura sea sencilla

baldurgate:~ terron$curl -XPUT http://localhost:9200/prueba?pretty
{
  "acknowledged" : true
}
baldurgate:~ terron$curl -XGET http://localhost:9200/prueba?pretty
{
  "prueba" : {
    "aliases" : { },
    "mappings" : { },
    "settings" : {
      "index" : {
        "creation_date" : "1449933189870",
        "number_of_shards" : "1",
        "number_of_replicas" : "1",
        "uuid" : "wFT1ymODQCqsXIOkeCakVw",
        "version" : {
          "created" : "2000099"
        }
      }
    },
    "warmers" : { }
  }
}

Introducir datos en el índice se puede hacer con curl de manera sencilla. Voy a dejar, de momento el fundamental tema de los mapeos, dejando que sea el propio servidor el encargado de generarlos automáticamente. Por ejemplo, para crear dentro del índice prueba un tipo de datos llamado libro, introducimos un

baldurgate:~ terron$curl -XPOST http://localhost:9200/prueba/libro/?pretty \
  -d '{"autor": "Julio verne","titulo": "Veinte mil lenguas de viaje submarino"}'
{
  "_index" : "prueba",
  "_type" : "libro",
  "_id" : "AVGWzzLD6jhN-gT8oefN",
  "_version" : 1,
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "created" : true
}

Y una búsqueda rápida que devuelva todo lo que tiene el índice

baldurgate:~ terron$curl -XGET http://localhost:9200/prueba/_search
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 1.0,
    "hits" : [ {
      "_index" : "prueba",
      "_type" : "libro",
      "_id" : "AVGWztnY6jhN-gT8oefM",
      "_score" : 1.0,
      "_source":{"autor": "Julio verne","titulo": "Veinte mil lenguas de viaje submarino"}
    }]
  }
}

Por último, se puede borrar todo el índice como un simple:

baldurgate:~ terron$curl -XDELETE http://localhost:9200/prueba {
  "acknowledged":true
}

viernes, diciembre 04, 2015

ssh-agent: Agente de autentificación de ssh

Aunque llevo casi dos décadas usando openssh para conectar a máquinas remotas1 no ha sido hasta estos dos últimos años cuando he dejado de usar la autentificación con contraseñas y he pasado a usar la autentificación basada en claves públicas y privadas. Y no ha sido hasta estos días cuando he empezado a usar el agente de autentificación ssh-agent

ssh-agent se encarga de gestionar nuestras claves privadas y pasar las mismas a los programas que la soliciten. ssh-agent se localiza en el sistema con ayuda de varibles de entorno. Estas variables le dice a los posibles clientes de ssh-agent como contactar con él para usar las claves privadas que almacena.

Normalmente el agent se arranca durante el inicio de sesión. La configuración que uso es la siguiente:

export SSH_AUTH_SOCK=~/.ssh/ssh-agent.$HOSTNAME.sock
ssh-add -l 2>/dev/null >/dev/null
if [ $? -ge 2 ]; then
  ssh-agent -a "$SSH_AUTH_SOCK" >/dev/null
fi

Estas líneas lo primero que establecen es la ruta hacia el socket Unix que se utilizará para comunicarnos con el agente. Luego usamos la aplicación encargada de añadir claves al agente para comprobar si está corriendo. Si se consulta la página de manual de ssh-add, vemos que la opción -l intenta listar las claves que tiene el agente. En caso de error, el valor de retorno será mayor que cero. Concretamente dos, si no puede contactar con el agente. El autor del script detecta ese valor de retorno para ejecutar el agente si éste está parado.

Para añadir una clave privada al agente basta con usar ssh-add:

ssh-add clave_privada

En caso de que la clave privada la hayamos creado protegida con una contraseña, nos la preguntará para poder desbloquarla y cargarla en el agente. Una vez realizado este paso, ssh consultará el agente buscando las claves privadas para poder hacer la autentificación.

El uso del agente y la autentificación con clave pública/privada es más seguro y permite olvidarse de estar tecleando claves constantemente.

Notas

  1. Incluyo en este tiempo el precursor, el ssh escrito por Tatu Ylönen del cual deriva en openssh

miércoles, diciembre 02, 2015

Mac OS X: Configurar paths y uso de path_helper

Estaba configurando algunos directorios en la ruta de búsqueda de ejecutables (PATH) de mi OS X y en principio recurrí a modificar mi $HOME/.profile - uso bash como shell - añadiendo las nuevass rutas a la variable PATH, si estas rutas no están añadidas con un código similar al siguiente:

DIRS=(/usr/local/java/maven/bin)
for d in ${DIRS[@]}; do
    if [[ !  ":$PATH:" == *":$d:"* ]]; then
       PATH=$PATH:$d
    fi
done
export PATH

Normalmente, si quería que ese PATH estuviera disponible en todo el sistema, solía modificar uno de los scripts en /etc que se ejecutan cuando el usuario hace login. Sin embargo, viendo el valor de la variable en mi OS X me di cuenta que había algunos directorios en el PATH que habían sido añadidos por alguno de los paquetes que he ido instalado en el sistema a lo largo del tiempo. He buscado qué mecanismo utiliza OS X para establecer esas ruta en la configuración, encontrando la respuesta en en esta entrada de StackOverflow: OS X utiliza un mecanismo llamado path_helper para configurar la variable PATH.

path_helper lee los directorios de búsqueda por defecto de ejecutables de /etc/paths y luego los ficheros que estén en /etc/paths.d y compondrá las rutas de búsquedas definidas en la variable PATH de acuerdo al contenido de los mismos.

Si se quiere añadir una ruta, por ejemplo /usr/local/java/maven/bin al sistema, basta con crear un fichero /etc/path.d/maven donde cada línea especifica una ruta donde se deben de buscar los ejecutables y path_helper se encargará del resto.

Este mecanismo también se usa para las rutas de las páginas de manual. Las rutas por defecto se definen en /etc/manpaths y se pueden añadir otras en el directorio /etc/manpaths.d

La ventaja de este tipo de mecanismos es que nos permite no tener que tocar scripts del sistema que pueden machacarse con posteriores actualizaciones.