"Después del juego es antes del juego"
Sepp Herberger

miércoles, 28 de octubre de 2015

Clonar pantalla y cañón de vídeo en el inicio de sesión.

Las tarjetas VGA son bastante rebeldes, cuando tienen dos salidas (típicamente una VGA D-sub 15 y una HDMI) a las que conectamos un monitor y un cañón de vídeo el comportamiento es bastante errático en función de la tarjeta de vídeo y los drivers usados: unas veces aparecen clonadas, otras veces como escritorio extendido y, por último, algunas veces aparece apagada una de ellas.

Como normalmente nuestra intención es que ambas aparezcan clonadas (ya que es lo que desea el usuario el 99% de las veces) lo mejor es poner un script que nos las clone usando el comando "xrandr". Luego, el propio usuario puede cambiar esa configuración por si mismo usando el programa "arandr".

En mi caso tengo un PC con 2 salidas de vídeo: VGA-0 (que va al monitor) y DVI-I-0 (que va al cañón de vídeo). El nombre de cada salida se conoce ejecutando "xrandr" sin parámetros, tal como conté aquí.

El comando que debemos ejecutar es:
xrandr --output VGA-0 --rate 60 --mode 1024x768 --output DVI-I-0 --mode 1024x768 --same-as VGA-0
En el que se fuerza una resolución de 1024x768 en ambas pantallas y hago que DVI-I-0 se clone de VGA-0. El monitor es realmente de 16:9, mientras que el cañón es de 4:3, por lo que la resolución de 1024x768 en el monitor queda un poco deforme, pero si queremos tener lo mismo es lo que hay. Se podría jugar con los parámetros "panning" y "scale" de xrandr para intentar conciliar 2 resoluciones distintas en el clonado, pero al final queda como el discurso de C's: totalmente amorfo por querer mezclar 2 agua y aceite, así que no he seguido por ese camino.

Para que esto se ejecute automáticamente en el arranque del sistema hay que poner el comando en algún script de inicio. En mi caso, como uso gdm3 para iniciar sesión lo añado al final de "/etc/gdm3/PreSession/Default", que es un script que se ejecuta justo antes de que el usuario inicie sesión en la máquina. De esta manera garantizo que cada vez que se haga login se configuren ambas pantallas como clonadas, independientemente de que alguien lo haya cambiado durante la sesión anterior.

martes, 27 de octubre de 2015

Desactivar el audio HDMI y dejar solo el sonido analógico mediante una tarea puppet.

En algunos de nuestros PC el sistema identifica 2 tarjetas de sonido: la tarjeta analógica tradicional y otra salida digital vinculada a la salida HDMI de la tarjeta VGA. Tenemos los altavoces conectados a la salida analógica, de tal manera que si por cualquier motivo en pulseaudio se selecciona (y pasa, no sabemos como, pero pasa) de forma espontánea la salida digital, el sonido deja de salir por los altavoces normales, que quedan mudos ante el desconcierto de los usuarios.

Lo solucionaremos en dos partes: primero veremos como hacer desaparecer la tarjeta de sonido digital y luego como automatizarlo vía puppet.

1. Desactivar la tarjeta de sonido.

En Debian Squeeze esto se evitaba blacklistando el módulo del kernel que maneja la tarjeta digital de audio (snd_hda_codec_hdmi), pero en Wheezy este método no funcionaba así como así. Menos mal que nuestro compañero Ricardo encontró la solución con el siguiente comando:
# echo 1 > "/sys/bus/pci/devices/..../remove"
Este comando enviado al dispositivo pci en concreto que representa nuestra tarjeta digital de audio hace que se vaporice, desapareciendo del hardware de la máquina, de pulseaudio y de todos lados. La tarjeta analógica queda como única salida de audio.

Antes hay que saber exactamente cual es el dispositivo pci asociado a la tarjeta de audio:
bus=$(lspci | grep "RV620 HDMI Audio" | cut -d" " -f1)
if [ -n $bus ]
then
      echo 1 > "/sys/bus/pci/devices/0000:00:01.0/0000:$bus/remove"
fi
Siendo "RV620 HDMI Audio" la cadena que identifica nuestra tarjeta de audio HDMI (la descripción se saca con la orden lspci) y debería adaptarse la tarjeta que tenga cada cual. Escrito de forma mas breve sería:
bus=$(lspci | grep "RV620 HDMI Audio" | cut -d" " -f1); test -n $bus && echo 1 > "/sys/bus/pci/devices/0000:00:01.0/0000:$bus/remove"
Como debe ejecutarse al arrancar el sistema, para que quede desactivado desde el principio, el sitio mas adecuado es en /etc/rc.local, antes del exit 0 con el que acaba dicho script.

2. Insertar una línea en rc.local de forma automatizada vía puppet.

Si queremos meter esta línea en rc.local vía puppet (para así poder aplicarlo de forma automatizada en un grupo de máquinas) tenemos que encontrar la manera de añadir dicha línea en el fichero antes del exit 0, verificando que no estuviera ya. Hay varias maneras de hacerlo, pero me he decantado por usar un define de puppet.

Actualmente tengo en /etc/puppet/defines/* de mi servidor puppet un conjunto de funciones puppet útiles para tratar con ficheros y lineas de texto. Es una gran idea cogida de mi compañero Esteban Navas y son una serie de funciones descritas en https://projects.puppetlabs.com/projects/puppet/wiki/Simple_Text_Patterns/1:

  • delete_lines.pp
  • line.pp
  • prepend_if_no_such_line.pp
  • replace.pp

Aunque ninguna servía para hacer lo que quiero (añadir una línea que no está antes del "exit 0" del rc.local), los defines anteriores me sirven de base para hacerlo. El nuevo define en cuestión queda:
# cat /etc/puppet/defines/add_line_above.pp

#Añade la linea "line" al fichero "file", siempre que la cadena "search" no esté en el fichero.
#La línea la añade inmediatamente por encima de la línea que contenga la cadena "above".
#Usado por ejemplo para añadir lineas a /etc/rc.local por encima del "exit 0" con el cual
#siempre finaliza dicho script.

define add_line_above($file, $line, $search, $above) {
    exec { "/bin/sed -i '/${above}/i\\${line}' '${file}' ":
           unless => "/bin/grep -q '${search}' '${file}'"
    }
}
A continuación tenemos que referenciar este define metiéndolo en el init.pp de una tarea puppet específica que hagamos o bien añadiéndolo a una ya hecha (yo prefiero eso: hacer tareas omnibús que aplican conjuntos de pequeños ajustes de configuración antes que llenar todo de pequeñas tareitas haiku muy especializadas)

Sea como fuere, en el init.pp que escojamos tenemos que importar los .pp de /etc/puppet/defines, poniendo al principio del fichero, antes del "class":
import "/etc/puppet/defines/*.pp"
Y luego dentro del "class":
add_line_above { desactiva_audio_hdmi:
              file=> "/etc/rc.local",
              line=> 'bus=$(lspci | grep "RV620 HDMI Audio" | cut -d" " -f1); test -n $bus && echo 1 > "/sys/bus/pci/devices/0000:00:01.0/0000:$bus/remove"',
              search=> "RV620",
              above=> "^exit 0$"
}

Y ya está. Eso lo que hará será modificar el fichero rc.local de todos los equipos que usen la clase puppet para añadir:
bus=$(lspci | grep "RV620 HDMI Audio" | cut -d" " -f1); test -n $bus && echo 1 > "/sys/bus/pci/devices/0000:00:01.0/0000:$bus/remove"
Justo antes del exit 0 con el que finaliza dicho fichero. Y con esto ya tenemos ambos objetivos conseguidos, trabajo hecho :-).


miércoles, 21 de octubre de 2015

Como cambiar la contraseña de root de un Linux cuando no la sabemos previamente.

A veces heredamos o nos llega un sistema Linux en el que la contraseña de root es desconocida. Puesto que las contraseñas de Linux son en principio cuasi-imposibles de descifrar, no nos queda otra que cambiar la contraseña de root por una que conozcamos, ¿cómo se hace esto?.

Primero debemos arrancar con un CD o Pendrive conteniendo un Linux. Puede ser un SystemRescueCD, un Clonezilla o cualquier disco de instalación Live (uno de Ubuntu o Mint, por ejemplo). Una vez hemos arrancado tendremos que abrir un terminal. En un SystemRescueCD el terminal está allí mismo, en un Clonezilla hay que seleccionar la opción "Enter shell..." enlos menús y sobre un Linux Live habría que ir al menú de inicio y ejecutar la aplicación de terminal desde allí.

Ahora pasamos a ejecutar los siguientes comandos (el "sudo su" puede que no sea necesario, dependiendo de que distribución estemos usando):
$ sudo su
# fdisk -l

Esto nos mostrará las particiones del disco duro del PC, algo así como:
Disco /dev/sda: 160.0 GB, 160040803840 bytes
.....
.....
Dispositivo Inicio    Comienzo      Fin      Bloques  Id  Sistema
/dev/sda1   *        2048   156250111    78124032   83  Linux
/dev/sda2       156264255   312576704    78156225   83  Linux
En esta lista de particiones estará la que contiene el sistema Linux al cual queremos cambiar la contraseña. En el ejemplo anterior sería /dev/sda1 (es una partición de Linux y está marcada como arrancable).

Una vez identificada la partición, la montamos:
# mount /dev/sda1 /mnt
Y entramos en ella con una jaula chroot:
# chroot /mnt
Puede que nos de algún error relacionado con "zsh" u otra shell, en ese caso lo haremos así:
# chroot /mnt /bin/bash
Con esta orden chroot estamos dentro del Linux contenido en el disco duro, ya que nuestro / ha pasado a ser /dev/sda1. Eso quiere decir que cualquier comando que tecleemos se hará y tendrá efecto sobre dicho Linux y no sobre el sistema con el que hemos arrancado. Por tanto, haciendo:
# passwd root
Nos pedirá la nueva contraseña de root: la introducimos por duplicado y ya está, esa será la contraseña de root del sistema instalado en el disco duro. Salimos de la jaula y desmontamos:
# exit
# umount /mnt
Si por algún motivo el comando "passwd root" no funciona podemos optar por lo siguiente una vez averiguada la partición donde está nuestro Linux:
# mount /dev/sda1 /mnt
# nano /mnt/etc/shadow
# # Borrar contraseña root
# umount /mnt
Si no funciona el editor "nano" probaremos con "vi". Por "borrar contraseña de root" quiero decir localizar en /etc/shadow la línea parecida a:
root:$6$0UeP/qy$XzJ3Ztmd0wsNrNx1rEnnp8K2VYtHsEO1so5UN7FsfaDPEXTxImxYyKAWpeIvQrQwxNwTNjUD25gz6aVq5/:16280:0:99999:7:::
y borrar todo lo que hay entre el primer y segundo ":", quedando:
root::16280:0:99999:7:::
Con esto quedamos la contraseña de root en blanco, pudiendo entrar con facilidad.

Una vez hecho esto reiniciamos el sistema, quitando el pendrive o el CD y arrancando con el sistema en el disco. Ahora podremos entrar como root con la contraseña que hemos establecido. Como vemos, es mucho mas fácil de lo que parecía.

¿Y tú de quién eres?

Más de una vez he necesitado saber la procedencia de un fichero que encontramos dentro de nuestro sistema Debian y no se de dónde ha salido. Los pasos que sigo son:

1) Averiguar a que paquete pertenece el fichero.

Eso lo hago con:
# dpkg -S /usr/lib/x86_64-linux-gnu/libavformat.so.54
libavformat54:amd64: /usr/lib/x86_64-linux-gnu/libavformat.so.54
Como vemos, el fichero en cuestión vino con el paquete libavformat54:amd64.

Si nos dice:
dpkg-query: no se ha encontrado ningún paquete que corresponda con el patrón ....
entonces el fichero no ha venido dentro de un paquete del sistema y va a ser bastante mas complicado saber su procedencia.

2) Averiguar de dónde proviene el paquete.

Los paquetes de nuestro sistema pueden venir de distintos repositorios o haber sido instalados a mano, ¿cómo sabemos su origen?, pues con:
# apt-cache policy libavformat54:amd64
libavformat54:
 Instalados: 8:1.0.10-dmo1
 Candidato:  8:1.0.10-dmo1
 Tabla de versión:
     *** 8:1.0.10-dmo1 0
              500 http://ldap/mirrors/multimedia-wheezy/ wheezy/main amd64 Packages
              100 /var/lib/dpkg/status
Segun se ve, viene de multimedia-wheezy. En mi caso de un mirror local que hago cada noche en mi servidor "ldap". De no tener mirror su origen seria el repositorio oficial de Debian Multimedia: http://www.deb-multimedia.org/dists/oldstable/main/.

Si el paquete ha sido instalado a mano habría que busca el origen del .deb por Internet. A las malas, podemos usar dpkg-repack para "reconstruir" el paquete .deb desde el sistema donde está instalado, de tal forma que tenemos el .deb tal y como lo descargamos originalmente, con la ventaja de que podremos guardar una copia del mismo y reinstalarla cuando y donde queramos.

Bueno, pues con esto ya se de donde vino el fichero y puedo instalar el paquete que lo trajo cuando me haga falta tener el mismo fichero en otra máquina.

3) ¿Y si el fichero no está en nuestro sistema, pero queremos saber en que paquete de los repositorios está?.

Si queremos buscar un fichero en paquetes no instalados en el sistema usamos apt-file:
# apt-get install apt-file
# apt-file update
# apt-file find kwallet.h
kdelibs5-dev: /usr/include/kwallet.h
libkf5wallet-dev: /usr/include/KF5/KWallet/kwallet.h
Ojo: esto sólo buscará el fichero en los repositorios que tenemos configurados en el sources.list y sources.list.d de nuestra máquina, no mas allá.

Bueno, pues con estos consejos podremos localizar el origen de los ficheros que rulan por nuestro sistema, de igual manera que se puede hacer con la herramienta equivalente de Windows....



Y así es como tenemos identificado cualquier fichero que ande por nuestros discos duros.

martes, 13 de octubre de 2015

SimpleScreenRecorder para Debian Wheezy

Un compañero profesor me pidió buscar un software sencillo para grabar las clases capturando toda la actividad en pantalla al usar la pizarra digital en un vídeo que luego podría editar para publicarlo o revisarlo.

Estuve buscando y encontré como opción mas sencilla y completa el SimpleScreenRecorder, que incluso permite grabar el sonido. Yo lo probé en mi Linux Mint y funcionaba estupendamente. El problema vino cuando se dió cuenta de que había que hacerlo funcionar en Debian Wheezy de 64bits, que es el sistema que tenemos en las aulas.

La primera opción fue buscar versiones antiguas para Ubuntu o Mepis, pero los paquetes encontrados daban errores con las versiones de los paquetes dependientes al instalarlos en nuestro Debian Wheezy.

Podría haber intentado probar versiones de otras distribuciones Linux, convirtiéndolas con alien, pero había otra opción más divertida: compilar desde los fuentes. Los afectados de fetichindows (neopalabro formado por la fusión de conceptos "fetichismo" y "Windows") que odian-temen Linux  dicen que los linuxeros estamos todo el día compilando programas desde que amanece hasta que se pone el sol. Pues vamos a darles la razón por 10 minutos.

Tenemos este manual  para compilarlo para Debian Jessie, así que no debe ser muy distinto hacerlo para Wheezy. Vamos allá, haremos todo con un usuario regular que tenga acceso sudoer (luego podemos quitar dicho acceso). Los pasos son:

$ cd
$ wget https://github.com/MaartenBaert/ssr/archive/master.tar.gz
$ tar xfvz master.tar.gz
$ sudo dpkg --add-architecture i386
$ sudo apt-get update 
$ sudo apt-get install build-essential pkg-config qt4-qmake libqt4-dev libavformat-dev libavcodec-dev libavutil-dev libswscale-dev libasound2-dev libpulse-dev libjack-jackd2-dev libgl1-mesa-dev libglu1-mesa-dev libx11-dev libxfixes-dev libxext-dev libxi-dev g++-multilib libx11-6 libxext6 libxfixes3 libxfixes3:i386 libglu1-mesa:i386
$ cd ssr-master 
$ ./simple-build-and-install 

Bueno, pues me dio algunos errores en la primera compilación. Así que hice lo que pone en la página indicada:

$ cd /usr/lib/i386-linux-gnu
$ sudo ln -s libGL.so.1 libGL.so
$ sudo ln -s libGLU.so.1 libGLU.so
$ sudo ln -s libX11.so.6 libX11.so
$ sudo ln -s libXext.so.6 libXext.so
$ sudo ln -s libXfixes.so.3 libXfixes.so
$ sudo ldconfig
$ cd ~/ssr-master
$ ./simple-build-and-install  

De nuevo me dió error. Viendo mejor el error de compilación me encuentro con que se queja de que no encuentra un tipo de datos llamado AVPixelFormat. Una breve búsqueda en Google me dice que AVPixelFormat es de Jessie, que en Wheezy es PixelFormat, asi que busco en el código todas las apariciones:

$ cd ~/ssr-master/src
$ grep -irl AVPixelFormat * 

Y voy fichero por fichero fuente cambiando AVPixelFormat por PixelFormat. Podría haberlo hecho automáticamente mediante sed, pero tampoco eran muchos cambios. Una vez acabado, lanzamos de nuevo el proceso:

$ cd ~/ssr-master
$ ./simple-build-and-install  

Y ahora si compilaba. Al acabar nos pide contraseña del usuario para ejecutar con sudo la instalación y tachán... en unos instantes está todo instalado.

Indagando un poco sobre la instalación veo que ha copiado los siguientes ficheros:

  • El ejecutable: /usr/bin/simplescreenrecorder 
  • Las librerias:  /usr/lib/i386-linux-gnu/libssr-glinject.la y /usr/lib/i386-linux-gnu/libssr-glinject.so, haciendo un "ldconfig -n /usr/lib/i386-linux-gnu" después.
  • El fichero .desktop: /usr/share/applications/simplescreenrecorder.desktop, haciendo un update-desktop-database después para añadirlo al menú del entorno gráfico (en mi caso XFCE).
Y con esto ya está instalado. Desde el menú o desde terminal podemos ejecutar simplescreenrecorder  y se nos carga la ventana de inicio para empezar el asistente de grabación de Escritorio:


Despúes me planteé copiarlo a otras máquinas. Como todavía no me he puesto en serio a hacer paquetes Debian un poco mas complejos de lo normal, con dependencias y scripts de postinstalación  (a ver si me pongo a aprenderlo y así puedo contarlo aquí) pensé en hacer un script bash de instalación para automatizarlo un poco, pero antes me dió por copiar el ejecutable /usr/bin/simplescreenrecorder  a una máquina cualquiera y probarlo allí: carajo, funcionaba. No tengo ni idea de para que son las librerías (aunque supongo que será para integrar la funcionalidad de grabación en aplicaciones que compilemos nosotros), pero no son necesarias: con el ejecutable es suficiente.

Aquí va un enlace al ejecutable para Debian Wheezy de 64 bits, por si alguien quiere instalarlo de una forma rápida y sucia. Para ejecutarlo solo habría que abrir un terminal y lanzarlo desde allí. Si da algún error seguramente sea porque no encuentra alguna librería (fichero .so) que necesite el programa y no la tienes en tu sistema. La solución es sencilla: averigua a que paquete pertenece buscando en Internet e instálala.

Bueno, pues otro día seguimos con mas cosas.


viernes, 9 de octubre de 2015

Un blog de andar por casa

Hasta hace poco tenía recopilada información y enlaces sobre el centro en una intranet constituida por páginas web, con una estética directamente salida de los 90 que daba vergüenza ajena. Recolocando cosas me planteé buscar un CMS/Blog sencillo que pudiese montar en poco tiempo para organizar todo ese contenido y permitir la publicación sencilla y rápida de nueva información dentro de la intranet.

El objetivo era encontrar algo ligero, que no necesitase ningún extra para funcionar: ni base de datos, ni librerías, ni entornos de servidor (tipo Tomcat o algún otro monstruo hecho en Java que esté de moda ahora). Sorpresivamente me encontré una gran abundancia de sistemas de este tipo y páginas con recopilaciones como estas:
Al final, abrumado ante tanta oferta me decanté por NibbleBlog, por varias razones:
  • Para instalar simplemente se necesita descomprimir el fichero zip en /var/www/.... dentro de un servidor con Apache y PHP5 y poco más.
  • Tiene un pequeño conjunto de temas fáciles de aplicar y retocar.
  • Tiene un pequeño conjunto de plugins también sencillos instalar y adaptar si te manejas en php.
  • Los posts y las páginas publicadas se guardan en ficheros planos XML, fáciles de mantener.
La instalación es tan sencilla como bajar el .zip y descomprimirlo dentro dela ruta /var/www/.... del servidor elegido, que suponemos tendrá instalado apache2 y php5. El resultado final será este:









Tenemos una zona de publicación de posts a la derecha y a la izquierda 4 apartados fijos:
  • Una colección de enlaces permanentes. Me gustaría ser mas discreto pero la he puesto en colores chillones para que sea fácil de identificar.
  • Una serie de enlaces a páginas fijas dentro del CMS, con posts que siempre se podrán consultar.
  • Un listado con los títulos de los ultimos posts.
  • Un buscador dentro del CMS/Blog.
En el área de administración entramos con un usuario y contraseña definidos en la primera entrada al mismo, tras la instalación. La ruta para entrar en el panel de administrador es http://servidor.que.sea/carpeta-donde-esta-el-blog/admin.php.
:


Una vez dentro vemos el pequeño conjunto de opciones de configuración que hay:



Una para la publicación de posts/creación de páginas fijas/subida de vídeos, con un editor de HTML sencillo pero muy completo.



Un apartado para administrar todo lo que se ha publicado:

Un apartado para la típica configuración general del CMS:



Otro apartado para elegir el tema. Vienen 4 o 5 instalados de serie, pero se pueden instalar mas desde su página/foros, simplemente hay que bajarlos y meterlos en la carpeta themes de la ruta donde descomprimimos el zip de instalación. Yo he elegido el tema "Echo", aunque luego he tuneado un poco sus CSS .



Por último, también tenemos un apartado para añadir los plugins. Al igual que los temas, vienen varios por defecto y es fácil añadir nuevos plugins descargados de su página/foros.  En la configuración de cada plugin siempre hay un "número de orden" que nos permite definir  en que orden (de arriba a abajo) se colocarán en la parte izquierda de la pantalla. Los plugins están en PHP y son bastante fáciles de modificar.


Un plugin muy interesante es HTML Code, que permite meter código HTML arbitrario. Yo lo he usado por ejemplo para crear el menú de enlaces multicolor de la izquierda.


Y ya está, con esto he conseguido dar algo mas de glamour a una página que ve a diario todo el mundo en el centro, ya que como buen tirano tengo puesta su apertura automática al abrir sesión en el autostart de los Linux y la carpeta Inicio de los Windows.

Nos vemos pronto...

martes, 29 de septiembre de 2015

Lenovo A630/MediaTek 6577: ROM nueva, CWM recovery y reparticionado de memoria interna.


El Lenovo A630 que tenemos en casa llevaba un tiempo dando problemas: necesitaba una buena limpieza y quería aprovechar para instalar un recovery mas potente, por ejemplo el ClockWorkMod y, ya de paso, reparticionar la SD ya que con solo 512Mb de memoria para aplicaciones estaba constantemente quejándose de que se quedaba sin espacio. Vamos a ver una colección de guías y enlaces para hacer todo esto sin brickear nuestro móvil, junto con la solución de los posibles problemas que a mi se me han presentado.

Tenemos pues un Lenovo A630, equipado con un chip MediaTek MK 6577 con la siguiente ROM:

A630_S009_130510
Android 4.0.4
BANDA BASE: A630.V5, 2012/12/17 16:15

En su día ya había rooteado el móvil con ayuda de este manual de mi compañero Esteban.


1. Poner una ROM nueva y limpia.

Por "limpia" entiendo una ROM libre de aplicaciones chinas, con las Gapps y rooteada. Por desgracia la scene de cocineros de este móvil es inexistente, así que no hay mucho donde elegir. Me decanté por ésta de needrom (realmente tampoco hay muchas mas de fiar). Sus características son:

ROM Phone LENOVO A630 ROM Android 4.0.4
Based on Official ROM LENOVO A630 version: Lenovo A630_S008_130111
Gapps include - Rooted
Language support:  Multilang

Los pasos para la instalación deben realizarse en Windows, ya que las aplicaciones necesarias no están para Linux o lo están en modo beta y estas cuestiones tan delicadas no son para experimentar. Estos son:

1) Instalar los drivers para Windows del modo preloader USB VCom de Mediatek 65XX. Instrucciones aquí, es una instalación manual ya que se hace sin tener conectado el móvil al PC. El modo preloader es el modo usado para cargar las ROM en los móviles y tablets MediaTek desde un PC usando un cable USB.

2) Luego descargar la ROM elegida de http://www.needrom.com/download/lenovo-a630-2/. Una vez bajada la descomprimimos y, por comodidad, movemos el directorio entero a C:\, en la raíz de la partición Windows. Estrictamente no es necesario, pero me gusta ponerlo ahí porque a veces las rutas muy largas o con espacios me han chafado la carga de las ROM.

3) Descargar e instalar la aplicación SPFlash, que es la que usaremos para la carga de la ROM. Cualquier versión entre la 3.1320 y la 5.1452 (la última por ahora) nos servirá. Yo he usado la 3.1320. Manuales de uso de SPFlash tenemos en abundancia:

4) Cargar la ROM, siguiendo estos pasos:

  • Abrir SPFlash y elegir el archivo scatter "MT6577_Android_scatter_emmc.txt" en la carpeta de la ROM descargada en el paso 2.
  • Dentro de SPFlash, en Opciones, elegir "USB Model" y "DA Download All->Speed->High Speed"
  • Apagar el móvil y quitar la batería.
  • En SPFlash seleccionar la opción Download o Updgrade ROM Firmware. A mi la primera me daba un error al comenzar el proceso y he tenido que usar la segunda.
  • Enchufar el móvil apagado y sin batería a un puerto USB del PC.
  • Tan pronto se detecte el móvil, empezarán a aparecer barras de progreso de colores morado, amarillo, etc. Cuando todo acabe aparecerá un círculo verde indicando que se acabó. En ese momento se puede desconectar el móvil, poner la batería y encender.

Bueno, pues en la práctica a mi todos estos pasos tan sencillos siempre me han dado problemas en la última fase: en las barras de progreso tarde o temprano me aparecía un error, con mensajes bastante oscuros. Tras probar varios SPFlash distintos e intentar interpretar los errores sin éxito se me ocurrió conectarlo al puerto USB con estas 2 condiciones:

  • Una tarjeta miniSD puesta en el móvil.
  • La bateria puesta de nuevo en el móvil (la he quitado 10 segundos y luego la he vuelto a poner, sin encenderlo).

No se si ambas cosas son necesarias o no, pero sospecho que solo lo sería la segunda. También he leído testimonios de gente con otros MediaTek que pone la batería con el móvil ya enchufado al USB, o que pulsa el botón Vol- y no lo suelta hasta que la ROM esta copiada.... es decir, no hay un método universal, dependerá de nuestro aparato en cuestión.

Una vez hecho esto encendemos el móvil y tras la típica eterna espera de los primeros arranques de una ROM nueva nos saltarán el asistente de configuración de idioma, cuenta, etc. Primera fase acabada.

2. Instalar el Recovery CWM.

Hay varias formas de meter un ClockWorkMod Recovery en un teléfono MediaTek: la primera consiguiendo un fichero .img con la partición de recovery CWM ya preparada y flasheando dicha partición usando SP Flash tools. No encontraba ningún recovery de confianza para el A630, asi que utilicé otro método mas fiable: usar MTKDroidTools.

Una vez mas, mi compañero Esteban lo explica de forma sencilla.

Para no variar  he tenido varios obstáculos: el móvil no me aparecía como rooteado (el recuadro de abajo-izquierda de las MTKDroidTools estaba amarillo en lugar de verde) y al intentar seguir los pasos del enlace anterior me daba error "adbd not install", además en "Recovery y root" solo me salia la opción "seleccionar archivo boot.img" en lugar de las 3 que deberían salir.

Solución: instalar desde Google Play la aplicación busybox y ejecutarla, luego instalar a mano la aplicación "ADBD insecure" y ejecutarla para ponerla en modo "enable". Fuentes y enlaces para descargar:

Un truco que a mi no me ha hecho falta: si el teléfono no arranca después de meter el CWM recovery debemos instalar con SPFlash un boot parcheado (también se crea un recovery) que se crea en la carpeta recovery de MTKDroidTools.

Una vez instalado, apagamos el móvil y para arrancar el recovery pulsamos Vol+ y sin soltarlo apretamos el botón de power. Cuando se encienda soltamos power pero seguimos pulsando Vol+. En un instante aparecerá el texto "Recovery" en la parte inferior de la pantalla, entonces pulsamos el botón central ("Home") del teléfono y ya nos saldrá un menú CWM estándar, desde el que podremos flashear de forma sencilla, realizar wipes (borrados de configuración) y hacer copias de seguridad a la SD del equipo.

3. Hacer copia de seguridad completa con MTK DroidTools.

Desde el Recovery CWM podemos hacer copias de seguridad del sistema a la tarjeta SD, que luego podremos recuperar con el mismo recovery. Pero también es muy interesante hacer una copia de seguridad completa para restaurar con SPFlash, por si el móvil se queda tan brickeado que no nos deja ni entrar en el recovery.

Esta copia se hace con MTKDroidTools siguiendo estos sencillos tutoriales:


Es imprescindible después de realizar la copia con la opción Backup no olvidar usar la opción "Comprobar y Preparar blocks para el FlashTools" (nos pedirá elegir el fichero .md5 de la carpeta del backup que hemos hecho), lo que nos crea una carpeta "!Files_to_FlashTool" con una versión del backup apta para restaurar con SPFlash del paso 1.

4. Reparticionar para dar mas espacio a las aplicaciones.

Como en muchos móviles, la partición inicial para aplicaciones es mísera: 512Mb o menos que se llenan enseguida y hay que andar con Link2SD, int2SD y trucos por el estilo. Lo mas deseable es reparticionar y aumentar esa partición a costa de reducir el espacio para la SD Interna. Nunca entenderé esa costumbre de simular una SD con una partición de la memoria interna del móvil: a fin de cuentas es sencillo y barato poner una SD externa para almacenar las fotos y demás cosas.

Propongo dos métodos:

  1. El método usado por Esteban, le voy a tener que pagar derechos de autor.
  2. Usando HKPhone, muy sencillo si tu móvil es compatible. Se basa en usar una apk que te hace todo y funciona sin problemas en el A630, siempre que esté rooteado y tenga CWM Recovery instalado.

Yo he optado por configurar 2GB para aplicaciones y 512Mb para SD Interna, después entro en el recovery y hago un Wipe-Factory Reset. Una vez dentro del móvil, verifico que en Ajustes->Aplicaciones hay 2Gb de espacio (ahora si que será difícil llenarla) y, por último, en Ajustes->Almacenamiento le digo que guarde las cosas en la SD Externa.

Para comparar, veremos el particionamiento antes de reparticionar usando para ello la apk DiskInfo:

 Internal Storage (MMC)
--------------------------
 * ebr1 [mmcblk0p1] Not mounted
 * sec_ro [mmcblk0p2] (/system/secro) [ext4]                          Used: 5 MB, Free: 0 B, Total space: 5 MB
 * System (android) [mmcblk0p3] (/system) [ext4]                      Used: 419 MB, Free: 92,1 MB, Total space: 512 MB
 * Cache [mmcblk0p4] (/cache) [ext4]                                  Used: 17,4 MB, Free: 494 MB, Total space: 512 MB
 * Data (usrdata) [mmcblk0p5] (/data) [ext4]                          Used: 268 MB, Free: 243 MB, Total space: 512 MB
 * SD card (fat) [mmcblk0p6] (/mnt/sdcard, /mnt/secure/asec) [vfat]   Used: 109 MB, Free: 1,9 GB, Total space: 2,1 GB
 * mmcblk0boot1 [mmcblk0boot1] Not mounted
 * mmcblk0boot0 [mmcblk0boot0] Not mounted

y después de reparticionar:

 Internal Storage (MMC)
--------------------------
 * ebr1 [mmcblk0p1] Not mounted
 * sec_ro [mmcblk0p2] (/system/secro) [ext4]                          Used: 5 MB, Free: 0 B, Total space: 5 MB
 * System (android) [mmcblk0p3] (/system) [ext4]                      Used: 422 MB, Free: 89,2 MB, Total space: 512 MB
 * Cache [mmcblk0p4] (/cache) [ext4]                                  Used: 16,4 MB, Free: 495 MB, Total space: 512 MB
 * Data (usrdata) [mmcblk0p5] (/data) [ext4]                          Used: 477 MB, Free: 1,5 GB, Total space: 2 GB
 * SD card 2 (fat) [mmcblk0p6] (/mnt/sdcard2) [vfat]                  Used: 3,9 MB, Free: 563 MB, Total space: 567 MB
 * mmcblk0boot1 [mmcblk0boot1] Not mounted
 * mmcblk0boot0 [mmcblk0boot0] Not mounted


Con esto ya tenemos el móvil preparado para funcionar una temporada más.

5. Un par de cosas interesantes.


  • Si  enredando perdemos los IMEI del móvil (*) siempre podemos recuperarlos con cualquiera de estos dos métodos:

a) Usando el modo ingeniero de Mediatek. Hay aplicaciones para entrar en el modo ingeniero en el Google Play, una vez allí se usan comandos AT para fijar el IMEI, tal como cuenta, como no, Esteban aquí.

b) Más sencillo: la aplicación MTK DroidTools tiene una opción para meter los IMEI a mano directamente.

Bueno, pues a ver que me pasa está semana para contarlo la próxima.

(*) Considérate afortunado por tener un móvil MediaTek. Los que tienen chip SnapDragon y pierden los IMEI sin tener copia de seguridad de las particiones donde se guardan pueden darse por jodidos. Hay manuales de las herramientas necesarias, pero yo no he podido hacerlas funcionar correctamente y ni Qualcomm ni Xiaomi (en mi caso) te dan ninguna solución para volver a generar las particiones con sus IMEI correspondientes. Por ese motivo, mientras no se tomen en serio a sus clientes y liberen la información para regenerar los IMEI voy a pasar de comprar cualquier aparato con SnapDragon.

miércoles, 23 de septiembre de 2015

Uso de getent para consultar los netgroup


El comando getent es una forma cómoda y sencilla de consultar nuestras bases de datos de usuarios, grupos, máquinas, etc. Por ejemplo, si hacemos:
root@exmachina:~# getent passwd
Nos mostrará todos los usuarios del sistema. En principio diremos: "vaya tonteria, es como un cat  /etc/passwd". Pues no: si los usuarios están además en una BD ldap getent nos mostrará los que hay allí, sin tener que tirar de esotéricas consultas mediante ldadsearch.

Para saber donde están los datos que debe mostrar getent éste consulta el fichero /etc/nsswitch.conf:
root@exmachina:~# cat /etc/nsswitch.conf
# /etc/nsswitch.conf
#
# Example configuration of GNU Name Service Switch functionality.
# If you have the `glibc-doc-reference' and `info' packages installed, try:
# `info libc "Name Service Switch"' for information about this file.

automount:         files ldap

passwd:         compat ldap
group:          compat ldap
shadow:         compat ldap

hosts:          files mdns4_minimal [NOTFOUND=return] dns mdns4
networks:       files

protocols:      db files
services:       db files
ethers:         db files
rpc:            db files

netgroup:       files ldap
root@exmachina:~#
Como se ve, passwd está en "compat ldap", eso quiere decir que el sistema buscará los usuarios en /etc/passwd y en el servidor ldap de nuestra red. Si al llamar a getent además añadimos un parámetro nos filtrará por dicho usuario, mostrando solamente sus datos:
root@exmachina:~# getent passwd aasanchezl01
aasanchezl01:x:12568:12568:Alberto Antonio Sanchez Lara:/home/alumnos/aasanchezl01:/bin/bash
root@exmachina:~# 
Igual que passwd, con getent podemos consultar varias bases de datos mas: la de grupos de usuarios, la de hosts, etc. La que nos interesa ahora es la de netgroup. Esta base de datos permite hacer grupos de máquinas para aplicarles determinadas directivas. Por ejemplo, podemos definir un grupo de hosts llamado workstation-hosts y luego exportar mediante NFS una carpeta sólo a dicho grupo:
root@servidor-nfs:~# cat /etc/exports 
# /etc/exports: the access control list for filesystems which may be exported
..........
..........
/data/folder    @workstation-hosts(rw,async,no_subtree_check,insecure)
..........
..........
De esta manera solo las máquinas miembros de workstation-hosts pueden montar servidor-nfs:/home/folder.

La definición de los netgroups puede realizarse en el fichero /etc/netgroup (sintaxis aquí) y en el árbol ldap. En este último caso queda con este aspecto:


Si queremos consultar los netgroup definidos la orden sería "getent netgroup", pero puesta así sola da un error diciendo que esa base de datos no soporta enumeración. Eso traducido quiere decir que hay que especificar además que netgroup estamos consultando (es decir, no podemos preguntar por todos los netgroups a ciegas, debemos saber sus nombres), por ejemplo:
root@exmachina:~# getent netgroup workstation-hosts
workstation-hosts     (a01-pro, -, -) (a13-o01, -, -) (...................
root@exmachina:~#
Si hacemos la prueba veremos que saca todas las máquinas del grupo en una sola línea, en la forma de tuplas "(nombre, -, -)" que lo hacen bastante ilegible. Si queremos que saque las máquinas en líneas separadas y adicionalmente filtrar por algún valor tendremos que usar una combinacion de sed y grep. Por ejemplo:
root@exmachina:~# getent netgroup workstation-hosts |  sed 's/-)/-)\n/g' | grep a2
  (a20-pro, -, -)
  (a21-pro, -, -)
root@exmachina:~#
Se enumeran los hosts, pero en lineas separadas con el sed que convertirá "-)" en "-)\n", insertando un retorno de carro. Después se filtra para que solo salgan los hosts cuyo nombre contenga "a2". De esta forma consultamos de una forma rápida si un host está o no en un netgroup.

Este uso de sed permite dividir en líneas separadas sentencias muy largas. Por ejemplo, otro uso si tenemos un fichero de insert sql todo en una línea y queremos dividirlo en un registro por línea:
root@exmachina:~# cat aminno_member_email.dump 
INSERT INTO `member_details` VALUES (9,0,0,'1953-11-24','Speak',1,65772,173,2,1,1,5), (10,0,0,'1971-10-11','Fine',1,47628,163,1,1,1,3), (11,0,0,'1968-02-11','Help',1,38556,152,1,1,2,0), (12,0......
root@exmachina:~#
El comando sed haria una sustitución de  ",)" por ",)\n":
root@exmachina:~# sed 's/,(/,\n(/g' aminno_member_email.dump > mail.dump
Bueno, pues hasta la siguiente, :-).

martes, 15 de septiembre de 2015

Panel inmutable para todos los usuarios en XFCE

En entornos educativos/empresariales como los nuestros es muy conveniente mantener uniformes los escritorios de todos los usuarios, haciendo que sean personalizables el menor número de opciones posible.

Cuando usábamos Gnome2 teníamos los ficheros mandatory que nos permitían fijar cosas como el fondo de pantalla y varias opciones mas del escritorio. En nuestro breve paso por Gnome3 también vimos que había una manera de hacerlo.   Al pasarnos a XFCE nos llevamos la agradable sorpresa de que también existía esa posibilidad: el modo kiosco que permite bloquear configuraciones de xfconf, el gestor de configuraciones de dicho escritorio.

Básicamente consiste en meter ficheros xml (donde se almacena la configuración de XFCE) en la ruta /etc/xdg/xfce4/xfconf/xfce-perchannel-xml/, con determinadas partes bloqueadas o desbloqueadas (con los parámetros locked/unlocked). Estas configuraciones bloqueadas se impondrán siempre sobre la configuración personal del usuario almacenada en ~/.config/xfce4/xfconf/xfce-perchannel-xml/. En ambos directorios hay muchos ficheros xml, cada uno de los cuales configura determinados aspectos de nuestro entorno XFCE4.

root@servidor:~/.config/xfce4/xfconf/xfce-perchannel-xml# ls -1
displays.xml
keyboards.xml
pointers.xml
thunar-volman.xml
xfce4-desktop.xml
xfce4-keyboard-shortcuts.xml
xfce4-mixer.xml
xfce4-panel.xml
xfce4-session.xml
xfce4-settings-manager.xml
xsettings.xml 
Se puede configurar y bloquear el panel, el fondo de pantalla, el control de volumen, el volume manager del explorador de archivos y muchísimas cosas más. Las posibilidades son mucho mayores que en Gnome2 y Gnome3.

Como ejemplo vamos a ver como poner un panel (definido en el fichero xfce4-panel.xml) fijo e inmutable para todos los usuarios. Para ello cogemos un usuario de prueba y configuramos desde el entorno gráfico el panel tal como queremos quedarlo finalmente. Luego simplemente copiamos el fichero ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml a la ubicación /etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml y lo modificamos para que quede bloqueado para todo el mundo excepto para el usuario "root" (fragmento marcado en rojo).

root@servidor:/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/# cat xfce4-panel.xml
<?xml version="1.0" encoding="UTF-8"?>

<channel name="xfce4-panel" version="1.0" locked="*" unlocked="root">
  <property name="panels" type="uint" value="1">
    <property name="panel-0" type="empty">
      <property name="size" type="uint" value="36"/>
      <property name="length" type="uint" value="100"/>
      <property name="locked" type="bool" value="true"/>
      <property name="autohide" type="bool" value="false"/>
      <property name="position-locked" type="bool" value="true"/>
      <property name="plugin-ids" type="array">
        <value type="int" value="1"/>
        <value type="int" value="2"/>
        <value type="int" value="3"/>
        <value type="int" value="4"/>
        <value type="int" value="5"/>
        <value type="int" value="6"/>
        <value type="int" value="7"/>
        <value type="int" value="8"/>
        <value type="int" value="9"/>
        <value type="int" value="10"/>
        <value type="int" value="11"/>
        <value type="int" value="12"/>
      </property>
      <property name="horizontal" type="bool" value="true"/>
      <property name="position" type="string" value="p=10;x=0;y=991"/>
      <property name="leave-opacity" type="uint" value="80"/>
      <property name="enter-opacity" type="uint" value="100"/>
      <property name="background-style" type="uint" value="1"/>
      <property name="background-color" type="array">
        <value type="uint" value="38053"/>
        <value type="uint" value="38053"/>
        <value type="uint" value="38053"/>
        <value type="uint" value="65535"/>
      </property>
    </property>
  </property>
  <property name="plugins" type="empty">
    <property name="plugin-1" type="string" value="whiskermenu">
      <property name="show-menu-icons" type="bool" value="true"/>
      <property name="show-button-title" type="bool" value="true"/>
      <property name="custom-menu-file" type="string" value=""/>
      <property name="button-icon" type="string" value="linex-icon"/>
      <property name="button-title" type="string" value="Inicio"/>
      <property name="custom-menu" type="bool" value="false"/>
    </property>
    <property name="plugin-2" type="string" value="separator">
      <property name="style" type="uint" value="1"/>
    </property>
    <property name="plugin-3" type="string" value="showdesktop"/>
    <property name="plugin-4" type="string" value="launcher">
      <property name="items" type="array">
        <value type="string" value="system-config-printer.desktop"/>
      </property>
    </property>

    <property name="plugin-5" type="string" value="launcher">
      <property name="items" type="array">
        <value type="string" value="google-chrome.desktop"/>
      </property>
    </property>
    <property name="plugin-6" type="string" value="launcher">
      <property name="items" type="array">
        <value type="string" value="rayuela.desktop"/>
      </property>
    </property>
    <property name="plugin-7" type="string" value="places"/>
    <property name="plugin-8" type="string" value="actions"/>
    <property name="plugin-9" type="string" value="tasklist">
      <property name="grouping" type="uint" value="0"/>
      <property name="include-all-workspaces" type="bool" value="false"/>
      <property name="flat-buttons" type="bool" value="false"/>
      <property name="show-handle" type="bool" value="true"/>
    </property>
    <property name="plugin-10" type="string" value="systray">
      <property name="show-frame" type="bool" value="false"/>
      <property name="rows" type="uint" value="1"/>
    </property>
    <property name="plugin-11" type="string" value="gnome-sound-applet"/>
    <property name="plugin-12" type="string" value="datetime"/>

  </property>
</channel>
Al ser XML no es muy legible (tampoco importa mucho, ha sido generado automáticamente al configurar el panel con el entorno gráfico), pero mas o menos se puede ver que  se define el tamaño, el orden de los plugins y el color de fondo. Posteriormente se definen los plugins que formarán parte del panel:
  1. Menú Whisker.
  2. Separador.
  3. Botón de "Mostrar escritorio".
  4. Lanzador system-config-printer.desktop (este lanzador y los siguientes deben estar definidos en /usr/share/applications/, como cualquier otro fichero .desktop ), para abrir la aplicación de gestión de impresoras.
  5. Lanzador google-chrome.desktop, para abrir Google Chrome.
  6. Lanzador  rayuela.desktop, para abrir directamente la página de Rayuela.
  7. Plugin "Lugares", con accesos directos a las carpetas más comunes. Necesita que instalemos previamente el paquete xfce4-places-plugin.
  8. Plugin "Actions", para botón de salida de sesión.
  9. Plugin "Tasklist", para mostrar la lista de ventanas abiertas.
  10. 11. 12....  Fecha, control de volumen, etc.
Al principio del todo, las líneas:
locked="*" unlocked="root"
Hacen que todo lo que cuelgue de ese nodo XML esté bloqueado para todo el mundo excepto para el usuario root, de tal forma que no podrá modificarse. Podemos especificar grupos de usuarios anteponiento  "@" y poner varios separándolos por ";", por ejemplo:
locked="*" unlocked="root;@teachers;usuario01"
El panel estará bloqueado para todos, excepto para root, los miembros del grupo "teachers" y el usuario "usuario01".

Al aplicar el locked/unlocked un "channel" afecta a todo lo contenido dentro de él. Cuando se aplica sobre una "property" solo afecta a dicha property, no a las que estén dentro de ella.

El resultado final es algo así como:
 

Este panel será inmodificable por el usario y aparecerá con ese aspecto a todos los usuarios que hagan login en la máquina donde se ha configurado, imponiéndose sobre sus configuraciones particulares. Con ayuda de puppet podemos distribuirlo a todas las máquinas que queramos.

Si queremos que un usuario pueda modificar el panel, simplemente hay que añadir su nombre de usuario en el atributo unlocked del XML.

Para finalizar un par de cosas: mostramos el contenido de /usr/share/applications/rayuela.desktop, ya que no viene por defecto en nuestras distribuciones:

~ # cat rayuela.desktop 
[Desktop Entry]
Version=1.0
Name=Rayuela
Comment=Aplicación Rayuela
Exec=google-chrome http://rayuela.educarex.es
Terminal=false
Icon=/usr/share/icons/hicolor/64x64/apps/rayuela.png
Type=Application
Categories=Network;WebBrowser;
MimeType=text/html;text/xml;application/xhtml_xml;image/webp;x-scheme-handler/http;x-scheme-handler/https;x-scheme-handler/ftp;
X-Ayatana-Desktop-Shortcuts=NewWindow;NewIncognito

El icono rayuela.png usado es este:

Otra cosa que quiero comentar es la configuración del plugin Places. Como se puede ver tengo varias carpetas que quiero que siempre estén accesibles para el usuario desde allí (y desde el explorador de archivos Thunar, ya que usa el mismo fichero de configuración). El fichero usado por Places es ~/.gtk-bookmarks y tiene el siguiente contenido:

~ # cat .gtk-bookmarks
file:///home/aulas
file:///home/instituto
file:///media/salaprofesores
file:///media/escaner
file:///media/docprofesorado
file:///media/filmoteca

Siendo todas distintas carpetas de red montadas en el /etc/fstab de la máquina. Si queremos que se aplique a todos los usuarios una alternativa es copiar este .gtk-bookmarks a todos sus home. Otra opción mas cómoda es configurarlo de una manera centralizada, por ejemplo en la carpeta de red de acceso libre /home/instituto :

~# ls -l /home/instituto/comunes/.gtk-bookmarks.sprof
-r--r--r-- 1 root teachers 146 jul 17 13:14 /home/instituto/comunes/.gtk-bookmarks.sprof

Para conseguir  que todos los usuarios que hagan login en una máquina tengan su ~/.gtk-bookmarks apuntando a /home/instituto/comunes/.gtk-bookmarks.sprof lo que hago es meter el siguiente script en el arranque de la sesión X:
~# cat /etc/X11/Xsession.d/99session_tasks
#!/bin/bash
#Irá en /etc/X11/Xsession.d
#El nombre no es al azar, debe ser: XXcustom_script, sin extensiones, sino Xsession no lo procesa.
#Meter aqui cosas a realizar en cada inicio de sesión
#Crea un acceso a la lista de carpetas estándar para que se muestren en thunar y en el plugin lugares del panel.

ln -sf /home/instituto/comunes/.gtk-bookmarks.sprof $HOME/.gtk-bookmarks
Nota 8/2/2016: lo anterior era para Wheezy. En Ubuntu Trusty los bookmarks se guardan adicionalmente en la ruta $HOME/.config/gtk-3.0/bookmarks, por lo que el script debería ser:
~# cat /etc/X11/Xsession.d/99session_tasks
#!/bin/bash
#Irá en /etc/X11/Xsession.d
#El nombre no es al azar, debe ser: XXcustom_script, sin extensiones, sino Xsession no lo procesa.
#Meter aqui cosas a realizar en cada inicio de sesión
#Crea un acceso a la lista de carpetas estándar para que se muestren en thunar y en el plugin lugares del panel.

ln -sf /home/instituto/comunes/.gtk-bookmarks.sprof $HOME/.gtk-bookmarks
ln -sf /home/instituto/comunes/.gtk-bookmarks.sprof $HOME/.config/gtk-3.0/bookmarks
De esta manera, aun cuando el usuario borrase o manipulase su .gtk-bookmarks, en el siguiente inicio de sesión se restauraría. Adicionalmente en /home/instituto/comunes podemos ubicar varios .gtk-bookmarks.xxx para usar en función de la máquina y/o el usuario.

Bueno, pues el resto de ficheros XML de xfce4 se configurarían de forma similar. Solo hay que probar e investigar que demonios se configura dentro de cada uno y tendremos un escritorio totalitario y dictatorial que haría las delicias del Amado Líder:


Hasta la próxima, tovariches.

martes, 8 de septiembre de 2015

OpenWrt: repetidor de redes wifi con los router Astoria ARV7518 y ARV4158 de ya.com.

Ya prometí en su día continuar con OpenWrt. Como lo prometido es deuda y un Lanister siempre paga sus deudas, aquí estamos.

Despues del proyecto con un servidor usbip basado en un router Astoria ARV7158PW de ya.com, seguía teniendo otro ARV7518 (blanco) y además un ARV4518 (gris oscuro). Quería hacer con en ellos un repetidor wifi para extender un par de señales wifi que me llegaban débiles en dos ubicaciones.

Sobre este tema de la repetición/extensión de señales wifi existe una gran confusión que al final se me ha contagiado. Voy a intentar exponer lo que creo que tengo claro:

  • El repetir/extender una señal wifi puede hacerse con el mismo BSSID y contraseña o bien con una BSSID (y opcionalmente contraseña) distinta. Depende del método elegido.
  • El WDS permite extender una red wifi pero los dos routers deben ser compatibles (a veces misma marca, modelo y firmware) y usar cifrado WEP. Es  por tanto un método quisquilloso e inseguro.
  • Hay dispositivos repetidores que se pueden comprar por unos 20-30 euros, que se conectan a un enchufe de corriente, se configuran mediante un interfaz web y ya está. Esa es la forma fácil.
  • La forma divertida es utilizar OpenWRT sobre un router abandonado. Dependiendo de la tarjeta de red que tenga, se puede hacer de dos maneras:
  1. Si tiene una tarjeta de red Atheros, se puede usar el método del pseudo-bridge con el paquete relayd, que es el que usado yo en este tutorial.
  2. Si tiene una tarjeta Broadcom u otra marca, o bien Atheros y no queremos usar pseudo-bridge tenemos que pinchar un dispositivo wifi USB en el puerto correspondiente del router, que servirá para repetir/extender la señal que llegue por la tarjeta wifi propia del router. Necesitamos por tanto un dispositivo wifi USB extra compatible con OpenWRT y programar el encaminamiento entre ambas tarjetas de red.

Como he adelantado, voy a usar el método del pseudo-bridge con relayd, aprovechando que ambos routers Astoria tienen tarjeta Atheros (eso se ve en la página de http://wiki.openwrt.org dedicada a cada router).

1. Instalación de OpenWRT

Si ya tenemos cargado OpenWRT o bien el router no es de este tipo, podemos saltarnos este apartado.

El primer paso es cargar OpenWRT en ambos routers. Eso está sobradamente explicado en mi entrada previa y en estás páginas:


Conviene leerse todo varias veces para tener claro todo el proceso, la carga de OpenWrt en estos routers no es trivial. Además hace falta conseguir un conversor TTL-USB para conectar via puerto serie en los pines de la placa base del router y poder cargar el firmware desde minicom u otra utilidad de comunicación por puerto serie.

A la hora de cargar OpenWRT tenemos que decantarnos por el firmware mas adecuado posible. Después de múltiples pruebas puedo decir que los que mejor me han funcionado cotidianamente y a la hora de instalar/actualizar luego desde los repositorios de software de OpenWRT son:

  1. Attitude: mas estable, pone la wifi a 3db maximo
  2. Barrier: un pelín menos estable, pero pone la wifi a 20db. Es la que aconsejo: https://downloads.openwrt.org/barrier_breaker/14.07/lantiq/xway/openwrt-lantiq-xway-ARV7518PW-squashfs.image

El hilo de referencia para cualquier duda y problema es éste del foro Seguridad Wireless. Aquí vienen explicados todos los problemas, hay enlaces en abundancia y siempre te echan una mano si te pasa algo inesperado.

Recordemos que, de forma general, tras instalar OpenWRT el router queda iempre configurado con la IP 192.168.1.1 y podemos conectar a el por cable ethernet usando el comando telnet sin contraseña. En la primera conexión es conveniente dar una contraseña al usuario root y a partir de entonces las conexiones se harán con ssh.

2. Configurar el repetidor.

Ya tenemos OpenWRT y nuestro router tiene tarjeta de red wifi Atheros, así que vamos a configurarla como repetidor. Hay varios métodos, mis fuentes han sido:

Tras leer lo anterior y ver las distintas posibilidades me decidí por usar el método de pseudo-bridge con relayd, ya que mis  router  tienen una sola tarjeta de red. Este método hace que con una sola tarjeta y antena wifi podamos "levantar" dos tarjetas de red virtuales: una recibe la señal como cliente wifi conectado a la red remota y la otra crea un punto de acceso (con un BSSID nuevo) que reemite la señal con mas potencia de la que llega. Ambas tarjetas se conectan entre sí con el software relayd.

La documentación disponible sobre relayd que he consultado es:
Los pasos preliminares son instalar el paquete relayd y wireless-tools. Para toda la configuración tenemos que conectar con cable de red el router con un PC y usar la conexión ssh para introducir los comandos y configuraciones.

root@OpenWrt:/root# opkg update
root@OpenWrt:/root# opkg install wireless-tools
root@OpenWrt:/root# opkg install relayd
root@OpenWrt:/root# /etc/init.d/relayd enable
Con wireless-tools se nos instalan dos comandos muy útiles:
  • iwconfig: que nos muestra la configuración de las tarjetas wifi, si están conectadas y en que modo están funcionando.
  • iwlist: comando que nos muestra una lista de las redes wifi detectadas, para que veamos si nos llega la red que queremos repetir. Este escaneo de las señales wifi se hace con:
root@OpenWrt:/root# iwlist wlan0 scan
Veamos ahora como configurar los diferentes ficheros que entran en juego, esto lo podemos hacer con un editor de textos sencillo como nano o vi. Antes de nada aclarar dos cosas:
  • Suponemos que la red wifi a la que nos queremos conectar tiene IP en el rango 192.168.1.X y el router wifi principal tiene la IP 192.168.1.1 y activo el servidor DHCP, mientras que la tarjeta wifi de nuestro router con OpenWRT se configurará con la IP 192.168.1.254
  • La tarjeta ethernet de nuestro router se configurará con la IP 192.168.10.1, para que no esté en el mismo rango que la red wifi. Eso quiere decir que una vez establecida está IP para conectarnos al router por cable tendremos que usar una dirección del rango 192.168.10.X en la tarjeta de red del PC usado.
Empezamos con etc/config/network:

root@OpenWrt:/etc/config# cat network
config interface 'loopback'
 option ifname 'lo'
 option proto 'static'
 option ipaddr '127.0.0.1'
 option netmask '255.0.0.0'

config interface 'lan'
 option ifname 'eth0'
 option type 'bridge'
 option proto 'static'
 option ipaddr '192.168.10.1'
 option netmask '255.255.255.0'
        option gateway '192.168.1.1'
        option dns   '192.168.1.1'

config interface 'wwan'
 option proto 'static'
        option ipaddr '192.168.1.254'
        option netmask '255.255.255.0'
        option gateway '192.168.1.1'

config interface 'stabridge'
        option 'proto' 'relay'
        option 'network' 'lan wwan'
        option ipaddr '192.168.1.254'

Repetimos para que quede claro: la tarjeta de red cableada se configura con la ip 192.168.10.1, para que no entre en conflicto con la red inalámbrica, que está en el rango 192.168.1.X.  De ese rango, el router principal estará en 192.168.1.1 y nuestro router repetidor tendrá la IP 192.168.1.254 en su tarjeta wifi. En el caso de que nuestra wifi trabaje con otros rangos nos toca adaptar todo a esos rangos.

Seguimos por /etc/config/dhcp:
root@OpenWrt:/etc/config# cat dhcp

config dhcp 'lan'
 option interface 'lan'
 option start '100'
 option limit '150'
 option leasetime '12h'
 option ignore '1'

config dhcp 'wan'
 option interface 'wan'
 option ignore '1'
 option ipaddr '192.168.1.254'

Como se puede ver, desactivamos el servidor dhcp en todos los dispositivos de nuestro router, debido a que el servidor dhcp que se usará será el que trae el router principal.

A continuacion vemos /etc/config/wireless:
root@OpenWrt:/etc/config# cat wireless 

config wifi-device 'radio0'
 option type 'mac80211'
 option hwmode '11g'
 option path 'pci0000:00/0000:00:0e.0'
 option htmode 'HT20'
 option disabled '0'
 option channel '1'
 option txpower '30'
 option country 'ES'

config wifi-iface
 option network 'wwan'
 option encryption 'psk'
 option device 'radio0'
 option mode 'sta'
 option bssid '20:08:E0:1A:EF:00'
 option key '023AB82VBT207E'
 option ssid 'RED_PPAL'

config wifi-iface
        option device 'radio0'
        option mode 'ap'
        option ssid 'RED_PPAL_EXT'
        option encryption 'psk'
        option key '021FC3DABDEFF9'
        option network 'lan'
Comentemos, porque aquí está lo importante:

Las partes en rojo serían las que se deben modificar para adaptar a nuestro caso.
  • En la primera parte configuramos el interfaz de red "radio0" en modo "sta", es decir, cliente de una red llamada RED_PPAL, con el BSSID 20:08:E0:1A:EF:00 y la contraseña especificada allí. Su canal de emisión es el 1. Estos datos los podemos haber sacado con el comando "iwlist wlan0 scan"
  • En la segunda parte configuramos el mismo interfaz "radio0" ahora como "ap", es decir punto de acceso que emite una red llamada RED_PPAL_EXT con la contraseña indicada.
  • Ambas redes están conectadas entre si por "relayd" con la configuracion que pusimos en /etc/config/network en el apartado que reproduzco a continuaciónor:
    config interface 'stabridge'
            option 'proto' 'relay'
            option 'network' 'lan wwan'
            option ipaddr '192.168.1.254' 
  • Para generar un archivo wireless inicial que nos sirva de esqueleto con las opciones básicas podemos usar el comando:
root@OpenWrt:/etc/config# wifi detect > /etc/config/wireless

Despues de todo esto podemos reiniciar el router o bien hacer:
root@OpenWrt:/etc/config# wifi restart
root@OpenWrt:/etc/config# /etc/initd.d/network reload

Para que se apliquen todos los cambios. Una vez hecho todo podemos hacer un ifconfig para ver si todas las IP están bien:

root@OpenWrt:/etc/config# ifconfig
br-lan    Link encap:Ethernet  HWaddr 00:00:83:89:C0:00  
          inet addr:192.168.10.1  Bcast:192.168.10.255  Mask:255.255.255.0
          inet6 addr: fe80::200:83ff:fe89:c000/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:3675589 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3947947 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:171524389 (163.5 MiB)  TX bytes:1227898183 (1.1 GiB)

eth0      Link encap:Ethernet  HWaddr 00:00:83:89:C0:00  
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:262442 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2985540 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:15931319 (15.1 MiB)  TX bytes:126165971 (120.3 MiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

wlan0     Link encap:Ethernet  HWaddr 74:31:70:E3:C5:2C  
          inet addr:192.168.1.254  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::7631:70ff:fee3:c52c/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:3969028 errors:0 dropped:0 overruns:0 frame:0
          TX packets:9536355 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:1289510975 (1.2 GiB)  TX bytes:656004708 (625.6 MiB)

wlan0-1   Link encap:Ethernet  HWaddr 76:31:70:E3:C5:2C  
          inet6 addr: fe80::7431:70ff:fee3:c52c/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:3418118 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3950724 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:207491261 (197.8 MiB)  TX bytes:1296309014 (1.2 GiB)

Con iwconfig veremos que las dos tarjetas de red wifi virtuales están en el modo correcto y si vemos el espacio radioeléctrico con un dispositivo wifi (un móvil con Wifi Analyzer, por ejemplo) nos aparecerá  con una potencia estupenda la nueva red RED_PPAL_EXT a la que podremos conectarnos y ver que recibimos una IP sumistrada por el router wifi principal y que nos conectamos a la red que comparte éste sin problema.

Y con esto acaba el artículo de OpenWRT. Si encontrase alguna otra cosa interesante más que se pueda hacer le dedicaré otro artículo....

Addenda 28/Julio/2017: hubo una pequeña cosa (comentada en los enlaces referenciados) que se me pasó comentar y que luego he tenido que implementar varias veces. Siempre se me olvidaba anotarlo aquí y siempre perdía un rato recordando el paso que faltaba. De hoy no pasa que lo apunte.

Es un problema con el firewall de OpenWrt: si lo dejamos tal cual viene de serie corta el tráfico entre lan y wwan, por lo que conectamos a la red wiri nueva y recibimos IP, pero no deja navegar. La solución es sencilla: o deshabilitamos el firewall o, menos bruto, permitimos el tráfico entre ambas redes. Para permitir el tráfico hay que editar /etc/config/firewall y modificarlo así (en negrita la parte que seguramente tengamos que tocar/añadir):
.....
.....
config 'zone'
 option 'name' 'lan'
 option 'input' 'ACCEPT'
 option 'output' 'ACCEPT'
 option 'forward' 'ACCEPT'
 option 'network' 'lan wwan'
.....
.....
Después reiniciamos el firewall y ya funcionará bien todo:
root@OpenWrt:/# /etc/init.d/firewall restart
Con esto ya tenemos configurado nuestro Astoria, un pequeño gran router que nos está dando un servicio tremendo.