top of page

DMVPN con VyOS: VPN dinámicas

  • jogofus
  • hace 3 horas
  • 5 Min. de lectura

El otro día salió un tema que, a mí personalmente, me fascina: las VPN site-to-site dinámicas.

Hasta el día de hoy siempre he utilizado protocolos propietarios: DMVPN en Cisco, ADVPN en Fortigate...


Por todos es sabido que no me gusta quedarme con lo estándar, con lo que te da un único fabricante. Me gusta, sobretodo, lo opensource.


Es por ello que estuve investigando y encontré una alternativa, y además, con un software que lleva tiempo ganándose mi respeto (y mi cariño, por qué no).

Resulta que leyendo la documentación de VyOS éste permite crear DMVPN, y además tenemos la ventaja de que VyOS, al ser una distribución Linux (Debian concretamente) podemos instalarlo tanto bare-metal como virtualizado. No entro en el debate de si un router/firewall debe estar virtualizado, cada uno escoge lo que más le conviene. En mi opinión particular, router/firewall siempre bare-metal.


Pero empecemos...

¿Qué es DMVPN?

DMVPN son las siglas de Dynamic Multipoint VPN, evolución que (creo) es natural al típico Hub-and-Spoke.


En la topología Hub-and-Spoke todo el tráfico pasa por el HUB. Esto tiene sus partes positivas y negativas.

En cuanto las positivas es que puedes filtrar el tráfico recibido en el HUB, pero en cuanto a los contras es que puedes saturar tanto el/los enlaces WAN como el hardware dedicado al HUB.

¿Es DMVPN un protocolo? La respuesta es no.


DMVPN se trata de una arquitectura overlay que combina protocolos de túnel, cifrado y enrutamiento para establecer y gestionar conexiones VPN spoke-to-spoke de forma dinámica sin una configuración estática previa en el hub.

Componentes de DMVPN

Como he comentado en el párrafo anterior, DMVPN es un conjunto de protocolos que permiten el funcionamiento.

Cada uno se encarga de una cosa en particular.


mGRE: Interfaces de túnel GRE multipunto

Los túneles mGRE permiten que los sitios remotos (spokes) utilicen una única interfaz GRE para múltiples túneles IPsec.

GRE establece túneles punto a punto (P2P) pudiendo transportar múltiples protocolos de capa 3 (de esto hablamos en una anterior entrada) pero no ofrece ni cifrado ni autenticación.

Si tuviéramos 10 sucursales conectadas al hub central necesitaríamos 10 túneles GRE.

Como es obvio, esto genera problemas de escalabilidad.


Para subsanar esto apareció mGRE, que es una extensión del protocolo que permite que un solo túnel soporte múltiples peers.

En lugar de definir un único destino del túnel se configura como multipunto, permitiendo que múltiples routers participen en la misma interfaz del túnel.


NHRP: Next Hop Resolution Protocol

Actúa como protocolo de resolución de direcciones distribuido.

Permite a los spoke descubrir dinámicamente las direcciones IP públicas del resto de spokes a través del HUB, pudiendo así establecer comunicación directa.

En primer lugar, los spoke se registran en el hub con su dirección NBMA (Non-Broadcast Multi-Access; IP pública) mapeada a su dirección del túnel.

Los spoke realizan una solicitud al next hop server (NHS), el HUB, para obtener la dirección física del otro spoke.


En mGRE, la interfaz del túnel tiene una IP lógica (overlay), pero para construir un paquete GRE el router necesita conocer la IP real del underlay del peer destino, siendo esta la función del protocolo NHRP.


El NHS (el HUB) mantiene una base de datos NHRP, similar a ARP, en la que se mapea la IP lógica del túnel con la IP pública.

Además, NHRP facilita la comunicación entre spokes aún cuando estos se encuentran detrás de NAT.


IPsec: La seguridad detrás de todo esto

Sobre IPsec he hablado bastante en este blog, así que poco me voy a detener.


En definitiva, mGRE y NHRP no ofrecen cifrado, por lo que la comunicación sería en plano y cualquiera que "estuviera en medio" podría ver nuestro tráfico.

Para evitar esto, hacemos uso de IPsec.

El ingrediente que falta: BGP como plano de control

Todo esto queda muy bien, pero si no conocemos las redes que están disponibles para acceder de poco nos sirve.

Podríamos hacerlo de forma manual, con rutas estáticas, y funcionaría, pero no es escalable.


Imaginad cinco sedes con 10 redes cada una.

Ahora imaginad que pasais a tener 10 sedes.


Yo, por lo menos, no querría vivir eso.


Para evitar esto haremos uso de BGP y poder compartir los prefijos (las redes detrás de nuestro router) para poder comunicarnos entre ellas.

Como hacemos uso de mGRE (extensión de GRE) podemos encapsular tráfico multicast y por ello podríamos hacer uso de OSPF, pero en este caso he preferido usar BGP.

Vamos con lo bueno: el laboratorio

Ya sabéis que a mi me gusta demostrar las cosas con hechos.

Para este ejemplo he preparado un laboratorio muy sencillo, compuesto por dos SPOKE y un HUB. No he añadido ninguna máquina Windows/Linux para hacer las pruebas ya que no era necesario.

Tampoco he creado muchas redes por router, sino que he creado una red por router para comprobar que llega de una a otra sin pasar por el HUB.


HUB:

WAN - 1.1.1.1/24

IP tunel GRE - 10.0.0.1/32


SPOKE1:

WAN - 1.1.1.2/24

IP tunel GRE - 10.0.0.2/32

LAN - 192.168.11.1/24


SPOKE2:

WAN - 1.1.1.3/24

IP tunel GRE - 10.0.0.3/32

LAN - 192.168.21.1/24



En primer lugar deberemos configurar las interfaces, paso que aquí vamos a saltarnos por obviedades.


Después, procedemos a crear el túnel mGRE.


HUB:

set interfaces tunnel tun10 address 10.0.0.1/32
set interfaces tunnel tun10 encapsulation gre
set interfaces tunnel tun10 enable-multicast
set interfaces tunnel tun10 parameters ip key 1
set interfaces tunnel tun10 source-interface eth0

SPOKE1:

set interfaces tunnel tun10 address 10.0.0.2/32
set interfaces tunnel tun10 encapsulation gre
set interfaces tunnel tun10 enable-multicast
set interfaces tunnel tun10 parameters ip key 1
set interfaces tunnel tun10 source-interface eth7

SPOKE2:

set interfaces tunnel tun10 address 10.0.0.3/32
set interfaces tunnel tun10 encapsulation gre
set interfaces tunnel tun10 enable-multicast
set interfaces tunnel tun10 parameters ip key 1
set interfaces tunnel tun10 source-interface eth7

Aquí podréis ver que en los spoke pone eth7 mientras que en la captura de pantalla aparece eth0. Esto es debido a un pequeño bug en mi entorno de EVE-ng, concretamente con VyOS, que asigna nombres aunque luego no corresponden.


El siguiente paso es configurar el protocolo que nos permitirá descubrir al resto de spokes.


HUB:

set protocols nhrp tunnel tun10 authentication Test123
set protocols nhrp tunnel tun10 holdtime 300
set protocols nhrp tunnel tun10 multicast dynamic
set protocols nhrp tunnel tun10 network-id 1
set protocols nhrp tunnel tun10 redirect
set protocols nhrp tunnel tun10 registration-no-unique

SPOKE1:

set protocols nhrp tunnel tun10 authentication Test123
set protocols nhrp tunnel tun10 holdtime 300
set protocols nhrp tunnel tun10 multicast dynamic
set protocols nhrp tunnel tun10 network-id 1
set protocols nhrp tunnel tun10 nhs tunnel-ip dynamic nbma 1.1.1.1
set protocols nhrp tunnel tun10 registration-no-unique
set protocols nhrp tunnel tun10 shortcut

SPOKE2:

set protocols nhrp tunnel tun10 authentication Test123
set protocols nhrp tunnel tun10 holdtime 300
set protocols nhrp tunnel tun10 multicast dynamic
set protocols nhrp tunnel tun10 network-id 1
set protocols nhrp tunnel tun10 nhs tunnel-ip dynamic nbma 1.1.1.1
set protocols nhrp tunnel tun10 registration-no-unique
set protocols nhrp tunnel tun10 shortcut

Como se puede apreciar, lo que diferencia a un spoke del NHS es que en el HUB le indicamos que redirija, mientras que en los spoke nos registramos en el NHS y aplicamos un shortcut.


Ahora, para conocer la red a la que queremos acceder, creamos una ruta estática. En el HUB le indicaremos la interfaz, mientras que en los spoke le indicaremos que el next-hop es el HUB.


HUB:

set protocols static route 10.0.0.0/24 interface tun10

SPOKE1:

set protocols static route 10.0.0.0/24 next-hop 10.0.0.1

SPOKE2:

set protocols static route 10.0.0.0/24 next-hop 10.0.0.1

Configuramos ahora los túneles IPsec. En todos va a ser la misma configuración:

set vpn ipsec esp-group ESP-HUB lifetime 1800
set vpn ipsec esp-group ESP-HUB mode transport
set vpn ipsec esp-group ESP-HUB pfs dh-group14
set vpn ipsec esp-group ESP-HUB proposal 1 encryption aes256
set vpn ipsec esp-group ESP-HUB proposal 1 hash sha256
set vpn ipsec ike-group IKE-HUB key-exchange ikev2
set vpn ipsec ike-group IKE-HUB lifetime 3600
set vpn ipsec ike-group IKE-HUB proposal 1 dh-group 14
set vpn ipsec ike-group IKE-HUB proposal 1 encryption aes256
set vpn ipsec ike-group IKE-HUB proposal 1 hash sha256
set vpn ipsec interface eth0
set vpn ipsec profile NHRPVPN authentication mode pre-shared-secret
set vpn ipsec profile NHRPVPN authentication pre-shared-secret Secreto123
set vpn ipsec profile NHRPVPN bind tunnel tun10
set vpn ipsec profile NHRPVPN esp-group ESP-HUB
set vpn ipsec profile NHRPVPN ike-group IKE-HUB

Y para finalizar, configuraremos el protocolo de enrutamiento dinámico para que sepan donde están las redes a las que queremos acceder.


HUB:

set protocols bgp system-as 65000
set protocols bgp parameters router-id 10.0.0.1
set protocols bgp listen range 10.0.0.0/8 peer-group SPOKES
set protocols bgp peer-group SPOKES remote-as external
set protocols bgp peer-group SPOKES update-source tun10
set protocols bgp peer-group SPOKES address-family ipv4-unicast soft-reconfiguration inbound
set protocols bgp peer-group SPOKES address-family ipv4-unicast allowas-in

SPOKE1:

set protocols bgp system-as 65001
set protocols bgp parameters router-id 10.0.0.2
set protocols bgp neighbor 10.0.0.1 remote-as 65000
set protocols bgp neighbor 10.0.0.1 update-source tun10
set protocols bgp neighbor 10.0.0.1 address-family ipv4-unicast soft-reconfiguration inbound
set protocols bgp address-family ipv4-unicast network 192.168.11.0/24

SPOKE2:

set protocols bgp system-as 65002
set protocols bgp parameters router-id 10.0.0.3
set protocols bgp neighbor 10.0.0.1 remote-as 65000
set protocols bgp neighbor 10.0.0.1 update-source tun10
set protocols bgp neighbor 10.0.0.1 address-family ipv4-unicast soft-reconfiguration inbound
set protocols bgp address-family ipv4-unicast network 192.168.11.0/24

Comprobaciones finales

Como siempre, vamos a comprobar que todo funciona como se espera.


HUB:


SPOKE1:


Como se ve, solo hay una VPN establecida, pero si intento generar tráfico hacia la red 192.168.21.0/24 ocurre lo siguiente:


¡Se acaba de generar otra VPN! Esta vez con el spoke con el que queremos hablar, por lo que el tráfico no pasará por el HUB.


Y con esto terminamos la implementación de DMVPN, un conjunto de protocolos que facilita mucho la gestión de conexiones entre sedes y que, además, es fácilmente escalable.


 
 
 

Comentarios


bottom of page