Introducción #
En las redes en Azure con modelo Hub and Spoke hay que resolver la conectividad entre los diferentes spokes ya que los peerings no son transitivos; es decir, una spoke que necesite comunicar con un segundo spoke no podrá hacerlo de forma nativa. Este comportamiento se debe a cómo se propagan las rutas en Azure. Al crear un peering las dos VNET implicadas comparten las tablas de rutas entre ellas, pero no las comparten con otras VNETs.
En el ejemplo siguiente el Spoke 1 conocerá sus rutas internas y la ruta con el direccionamiento del Hub, pero no “conocerá” cómo alcanzar a Spoke n, ni siquiera sabrá su direccionamiento. El comportamiento es el mismo para Spoke n. En el caso del Hub, este conocerá el direccionamiento de dos spokes así como el camino a seguir para alcanzarlos.
Para habilitar esta conectividad es necesario un elemento de Azure desplegado en el Hub que habilite esta comunicación. El motivo de desplegarlo en el Hub es que es la única VNET que tiene todas las tablas de rutas y por lo tanto conoce cómo alcanzar a todos los spokes.
En Azure los elementos que pueden habilitar esta comunicación de forma nativa son:
- Azure Firewall: Permite tráfico TCP y UDP a capa cuatro y además es la única opción que permite centralizar el tráfico hacia internet. Adicionalmente permite trazabilidad del tráfico. El problema de Azure Firewall radica en el altísimo coste que supone por lo que no es viable económicamente para todos los proyectos.
- Application Gateway (con o sin WAF): Solo funciona con tráfico HTTP/S y no permite la salida a Internet por lo que cada elemento desplegado saldría a Internet con una IP diferente. La trazabilidad del tráfico es parcial y complicada de obtener.
- VPN Gateway: Permite tráfico TCP y UDP, pero no permite filtrado de tráfico ni centralizar la salida a Internet.
Como vemos, la mejor opción es usar Azure Firewall. Pero, ¿qué ocurre si nos interesa una topología Hub and Spoke y no podemos pagar el alto coste de Azure Firewall? En estos casos podemos desplegar una pareja de máquinas virtuales que hagan de enrutador entre VNETs y permitan centralizar la salida a Internet. La trazabilidad de la red se puede hacer utilizando NSG.
Este documento explica paso a paso cómo desplegar esta solución que, sin ser la más óptima, sí es la más económica.
Arquitectura #
El siguiente diagrama muestra la infraestructura objetiva:
Detalle de la infraestructura #
Queda fuera del alcance de este documento definir cómo se desplegará la infraestructura, aunque se recomienda hacerlo con IaC (Terraform, Bicep, etc.).
Componentes necesarios:
- 2× Máquina Virtual Linux desplegadas cada una de ellas en una Zona de disponibilidad diferente. Se podría desplegar una sola VM, pero perderíamos la alta disponibilidad y hay que tener en cuenta que una caída provocaría la pérdida total de nuestra red. Estas máquinas virtuales no tienen grandes requerimientos en cuanto a memoria o CPU: una máquina B1 sería suficiente, aunque si el escenario crece es probable que haya que hacer un escalado vertical.
- 2× Tarjetas de red (NIC) por VM. La tarjeta de red eth0 (pública) será desplegada en la public snet y se utilizará para el tráfico de salida; será la tarjeta de red primaria de la VM. La tarjeta de red eth1 será desplegada en la private snet y deberá tener habilitada la opción Enable IP Forwarding.
- 1× Balanceador Standard Interno (ILB). La IP de este balanceador será el punto de entrada de los enrutadores. Tendrá un único Backend Pool con las tarjetas de red eth1 y utilizará como Probe el puerto TCP 22. La regla de balanceo estará asociada a la IP interna y al único backend pool, habilitando la opción High availability Ports.
-
1× Balanceador Standard Externo (ELB) con una IP pública Standard y una única regla de salida (outbound rule): Este balanceador hará de punto de salida de todas nuestras comunicaciones. El balanceador usará como backend pool las tarjetas eth0 y como frontend una IP Pública Standard. Se le añadirá una regla outbound que será configurada según las necesidades de la infraestructura a desplegar.
-
Cada VNET Spoke contará con una UDR que tendrá como Next Hop la IP del balanceador interno y será de tipo Virtual Appliance.
-
(Opcional) Se puede vincular una NSG a cada una de las subnets para controlar el tráfico. La NSG asociada a la subnet pública llevará una regla de entrada que deniegue todo el tráfico.
Configuración del sistema operativo #
Una vez desplegada la infraestructura deberemos configurar iptables en el sistema operativo de las máquinas virtuales para que actúen como enrutadores.
Supongamos el siguiente diagrama con el siguiente direccionamiento:
Nota de gateways
- Subnet pública 10.0.2.0/24 → Gateway: 10.0.2.1 (primera IP de la subnet)
- Subnet privada 10.0.1.0/24 → Gateway: 10.0.1.1 (primera IP de la subnet)
IPs de las NIC:
- VM1 — eth0: 10.0.2.4
- VM1 — eth1: 10.0.1.4
- VM2 — eth0: 10.0.2.5
- VM2 — eth1: 10.0.1.5
A continuación se muestran los comandos a ejecutar en cada VM (hay que repetirlos en las dos VMs que actúan como enrutadores; cambiarán las direcciones en la tabla de rutas):
1) Habilitar IP Forwarding #
# enable ip forwarding
sudo sed -i 's/#net\.ipv4\.ip_forward=1/net\.ipv4\.ip_forward=1/g' /etc/sysctl.conf
2) Habilitar el routing (NAT de salida) #
# enable the routing
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
3) Instalar iptables-persistent y reiniciar #
# install software to save iptables on reboot
sudo apt-get update && sudo DEBIAN_FRONTEND=noninteractive apt-get install -y iptables-persistent
sudo iptables-save | sudo tee -a /etc/iptables/rules.v4
sudo reboot
4) Añadir las rutas #
# add the routes (eth1 = private, eth0 = internet)
sudo ip route add <destination_vnet_cidr> via <internal_snet_gateway_ip> dev eth1
sudo ip route add 168.63.129.16 via <internal_snet_gateway_ip> dev eth1 proto dhcp src <eth1-ip-address>
# persist on boot
sudo tee -a /etc/rc.local <<'EOF'
#!/bin/bash
/sbin/iptables-restore < /etc/iptables/rules.v4
ip route add <destination_vnet_cidr> via <internal_snet_gateway_ip> dev eth1
ip route add 168.63.129.16 via <internal_snet_gateway_ip> dev eth1 proto dhcp src <eth1-ip-address>
EOF
sudo chmod +x /etc/rc.local
Ejemplo VM1:
sudo ip route add 10.0.0.0/16 via 10.0.1.1 dev eth1
sudo ip route add 168.63.129.16 via 10.0.1.1 dev eth1 proto dhcp src 10.0.1.4
# persist on boot
sudo tee -a /etc/rc.local <<'EOF'
#!/bin/bash
/sbin/iptables-restore < /etc/iptables/rules.v4
ip route add 10.0.0.0/16 via 10.0.1.1 dev eth1
ip route add 168.63.129.16 via 10.0.1.1 dev eth1 proto dhcp src 10.0.1.4
EOF
sudo chmod +x /etc/rc.local
Ejemplo VM2:
sudo ip route add 10.0.0.0/16 via 10.0.1.1 dev eth1
sudo ip route add 168.63.129.16 via 10.0.1.1 dev eth1 proto dhcp src 10.0.1.5
# persist on boot
sudo tee -a /etc/rc.local <<'EOF'
#!/bin/bash
/sbin/iptables-restore < /etc/iptables/rules.v4
ip route add 10.0.0.0/16 via 10.0.1.1 dev eth1
ip route add 168.63.129.16 via 10.0.1.1 dev eth1 proto dhcp src 10.0.1.5
EOF
sudo chmod +x /etc/rc.local
Recomendaciones finales #
- Validar que IP Forwarding está habilitado en la NIC eth1 de las VMs.
- Comprobar que las UDR de los spokes apuntan al ILB como Virtual Appliance.
- Registrar y auditar el tráfico con NSG y flow logs si se requiere trazabilidad.
- El tráfico se podría filtrar mediante el uso de NSG, como si se tratara de un Firewall