Interruptor de emergencia tras un cambio de Wi-Fi a datos móviles: qué se rompe
Un interruptor de emergencia se escribe contra nombres de interfaz que un cambio de red reemplaza. Comprueba la ruta exterior, las familias de direcciones y el resolutor antes de confiar en él.
En un momento el portátil está en la Wi-Fi de la oficina, al siguiente está conectado a un teléfono, y el indicador del túnel vuelve a estar verde antes de que termines de cambiar de ventana. La luz verde solo informa de que el túnel se ha reconectado; qué hizo la política de enrutamiento y bloqueo durante el hueco es otra pregunta. Esa política es un conjunto de condiciones de coincidencia compiladas cuando se instaló por última vez, y nombra una interfaz, una dirección y una familia de direcciones que el traspaso acaba de eliminar. El mismo cambio produce, por tanto, tres resultados que parecen idénticos: el bloqueo continúa, la política bloquea su propia recuperación o se abre una ruta que nada cubre.
Nada en pantalla separa esos tres estados, así que pregunta a qué identificadores estaban ancladas las reglas en lugar de qué color muestra el indicador. En Linux una regla puede nombrar una interfaz o un ipset llenado desde una; en Android se le puede decir a un VpnService qué redes subyacentes seguir mediante setUnderlyingNetworks. Cada anclaje apunta a un enlace que está a punto de ser reemplazado, y cada uno debe reevaluarse después.
Qué reescribe realmente el traspaso
Cuando el enlace antiguo desaparece, el núcleo elimina sus direcciones, retira las rutas que apuntaban a través de él y reconstruye la selección de dirección de origen con lo que queda. La ruta por defecto se mueve a la nueva puerta de enlace, y el índice de interfaz al que hacían referencia las reglas antiguas ha desaparecido o se ha reciclado para otro dispositivo. Los resolutores por enlace también se refrescan, aunque no en el mismo instante que las rutas. Todo esto ocurre por debajo del cliente VPN, así que un cliente que solo vigila el estado de su propio túnel no ve nada de ello.
El problema es que una regla codifica un identificador concreto en lugar de la intención que hay detrás. Una regla que descarta todo lo que no sale por la interfaz del túnel codifica un nombre de interfaz; una regla que permite el punto final codifica una dirección que la nueva red puede enrutar a otro sitio. Cuando el identificador desaparece, la regla no se vuelve visiblemente incorrecta: o deja de coincidir con nada o empieza a coincidir con lo equivocado.
Reconstruir el túnel exterior sin abrir un agujero
El transporte exterior estaba ligado a la dirección de origen antigua, así que tiene que abrir un socket nuevo desde la nueva. Cuando el punto final es un nombre de host y no una dirección literal, una consulta debe tener éxito mientras el bloqueo sigue vigente. Esa es la trampa del orden: una política lo bastante estricta como para descartar todo excepto el punto final también descartará la consulta necesaria para encontrarlo, salvo que la resolución ocurra antes de levantar el bloqueo o se transporte por un túnel que aún esté vivo. Cualquiera de los dos órdenes puede funcionar, pero solo si el cliente sabe en cuál está.
Los clientes difieren aquí de una forma que importa al diagnosticar. Algunos resuelven primero e instalan las reglas después, de modo que un traspaso cuesta una interrupción visible y luego se recupera solo; otros mantienen el bloqueo y dependen del túnel superviviente para llevar la consulta, lo que falla del todo cuando el túnel murió con el enlace. Añadir una ruta directa por defecto amplia para restaurar la conectividad siempre hace pasar la prueba y siempre deja la fuga que estabas evitando.
Una ruta que todavía apunta a la puerta de enlace antigua da la misma recuperación atascada por una causa distinta, así que lee la tabla antes de culpar al cliente. Los comandos de abajo nombran la interfaz y la dirección de origen que el núcleo usaría de verdad, lo que resuelve en una línea si la ruta antigua sigue instalada.
ip route get 1.1.1.1
ip -6 route get 2606:4700:4700::1111Cuando el enlace nuevo trae IPv6 y las reglas no
Las redes móviles y de invitados suelen repartir un prefijo IPv6 global aunque la LAN cableada de la oficina nunca lo haya hecho. Una política escrita solo como reglas IPv4, la forma por defecto de la mayoría de las recetas hechas a mano de iptables y nftables, no cubre nada de eso. El túnel sigue conectado, las aplicaciones con alcance IPv6 salen fuera de él, y el indicador no puede mostrar la diferencia porque el túnel realmente está levantado. El caso espejo es igual de común: un conjunto de reglas solo para IPv6 no hace nada en una red que no ofrece v6.
Compara lo que ofrece el enlace con lo que menciona la política, en ambos lados del traspaso. Estos comandos imprimen los mismos hechos con los que trabaja el cliente:
ip -4 route show default
ip -6 route show default
sudo nft list ruleset | grep -c 'ip6 'Si el segundo comando imprime una ruta por defecto mientras el tercero devuelve cero, el enlace nuevo puede sacar la máquina por IPv6 sin ninguna regla que lo vigile. Ejecuta los tres otra vez tras el cambio, porque el número interesante es la diferencia entre las dos ejecuciones. Si el segundo no imprime nada, se aplica el caso inverso y cualquier política cargada de v6 allí es solo decoración.
El resolutor cambia de manos a mitad de sesión
En los sistemas modernos los resolutores van ligados a los enlaces, así que un enlace nuevo llega con un conjunto nuevo de resolutores y quizá con una vista distinta de split-DNS. systemd-resolved mantiene un ámbito por enlace y elige entre ellos por ruta, mientras que macOS lee resolutores con ámbito del almacén dinámico y respeta el orden de interfaces. Un cliente que instala su propio resolutor compite con el del enlace, y las reglas de prioridad que nadie vigila deciden el ganador. Entonces la resolución de nombres puede romperse mientras el filtrado de paquetes hace exactamente aquello para lo que se escribió.
Lee el resolutor que está activo en lugar del configurado. En un host systemd el subcomando status muestra de qué enlace vino cada ámbito y si hay un nombre private-DNS en vigor:
resolvectl status --no-pager
resolvectl query intranet.example.comSi la consulta sale por el enlace físico en lugar del túnel, el cliente perdió la competición de prioridad y ningún ajuste del cortafuegos arreglará el nombrado. Compara el camino de la consulta en ambos lados del traspaso para ver cuál se movió. Un nombre que resuelve a una dirección privada que la red nueva no puede enrutar es un tercer caso, y se presenta como un tiempo de espera y no como un error.
Ensaya el traspaso y guarda el registro
Reproduce el cambio a propósito en lugar de esperarlo. Levanta el túnel en el primer enlace, inicia una transferencia larga y una consulta repetida, luego cambia el enlace y observa cuál sobrevive. Anota el intervalo entre la desaparición del enlace antiguo y el informe del túnel de que está conectado, porque en esa ventana la política o aguantó o no. Ejecuta la secuencia también en la otra dirección, para que el resultado no sea unilateral.
Las excepciones necesitan su propio paso, porque un bypass justificado en la red antigua no queda justificado automáticamente en la nueva. Una impresora, un NAS o un portal cautivo en la LAN de casa no tienen equivalente en la red móvil, y la excepción que llegaba a ellos se convierte en una regla sin equivalente.
Anota los nombres de interfaz, las familias ofrecidas, el resolutor en vigor y la duración de la interrupción para cada dirección. Una reconexión demuestra que el transporte se recuperó, no que el bloqueo aguantara durante el hueco, y son afirmaciones separadas que poner en un tique. Con ese registro el siguiente traspaso se compara con un estado conocido y no con la memoria.