Probando bmx7
Probando protocolo BMX7
En este post compartiré unas pruebas y pequeña guía del protocolo de enrutamiento Bmx7 para una red en malla.
Para construir una red en malla autónoma hace falta uno o más protocolo de enrutamiento, donde cada nodo en la red se hace descubrir, descubre a otros nodos, avisa a sus vecinos a quienes ha descubierto y también ayuda a llevar información de un nodo a otro a través de el mismo.
Existen varios protocolos de enrutamiento para redes mesh como Batman-adv, Babel, OLSR, bmx6, etc. y en el proyecto LaOtraRed hemos estado probando varios y buscando el protocolo que más se ajuste a las necesidades de una red libre comunitaria y de control colectivo. En ese afán hemos estado trabajando sobre una primera versión estable o 1VE donde hemos definido el protocolo bmx7 como el principal.
Sobre bmx7¶
Este protocolo es una versión más segura de bmx6. Bmx6 siendo una modificación de Batman-adv, está enfocado a redes en malla (que es lo mismo que decir redes mesh) pero le agrega soporte para IPv6, mejora la difusión del estado de cada nodo, etc [1] .
Bmx7 además le agrega seguridad usando SEMTOR lo que hace que los anuncios de rutas estén firmados criptográficamente [2] .
A pesar de lo complejo que se ve el protocolo, configurar enrutadores para que lo utilicen es sencillo una vez se consigue poner el software necesario en el equipo.
Preparando el escenario¶
Son básicamente dos nodos, el nodo A y el nodo B se descubren y establecen comunicación con la ayuda de bmx7. El nodo A tiene la dirección IPv6: fa99:1:a::a y también IPv4: 10.64.1.1, de manera similar el nodo B tiene sus propias direcciones IP.
En el escenario descrito A y B anuncian también bloques de red, por ejemplo A dirá que es acreedor del bloque IPv6 fa99:1:a::/48
directamente y también anuncia un bloque IPv4: 10.64.1.1/24
a través de un túnel, la manera de hacer anuncios varía en bmx7 y veremos eso más adelante.
La idea de este escenario es que se puede hacer que un nodo le diga a toda la red y más específicamente a sus vecinos, que tiene conexión a un grupo de direcciones IP (bloque IP) y que a través de si mismo los demás nodos de la red pueden conectarse a los dispositivos sean cuales fueren dentro de los bloques que anuncia.
Preparando los nodos¶
Vamos a configurar paso a paso ambos enrutadores, para esta prueba he usado dos modelos de enrutadores baratos, el TP-link mr3040 y mr3020.
Normalmente bastaría con descargar la última versión estable del sistema operativo openwrt o lede para estos enrutadores desde https://downloads.lede-project.org/releases/17.01.4/targets/ar71xx/generic/ y buscando las imagenes .factory.bin
o .sysupgrade.bin
para el mr3020 y 3040 respectivamente. Luego instalar los paquetes necesarios con:
opkg install bmx7 libmbedtls bmx7 bmx7-uci-config \ bmx7-iwinfo bmx7-tun bmx7-table kmod-iptunnel6 \ kmod-ip6-tunnel kmod-iptunnel4 kmod-iptunnel
Las imágenes de firmware por defecto en el repositorio de paquetes de lede u openwrt vienen con la interfaz luci
para administrar el enrutador.
Debido a que bmx7 usa criptografía para firmar paquetes y verificar autenticidad, requiere la biblioteca mbedtls instalada en el sistema, como los enrutadores mr3020 y 3040 sólo tienen 4MB de memoria FLASH, si se incluye el luci no hay cabida para bmx7. En modelos de enrtuadores con 8 MB de FLASH no se tiene esta limitación.
Una solución sería desinstalar completamente luci pero no he encontrado una forma sencilla de hacerlo, por lo que se puede construir imágenes de firmware usando buildroot o image-generator, en el post construir imágenes de firmware para enrutadores con build root puedes ver cómo hacerlo.
Por ejemplo usando el image-generator se puede construir imágenes de firmware sin luci y con las dependencias necesarias para bmx7 con:
make image PACKAGES="-libiwinfo-lua -liblua -libubus-lua -libuci-lua \ -lua -luci -luci-app-firewall -luci-base -luci-lib-ip -luci-lib-nixio\ -luci-mod-admin-full -luci-proto-ipv6 -luci-proto-ppp \ -luci-theme-bootstrap -uhttpd -uhttpd-mod-ubus \ bmx7 bmx7-iwinfo kmod-ip6-tunnel kmod-iptunnel6 kmod-iptunnel4 \ kmod-iptunnel bmx7-json bmx7-sms bmx7-table bmx7-topology bmx7-tun\ bmx7-uci-config libmbedtls"
--> También puedes descargar las imágenes de firmware con estas características de mi repositorio de imágenes de firmware de openwrt (este repositorio cambia y no esta garantizado que siempre vaya a funcionar):
Luego instalar las imágenes de firmware correspondientes en los enrutadores. Si nunca lo has hecho revisa esta guía.
Configurando interfaces de red y WiFi¶
Primero el archivo de interfaces de red para el Nodo A.
/etc/network/interfaces¶
config interface 'loopback' option ifname 'lo' option proto 'static' option ipaddr '127.0.0.1' option netmask '255.0.0.0' config globals 'globals' # mejor no cambiar esto en el enrutador option ula_prefix 'fd91:9cd6:f633::/48' config interface 'lan' option proto 'static' option type 'bridge' option ipaddr '10.64.1.1' option netmask '255.255.255.0' option ifname 'eth0' config interface 'mesh' option proto 'static' option ip6addr 'fa99:1:a::a'
Con lo anterior configuramos dos interfaces, lan
en IPv4 y mesh
en IPv6.
/etc/config/wireless¶
config wifi-device 'radio0' option type 'mac80211' option hwmode '11g' option path 'platform/ar933x_wmac' option htmode 'HT20' option channel '2' option country 'BO' option txpower '18' option disabled '0' config wifi-iface option device 'radio0' option network 'mesh' option mode 'adhoc' option ssid 'bmx7.pruebas' option bssid 'D0:D0:11:11:11:11' option encryption 'none'
Hacemos que el nodo emita una señal wifi en modo adhoc que con ssid "bmx7.pruebas" y ligada a la interfaz "mesh" definida anteriormente.
/etc/config/bmx7¶
# modificamos un poco el archivo de configuracion por defecto # en bmx7 config 'bmx7' 'general' # usando la interfaz mesh config 'dev' 'mesh' option 'dev' 'wlan0' # anuncios UHNA (para ipv6 directo) config 'unicastHna' 'miPrefijoDeRed' option 'unicastHna' 'fa99:1:a::/48' # tuneles (para bloques ipv4) # anunciar tunel ipv4 config 'tunDev' defaultbmx7 option 'tunDev' 'defaultbmx7' option 'tun4Address' '10.64.1.0/24' # aceptar anuncios config 'tunOut' option 'tunOut' 'ip4' option 'network' '10.64.0.0/16' # lo siguiente es para habilitar el plugin bmx7-tun # y con esto poder crear tuneles config 'plugin' option 'plugin' 'bmx7_tun.so' config 'plugin' option 'plugin' 'bmx7_table.so'
En la configuración de bmx7, primero definimos en que interfaz va a trabjar el protocolo.
Luego definimos anuncios uHNA que son mensajes que anuncian a los nodos vecinos bloques y direcciones IP que tiene un nodo en la red. Lo bueno de usar UHNAs es que se garantiza que ningún otro nodo pueda utilizar las IP que anuncia un nodo mediante un identificador único y que los bloques de direcciones no se solapen. Todos estos paquetes se asocian a un indentificador único por cada nodo y van firmados criptográficamente.
Finalmente, bmx7 es sólo IPv6 y para anunciar bloques IPv4 utiliza anuncios de túneles. Afortunadamente no tenemos que crear los túneles manualemente ya que bmx7 los crea por nosotros, sólo indicamos mediante tun4Address
que este nodo anuncia la red 10.64.1.0/24
y mediante tunOut
le decimos que acepte anuncios que estén dentro de 10.64.0.0/16
y que los retransmita.
En el nodo B las configuraciones son similares donde sólo cambian los bloques y direcciones IP correspondientes, si habría otro nodo C o otros más se hace de la misma forma.
Una vez guardadas estas configuraciones, reiniciamos el demonio bmx7 con:
/etc/init.d/network restart /etc/init.d/bmx7 restart
Haciendo pruebas¶
El demonio bmx7 se puede consultar en cualquier momento para consultar su estado ,nodos asociados o túneles, a continuación algunas consultas hechas en el enrutador.
La guía completa de comandos se puede ver en https://github.com/bmx-routing/bmx7 o una descripcion mas corta con bmx7 --verboseHelp
.
Como en las consultas anteriores vemos que el nodo B se ha dectectado, comprobamos que en el enrutador se hayan establecido rutas hacia él, por ejmplo con:
ip -6 route # que muestra entre su salida que hay una ruta establecida hacia el nodo B fa99:1:b::/48 via fe80::ea94:f6ff:fe6b:80fa dev wlan0 metric 1024 fd70:7b03:7847:472a:414:9eee:2d98:3e14 via fe80::ea94:f6ff:fe6b:80fa dev wlan0 metric 1024 unreachable default dev lo metric -1 error -128 fa99:1:a::a dev wlan0 metric 256
En bmx7 los nodos configuran automáticamente una dirección IPv6 al azar y un indentificador único en la red, pero los anuncios de redes UHNA son únicos y eso suprime el riesgo de IP spoofing.
Ahora la comunicación entre el nodo A,B o una cantidad arbitraria de nodos es posible, podemos comprobar haciendo por ejemplo la prueba trazando rutas.
traceroute -6 fa99:1:b::b
Que muestra que se puede llegar a esa direccion IP iendo por el nodo B.
traceroute to fa99:1:b::b (fa99:1:b::b), 30 hops max, 16 byte packets 1 fa99:1:b::b (fa99:1:b::b) 1.392 ms 1.581 ms 1.329 ms # usando ip para ver que ruta se sigue para alcanzar una IP ip route get fa99:1:b::b fa99:1:b::b from :: via fe80::ea94:f6ff:fe6b:80fa dev wlan0 src fc99:1:a::a metric 1024
Modificaciones "en caliente"¶
En bmx7 no es obligatorio utilizar un archivo de configuración para modificar el comportamiento del protocolo. Cuando el demonio bmx7 esta ejecutándose con comandos se puede por ejemplo hacer que se anuncien bloques adicionales mediante UHNA.
bmx7 -c u=fc01:1934:ffed::/64
Que haría que el nodo también anuncie el bloque fc01:1934:ffed::/64
, de igual manera se puede hacer que se anuncien túneles, quitarlos, establecer póliticas para aceptar anuncios y distribuirlos, etc. Consulta la guía oficial.
Con toda la flexibilidad que ofrece bmx7 ya tenemos construida una pequeña red en malla :)