Aquí se muestra una manera de construir el programa [Babeld](https://github.com/jech/babeld) mediante compilación cruzada para enrutadores con el sistema operativo LEDE. 

![term.png](/static/imgs/terminal16.png) Babeld que es una implementación del protocolo de enrutamiento [Babel](https://www.irif.fr/%7Ejch/software/babel/) escrito en lenguage C, se utliza frecuentemente en enrutadores de redes inlámbricas en malla que crecen y se gestionan automáticamente.

Contenido:

* [Como construir programa Babeld para enrutadores de la rama ar71xx](#Babeld) que tengan el sistema operativo [LEDE](https://lede-project.org/) por ejemplo para el enrutador TL-MR3020 o TL-MR3040.

* [Como construir Babeld-lor para enrutadores de la rama ar71xx](#Babeld-lor), [Babeld-lor](https://git.laotrared.net/LaOtraRed-dev/babeld-lor) que es una implementación de un método de autenticación para el protocolo Babel que he estado probando y desarrollando.

## Obteniendo lo necesario ##

Para poder obtener el ejecutable de Babeld (construirlo) y que se pueda ejecutar en un enrutador básicamente se necesita:

* Compilador cruzado *Cross compiler* de lenguage C.
* Enlazador, bibliotecas y otros utilitarios para lenguage C.

### Compilador cruzado (cross compiler) ###

Como queremos que el programa se ejecute en un enrutador TL-MR3020, primero debemos obtener el compilador cruzado apropiado. Dentro del Sistema operativo LEDE u Openwrt, el TL-MR3020 esta dentro de la rama objetivo `ar71xx`.

#### Descargando el SDK ya construido ####

La primera forma de obtener el *cross compiler* es **descargándolo** del repositorio oficial, el proyecto LEDE mantiene un [SDK](https://es.wikipedia.org/wiki/Kit_de_desarrollo_de_software).

En [https://downloads.lede-project.org/releases/17.01.4/targets/ar71xx/generic/](https://downloads.lede-project.org/releases/17.01.4/targets/ar71xx/generic/) debería haber un archivo que contenga **sdk** por ejemplo: [lede-sdk-17.01.4-ar71xx-generic_gcc-5.4.0_musl-1.1.16.Linux-x86_64.tar.xz](https://downloads.lede-project.org/releases/17.01.4/targets/ar71xx/generic/lede-sdk-17.01.4-ar71xx-generic_gcc-5.4.0_musl-1.1.16.Linux-x86_64.tar.xz).

En la [wiki de LEDE se describe mejor el SDK](https://lede-project.org/docs/guide-developer/compile_packages_for_lede_with_the_sdk), básicamente es una cadena de herramientas (*toolchain*) para hacer [compilación cruzada](https://es.wikipedia.org/wiki/Compilaci%C3%B3n_cruzada) y construir programas para una determinada plataforma objetivo (en nuestro caso ar71xx).

Luego debemos descomprimir este archivo, que contiene el *toolchain* que necesitamos.

#### Construyendo todo usando buildroot ####

Si lo que quieres es construir todo incluyendo el SDK, puedes usar Build root. El proceso de construcción lo he descrito en el post: [Construir firmware para enrutadores con Buildroot](/posts/construir-firmware-para-enrutadores-con-buildroot), no olvides marcar la opción: `Build the ... SDK`.

Una vez termine el largo proceso de construcción, hay que ubicarse en `bin/targets/ar71xx/generic` donde debería estar un archivo comprimido con el SDK recién construido.

--> **En general**, es preferible usar la primera forma y sólo descargar el SDK precompilado desde el repositorio oficial de LEDE.

### Código Fuente de Babeld ###

El código fuente de Babeld se puede obtener desde [https://www.irif.fr/~jch/software/files/babeld-1.8.0.tar.gz](https://www.irif.fr/~jch/software/files/babeld-1.8.0.tar.gz) o descargando la versión de desarrollo con:

    git clone git://github.com/jech/babeld.git

Con todo lo necesario, ya podemos empezar a construir Babeld.

<hr id="Babeld">
## Construyendo Babeld ##

Primero como en todo programa nos ubicamos en el directorio raíz del código fuente, luego de clonar u obtener Babeld en el directorio raíz existe un archivo `Makefile`, con instrucciones básicas para la construcción del programa.

En el Makefile, la regla con la instrucción de compilación:

    babeld: $(OBJS)
            $(CC) $(CFLAGS) $(LDFLAGS) -o babeld $(OBJS) $(LDLIBS)

Ahí la variable `$(CC)` es la que se puede reemplazar para que se utilice el compilador cruzado del SDK de LEDE.

Babeld no utiliza bibliotecas adicionales y todas las necesarias (libc) vienen en el SDK asi que para construirlo solamente apuntamos al compilador cruzado del SDK que tenemos, esto se hace con el comando:

`make CC=/ubicacion/del/SKD/staging_dir/toolchain-mips_24kc_gcc-5.4.0_musl/bin/mips-openwrt-linux-musl-gcc PLATFORM_DEFINES='-march=mips32'`

La parte que dice `/ubicacion/del/SKD/` apunta a la ubicación en nuestro compuador donde descomprimimos el SDK, ahí dentro esta `staging_dir/` y ahí debería estar el *toolchain* para la arquitectura, en este caso `mips_24kc`.

Para comprobar que en este directorio se encuentra el compilador cruzado:

    :::bash
    ./ubicacion/del/SKD/staging_dir/toolchain-mips_24kc_gcc-5.4.0_musl/bin/mips-openwrt-linux-gcc --version

Usaremos el compilador `gcc-5.4.0` cuyo archivo ejecutable es `mips-openwrt-linux-gcc` y si en la pantalla aparece un mensaje con la version 5.4.0 el archivo es correcto, por ejemplo:

    mips-openwrt-linux-gcc (LEDE GCC 5.4.0 r3664-4124847) 5.4.0

Ahora, construimos con:

    :::bash
    make CC=/ubicacion/del/SKD/staging_dir/toolchain-mips_24kc_gcc-5.4.0_musl/bin/mips-openwrt-linux-musl-gcc \
	PLATFORM_DEFINES='-march=mips32'

El proceso debería terminar rápidamente y debería haber un archivo ejecutable con nombre `babeld`. Este archivo se puede ejecutar en un enrutador con LEDE, para comprobar que la arquitectura objetivo del ejecutable es correcta usamos:

    :::bash
    file babeld

Que debería mostrar:

    :::bash
    babeld: ELF 32-bit MSB executable, MIPS, MIPS32 rel2 version 1, dynamically linked, interpreter /lib/ld-musl-mips-sf.so.1, not stripped

Ahora solo hace falta probarlo copiando el archivo `babeld` al enrutador digamos en el directorio `/tmp/` y luego ejecutarlo con:

    ./babeld

**-->** De esta forma hemos usado el compilador cruzado directamente para construir desde el código fuente, de forma similar se construyen programas para los enrutadores y cada programa puede tener sus necesidades específicas. Pero con esto podríamos modificar el código de Babeld y probar estos cambios directamente en el enrutador.

<hr id="Babeld-lor">
## Construyendo Babeld-lor ##

Ahora podemos usar el SDK para construir una versión modificada de Babeld llamada [Babeld-lor](https://git.laotrared.net/LaOtraRed-dev/babeld-lor), esta versión en desarrollo pretende implementar un método de autenticación en el protocolo Babel para protegerlo contra ataques de suplantación de identidad.

### Instalando o construyendo mbedtls ###

Babeld-lor utiliza descifrado RSA y una clave pública RSA generada por una entidad central para autenticación, por eso es necesario copiar o tener instalada la biblioteca [mbedtls](https://tls.mbed.org/) en el enrutador.

Una forma sencilla de instalarla es mediante el mediante manejador de paquetes de LEDE, en el enrutador:

    opkg install libmbedtls

Para más detalles sobre esta biblioteca revisa este post [como construir mbedtls](/posts/probando-mbedtls).

#### Copiando mbedtls si no hay espacio suficiente el directorio raíz del enrutador (opcional) ####

Se puede copiar a la partición `/tmp` los archivos necesarios para la biblioteca mbedtls. El siguiente procedimiento es una solución temporal y cada que el enrutador se reinicie se debe volver a repetir cierta parte.

    :::bash
    # Conectándose al enrutador que digamos tiene la IP: 192.168.1.1
    ssh root@192.168.1.1
	# una vez dentro el enrutador
    ### obteniendo mbdetls 
    cd /tmp/
    wget https://downloads.lede-project.org/releases/17.01.4/packages/mips_24kc/base/libmbedtls_2.6.0-1_mips_24kc.ipk
    mv libmbedtls_2.6.0-1_mips_24kc.ipk libmbedtls_2.6.0-1_mips_24kc.tar.gz
    tar -zxvf libmbedtls_2.6.0-1_mips_24kc.tar.gz
    tar -zxvf data.tar.gz
    cd usr/lib
	mkdir /tmp/mbedtls
    cp libmbedcrypto.so.0 libmbedtls.so.10 libmbedx509.so.0 /tmp/mbedtls
    ######
    # creando un enlace simbolico para que el sistema apunte a los archivos correctos
    cd /usr/lib
    ln -s /usr/lib/libmbedcrypto.so /tmp/mbedtls/libmbedcrypto.so.0
    ln -s /usr/lib/libmbedtls.so /tmp/mbedtls/libmbedtls.so.10
    ln -s /usr/lib/libmbedx509.so /tmp/mbedtls/libmbedx509.so.0

Ahora la biblioteca libmbedtls esta instalada temporalmente en el sistema, pero al apagar el equipo la partición temporal `/tmp` se vaciará y tiene que repetir la parte que dice "### obteniendo mbdtls".

### Clave pública y credenciales para Babeld-lor ###

Como Babeld-lor utiliza una clave pública RSA de una entidad central, es necesario que el enrutador la tenga para poder descifrar las actualizaciones de rutas y autenticarlas. También, se requiere que cada enrutador cuente con un conjunto de tokens de autenticación.

#### Creando credenciales ####

Primero se debe crear el par de claves **pública y privada** y lo podríamos hacer en nuestra computadora, esta clave debe ser creada con la biblioteca mbedtls, una forma rápida de construir mbedtls está la sección "construyendo mbedtls" del post: [probando mbedtls](/posts/probando-mbedtls)

Una vez lo tengamos, en el directorio del código fuente de mbedtls:

    cd programs/pkey
    ./gen_key

Que generará el par de claves de la entidad central.

Ahora podemos utilizar este script para generar tokens cifrados para direcciones IP dadas:

    :::bash
    DIR_BASE=$PWD
    DIR_RSA=/Ruta/donde/esta/mbedtls-2.4.2/programs/pkey # modificar esto segun convenga
    ARCH_TOKEN=$DIR_RSA/result-enc.txt
    DIR_DEST=$DIR_BASE/tokens
    PREFIJO=$1
    
    echo "preparando para prefijo $PREFIJO"
    
    if [ ! -e tokens ]
    then
        mkdir tokens
    fi
    
    if [ -e $DIR_DEST/$PREFIJO.ctxt ]
    then
        echo "borrando tokens/$PREFIJO.ctxt"
        rm $DIR_DEST/$PREFIJO.ctxt
    fi
    
    for((i=0;i<100;i++))
    do
        B=$(head -c 19 /dev/urandom  | sha1sum | head -c 6 | tr "[a-z]" "[0-9]")
        if [ $i -lt "10" ]
        then
            CAD=$PREFIJO"_"$B"0"$i
        else
            CAD=$PREFIJO"_"$B$i
        fi
    
        echo "mensaje: $CAD"
    
        # cifrando
        cd $DIR_RSA
        ./rsa_encrypt_con_clave_privada $CAD > /dev/null
        #$PPK "$CAD" 2> /dev/null
        TOKEN=$(cat $ARCH_TOKEN | tr -d ' ')
        #echo "TOKEN: $TOKEN"
        # quitando newlines
        while read -r linea
        do
            L=$(echo "$linea"| tr -d ' ' )
            #echo -n "$L"
            echo -n "$L" >> $DIR_DEST/$PREFIJO.txt
        done < $ARCH_TOKEN
        echo >> $DIR_DEST/$PREFIJO.txt
    done
    
    # eliminando ^M
    cat $DIR_DEST/$PREFIJO.txt | tr -d $'\r' > $DIR_DEST/$PREFIJO.ctxt
    rm $DIR_DEST/$PREFIJO.txt
    
    cp $DIR_RSA/rsa_pub.txt $DIR_DEST/
    
    echo "Hecho."
    exit 0

Guardamos este script como digamos "gk.sh", ahora creamos los tokens con:

    :::bash
    bash gk.sh 192.168.1.1

Que generará un total de 100 tokens de autenticación para la dirección ip 192.168.1.1 en una carpeta `tokens`

### Proceso de construcción manual ###

Ahora necesitamos descargar el código fuente de Babeld-lor, por ejemplo de la rama de desarrollo forked-updateTLV:

    git clone https://notabug.org/strysg/babeld-lor/src/forked-updateTLV

Este repositorio contiene un Makefile para compilar usando mbedtls y un SDK.

También un script llamado `set-up.sh` que apunta a un SDK en el directorio actual y como podríamos tener el SDK de LEDE en otro directorio podemos crear un enlace simbólico al SDK con:

    ln -s /ruta/donde/esta-el-SDK/ SDK

El script [set-up.sh](https://notabug.org/strysg/babeld-lor/src/forked-updateTLV/set-up.sh) extrae la clave pública, los tokens de autenticación, el ejecutable construido y los copia al enrutador en la carpeta `/tmp`, no instala Babeld-lor ya que estamos solamente haciendo una prueba.

Antes de ejecutar el script deberíamos copiar el contenido de la carpeta `tokens` donde se generaron las claves de autenticación al directorio donde descargamos Babeld-lor, concretamente en un directorio `pruebas/tokens` dentro el código fuente de Babeld-lor.

Finalmente para construir babeld-lor usamos:

    ./set-up.sh export 192.168.1.1

Que construirá el programa usando el SDK, y copiará lo necesario al enrutador con la direccíon IP `192.168.1.1`.

Para probar que esto funciona **en el enrutador**:

    :::bash
    cd /tmp/
    # para que babeld-lor exporte las rutas por la interfaz wifi wlan0
    ./babeld wlan0
    # o si queremos mas verbosidad
    ./babeld -d 2 wlan0
    # Para utlizar el archivo de configuracion por defecto
    ./babeld -c /var/etc/babeld.conf -d 2

Si funciona ahora se puede probar y modificar Babeld-lor a gusto.

