Dos puertas de enlace, una VPN: por qué OpenVPN elige el enlace ascendente equivocado
El túnel está bien; el socket sale por la WAN equivocada. Lee la dirección del par activa, fija una ruta de host y revisa primero las reglas de política.
Dos enlaces ascendentes, un túnel, y el tráfico sale por el que no elegiste. Las subredes privadas son accesibles, el registro informa de una conexión correcta y es el enlace medido el que la transporta. Nada en la salida de OpenVPN menciona una puerta de enlace, porque el cliente nunca eligió una. Abrió un socket hacia una dirección remota y dejó que el núcleo decidiera cómo llegar a esa dirección.
La dirección del túnel no es el extremo
En cada sesión existen dos caminos distintos. El camino exterior transporta el tráfico cifrado hasta la dirección pública del servidor. El camino interior transporta todo lo que el servidor empuja dentro del túnel, y las reglas de enrutamiento de uno no afectan al otro.
La entrada remote del perfil nombra el destino exterior, así que esa es la dirección que hay que fijar. También es el valor que cambia cuando un nombre de host se resuelve de forma distinta o el perfil enumera varios remote.
Encuentra la dirección a la que el cliente marcó de verdad
Lee el socket activo en lugar del archivo de configuración. La tabla de sockets muestra el par al que el proceso se conectó realmente, y ese es el valor con el que debe coincidir la excepción. Un perfil puede editarse después de que empiece la sesión, y el socket es la única prueba de lo que se marcó:
ss -tunp | grep -i openvpn
journalctl -u openvpn-client@work --no-pager | grep -i "Peer Connection Initiated"
La línea del registro indica la dirección y el puerto del par en el momento de la conexión. Si no coincide con el perfil, algo delante del cliente reescribe el destino antes de que empiece la conexión.
Comprueba también la familia de direcciones. Un perfil de doble pila puede conectarse por IPv6 mientras tu excepción solo cubre IPv4, y entonces el tráfico sigue una regla distinta de la que escribiste. Lo mismo vale para un proxy que responde en nombre del extremo. Ambos casos producen un túnel que funciona mientras tu ruta no hace nada.
Fija el extremo y lee el orden de la política
Una ruta de host es más específica que cualquier ruta predeterminada. Por eso una /32 para la dirección del par gana dentro de la tabla que la contiene. La forma habitual nombra explícitamente la puerta de enlace y el dispositivo:
ip route add 203.0.113.40/32 via 192.168.10.1 dev eth0
Esa ruta solo ayuda si la búsqueda llega a esa tabla. Las reglas de política se evalúan en orden y la primera coincidencia decide, así que una regla que envía todo a una segunda tabla omite tu ruta de host en main. Lee las reglas antes de suponer que la ruta es autoritativa:
ip rule show
ip route get 203.0.113.40
Pregunta al segundo comando con la misma dirección de origen o marca que usa el cliente cuando la política depende de ellas. Informa de la ruta que el núcleo elegiría, lo que es una prueba sobre la búsqueda y no una prueba de que el socket activo use ese camino.
Cuando el extremo se mueve
Un nombre de host que se resuelve en varias direcciones invalida una /32 permanente en cuanto cambia la respuesta. Un perfil con varias líneas remote tiene el mismo problema, porque el cliente puede aterrizar en cualquiera de ellas. Refresca la ruta desde los propios ganchos del ciclo de vida del cliente en lugar de añadirla a mano. Un script up que lee el par negociado e instala la ruta de host mantiene la excepción alineada con la realidad, y un script down correspondiente la retira.
Registra el refresco en el mismo lugar que el resto de la configuración de enrutamiento del host. Una ruta que solo existe hasta el próximo reinicio es una prueba, no una corrección.
Mantén la política interior separada
Mover el camino exterior no da acceso a una nueva subred privada ni cambia qué destinos empuja el servidor dentro del túnel. La ruta de la capa inferior elige el cable; las rutas empujadas eligen qué entra en el túnel. Mantener esas dos decisiones separadas es lo que hace previsible la división.
Si el objetivo solo es mantener el transporte cifrado fuera de un enlace medido, deja la ruta predeterminada en paz y añade la única excepción de host. Sustituir la ruta predeterminada de toda la máquina para mover una sola conexión VPN rompe cualquier otra aplicación del host.
Confirma el resultado con dos observaciones independientes: la dirección local y el dispositivo del socket, y la ruta a la que se resuelve el destino privado. Cuando ambas coinciden con tu intención, la división es real. El manual de OpenVPN 2.6 cubre las opciones remote y de enlace local que deciden a qué dirección marca el cliente.