miércoles, 25 de diciembre de 2013

Fichero de claves de keepass en apache con webdav

Un problema que se puede plantear es disponer de un lugar en internet en el que guardar tus ficheros de claves, accesible desde todos los sitios, que utilice algún protocolo seguro y que te permita también realizar las actualizaciones convenientes.

Para que sea accesible desde todos los sitios sin tener problemas con firewalls y restricciones de navegación, con comunicación cifrada, lo mejor es utilizar el protocolo https. El servidor apache nos da esa parte, si ademas le metemos la capacidad para manejar webdav que también es soportado por keepass, tenemos la funcionalidad de poder realizar las modificaciones desde donde realizamos las conexiones. En resumen, apache con modulo dav y dav_fs. El soporte para la comunicación cifrada con SSL es trivial.

En /etc/apache2/mods-available creamos el ficheros dav.conf con el siguiente contenido
Alias /ruta_publicacion/ /var/www/ruta_ficheros/
<Location /ruta_publicacion/ >
  DAV On
  Options -MultiViews
<Location>
 e igualmente creamos también dav_fs.conf (si no existe).
DAVLockDB ${APACHE_LOCK_DIR}/DAVLock
Lo primero establece un directorio donde se va a poder utilizar webdav, es decir, es el directorio donde podremos hacer modificaciones remotamente en los ficheros ofrecidos por el servidor apache. Lo segundo establece la ruta del fichero de bloqueos para el modulo webdav y no tener conflictos con actualizaciones simultáneas.

Nos aseguramos que el directorio /var/www/ruta_ficheros/ y sus ficheros son accesibles por el propietario que ejecuta apache (normalmente es www-data) y que los permisos adecuados para poder leer y escribir los ficheros (usualmente que coincida el propietario y grupo con los que se ejecuta el proceso apache). Luego ejecutamos la habilitación de los modulos y reiniciamos el apache con
$ a2enmod dav
$ a2enmod dav_fs
$ service apache2 restart
En /var/www/ruta_ficheros/ copiamos nuestros ficheros de claves que tenemos con keepass. Adicionalmente, podemos proteger con contraseñas el acceso al directorio /var/www/ruta_ficheros/ con las directivas dentro de las directivas Location de apache anteriores.
AuthType Basic
AuthUserFile /path/htpasswd/db
AuthName "Acceso restringido"
require valid-user
También podemos agregar el -Indexes a las opciones de Location, pero eso depende de los gustos del consumidor. Es importante la opción -MultiViews, de lo contrario aparecerá un error con el siguiente texto "Negotiation: discovered file(s) matching request:" en nuestro querido apache. Lo cual no te deja mucho margen de maniobra, salvo buscar en san google.

PD: Publicado inicialmente en Fichero de claves de keepass en apache con webdav.

lunes, 16 de diciembre de 2013

VirtualBox Error VERR_VMX_NO_VMX

Hacía unos días que no ejecutaba la máquina virtual en el portátil y al intentarlo hoy me ha aparecido un error:
VERR_VMX_NO_VMX 0x80004005
Fallo al abrir una sesión para la máquina virtual W XP Professional.
VT-x is not available. (VERR_VMX_NO_VMX).
Código Resultado: NS_ERROR_FAILURE (0x80004005)
Componente: Console
Interfaz: IConsole {8ab7c520-2442-4b66-8d74-4ff1e195d2b6}
Me ha descolocado el error porque hasta hace unos días, nunca habían protestado porque no tuviera habilitada la virtualización a nivel de BIOS, principalmente porque el microprocesador del portátil no soporta la virtualización a nivel de hardware.

Cómo recordaba que hacía poco que se había actualizado el equipo de la oficina, utilizando ahora VirtualBox 4.3.4, he mirado en los foros de virtualbox.org y he encontrado que precisamente se trata de un cambio introducido en dicha versión: por defecto, si no encuentra el hardware de aceleración, da error. Basta con indicarle el modo para que funcione correctamente:
$ VBoxManage modifyvm <vmname> --longmode off


No pierdas de vista que:
  • La solución no puede ser aplicada desde la interfaz, sino que ha de emplearse la consola de administración.
  • Debe lanzarse con el usuario que ejecutas las máquinas virtuales y no como root o cualquier otro.
  • Se debe sustituir <vmname> por el nombre de la máquina virtual. Si el nombre contiene espacio, se han de usar las comillas (simples o dobles) para proteger los espacios.

Actualización (13/01/2014):
En configuraciones de 64 bit que no soportan virtualización, es necesario no sólo deshabilitar el longmode si no prácticamente cualquier función de virtualización de la CPU. La mejor forma de hacerlo es editando el fichero descriptor de la máquina virtual, que normalmente está ubicado en el directorio home o user, dependiendo del SO, de cada usuario del sistema.

La configuración debería quedar tal que así:
...
 <CPU count="1" hotplug="false">
       <HardwareVirtEx enabled="false"/>
       <HardwareVirtExNestedPaging enabled="false"/>
       <HardwareVirtExVPID enabled="false"/>
       <HardwareVirtExUX enabled="false"/>
       <PAE enabled="false"/>
       <LongMode enabled="false"/>
       <HardwareVirtExLargePages enabled="false"/>
       <HardwareVirtForce enabled="false"/>
 </CPU>
...
Fuente: Foro VirtualBox

lunes, 13 de mayo de 2013

La breve chuleta del comando ip

El comando ip forma parte de iproute (o iproute2). Iproute en sí es un gran desconocido. De hecho, me he encontrado en varios clientes que la utilización de iproute lo ven como algo 'opcional'. Un sin sentido que muestra desconocimiento de los sistemas Linux actuales.

También parte es culpa de muchos manuales, que todavía nos hablan de los comandos ifconfig y route como la referencia para la configuración de la red, la realidad es que esto no es así, teniendo comportamientos inadecuados en ciertos escenarios. Bueno, al grano que me pierdo, que esto sólo iba a ser una breve chuleta de lo se puede hacer con ip para consulta rápida.

Configuración de la IP en una interfaz


Aunque la configuración de la IP en una interfaz de red se hace en los ficheros de configuración (/etc/network/interfaces en Debian o /etc/sysconfig/networking-scripts/ifcfgX en Red Hat) o con los comandos ifconfig, esto no hace más que llamar a ip para realizar las acciones convenientes. 

El esquema general de ip es
ip [OPTIONS] OBJECT { COMMAND }
Los objetos son link, addr (utilizados ambos por ifconfig para asignación de ip y activar la interfaz), route (empleado por el comando route). Hay otros objetos como rule (configuración de rutas más avanzada) o tunnel (para los túneles) por nombrar alguno.

Poner la ip 10.20.30.40 con mascara de red 255.255.255.0 a la interfaz eth0 es algo tan simple como
ip addr add 10.20.30.40/24 dev eth0
Para retirar la ip a la interfaz, sustituimos el add por un del.
ip addr del 10.20.30.40/24 dev eth0
Al ejecutar el comando asignación de ip, también estamos estableciendo una ruta para comunicarnos con la red 10.230.30.0/24. Podemos hacer la prueba viendo antes las rutas (con el comando ip route) antes y despues de quitar la ip a la interfaz eth0.

Rutas y rutas por defecto


Aunque antes lo dije, cuando se establece un ip a un dispositivo, ya estamos agregando una entrada de ruta. Esta ruta sirve para comunicarse con los dispositivos de la misma red. Para comunicarnos con dispositivos de otras redes, hay que poner rutas adicionales. Con estas rutas indicamos que dispositivos se puede utilizar para enviar esas comunicaciones (o que ips se deben utilizar para comunicarnos con esos elementos).

Para comunicarnos con un equipo que pertenece a una red 192.168.100.1/26 podemos hacerlo mediante la una ruta que utilice la interfaz eth0 o con un ruta por defecto (todas las comunicaciones que vayan fuera, utilizan la de por defecto)
ip route add 192.168.100.100/26 via eth0ip route add default via eth0
Para quitar las rutas, se emplan los mismos comandos pero se sustituyen los add por del.

En el 100% de los casos, con esto tenemos resuelto los problemas que puede traernos hacer la configuración ip de cualquier dispositivo en nuestro Linux. Los problemas que nos pueden surgir desde aquí, tendrán más bien relación con el establecimiento de rutas avanzadas (objeto rules) y quedan fuera de esta chuleta.



jueves, 29 de noviembre de 2012

¡RaspberryPi en casa!

¡Por fin tenemos las placas!

Ayer, tras varios meses de espera, nos llegaron las placas de la RaspberryPi.
Ahora queda el proceso de ponerlas en marcha, que iremos detallando y sobre todo contando que uso hemos pensado darles.
Vienen tal cuales, desnuditas ... aunque compramos la carcasa blanca por aquello de la presentación y que no nos mataran en casa por tener otro "cacharro" más en medio.
Ahora a por una tarjeta SD, un cargador compatible con la placa, un cable HDMI y un cable de red.
Iremos dando detalles.

martes, 20 de noviembre de 2012

Breves notas sobre scripts en bash

Obtener directorio donde se encuentra el ejecutable, asi evitamos tener que configurar una variable con el path del ejecutable (sobre todo el aplicaciones de shell que manejan varios ficheros fuente).
PREFIX=$(readlink -f $(dirname $0))
Redirigir salida dentro de script hacia un fichero de log. Con esto conseguimos que no sea necesario ir añadiendo pipes (&gt;) a cada uno de los comandos de nuestro script y que podamos, al finalizar el script, mandar por mail el log de ejecución.
exec 2>&1 >> LOGERRORES
Añadir elementos a un array.
LISTADO=("${LISTADO[@]}" "ITEM");
Pueden parecer nimiedades, pero no quita que sean muy útiles.

PD: Publicado en Breves notas sobre scripts en bash

miércoles, 7 de noviembre de 2012

Jugando con getopt y getopts

Cuando me he tenido que enfrentar al problema de controlar el paso parámetros en los scripts, siempre lo he dejado como una tarea de google, es decir, que busco por encima lo que necesito, lo adapto a mis necesidades y luego lo olvido. Para la próxima vez, disponde de esta nota, que pretendía ser breve, pero que al final no lo será tanto.

¿Diferencias entre getopt y getopts?

Getopt, en singular, es un comando que permite tratar los parámetros que llegan, sean cortos (del tipo -a, -b, -l) o largos (--long). El segundo es un comando incluido dentro de la bash que solo nos permite operar con los parámetros cortos.

¿Parámetros cortos y largos, con o sin argumentos?

Tanto los parámetros cortos como los largos, pueden tener argumentos (obligatorios o no). Esto se especificará en la cadena de parámetros que se le pasará a getopt/getopts. Por ejemplo, para indicar que vamos a tener dos parámetros sin argumentos podemos utilizar "ab". Si el parámetro 'a' va a llevar un argumento, pondremos "a:b". Si ambos llevan argumento "a:b:". Por último hay un caso más que podemos necesitar, que el parámetro 'a' pueda llevar un argumento, pero que no sea obligatoria la aparición del argumento, entonces la cadena de tratamiento sería 'a::b".

En el caso de los parámetros largos es algo similar. Tenemos el parámetro '--help' y el parámetro '--output=file' con un argumento. La cadena de tratamiento queda como 'help,output:'. Si queremos que '--help' lleve un argumento extra opcional, entonces tendríamos 'help::,output:'. Observese que en este caso, para separar los parámetros largos se utiliza la coma.

¿Cómo usar getopt?

La utilización de getopt es algo compleja de entender, pero con la siguiente estructura de código tenemos el análisis de todos los parametros que le pueden llegar a nuestros scripts con solo unas pequeñas modificaciones (ver ejemplo un poco más abajo).

La estructura va como sigue. Primero se costruye una cadena que contiene la ejecución del tratamiento de parámetro con getopt, indicando los parámetros cortos (-o) y sus versiones largas (--long). Se le pasa también el nombre del programa (-n), se indica cuando hay que dejar de procesar los parámetros (si se encuentra '--') y por último se le pasa la ristra de parámetros que se han recibido ($@). Si hay algun error en el tratamiento, saldremos.

El siguiente paso es evaluar la cadena, es en este momento donde entra en juego el uso de las comillas invertidas en su definición, utilizando set --, para hacer que los argumentos sean evaluados en función de su posición. Con la operación shift iremos desplazándonos entre los argumentos cuando entremos en el bucle, del que saldremos cuando topemos con el parámetro --, que indica que hemos llegado al final de los argumentos recibidos.

Dentro del bucle, hacemos el tratamiento con los case necesarios para los argumentos y si estamos en un argumento que tiene alguna opción, la recogemos al estar en la variable $2 ($1 es la propia opción). Siempre que tratemos un argumento habra que hacer el desplazamiento con shift (uno o dos veces dependiendo de si tiene opción o no), de lo contrario nos quedaremos en el bucle para siempre...
CADPARAM=`getopt -o ab:c:: --long a-long,b-long:,c-long:: \
     -n '$0' -- "$@"`
if [ $? != 0 ] ; then
      echo "Error en el tratamiento de parametros..." 1>&2 ;
      exit 1 ;
fi
# Se hace la evaluacion de los parametros
eval set -- "$CADPARAM"
while true ; do
        case "$1" in
                -a|--a-long) echo "Opcion a" ; shift ;;
                -b|--b-long) echo "Opcion b, argumento \`$2'" ; shift 2 ;;
                -c|--c-long)
                        # c tiene un argumento opcional.
                        # Sera generado vacio aunque no lo encuentre.
                        case "$2" in
                                "") echo "Opcion c, sin argumento"; shift 2 ;;
                                *)  echo "Opcion c, con argumento \`$2'" ; shift 2 ;;
                        esac ;;
                --) shift ; break ;;
                *) echo "Error de tratamiento de opciones!" ; exit 1 ;;
        esac
done
¿Cómo usar getopts?

Getopts es algo similar, solo que suprime la evaluación y no hay bucle con condición true, la propia condición de while va recorriendo los elementos de la lista de argumentos con getopts. Es una construcción algo más sencilla de entender, aunque tiene menos posibilidades.
while getopts "ab:c::" OPCION
do
case $OPCION in
a)
ARGUMENTO1=true
;;
b)
ARGUMENTO2=true
OPT2=$OPTARG
;;
c)
ARGUMENTO3=true
if [ $OPTARG != "" ]; then
OPT3=$OPTARG
fi
;;
*)
echo "Opcion no reconocida"
exit 1
;;
?)
echo "Uso: ejemplo [-a] [-b opcionb] [-c [opcionc]]"
exit 1
;;
esac
done
¿Y después qué?

Getopt y getopts está implementado en bibliotecas para otros lenguajes de programación como C, PHP, Perl, Java. Lo más complicado será encontrar la forma de invocación y la manera en la que iremos paseándonos por los argumentos. El cómo especificar la cadena de argumentos es similar.

viernes, 19 de octubre de 2012

Utilizar losetup para montar imágenes de dispositivos de bloques

Con las tarjetas de memoria tipo Compact Flash o las MicroSD es frecuente encontrarse que tienen varias particiones y que nos puede resultar díficil acceder a una de sus particiones a partir de un backup realizado sobre la tarjeta de memoria al completo.

Si hacemos un volcado con el comando dd de la partición sdb1 no hay problemas para montar luego la imagen, pero si hacemos el volcado del dispositivo al completo sdb, las opciones normales de mount no nos sirven para acceder a las particiones, impidiendo que podamos montarla. Hemos de recurrir al parámetro offset, dentro la opciones de mount. En este parámetro le pasamos el valor en bytes de donde empieza la partición que vamos a utilizar

Por ese motivo, necesitamos saber la disposición de las particiones (donde empiezan y acaban), es decir, necesitamos saber el mapa de particiones que tenía el dispositivo cuando hicimos el dump (salvar junto con el dump la salida del comando fdisk -l /dev/sdb por ejemplo).

Pero hay una opción mucho mejor, que evita ese paso, utilizando el comando losetup. Losetup nos permite montar un archivo de imagen (obtenido con dd) en un dispositivo /dev/loopX. Luego podemos utilizar el dispositivos loopX como si fuera un /dev/sdXX con el comando mount. La chuleta puede ser algo como esto:

  • Generar una imagen de un dispositivo al completo: dd if=/dev/sdb of=archivo_imagen.dd
  • Para montar en /dev/ hacemos : losetup -f archivo_imagen.dd
  • Para ver donde se ha montado: losetup -a
  • Para ver las particiones: fdisk -l /dev/loop0
  • Para montar la partición segunda: mount -t ext3 /dev/loop0p2 /mnt/particion2

Nota extra: no sólo sirve para memorias Compact Flash, microSD o Pendrive USB, se puede emplear con cualquier dispositivo de bloques (un disco duro por ejemplo).