Tu túnel está activo, el servicio escucha y la LAN de la oficina sigue sin recibir nada de vuelta. Nadie ha roto la VPN. Desde el lado de la LAN, la dirección de túnel del portátil no existe hasta que algo le dice a la LAN cómo llegar a ella, y la respuesta tiene que volver por el mismo camino por el que salió la petición. He visto a gente reconstruir un túnel perfectamente bueno tres veces antes de que alguien mirara el camino de vuelta.

El túnel no es lo que se rompió

Ambos extremos están en rangos privados, que es el caso normal y no una mala configuración. Una dirección como 10.8.0.6 es real dentro del túnel e inexistente en cualquier otro sitio, así que la LAN no tiene motivo para enviarle nada. Antes de tocar el enrutamiento, confirma que el servicio es alcanzable dentro del túnel: en el cliente, ss -ltn muestra si el oyente se enlaza a 127.0.0.1, a la interfaz de la LAN o a la dirección del túnel. Un demonio enlazado solo a loopback no responde a nadie más que a sí mismo, y ninguna ruta, DNAT o redirección de puerto lo cambia.

Un proxy en el puerto 80 o 443 es otra herramienta con otra visibilidad. Mueve peticiones, no paquetes, así que es la capa equivocada para una conexión directa a una base de datos, y recurrir a él es como este problema acaba tres herramientas más adentro antes de que alguien mida algo.

Forma de ruta: dile a la LAN dónde está el conjunto

Una ruta estática en la puerta de enlace de la LAN es la respuesta más limpia cuando la LAN y el conjunto del túnel no se solapan. Apunta el conjunto a la máquina que termina el túnel:

ip route add 10.8.0.0/24 via 192.168.1.12
route add -p 10.8.0.0 mask 255.255.255.0 192.168.1.12   # Windows, persistent

Eso arregla solo una dirección, y por eso las versiones a medias de este cambio parecen progreso. El lado del túnel necesita la mitad correspondiente, o la respuesta sale del cliente por su propia ruta por defecto y muere por el camino:

push "route 192.168.1.0 255.255.255.0"

Para una subred que está detrás de un cliente en lugar de detrás del servidor, el servidor necesita tanto una ruta de sistema como una entrada iroute en el archivo de ese cliente bajo client-config-dir. Sin iroute, OpenVPN sabe que el prefijo existe y no tiene idea de qué cliente es su dueño: los paquetes llegan y el demonio no tiene con qué emparejarlos.

Aquí está el mito que merece un nombre. Una ruta hace que una dirección sea alcanzable; no hace que el otro lado esté dispuesto a responder. Los pares sitio a sitio añaden otra capa encima, porque la puerta remota solo acepta orígenes dentro de los prefijos de su política, y un portátil que llega desde un conjunto doméstico no está dentro de ellos.

Forma NAT: DNAT hacia dentro y la línea SNAT que todos omiten

Cuando no puedes tocar la puerta de enlace de la LAN, o quieres publicar exactamente un puerto, la traducción en el host VPN funciona sin ninguna ruta en la LAN. Publica el puerto, redirígelo y traduce el origen de camino al túnel:

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j DNAT --to-destination 10.8.0.6:3000
iptables -A FORWARD -i eth0 -o tun0 -p tcp -d 10.8.0.6 --dport 3000 -j ACCEPT
iptables -t nat -A POSTROUTING -o tun0 -d 10.8.0.6 -p tcp --dport 3000 -j SNAT --to-source 10.8.0.1

La tercera línea es la que desaparece. Omítela y el cliente ve la dirección original de la LAN como origen, responde por su propia ruta por defecto, y esa respuesta se va al túnel en lugar de volver hacia la LAN. Si la conexión sobrevive depende entonces de un enrutamiento que nunca planificaste. Con SNAT el cliente ve la dirección de túnel del servidor, así que la respuesta sigue el túnel de vuelta al único host que puede deshacer la traducción.

El firmware de consumo usa sus propios nombres de cadena y no genera esa traducción por ti. En Tomato, una regla de entrada cae en WANPREROUTING y luego en una cadena de filtrado como wanin, y un conjunto de reglas que parece completo todavía necesita una línea POSTROUTING manual. Eso no es un fallo del firmware; es un conjunto de reglas escrito solo para tráfico de entrada.

Por qué una regla que parece correcta sigue descartando el paquete

La mayoría de estos fallos no están en la regla que estás mirando. Comprueba cuatro cosas en este orden y detente en la primera que no se cumpla:

  • Orden de las cadenas. iptables -I inserta arriba y -A añade al final, así que una regla permisiva o bloqueante anterior decide primero.
  • Cadena equivocada. El tráfico dirigido al propio router pasa por INPUT, y el tráfico reenviado nunca lo toca. Publicar un solo servicio puede necesitar reglas en ambas.
  • Banderas de dirección. -i tun0 coincide con el tráfico que llega de los clientes y -o tun0 con el que sale hacia ellos. Un REJECT con la bandera equivocada bloquea algo que no pretendías.
  • Restricción de origen. Una redirección que acepta una dirección de cliente funciona desde ese cliente y descarta cualquier otro origen sin decir nada.

Una regla con un contador de paquetes a cero no está en el camino en absoluto, y leer los contadores es la forma más rápida de separar un problema de cadena equivocada de uno de regla equivocada.

La redirección local, cuando nada en la LAN puede cambiar

Una redirección SSH local esquiva toda la cuestión. No necesita ruta en la LAN, ni cooperación del cortafuegos del cliente, ni ningún puerto publicado en ninguna parte:

ssh -N -f -L 3000:10.8.0.6:3000 user@vpn-host

El servicio aparece entonces en localhost:3000 de la máquina que mantiene el túnel, y en ningún otro sitio. Ese es el límite: una estación de trabajo, un puerto, y la redirección muere con la sesión salvo que algo la reinicie. Para un administrador que comprueba una base de datos de pruebas es la herramienta correcta. Para una cámara o un escáner al que otras personas tienen que llegar, no lo es, porque cada usuario necesitaría su propia redirección.

Verifica ambas direcciones antes de añadir otra regla

La traducción deja rastros, y leerlos es mejor que adivinar. En el host VPN, conntrack -L muestra si la traducción ocurrió, iptables -t nat -L -n -v muestra si los contadores se movieron y tcpdump -ni any port 3000 muestra qué dirección de origen llegó realmente. En el cliente, ss -ltn confirma que el oyente está en una dirección que el túnel puede alcanzar.

Luego elige la forma que vas a conservar. Un puerto publicado, una ruta para todo el conjunto y una redirección para un solo administrador son tres compromisos distintos, y mezclarlos es cómo una configuración que funciona se convierte en una que nadie sabrá explicar seis meses después. Anota qué dirección es alcanzable desde dónde, y la próxima persona que depure esto empezará por la respuesta en lugar del túnel.

Artículos relacionados