OpenVPN en GCE: añade una IP alias antes de empujar rutas
Una ruta empujada no convierte la VM en next hop. Añade el rango de IP alias, hazlo coincidir con el pool del servidor y crea la ruta de retorno de la VPC antes de probar los clientes.
Un cliente marca el servidor OpenVPN en una VM de Compute Engine, la ventana de estado dice conectado, y un ping a un host dentro de la VPC sigue sin llegar a ninguna parte. El instinto es añadir otra línea push, y eso nunca lo arregla. Compute Engine decide adónde van los paquetes a partir de su propia tabla de rutas y de las direcciones que una interfaz de la VM tiene realmente, así que un pool de túnel que la VM no posee es un pool al que nadie entrega.
Sigue el paquete que falla en lugar del archivo de configuración, y las piezas que faltan aparecen en orden.
Empezar por el paquete que muere
El SYN sale del cliente, entra en el túnel y llega a la VM como un paquete encapsulado hacia un destino de la VPC. OpenVPN lo desencapsula e intenta reenviarlo por eth0, donde la fabric hace una pregunta antes que nada: esta instancia posee la dirección de destino. Un pool de túnel recortado de la subred de otro falla esa pregunta, y el paquete se descarta antes de que se consulte cualquier ruta o regla de firewall.
Así que la dirección de cliente a VPC tiene dos requisitos separados, y ninguno de los dos es una directiva push. La VM necesita un rango alias que cubra el pool de túnel, y eso es lo que la convierte en propietaria legítima de esas direcciones. La VPC necesita una ruta que nombre la VM como next hop para cada prefijo protegido. Si falta uno, el paquete muere en otro sitio, mientras el cliente ve el mismo silencio.
Lee el fallo en ese orden, porque desde el lado del cliente las dos condiciones son idénticas. Un túnel que dice conectado mientras nada responde es la firma de un problema de topología, no de un cifrado malo.
La instancia posee el pool de túnel
Da a la VM un rango secundario dentro de su propia subred y luego haz que OpenVPN reparta direcciones exactamente de ese rango. En una instancia cuya dirección primaria es 10.156.0.10/20, un alias /28 mantiene el pool separado de las direcciones que otras instancias ya tienen:
gcloud compute instances network-interfaces update openvpn-vm \
--zone=europe-west1-b \
--aliases=eth0:10.156.1.0/28La directiva server tiene entonces que describir el mismo bloque. Su primera dirección pasa a ser la puerta de enlace del túnel, y las direcciones restantes se reparten a los clientes. Aquí dos números describen un bloque, una red y una máscara de red, y esa es la sintaxis de pool que OpenVPN sigue esperando.
server 10.156.1.0 255.255.255.240Confirma que la dirección llegó de verdad a la interfaz y no solo dentro de la configuración de OpenVPN. La fabric reenvía lo que informa la NIC, no lo que cree el demonio. Un solo comando lo resuelve:
ip -4 addr show dev eth0Una dirección secundaria que nunca llega a eth0, o un pool que se solapa con otra subred, aparece más tarde como pérdidas intermitentes en lugar de como un error de arranque. El demonio arranca, los clientes se conectan y solo algunos destinos se comportan mal. Mantén pequeño el rango alias para que el pool sea fácil de reconocer en una tabla de rutas. Nunca lo recortes de una subred que otra instancia ya use.
Dar un next hop al tráfico de retorno
Una respuesta de un host de la VPC se dirige a una dirección de cliente del pool de túnel, que no pertenece a ninguna subred que la VPC conozca. Sin una ruta para ese pool, la respuesta se detiene en el primer salto sin coincidencia, y la petición bien pudo haber tenido éxito en el extremo remoto.
gcloud compute routes create openvpn-return \
--network=prod-vpc \
--destination-range=192.168.127.0/24 \
--next-hop-instance=openvpn-vm \
--next-hop-instance-zone=europe-west1-b \
--priority=800La misma ruta hace falta para cualquier prefijo que viva detrás de un cliente en lugar de dentro de la VPC. Esos prefijos también necesitan una entrada iroute en el archivo ccd de ese cliente. Esa entrada es contabilidad del lado del servidor: le dice al servidor qué cliente posee el prefijo, y no instala nada en el propio cliente.
Conserva la lista push para el lado cliente de la conversación, porque solo añade rutas a la máquina que se conecta. Una línea push para una subred de la VPC y una ruta de la VPC de vuelta al pool son dos mitades del mismo camino, y cualquiera de las dos mitades por separado produce un túnel que lleva peticiones pero no respuestas.
Firewalls, reenvío y los saltos intermedios
El firewall de la VPC evalúa el paquete desencapsulado, así que una regla de entrada tiene que admitir el pool de túnel y cualquier prefijo de sitio que llegue a la VM por esa vía. Una postura de denegación por defecto falla en silencio aquí: el paquete se descarta tras el desencapsulado, y el registro de OpenVPN muestra una sesión sana.
En cualquier host Linux que reenvíe en lugar de terminar, comprueba que net.ipv4.ip_forward está activado. La regla de propiedad también se aplica ahí: una máquina que reenvía para una subred que no tiene descarta el paquete igual que lo haría la VM. Lee el valor antes de culpar al túnel.
Cuando falla exactamente un prefijo
El fallo parcial es el caso más fácil de leer, porque todo lo demás del camino ya está demostrado. Empieza por la lista de rutas y lee el rango de destino y el next hop de la entrada que debería cubrir el prefijo, luego lee la descripción de la instancia y compara su rango alias con el pool que reparte el servidor.
gcloud compute routes list --filter=destination-range~10.164.0.0
gcloud compute instances describe openvpn-vm --format=get(networkInterfaces[0].aliasIpRanges)Una ruta que falta se muestra como ausencia de next hop para el prefijo, mientras que un alias que falta se muestra como un paquete descartado en la interfaz; desde el cliente las dos cosas se parecen y en esas dos salidas son completamente distintas. Si están las dos, el sospechoso restante es el iroute ccd del cliente que reclama el prefijo.
Punta los cuatro valores junto al túnel: rango alias, pool del servidor, prefijos empujados, rutas de la VPC. Un alias obsoleto rompe cada dirección del pool, una ruta obsoleta rompe un sentido del tráfico, un push ausente esconde el prefijo al cliente, y un iroute equivocado manda el prefijo al par equivocado. La siguiente persona que añada una subred necesita los cuatro en un solo sitio, y la nota sale más barata que la noche.