Dos demonios de OpenVPN pueden informar ambos de un túnel correcto mientras la puerta de enlace envía a cada cliente por el mismo. Nada en el handshake decide qué túnel usa un cliente; lo decide el núcleo, paquete a paquete, recorriendo las reglas de política y después la tabla que cada regla nombra. Visto así, la configuración deja de tratar de opciones de OpenVPN y se convierte en una matriz de enrutamiento con dos propietarios.

El núcleo decide, no el demonio

Un paquete reenviado llega a la interfaz LAN y el código de enrutamiento evalúa la lista de reglas por orden de prioridad. La primera regla cuyo selector coincide nombra una tabla, y las rutas de esa tabla eligen el dispositivo de salida. Si la tabla no tiene una ruta coincidente, la búsqueda continúa hacia la siguiente regla, y ese es el detalle que hace que una configuración a medias falle en silencio en lugar de ruidosamente.

El proceso del túnel no tiene nada que decir en ese recorrido. Crea una interfaz y puede instalar rutas, pero si el paquete de un cliente concreto entra en esa interfaz depende por completo de la tabla a la que se envió. Por eso dos túneles con rutas importadas idénticas compiten, y el último que escribe gana para todos. Esa es la razón por la que una configuración puede verse equilibrada en los archivos y aun así enviar a todos los clientes por un solo demonio.

Dé a cada instancia su propio conjunto de recursos

Empiece por los nombres, porque los nombres reutilizados son la forma en que las dos instancias acaban compartiendo estado por accidente. Asigne dispositivos de túnel distintos, archivos de configuración distintos, credenciales distintas y unidades de servicio distintas. Anote el punto final exterior y la dirección del túnel de cada instancia en la misma tabla que la matriz de política, para que un cambio posterior tenga un solo lugar donde mirar.

dev tun-office
route-nopull
pull-filter ignore "redirect-gateway"

dev tun-lab
route-nopull

route-nopull mantiene las rutas que empuja un servidor fuera de la tabla local, que es justo lo que quiere cuando las tablas de política deben ser explícitas. Si un servidor determinado empuja también una opción redirect-gateway, y si su versión de cliente admite la forma con filtro, conviene comprobarlo en el manual en lugar de suponerlo.

Escriba la matriz: origen, tabla, dispositivo

Para cada grupo de clientes, añada una regla que seleccione una tabla por dirección de origen y luego ponga el camino deseado en esa tabla:

ip rule add from 10.8.1.0/24 lookup 100 priority 1000
ip rule add from 10.9.1.0/24 lookup 200 priority 1000
ip route add default dev tun-office table 100
ip route add default dev tun-lab table 200

La tabla necesita las rutas de destino que el grupo debería tener, más las excepciones locales o de gestión que mantengan utilizable la puerta de enlace. Una tabla que solo contiene una ruta predeterminada es una política de túnel completo para ese grupo, lo que puede ser exactamente lo correcto, pero debería ser una decisión y no una omisión.

El transporte del propio túnel no está en un grupo de clientes

Los paquetes cifrados de cada demonio se originan en la propia puerta de enlace y van dirigidos al par exterior. Una regla que solo coincide con un prefijo de origen de cliente deja tranquilos esos paquetes, y por eso las reglas limitadas al origen son más seguras que las que coinciden con todo. Una regla sin selector puede capturar el transporte del propio túnel y devolverlo por un túnel, y entonces la conexión falla de una manera que parece un problema del proveedor.

Mantenga la sesión de gestión local y la ruta de la capa inferior explícitamente fuera de las tablas de política. Anote esas excepciones junto a la matriz; forman parte del diseño, no son una solución provisional que haya que redescubrir durante un incidente.

Elegir un camino no lo permite

El permiso de reenvío es una segunda decisión que se toma más adelante en el camino. Una regla de cortafuegos que acepta paquetes que salen por el segundo túnel no hace que el código de enrutamiento lo elija, y una tabla correcta no concede permiso para reenviar. Ambas cosas deben existir, y una prueba que solo demuestra una le engañará sobre la otra. Cuando un grupo funciona y el otro no, compruebe esos dos pasos por separado en lugar de reescribir las tablas.

La traducción de origen es una tercera decisión, y debería acotarse al grupo de origen y al dispositivo de túnel que realmente lo transporta. Añada una cadena dedicada para las dos instancias en lugar de vaciar la cadena postrouting, porque servicios no relacionados pueden tener entradas allí y un vaciado las elimina en silencio.

Qué ocurre cuando cae un túnel

Decida el comportamiento ante fallos de antemano. Cuando una tabla de túnel pierde su ruta, la búsqueda cae a la siguiente regla y el tráfico del grupo continúa por el otro túnel o por el enlace ascendente normal sin ningún error. Si eso no es aceptable, añada una regla de terminación con un número de prioridad más bajo que devuelva un resultado inalcanzable para ese origen, para que la pérdida sea visible en lugar de quedar absorbida.

Envíe una petición nueva desde cada grupo de origen y anote cuatro hechos: la tabla seleccionada, el dispositivo de salida, el origen traducido y si la respuesta volvió por el mismo camino. Luego baje un túnel y repita. Dos dispositivos TUN en una lista de interfaces demuestran que ambos demonios arrancaron; no dicen nada sobre cuál usó un cliente concreto. La segunda ejecución, con un túnel menos, es la que muestra si su regla de reserva hace lo que pretendía.

Artículos relacionados