Red Mesh - Mesh Tunnel Broker
Fuente del gráfico: https://github.com/maverickp/cool-graphs-basket
El objetivo del "Mesh Tunnel Broker" o del, simplemente, "túnel mesh", es ofrecer acceso a la Red Mesh a dispositivos que no pueden conectarse directamente, valiéndonos de un túnel VPN atravesando Internet.
Este esquema de "Mesh Tunnel Broker" se puede extender de distintas maneras. Ejemplo: unir distintos proyectos de redes libres en zonas geográficamente distantes. En estos casos, proyectos como dn42.net son muy interesantes.
Recordemos que este servicio es limitado y sólo es para probar el servicio. La única manera de conectarse libremente a la red debería ser mediante las zonas Wi-Fi libres, o (para una conexión sin filtros ni límites) montar un nodo.
Características
- No se necesita configuración adicional en los demás nodos
- Conectividad end-to-end completa (no hay NAT)
- Posibilidad de distribuir la carga de tráfico entre varios nodos Mesh-Internet
- El bloque de IPs para clientes del túnel mesh es enrutable y públicamente alcanzable (no hay NAT)
- Resistente a caídas
- Baja latencia
- Funcionalidad completa incluso en nodos, supernodos voluntarios con conexión a Internet inestable, filtrada o parcialmente bloqueada (ejemplo: si el ISP usa carrier-grade NAT)
Requisitos
- Uno o más servidores externos (en Internet)
- Accesibles remotamente (IP dedicada o IP compartida con puertos DNAT)
- De preferencia cercanos al lugar de implementación de la Red Mesh (ciudad o país)
- Disponer de caudal considerable (al menos 10Mbps+ bidireccional dedicado)
- En caso de necesitar balanceo de carga, un servidor externo debería encargarse del trabajo.
- Uno o más nodos o supernodos dentro de la Red Mesh con conectividad a Internet dispuestos a donar ancho de banda.
- La conexión a la Red Mesh debe ser estable
- La conexión a Internet debe ser continua (funcionando 24 horas al día, 7 días a la semana, sin importar ocasionales caídas). No se admiten límites horarios estrictos.
- La conexión a Internet debe ser ilimitada (o tener un límite de consumo despreciable).
- La conexión a Internet debe ser nativa (no VPNs en medio)
- La conexión a Internet debe disponer de un caudal de subida, mínimamente, de 700Kbps.
- No es necesario disponer de una IP pública o IP pública fija, ni considerar si el ISP utiliza carrier-grade NAT (típico en 3G, 4G, 4G LTE) o soporta IPv6.
Funcionamiento
Los servidores externos, juntos a los nodos de la Red Mesh, formarán una red VPN mesh (red VPN sin un "servidor central" único).
Los servidores (no necesariamente todos), tendrán disponible para usuarios comunes, acceso vía VPN estándar (usualmente OpenVPN) a la Red Mesh. Los datos que llegan a un servidor mediante VPN estándar, son enrutados a un nodo de la Red Mesh pasando por la VPN mesh.
Todos los datos que atraviesen esta infraestructura lo harán encriptados, autenticados y seguros.
Implementación básica y ejemplo
1) VPN Mesh
Primero, necesitamos un software VPN no centralizado. Para montar una VPN Mesh entre distintos servidores externos, utilizamos Tinc (aunque tambien existen proyectos como PeerVPN (sólo admite clave simétrica) o FreeLAN). Escogimos Tinc ya que ha demostrado ser estable en varios proyectos como LibreNet6, soporta autenticación por par de claves RSA, admite todos los algoritmos de encriptación simétrica de OpenSSL disponibles, y el binario es liviano (para su instalación en routers o máquinas de recursos limitados).
En un ejemplo de configuración, asumimos que tenemos tres participantes en la VPN Mesh: Comegato, Chip y Cometa. Comegato y Chip son servidores: aunque Chip está en Bolivia y el otro fuera del país, los dos tienen conexiones veloces y estables a Internet. En el datacenter boliviano no nos dejaron colocar una antena hacia la red Mesh, pero contamos con Cometa: el router de un amigo, parte de la Red Mesh, que nos ofreció el sobrante de su poderosa línea de Internet domiciliaria que nadie usa en todo el día (a excepción de los familiares en fin de semana, o él, si tiene ganas luego del trabajo)
Instalamos tinc (disponible en los repos de Debian y OpenWrt) en los dos servidores y en el router, y los configuramos. Nuestra red VPN mesh se llamará "meshnet" (muy original) y usaremos el 100.64.12.0/27 como segmento de red aquí [1].
En Chip, deberian estar los sig. archivos:
/etc/tinc/meshnet/tinc.conf
Name=chip
AddressFamily=ipv4
# Escucha en el puerto 666
BindToAddress=* 666
Device=/dev/net/tun
Mode=switch
# Cambio estético del nombre de la interfaz [2]
Interface=meshnet0
ConnectTo=comegato
/etc/tinc/meshnet/tinc-up
#!/bin/sh
ifconfig $INTERFACE 100.64.12.11 netmask 255.255.255.224
/etc/tinc/meshnet/tinc-down
#!/bin/sh
ifconfig $INTERFACE down
No se olviden de hacer un chmod a+x /etc/tinc/meshnet/tinc-*
Cada aparato que sea parte de la VPN mesh debe tener su propio keypair RSA, y los aparatos a los que se conectará deben tener ya de antemano su clave pública, y este, la de ellos.
Aunque en una VPN mesh no es necesario propagar a todos y a cada uno de los aparatos la clave pública de cierto nodo, nuestra topología lo exige: en nuestra red de tres aparatos, todo están conectados directamente entre sí, excepto el router (que no recibe conexiones ya que podría estar detrás de un NAT). Si se añade un cuarto, quinto, sexto o enésimo router, sólo será necesario hacer modificaciones a uno o a dos servidores externos (por redundancia).
Las claves públicas de todos (yo, los que se conectan y a los que me conecto) están en la carpeta /etc/tinc/meshnet/hosts. Genero mi par de claves RSA a 3072-bits con el comando:
tincd -c /etc/tinc/meshnet -D -K3072
Reviso que los archivos estén en esta forma (por si acaso hay documentación de las variables de Tinc):
/etc/tinc/meshnet/hosts/chip
# Mi clave pública generada por el anterior comando. Esta es la
# que debo copiar a las demás máquinas.
-----BEGIN RSA PUBLIC KEY-----
MIIBigKCAYEA0B/ebu7RSI/803NWWR/SCEF1mtUC7ocJ/FJpMPuH2GdlDj2YtIqz
IZCat5b908G5jle4XdfgQMa8sywFz8AeseAeOh4D4El/DX2pgwtI1QzM3UUzHaLv
(...)
3J904VYW0/w6UTyUmWC2Ln8k2DNnQtguuzTOT52ZkMJhowIMw6TNaqfabR2Ps1KW
LSPNtsIr2It9AgMBAAEEEEE
-----END RSA PUBLIC KEY-----
/etc/tinc/meshnet/hosts/comegato
# La IP pública o el hostname de Comegato en Internet, seguido por el puerto
Address=comegato.03k.miamfl.us.troll-servers.xyz 666
# Compresión LZO (básica y rápida)
Compression=10
# Cifrado y autenticación
Cipher=aes-256-cbc
Digest=sha256
# La clave pública de Comegato
-----BEGIN RSA PUBLIC KEY-----
MIIBigKCAYEAxY6jPCh3fySmp8Xsn8SYHNZkwIXVLeRR/Ncwo8esGMPVl8qVYXl6
IZCat5b908G5jle4XdfgQNVMlFz8Ae5e8e7eOh4D4ElhDX2pgwtI1QzM3UUzHaLv
(...)
3J904VYW0/w6UTyUmWC2Ln8k2DNnQtguuzTOT52ZkMJhowIMw6TNaqfabR2Ps1KW
LSPNtsIr2It9AgMG77bn9BBBE
-----END RSA PUBLIC KEY-----
/etc/tinc/meshnet/hosts/cometa
(Similar a la anterior, pero sin la línea Address)
(recordemos que el router debe conectarse a los servidores pero es innecesario hacerlo al revés)
Para el servidor Comegato la configuración es similar, pero ahora la configuración adicional incluyendo Address pertenecería a Chip y estaría en el archivo hosts/chip; el archivo hosts/comegato sólo contendría la clave pública del servidor.
Para el router Cometa, los archivos [/etc/tinc/meshnet/] hosts/chip y hosts/comegato incluirán la configuración adicional incluyendo Address. También se especificarán dos veces ConnectTo (primero chip ya que es el más cercano, luego Comegato) en tinc.conf.
2) OpenVPN para dispositivos clientes
Se puede usar este auto-installer script: https://github.com/maverickp/openvpn-install (incompleto)
Los demás archivos deberían estar generados y revisados automáticamente para la Red Mesh. Posiblemente, para otros proyectos, necesitaría modificar el archivo /etc/openvpn/server.conf y /etc/openvpn/client-common.txt
Respecto a los certificados: se permite el ingreso de varios clientes con el mismo certificado. [TODO] Se pueden mantener instalaciones dobles: un subnet público con ancho de banda limitado y otro de acceso privado (donde cada uno tiene su certificado) sin limitaciones para los encargados de la red.
Recordemos que este servicio es limitado y sólo es para probar el servicio.
3) Completando detalles
Es necesario que la red mesh pueda "ver" al segmento de red donde los clientes OpenVPN estan conectados, y al revés.
En el nodo donde está instalado OpenVPN agregamos una ruta:
route add -net 10.1.0.0 netmask 255.224.0.0 gw 100.64.12.9
(asumiendo que el router en la Red Mesh está en 100.64.12.9)
A los routers también se les debería indicar cómo llegar a los clientes, sin NAT:
route add -net 172.16.1.64 netmask 255.255.255.224 gw 100.64.12.12
(asumiendo que el servidor con VPN Mesh y OpenVPN es 100.64.12.12. Para más servidores, se añaden más rutas)
(TODO: en este punto se podría aplicar balanceo de carga)
4) Pruebas
Ahora probemos ingresando al VPN (OpenVPN) y tracemos una ruta:
traceroute to speedtest.diag.anycast.laotrared.net (10.254.2.21), 30 hops max, 60 byte packets 1 chip.servers.laotrared (172.16.1.65) 8.985 ms 9.214 ms 9.147 ms 2 cometa.pmphsi2-wl-lpzbo.node.laotrared (100.64.12.9) 14.652 ms 17.212 ms 15.967 ms 3 2.rezo.mesh.hacklab.org.bo (10.65.2.17) 16.652 ms 15.917 ms 18.324 ms 4 chipsito.mesh.hacklab.org.bo (10.65.2.8) 19.351 ms 17.241 ms 18.147 ms
Listo!
[1] Este segmento, en realidad, es parte de 100.64.0.0/10, segmento de red (de uso privado) reservado en el RFC6598 para la red intermedia de proveedores de Internet que usan carrier-grade NAT para sus clientes, para que ellos dejen de usar el 10.0.0.0/8. Nosotros hacemos casi lo mismo, pero con el detalle de que no aplicaremos NAT.
[2] a TUN le puedes poner casi cualquier nombre para la interfaz virtual. Puedes hacer cosas como ifconfig meshbr0ker, ifconfig chap0 (el túnel mesh del Chapo Guzman :v ), o ifconfig nu11 (el número uno en vez de la letra L minúscula: en fuentes monospace la diferencia no se nota mucho)