Túnel completo frente a ruta de extremo: mantener accesible el servidor VPN
El túnel viaja por la red que sustituye. Compare una excepción de ruta de host con una marca de socket a nivel de aplicación y sepa cuándo falla cada una.
Añada una ruta predeterminada por el túnel y los propios paquetes del túnel la seguirán. La tabla contiene entonces una regla que se derrota a sí misma. La conexión cifrada al servidor intenta viajar dentro de la conexión que intenta establecer.
Dos mecanismos evitan ese bucle. Uno es visible en la tabla de rutas, el otro vive dentro de la aplicación.
El tráfico interno y el externo son decisiones distintas
Un paquete de aplicación entra en la interfaz virtual y se encapsula. El resultado es un paquete nuevo dirigido a la dirección pública del servidor. Ese paquete necesita una ruta en la red física, porque nada de él puede entrar en el túnel.
Ambas son decisiones de enrutamiento, y solo la primera pertenece al túnel. Cuando el cliente instala una ruta predeterminada que también cubre el servidor, el paquete externo también queda capturado.
Los síntomas son inmediatos y totales. El handshake se completa y después no fluye nada, o la conexión cae en el instante en que se instala la ruta. En ambos casos el keepalive ya no puede salir.
Opción uno: una ruta de host para el extremo
El enfoque directo añade una ruta para la dirección del servidor a través de la puerta de enlace original. Solo requiere una línea. Es visible para cualquiera que lea la tabla. También es fácil de explicar en un registro de cambios.
Su debilidad aparece cuando cambia la ruta subyacente. La ruta guardada nombra una puerta de enlace y una interfaz de la red antigua. Tras un cambio de Wi-Fi esa puerta de enlace puede no existir, y la ruta se queda atrás, parece correcta y no hace nada.
# before the tunnel: which path reaches the endpoint?
ip route get 198.51.100.7
# pin it through the current gateway
ip route add 198.51.100.7/32 via 192.168.1.1 dev wlan0
# after the tunnel is up, confirm the pin survived
ip route get 198.51.100.7
Un nombre de host lo dificulta. Si el extremo es un nombre que se resuelve en varias direcciones, la exclusión debe cubrir la dirección realmente en uso. Una consulta posterior puede devolver algo que la ruta nunca cubrió.
Opción dos: proteger el socket
El otro enfoque nunca toca la tabla de rutas. El cliente marca o protege el socket que transporta el túnel, de modo que el sistema operativo envía el tráfico de ese socket fuera del túnel por política. Android expone el mecanismo directamente a las aplicaciones VPN. Los clientes de escritorio implementan equivalentes con marcas de firewall o llamadas de vinculación al dispositivo.
La ventaja es que la excepción sigue a la conexión en lugar de a una puerta de enlace guardada. Un cambio de red reescribe la ruta subyacente, y el socket protegido se mueve con ella porque nunca estuvo fijado a una dirección. La tabla de rutas se mantiene limpia.
El coste es la visibilidad. Nada en la tabla de rutas muestra la excepción, así que un revisor que busca una ruta de host no encuentra nada y puede concluir que el diseño es inseguro. La protección vive en el código del cliente y en las reglas de política que ese código instala.
Elegir entre ambas
Elija el mecanismo de nivel de socket cuando el cliente lo admita, porque sobrevive a los cambios de red que rompen una ruta fijada. Elija la ruta de host cuando la excepción deba ser visible para otras herramientas o cuando el cliente no ofrezca nada mejor.
Ninguno de los dos mecanismos elimina la necesidad de que la dirección del servidor sea accesible. Una puerta de enlace privada tiene una dirección pública de escucha, y esa dirección es la que debe quedar fuera del túnel. Las redes internas que hay detrás solo son accesibles una vez que existe el túnel.
Elija lo que elija, manténgalo junto al componente que posee el túnel. Una ruta de host suelta añadida a mano funciona hasta la siguiente red, y entonces se convierte en la misteriosa caída de mañana.