La VPN se conecta, la barra de menús lo muestra y un host interno sigue sin responder. En esa situación hay tres causas candidatas, y cuál se aplica depende de cómo se configuró el túnel. O bien el comando de ruta usó una dirección de host donde se requería una dirección de red, o bien el propio perfil instala una ruta predeterminada que se traga la decisión, o bien el cliente es un túnel PPP que necesita un hook en lugar de una clave de perfil. Compruébelas en ese orden, porque la primera es la más barata de descartar.

El destino es una dirección de red, la máscara describe el prefijo

networksetup -setadditionalroutes toma ternas de destino, máscara de subred y puerta de enlace. La llamada que envía una subred interna por el túnel se ve así:

sudo networksetup -setadditionalroutes "VPN (L2TP)" 192.168.1.0 255.255.255.0 10.2.0.0

Fíjese en qué es el destino: la dirección de red, no la dirección del servidor que intenta alcanzar. En el caso que produjo este artículo, el comando idéntico con 192.168.1.20 en esa posición no hizo nada útil, y sustituirlo por 192.168.1.0 funcionó de inmediato. Misma máscara, misma puerta de enlace, un número distinto. Ese es todo el fallo en miniatura.

La razón es aritmética, no política. Una dirección de host emparejada con una máscara /24 no describe 192.168.1.0/24; describe algo que la tabla de enrutamiento no puede retener de forma útil, así que la entrada se rechaza o se ignora y el túnel acaba llevando menos de lo que pretendía.

Cuando quiera exactamente un host, use la dirección de host con una máscara 255.255.255.255. Los pares mixtos son donde esto falla, no el uso de una dirección de host como tal. Una /32 construida a partir de una dirección es una ruta legítima; una /24 construida a partir de una dirección es un error.

La llamada reemplaza la lista, y el nombre es literal

Dos comportamientos sorprenden a la gente en el primer intento. El comando establece la lista completa de rutas adicionales en lugar de añadir, así que una llamada que agrega un prefijo elimina en silencio las demás que estaban antes. Construya todo el conjunto en una sola invocación.

El nombre del servicio tampoco es la etiqueta que usted inventó. Léalo de la herramienta y cópielo exactamente, incluido el sufijo de tipo:

networksetup -listallnetworkservices

Un nombre que difiere en un carácter no produce ningún error que valga la pena leer ni ninguna ruta. Copiar y pegar es la técnica correcta aquí, no volver a escribir de memoria.

Cuando el perfil reclama la ruta predeterminada

Las rutas divididas pierden frente a una ruta predeterminada para cualquier destino que no cubran explícitamente, y un perfil L2TP configurado para túnel completo instala exactamente eso. Si el perfil dice que todo pasa por el túnel, la lista de rutas adicionales cambia muy poco. Su entrada no es incorrecta; simplemente es irrelevante para los destinos que nunca nombra. El control de esto suele estar en el ajuste de enviar todo el tráfico del perfil, no en ningún comando de ruta.

Decida qué modelo quiere realmente antes de editar más entradas. El túnel completo con excepciones es una configuración distinta del túnel dividido con prefijos concretos, y mezclar los dos produce una tabla que nadie puede predecir.

Si la organización exige túnel completo, deje de intentar dividirlo localmente y lleve el requisito a quien posea la política. Una ruta añadida localmente que la contradiga será eliminada por la próxima actualización del perfil de todos modos.

Los túneles PPP necesitan un hook en lugar de una clave

Para los túneles basados en PPP, defaultroute es la clave del perfil que crea una ruta predeterminada; elimínela y el cliente deja de reclamar cada destino. Luego se añaden rutas después de que aparezca la interfaz, normalmente desde /etc/ppp/ip-up:

#!/bin/sh
/sbin/route add -net 192.168.1.0 -interface ppp0

Mantenga el script en propiedad de root y ejecutable, y añada una protección sobre el nombre de la interfaz cuando exista más de un perfil de túnel en la máquina. Un hook que se ejecuta para cada enlace PPP y asume un solo nombre de dispositivo es un error pequeño con una vida larga.

Verifique la división con tres peticiones

Capture la tabla mientras está conectado y anote qué interfaz sirve al túnel. Luego compruebe el destino concreto en lugar de confiar en el estado de salida del comando que lo creó. Un código de salida informa si la herramienta aceptó los argumentos, no si el tráfico toma el camino que pretendía.

Termine con tres peticiones que demuestren la división: un host interno por dirección, un nombre interno a través del resolutor interno y un sitio público que todavía debería usar la conexión local. Si el sitio público ahora también viaja por el túnel, la división nunca ocurrió, diga lo que diga la lista de rutas.

Vuelva a conectar una vez más y repita la petición interna, porque las rutas añadidas a mano pueden sobrevivir a la interfaz que las hizo válidas y convertir en silencio el tráfico en un agujero negro después de que caiga el túnel.

Artículos relacionados