Archivos en la categoría 'Linux'

Hacking La Fonera

Jueves, Noviembre 30th, 2006

Pues bien, al final sucumbí al atractivo del chisme y me he pedido uno para jugar un poco entre sus entrañas. Para el que no conozca el movimiento fon, decir que es un movimiento que casi regala buenos routers configurados por ellos para que compartas ese ancho de banda que casi nunca llegamos a usar.

La fonera actual, pequeña y blanca, incorporta un ‘firmware’ basado en una distribucion de Linux para puntos de acceso y routers llamada OpenWrt que incluye entre otras cosas un extenso iptables. Por desgracia los accesos al router van cortados por defecto (e imagino que si de FON dependiese permanecerían así) pero hay algunos trucos que nos permiten activar dropbear (un mini sshd) como el puerto serie que incorpora dentro de la misma.

1. La Fonera físicamente.

La fonera se compone internamente de:

  • Chipset Atheros AR2315 construido en CMOS tech (bajo el disipador soldado).
  • 16Mb de memoria SDRAM (chip grande junto a la zona enjaulada).
  • 4Mb 8Mb de Flash rom (chip pequeño situado a la inversa de la ram, 16 patillas con una pegatina indicando la versión del firmware inicial, en teoria inamovible).
  • Linux 2.4.32 (compilación #10 x)
  • OpenWrt modificado por FON (en la flash).

El chipset de atheros es realmente todo el sistema. En un mismo circuito integrado atheros ha integrado nada menos que un procesador de 32bits MIPS de clase R4Kc a una velocidad de reloj que aun no he logrado determinar (183.50 BogoMIPS), wireless IEEE 802.11b y 802.11g, QoS integrado, red 10/100 Ethernet, buses para dispositivos de memoria SDRAM y Flash y un bus PCI 2.3. También creo que incluye una memoria rom de lectura y escritura en donde almacena los cambios realizados al SO inicial y otra para los parametros de arranque y el nucleo linux.

Esto hace que la union del chipset con una memoria ram resulte en toda una computadora. Además, la memoria flash de 4Mb contiene el SO original que se carga en un disco de memoria ram al arranque de la fonera. Despues monta la memoria interna del chip atheros en /jffs. Este directorio es el que se usa para guardar todo lo que se cambie en el sistema raiz (configuraciones, etc.) ya que en la flash no se puede por ser solo de lectura.

Debido a esto, es posible devolver la fonera a su estado inicial simplemente borrando el contenido de /jffs o pulsando el boton inferior a la fonera mas o menos durante >15 segundos siempre que la actualización de firmware no haya sido mediante el ‘flasheo’ de la fonera. En mi caso, la versión del firmware que me vino era el 0.7.0 rc4.

2. Accediendo.

El primer método es conectar el puerto série a un ordenador con un adaptador ttl max232 y un cliente como hyperterminal (windows) o minicom (*nix). Ya que no he probado este método no voy a explicarlo aqui. Existen muchos manuales sobre como hacerlo en google.

El segundo es inyectar código en la página de configuración del router de tal manera que lo ejecute como codigo de shell con permisos de root. Para ello hay que guardar estos dos códigos: paso1.html y paso2.html (boton derecho – guardar como).

Nota: Debido a la correcion de este fallo en la actualización 0.7.1 r1, este método deberá de realizarse después de haber reseteado la fonera (15 segundos de botón) y sin conectarla a internet (de hacerlo se actualizaría y no nos serviría).

Cuando tengamos ambos archivos, conectaremos a la red privada de nuestra fonera (con cliente dhcp hablitado en nuestra máquina) y ejecutaremos paso1.html en nuestro navegador. Al pulsar Enviar enviará a nuestra fonera una instrucción para que abra el puerto 22 (sshd). Si sale bien, veremos codigo html (no preocuparse por el permision denied).

Seguidamente, abriremos el paso2.html y volveremos a pulsar Enviar, lo que hará que la fonera ejecute /etc/init.d/dropbear, un mini servidor ssh. Otra vez, no preocuparse por el código html (e importante, no cerrar la pagina, ya que de hacerlo dropbear dejaría de ejecutarse).

Ahora ya podemos acceder a nuestra fonera mediante ssh (o putty en windows). El usuario es ‘root’ (no hay mas) y la contraseña por defecto es ‘admin’. Este método funcionaba hasta la versión 0.7.0 r4 y ha sido corregido en la versión 0.7.1 r1, junto a la que se ha añadido soporte multilingüe en la configuración web y soporte de direccionamiento de puertos, dos funciones muy esperadas, ademas de cliente ntp (la fonera no guarda la hora) .

Si no queremos tener que repetir los pasos 1 y 2 cada vez que queramos acceder a la fonera, tenemos que editar con vi el archivo /etc/firewall.user y descomentar las siguientes lineas:

### Open port to WAN
## — This allows port 22 to be answered by (dropbear on) the router
iptables -t nat -A prerouting_rule -i $WAN -p tcp –dport 22 -j ACCEPT
iptables -A input_rule -i $WAN -p tcp –dport 22 -j ACCEPT

Y ejecutar dicho script:

# /etc/firewall.user

Ahora que ya tenemos el puerto 22 abierto para poder conectar, haremos que dropbear se ejecute automáticamente en cada inicio con:

# ln -s /etc/init.d/dropbear /etc/init.d/S50dropbear

Ahora nuestra fonera ya está abierta :)

Site original del hack.

Version 2 (funciona en 0.7.1 r1)

Todos los pasos exactamente iguales, pero usando estos paso2-1.html y paso2-2.html.

3. La auto-actualización.

Entre las ‘features’ que incluye la fonera para hacernos la vida ‘fácil’ hay un script que se ejecuta cada cierto tiempo aleatoriamente o al iniciar la fonera (lo que antes suceda). Este script se llama thinclient y está en /bin. Como consejo recomiendo desactivarlo y comprobar siempre que hay en cada actualizacion antes de actualizar manualmente.

Esta actualización se realiza con la ejecución de código remotamente por parte de fon en nuestra fonera. El programa thinclient accede periodicamente a los servidores de fon y descarga las instrucciones a ejecutar en /tmp/.thinclient.sh.

Para deshabilitar la ejecución remota de código, editamos el archivo /bin/thinclient y cambiamos la última linea:

. /tmp/.thinclient.sh

por:

if [ ! -f /tmp/.thinclient.sh.tmp ]; then
touch /tmp/.thinclient.sh.tmp
fi
if [ "$(cat /tmp/.thinclient.sh)" != "$(cat /tmp/.thinclient.sh.tmp)" ]; then
cp /tmp/.thinclient.sh /tmp/.thinclient.sh.tmp
cp /tmp/.thinclient.sh /tmp/thinclient.sh-$(date ‘+%Y.%m.%d-%H:%M’)
fi

De este modo cada vez que quiera ejecutar algo, en lugar de hacerlo, nos guardará el código que quería ejecutar en un archivo renombrado por fecha.

Como ejemplo de lo que hace fon para ejecutar código remotamente:

cd /tmp
wget http://download.fon.com/firmware/update/0.7.0/4/upgrade.fon
/bin/fonverify /etc/public_fon_rsa_key.der /tmp/upgrade.fon
rm -f /tmp/.thinclient.sh
exit

Este código ejecutado en nuestra fonera actualizaría el firmware automáticamente al mas actual, el 0.7.1 r1. También se ejecuta código remotamente cuando cambiamos cualquier parámetro de nuestra fonera a través de la página web de fon, como el essid o la cantidad de ancho de banda que vamos a compartir.

Ya que la memoria flash no puede ser escrita, la actualizacion (es decir, cambios sobre la raiz base de la flash) se guardan en /jffs, lo que significa que borrando /jffs restauraríamos no solo la configuración actual sino también el firmware original.

La actualización 0.7.1 r1 no flashea la flash, tan solo cambia algunos archivos de nuestro sistema que pueden ser borrados en /jffs para reiniciar al firmware original.
Ha habido una versión de firmware que ha estado muy poco tiempo disponible (aun descargable) que si que flasheaba la memoria, con una imagen defectuosa. Los que actualizaron con este firmware se han quedado sin fonera a menos que reflasheen (posiblemente desoldando la flash).

En el script de upgrade del firmware fonera_0.7.1.1.fon encontramos esencialmente:

echo “Kernel image…”
mtd -e vmlinux.bin.l7 write kernel.lzma vmlinux.bin.l7 > /dev/null 2> /dev/null
rm kernel.lzma
echo “Rootfs image…”
mtd write rootfs.squashfs rootfs > /dev/null 2> /dev/null
echo “Rebooting…”

De modo que esta es la forma de flashear la memoria.

4. Archivos .fon

Los archivos de extensión .fon son los archivos que contienen las actualizaciónes que fon publica. He leido por ahí que se tratan de archivos encriptados y/o cifrados. Nada mas lejos de la realidad. El script /bin/fonverify nos da una idea de como se contruyen estos archivos que son tansolo una imagen con varios archivos que podemos ‘extraer’. Estos son:

  • Tipo de Archivo binario.
  • Offset del binario.
  • Firma del archivo binario.
  • Archivo comprimido .tar.gz

Tipo de Archivo: Para la fonera este archivo puede contener dos palabras, FON3 y FON4. Si tiene el indicador FON3 significa que el archivo comprimido tar.gz contiene una imagen para reprogramar la memória flash. El indicador FON4 significa que es un ‘hotfix’ o parche sobre el sistema actual. Las actualizaciones FON3 no tienen posibilidad de regresión al estado anterior de la actualización (a menos que consigas el firmware por tu cuenta y reflahees), mientras que las actualizaciónes que lleven FON4 si que se puede fácilmente con el reset >15seg o con rm -rf /jffs/*.

Offset: Es un parámetro utilizado para la posterior extracción del archivo comprimido.
Firma del archivo binario: Es una clave generada por fon en base al archivo para comprobar la autenticidad de la procedencia del archivo. Realmente no es necesario comprobar la firma para actualizar o meter lo que queramos.

Archivo comprimido tar.gz: Este es el archivo que contiene todo lo necesario para la actualización. Dentro caben destacar dos archivos, uno de texto llamado hotfix que contiene información sobre el paquete (nombre, versión, arquitectura, dependencias e incompatibilidades) y un shellscript que se llama upgrade, el cual ejecuta los comandos necesarios para actualizar el sistema.

Para extraerlo todo en un directorio, he montado este pequeño shellscript que podemos emplear tanto en nuestro ordenador como en la fonera:

#!/bin/sh
# .fon files extractor
# KaR]V[aN GPL
dd if=$1 of=TipoActualizacion bs=1 count=4 > /dev/null 2>&1
VERSION=$(cat TipoActualizacion)
if [ "$VERSION" = "FON3" ]; then
echo “Esta actualizacion es de tipo FON reflash v2″
elif [ "$VERSION" = "FON4" ]; then
echo “Esta actualizacion es de tipo FON parche v2″
else
echo “No reconozco el tipo de actualizacion”
exit
fi
echo “Extrayendo el Offset..”
dd if=$1 of=Offset bs=1 count=3 skip=4 > /dev/null 2>&1
OFFSET=$(expr $(cat Offset))
if [ $OFFSET -eq 0 ]; then
echo “Error: offset demasiado pequeño”
exit
fi
echo “Extrayendo la Firma del archivo..”
dd if=$1 of=Firma bs=1 count=$OFFSET skip=7 > /dev/null 2>&1
TO_SKIP=$(expr $OFFSET + 7)
echo “Extrayendo el archivo comprimido de actualización..”
dd if=$1 of=$(basename $1 | sed ’s/….$//’).tgz bs=1 skip=$TO_SKIP > /dev/null 2>&1

Simplemente hay que ejecutar el script con el nombre del archivo.fon como argumento y el script hará el resto.

X. Cosillas.

  • En la actualización 0.7.1 r1 fon ha añadido funcionalidad de hora en nuestra fonera con un cliente ntp. Cada vez que iniciamos la fonera, el script que ejecuta el cliente ntp se añade a si mismo en el crontab incondicionalmente. El resultado es que si reinicias de forma habitual el router o se te va la luz, en el crontab acabará por haber muchas entradas llamando aleatoriamente al cliente ntp creando un peligro de que el ntp esté en constante ejecución.
  • Por ahí he leido que la foner planea funcionar como el airport de apple que permite reproducir música a través de la wifi en un equipo de sonido que vaya conectado directamente a el, así como tener disco duro o memoria flash conectada por usb para descargar directamente en ella. No se si estas características que anuncian son de viejas noticias y/o rumores, ya que la fonera no tiene ni salida de audio ni de usb, aunque si que tiene curiosas zonas de soldadura en la placa principal.
  • El disipador que incluye no me convence para la disipación del calor generado por el microcontrolador atheros ya que si lo tocas despues de un par de horas funcionando este quema. No he logrado encontrar el rango de temperaturas idóneo para el buen funcionamiento, pero creo que lo excede por poco o lo roza muy de cerca.

Denegación P2P en LAN

Lunes, Noviembre 27th, 2006

Debido a un uso excesivo de la banda de subida a internet en la red de mi casa, me vi obligado a denegar cualquier p2p que procediese del ordenador de mi hermana.

Encontré un módulo para iptables de tipo MATCH que me identifica perfectamente los paquetes pertenecientes a cualquiera de los siguientes clientes p2p:

  • KaZaA
  • Gnutella
  • eDonkey/eMule/Overnet
  • BitTorrent
  • Direct Connect
  • AppleJuice
  • WinMX
  • SoulSeek
  • Ares

La fuente del módulo la podemos encontrar en su pagina oficial. Lo descargamos, descomprimimos y compilamos (hay que tener la fuente de la version de iptables que estemos utilizando):

# tar xvfz ipp2p-.tar.gz
# make
# cp ipt_ipp2p.ko /lib/modules/$(uname -r)/
# cp libipt_ipp2p.so /lib/iptables
# depmod -ae
# modprobe ipt_ipp2p

Si todo nos ha ido bien, ahora tendremos el módulo correctamente instalado en nuestro sistema. A continuación solamente tenemos que poner la regla que mas nos convenga segun nuestra situación.

En mi caso solamente necesitaba denegar a un solo ordenador, así que combiné ipp2p con coincidencia de dirección física MAC, quedando así:

iptables -A FORWARD -m mac –mac-source XX:XX:XX:XX:XX:XX -m ipp2p –ipp2p -j DROP

La opción –ipp2p para el módulo ipp2p significa cualquier p2p que el módulo sea capaz de detectar. Si solamente quisiesemos detectar una de las p2p disponibles utilizariamos las opciones combinadas segun necesitemos. Para mas ayuda:

# iptables -m ipp2p –help

Linux en iPAQ h1930

Domingo, Noviembre 19th, 2006

Hacía algún tiempo que venia buscando alguna forma de instalar linux en este Pocket PC para trastear un poco en las posibilidades de linux en dispositivos móviles, así que me puse a buscar y encontré el proyecto que por lo menos mas avanzado está.

Aun le queda un poco para acabar, pero con lo que ofrecen tendremos mas que suficiente para hacer nuestras pruebas.

Lo que haremos será construir un ‘disco duro’ con dos particiones, una para almacenar los archivos necesarios para arrancar y otra para el sistema de archivos del SO.

Las pegas que tiene actualmente el proyecto entre manos son el arranque de Linux y la gestión de energía. El primero de los problemas se solventa con un pequeño ejecutable que borra la RAM de la PDA y carga en ella el kernel de linux. Este ejecutable tiene que ejecutarse desde windows para pocket pc. El otro inconveniente no está solventado, por lo que no podemos apagar ni suspender la unidad, tan solo reiniciarla (tras lo cual restaurará windows ce en la RAM desde la ROM).

Comenzando con el particionado, si vamos a dedicar la tarjeta exclusivamente para linux, tenemos que crear la primera partición de la tarjeta SD con al menos 7 megas de espacio para los archivos de arranque y al menos 50 megas para la particion de Sistema. Este orden es obligado ya que la iPAQ solamente reconocerá y montará en windows ce la primera partición que encuentre en la tarjeta.

Para el ejemplo de particionado expodré mi caso, una tarjeta de 64 megas que me vino muy justa para hacer la instalación.

# fdisk -l /dev/mmcblk0
Disco /dev/mmcblk0: 62 MB, 62783488 bytes
1 cabezas, 16 sectores/pista, 7664 cilindros
Unidades = cilindros de 16 * 512 = 8192 bytes
Disposit. Inicio Comienzo Fin Bloques Id Sistema
/dev/mmcblk0p1   3  800  6384 1 FAT12
/dev/mmcblk0p2 801 7664 54912 83 Linux

Como puede verse la partición que emplearemos para arrancar ha de ser la primera y ha de ser forzosamente de tipo 1 (FAT12). La segunda, en la que he empleado el resto del disco, ha de ser de tipo Linux.

NOTA: mmcblk0 es el nombre del dispositivo tarjeta SD que mi tarjetero embenido en el portatil asigna para estas tarjetas. Si usas un lector externo, posiblemente tengas /dev/sdxz, donde x es el numero de dispositivo (a, b, c…) y z es el número de particion (ie: /dev/sda1, /dev/sda2).

Ahora que tenemos la tabla de particones adecuada tenemos que dar formato a las nuevas particiones adecuadamente:

# mkdosfs /dev/mmcblk0p1

# mke2fs /dev/mmcblk0p2

Comentar que forzosamente tienen que ser la primera de tipo dos y la segunda ext2.

Una vez hecho lo delicado, pasamos a lo facilon, la instalación de linux, que es tan sencilla como copiar los archivos necesarios en la tarjeta.

Empezamos descargando el nucleo (zImage) precompilado de la seccion de descargas de handheld y el HaRET, el programa que usaremos para arrancar linux y los copiaremos ambos en la primera particion de la tarjeta (la de arranque) descomprimiendo previamente haret.exe.

Por último hay que descargar el sistema de archivos con el entorno grafico, que pueden ser GPE o Opie. Yo prefiero GPE que se parece a Gnome. Para verlos y comparar cual os gusta mas, podeis verlos ambos aqui. Una vez descargado, descomprimirlo en la segunda partición y con esto ya habremos acabado de instalar nuestro linux experimental. Tan solo queda poner la informacion de arranque en la primera particion en un archivo llamado default.txt con el siguiente contenido:

set MTYPE 347 set KERNEL “zImage” set RAMADDR 0×30000000 set CMDLINE “root=/dev/mmcblk0p2 console=ttySAC2,115200n8 panic=30 rootdelay=5″ bootlinux

Notese de cambiar mmcblk0p2 por sdx2 o cualquiera que sea la partición en la que guardó el sistema de archivos.

Ahora ya podremos introducir la tarjeta preparada en la iPAQ y ejecutar haret.exe en la tarjeta SD y esperar que arranque el sistema.

Se puede encontrar el manual completo en ingles en la pagina original.

Sincronizacion de Hora

Domingo, Noviembre 19th, 2006

¿Alguna vez os habeis percatado de que se os va la hora en los relojes? Con el tiempo la falta de precisión hace que se nos adelante o retrase la hora. Tambien la falta de energía por agotamiento de una pila o el fin de la correa de un reloj pueden ser motivos de desincronización en un reloj.

Hace tiempo que me cansé de ello y decidí tener una hora maestra que se actualizase automaticamente a partir de la cual sincronizar el resto de relojes cada cierto tiempo.

Para ello he escogido mi servidor linux, ya que se trata de una máquina que no se apaga nunca. En cualquier caso no es necesario que sea una máquina 24 horas en pie.

Lo que básicamente necesitamos es un cliente del protocolo ntp. En debian lo podemos encontrar en el repositorio de apt:

# apt-get install ntpdate

Ahora el binario ntpdate se encuentra instalado en nuestro sistema. Para hacerlo funcionar basta con que ejecutemos

# ntpdate -u servidor.ntp

en donde servidor.ntp es un servidor que soprote el protocolo ntp. En mi caso yo utilizo ntp.upv.es.

Por último quise que se sincronizase la hora de forma automática cada domingo, para lo que añadí la siguiente entrada al archivo /etc/crontab:

#minute hour mday month wday who command

00 00 * * 1 root ntpdate -u ntp.upv.es

en donde el 1 es el día de la semana (domingo) que queremos que se ejecute la sincronización empezando por el domingo (1-7).