top of page

Nebula: diseño e implementación redes peer-to-peer seguras

  • jogofus
  • 27 jul
  • 5 Min. de lectura

Actualizado: 4 ago

Como ya se ha comentado en este blog en varias entradas, la interconectividad entre distintas sedes a día de hoy es prácticamente innegobiable. Si nuestra empresa dispone de cinco sedes repartidas geográficamente, querremos que entre ellas se puedan conectar, para disponer de diferentes recursos como alta disponibilidad, balanceo de carga o reparto de recursos.


Es por ello que casi siempre se han utilizado VPN site-to-site como IPsec, aunque a día de hoy también se utiliza OpenVPN (SSL VPN) y Wireguard, siendo este último el que más protagonismo está obteniendo últimamente.


Como he dicho, esto nos permite conectar distintos segmentos de red. Esto es algo a tener en cuenta, ya que, si se disponen de mismos segmentos de red, se deberá realizar un nateo, concretamente un POSTROUTING.

ree

Wireguard: el sustituto de las VPN tradicionales


Wireguard ha llegado para quedarse, eso lo sabemos todos.


Tiene un rendimiento de los mejores que existen, llegando a alcanzar casi el 1gbps (por lo menos lo que he visto yo, desconozco si hay casos de mayor velocidad. También es cierto que la red WAN era de 1gbps), aunque OpenVPN se ha puesto las pilas y está igualando en rendimiento con lo que se conoce como DCO, que significa Data Channel Offload, trasladando el cifrado del canal de datos al kernel de Linux, en lugar de ejecutarlo en el espacio de usuario.


¿Cómo funciona Wireguard?

Bueno, tenemos dos opciones: el típico site-to-site, que se ejecuta en un router, o el modelo Roadwarrior.


Cada dispositivo que se conecta a esta red debe tener una clave pública y una privada, y añadida al fichero de configuración del servidor.

En este caso, solo uno de los extremos (tanto en el modo S2S como en el modo Roadwarrior) debe ser accesible por el puerto UDP/51820 (o el que hayamos escogido y configurado previamente).


En los peers, o clientes, se deben definir las redes a las que va a poder acceder. Pero, ¿y si la persona a la que le hemos dado acceso a la VPN conoce un segmento de red al que no queremos que tenga acceso? Puede modificar el fichero de configuración y añadir la red, pudiendo así acceder a dicha red.


Además, en el modelo roadwarrior, el servidor central siempre ha de estar disponible, aún cuando la conexión ya se haya establecido entre dos clientes, ya que todo pasa a través de él. Esta topología se conoce como Hub and spoke.


En cuanto a seguridad, Wireguard utiliza un tipo de cifrado ChaCha20 , el cual es capaz de funcionar sin hardware offloading (ya que no usa AES). Su equivalente sería el AES-256 en resistencia, aunque no existe ningún ataque conocido sobre ChaCha20.

Como dato, este tipo de cifrado se ha probado y utilizado en TLS1.3, Wireguard, OpenSSH, DNSCrypt...

Nebula: la alternativa a las VPN tradicionales


Para empezar, debemos saber que Nebula se trata de un software de la empresa Slack. De hecho, es el método que ellos usan para interconectar distintos clientes.


La red Nebula, como dicen en su web, es una red overlay diseñada para ser rápida, segura y escalable.

Está basado en el framework Noise y es una red definida por software peer-to-peer con autenticación mutua.

Como detalle, Noise está creado por Trevor Perrin, coautor de Signal Protocol, una de las aplicaciones de mensajería más segura que existen.


Pero, ¿qué significa que es una red peer-to-peer?


Significa que todos los nodos que pertenecen a la red Nebula se conectan entre ellos, sin necesidad (a medias) de un dispositivo intermedio.


También ofrece la ventaja de que los clientes pueden estar detrás de un NAT y el túnel se establecerá igualmente, gracias al llamado UDP Hole Punching. Eston significa que podremos mover nuestros equipos a otra sede, red, ISP o lo que sea, que seguirá funcionando sin problema.


¿Y por qué he dicho a medias en lo referente al dispositivo intermedio?


Para que los clientes conozcan a que dirección IP pública deben conectarse según el cliente, se necesita un equipo que haga de intermediario, llamado lighthouse, que "registre" todas esas conexiones para luego distribuirlas al resto de equipos.


Por ejemplo:

Yo estoy en Valencia y tengo la IP de Nebula 192.168.100.5 y quiero conectar con el cliente que tiene la IP de Nebula 192.168.100.24. Yo lanzaré una petición al servidor intermedio preguntandole por la IP 192.168.100.24 y éste me dirá a qué IP pública remota deberé conectarme para establecer el túnel.


¿Cómo funciona el UDP Hole Punching?

Cada nodo envía un paquete UDP al servidor lighthouse, lo que provoca que el NAT de cada nodo cree una entrada de mapeo de puerto.

El servidor intercambia las IP públicas y puertos UDP de cada nodo y estos envían paquetes a las direcciones y puertos ofrecidos por el lighthouse.


La ventaja de esto es que, mientras la conexión siga activa, aunque el lighthouse deje de funcionar momentáneamente, no perderemos la conexión.


Además, una ventaja que ofrece Nebula es que los clientes pueden ser agrupados y permitir tráfico entrante y saliente según el grupo al que pertenezcan.

De esta forma, podremos tener los grupos servidores, usuarios y clientes y que clientes solo puedan verse entre ellos, mientras que usuarios y servidores puedan comunicarse bidireccionalmente.

Manos a la obra: configuración de Nebula


Vamos a partir de esta topología.

ree

Configuración lighthouse:

En primer lugar, configuraremos el servidor lighthouse, el cual yo he llamado principal. Para ello, deberemos descargarnos los binarios de su github: Descarga de binarios de Nebula


Yo los he descargado en todos los dispositivos en /opt por sencillez a la hora de hacer el laboratorio.

Si seguimos las instrucciones de la web oficial, descomprimimos el .tar.gz que se nos descarga y veremos que tenemos dos binarios: nebula y nebula-cert.


Procedemos a crear nuestra entidad certificadora:

./nebula-cert ca "Nombre de la empresa S.L"

Existen varios parámetros para esto, pero por lo que he visto, el certificado es válido por defecto 5 años.

Con el comando anterior habremos generado un ca.key y un ca.cert.

Ahora deberemos generar certificados, tanto para el lighthouse como para los clientes que queramos que se conecten a nuestra red nebula. Debemos tener presente que es aquí donde debemos indicar a qué grupos queremos que pertenezcan los clientes, para aplicar ACL más adelante.

./nebula-cert sign -name "principal" -ip "192.168.100.1/24"
./nebula-cert sign -name "cliente2" -ip "192.168.100.3/24"
./nebula-cert sign -name "cliente3" -ip "192.168.100.4/24"
./nebula-cert sign -name "cliente4" -ip "192.168.100.5/24"

Nota: para añadirlos a un grupo usaremos la flag -groups


Ahora nos descargamos el fichero de configuración base de su github, como indica la documentación oficial:

curl -o config.yml https://raw.githubusercontent.com/slackhq/nebula/master/examples/config.yml
cp config.yml config-lighthouse.yml

Ahora deberemos modificar ciertos parámetros. Por suerte, no son muchos.

En primer lugar, modificaremos la ubicación de los certificados:

ree

Luego cambiaremos el static_host_map. Aquí lo que hacemos es asociar nuestra IP de Nebula del lighthouse a una IP pública y un puerto.

ree

Posteriormente deberemos decirle que se trata de un lighthouse, modificando am_lighthouse y poniendolo en True. Si tuvieramos más lighthouses para hacer distribución o HA, deberemos indicarlo en hosts.

ree
ree

Procedemos a decirle al lighthouse que solo anuncie nuestra IP pública. Como podéis ver, yo estoy indicando la IP local del dispositivo, porque, para hacerlo más sencillo, he utilizado rutas en lugar de natear el dispositivo.

ree

Ahora le decimos que escuche en todas las interfaces por el puerto 4242 como se muestra a continuación.

ree

Y en la siguiente sección lo dejamos como en la imagen, para que haga el UDP hole punching.

ree


Configuración de clientes:

Aqui haremos lo mismo, configuraremos certificados y demás.

ree
ree
ree
ree

Aqui si que deberemos definir las reglas del firewall, que yo por simplificar he dejado en permitir todo el tráfico.

ree

Levantar la sesión tanto en el lighthouse y los clientes:

Lighthouse:

./nebula -config config-principal.yml

Clientes:

./nebula -config config.yml

Y podemos ver que se han establecido las conexiones con el lighthouse:

ree
ree

Vamos a probar la conectividad entre dos clientes.

Comprobamos sus IP:

ree
ree

Como vemos, se establece la conexión sin ningún tipo de problema.

Datos adicionales


Vamos a comprobar los certificados para ver que es lo que se esconde en ellos.

./nebula-cert print -path /home/test/certificados/cliente3.crt
ree

Y con esto ya tendríamos toda nuestra red overlay y totalmente segura.


¡Espero que os haya servido!

 
 
 

1 comentario


Luchi Puchi
Luchi Puchi
28 jul

Muy buen artículo. Me encanta cómo lo explicas con tono coloquial. Me apunto Nebula como una buena alternativa para entornos más dinámicos o distribuidos. Me guardo el artículo para futuras referencias.

Me gusta
bottom of page