WireGuard anidado: el salto intermedio no puede responder a su propio puerto
Cuando el salto intermedio lo envía todo por un solo túnel, las respuestas a su servicio de entrada salen por el camino equivocado. Una regla de puerto de origen en la interfaz lo arregla.
Tres saltos de WireGuard llegan a una red sin dirección pública, y entonces la máquina intermedia deja de responder en el puerto en el que se suponía que debía escuchar. El túnel hacia delante sigue funcionando, el host remoto sigue respondiendo, y solo el servidor intermedio se ha quedado callado desde fuera. Esa combinación desconcierta precisamente porque es autoinfligida: el salto intermedio obedece su propia tabla de enrutamiento, y la tabla envía sus respuestas por el camino equivocado.
Una cadena que funciona hasta que hablas con la caja intermedia
Tomemos una cadena ilustrativa: el cliente A llega al servidor B por UDP 500, y B llega más allá al servidor C por UDP 500. C solo acepta tráfico de la dirección de su único par, lo que lo convierte en una hoja y mantiene simple su comportamiento. B no es una hoja, y todo lo interesante de este fallo ocurre allí.
La distinción importa porque los papeles de hoja e intermedio tiran en direcciones opuestas. Una hoja puede enviarlo todo por un solo túnel sin consecuencias, ya que nada más depende de ella. Un salto intermedio es a la vez un extremo para los clientes y un cliente hacia el lado remoto, y esos dos trabajos quieren un enrutamiento distinto.
Por qué la respuesta sale por el túnel
En B, la interfaz que mira hacia C lleva AllowedIPs = 0.0.0.0/0 junto con la ruta predeterminada correspondiente. Por tanto, cada paquete que B origina entra en ese túnel, salvo que algo más específico tenga prioridad.
Un paquete de A dirigido a B llega y se acepta, porque B es el destino y la entrega local ocurre primero. La respuesta es un paquete completamente nuevo generado localmente y dirigido a la dirección pública de A, y ese destino coincide con la ruta predeterminada hacia el túnel. C lo recibe, no posee esa dirección y lo descarta.
El síntoma se lee como un problema de cortafuegos o un desajuste de claves, y aquí ninguna de las dos cosas es cierta. Una captura en el túnel hacia C muestra que las respuestas van en la dirección equivocada. Esa única observación ahorra más tiempo que cualquier cantidad de lectura de configuración, así que anótela antes de empezar a cambiar claves. Quien no haya visto la captura asumirá que el túnel mismo está roto.
La reparación estrecha: reglas de política que coinciden con un puerto de origen
Las respuestas del socket de escucha de B salen con el puerto de origen 500. Una regla de política puede coincidir con eso y devolver esos paquetes a la tabla ordinaria:
ip rule add sport 500 table main priority 100
ip rule add sport 8080 table main priority 101
Las reglas de política se consultan por orden de prioridad, y la tabla principal está en 32766, así que una regla en 100 se pregunta antes de que la ruta predeterminada del túnel tenga nada que decir. Añada una entrada por cada puerto que deba seguir siendo accesible desde fuera y nada más, para que el tráfico reenviado siga usando el túnel para el que se construyó.
Conozca el límite de este truco. El selector sport coincide con paquetes generados localmente, lo que cubre exactamente el caso de la respuesta y deliberadamente no cubre el tráfico que B solo reenvía para otro. Un servicio alojado detrás de B todavía necesita su propia respuesta, y fingir lo contrario produce una solución que funciona para el primer servicio y falla para el segundo.
Dele un dueño a la regla
Una regla escrita en un indicador desaparece la próxima vez que se reconstruya la interfaz. En una instalación de WireGuard, póngala donde se crea y se elimina la interfaz:
PostUp = ip rule add sport 500 table main priority 100
PostDown = ip rule del sport 500 table main priority 100
Si NetworkManager, un gancho de la distribución o un punto de entrada de contenedor es el dueño de la interfaz, el par pertenece a ese dueño y no a un archivo editado a mano. Compruebe las reglas efectivas tras una reconexión, no solo tras el primer arranque, porque el primer arranque es el caso que siempre funciona.
Compare las alternativas con honestidad
La regla de puerto de origen es una de cuatro salidas, y es la más estrecha de todas. Tiene la ventaja de no tocar en absoluto la política del túnel, por lo que suele sobrevivir a cambios posteriores. Las reparaciones estrechas también fallan ruidosamente cuando dejan de aplicarse, mientras que una excepción amplia sigue funcionando en silencio mucho después de que la razón haya desaparecido. Esa diferencia importa más que la elegancia cuando otra persona es dueña de la caja dentro de dos años.
| Approach | What it costs | Where it breaks |
|---|---|---|
| Source-port policy rule | One rule per exposed port | Anything B forwards rather than originates |
| Destination exception route | A route pinned to specific client addresses | Clients whose address changes |
| Stop full-tunnelling on B | Loses the catch-all path toward C | Designs that depend on it |
| Split into two tunnels | More interfaces and more policy | Nothing, at the cost of complexity |
Verifique desde ambos extremos una vez que haya elegido. Desde A, inicie una conexión al puerto de B y manténgala ocupada un rato. En B, haga que el núcleo justifique la ruta de respuesta con algo como ip route get <address-of-A> sport 500, y confirme que nombra la interfaz WAN en lugar del túnel. Después, compruebe que algo detrás de C sigue respondiendo a través de la cadena, lo que demuestra que la excepción siguió siendo estrecha en vez de convertirse en un desvío. Por último, anote los puertos en las notas de diseño, o el siguiente operador lo redescubrirá en otro servicio.