Tengo una puerta de enlace Linux que realiza NAT para mi red doméstica. Tengo otra red a la que me gustaría reenviar paquetes de forma transparente, pero solo a / desde puertos / IP específicos (es decir, no una VPN). Aquí hay algunos ejemplos de IP y puertos para trabajar:
Source Router Remote Gateway Remote Target
192.168.1.10 -> 192.168.1.1 -> 1.2.3.4 -> 192.168.50.50:5000
Me gustaría que la máquina de origen pueda comunicarse con puertos específicos en el destino remoto como si fuera directamente enrutable desde el enrutador. En el enrutador, eth0 es la red privada y eth1 tiene conexión a internet. Remote Gateway es otra máquina Linux en la que puedo ingresar y puede enrutar directamente a Remote Target.
Mi intento de una solución simple es configurar el reenvío de puertos ssh en el enrutador, como:
ssh -L 5000:192.168.50.50:5000 1.2.3.4
Esto funciona bien para el enrutador, que ahora puede conectarse localmente al puerto 5000. Por lo tanto, "telnet localhost 5000" se conectará a 192.168.50.50:5000 como se esperaba.
Ahora quiero redirigir el tráfico desde Source y canalizarlo a través del túnel ssh ahora establecido. Intenté una regla NAT para esto:
iptables -t nat -D PREROUTING -i eth0 -p tcp -s 192.168.1.10 --dport 5000 -d 1.2.3.4 -j DNAT --to-destination 127.0.0.1:5000
y dado que el enrutador ya es mi puerta de enlace NAT, ya tiene la regla de postrouting necesaria:
-A POSTROUTING -s 192.168.1.0/24 -o eth1 -j MASQUERADE
La mayoría de las preguntas y respuestas en este sitio o en otro lugar parecen tratar con puertos de reenvío de servidores o NAT de horquilla, los cuales he funcionado bien en otros lugares, ninguno de los cuales se aplica a esta situación. Ciertamente podría DMZ reenviar puertos de destino remoto a través de la puerta de enlace remota, pero no quiero que los puertos sean accesibles a Internet, solo quiero que sean accesibles a través del túnel SSH seguro.
La mejor respuesta que puedo encontrar se relaciona con el rechazo de paquetes marcianos en el kernel de Linux:
iptables, ¿cómo redirigir el puerto del loopback?
He habilitado el registro de marcianos y he confirmado que el núcleo está rechazando estos paquetes como marcianos. Excepto que no lo son: sé exactamente para qué son estos paquetes, de dónde son y hacia dónde van (mi túnel ssh).
La solución "indirecta" presentada allí es aplicable a esa pregunta original, pero no se aplica a mi caso.
Sin embargo, al escribir / investigar esta pregunta, he solucionado mi problema utilizando el enlace de IP de origen SSH de esta manera:
ssh -L 192.168.1.1:5000:192.168.50.50:5000 1.2.3.4
iptables -t nat -D PREROUTING -i eth0 -p tcp -s 192.168.1.10 --dport 5000 -d 1.2.3.4 -j DNAT --to-destination 192.168.1.1:5000
Como no estoy usando loopback, esto evita el rechazo marciano.
Todavía publico la pregunta aquí por dos razones:
- Con la esperanza de que alguien que esté tratando de hacer algo similar en el futuro pueda encontrar esto en sus búsquedas y esta solución les pueda ayudar.
- Todavía prefiero la idea de mantener mi conexión de reenvío de puerto ssh vinculada solo al bucle invertido y poder enrutarlos a través de iptables. Dado que sé exactamente qué son estos paquetes y hacia dónde van, ¿no debería haber alguna forma de marcarlos como tales para que el filtrado marciano de Linux no los rechace? Toda mi búsqueda en este tema conduce a rp_filter, que no ayudó en absoluto en mis pruebas. E incluso si funcionó, no es específico de los paquetes exactos que estoy tratando de permitir.
Estoy interesado en contribuir con mi pregunta y mi solución alternativa a la búsqueda general para ahorrarle a alguien las horas de búsqueda que hice solo para encontrar callejones sin salida, y espero que alguien responda la parte de bucle / marciano de mi pregunta que aún permanece abierta a mi.
fuente
Respuestas:
El problema con hacer un DNAT a 127.0.0.1:5000 es que cuando el lado remoto responde, estos paquetes regresan al motor de enrutamiento como si se originaran localmente (de 127.0.0.1) pero tienen una dirección de destino externa. SNAT / MASQUERADE que coincida con la interfaz externa los habría capturado y reescrito, pero las decisiones de enrutamiento que deben tomarse para que los paquetes lleguen a esa interfaz son lo primero, y rechazan estos paquetes que son falsos por defecto. El motor de enrutamiento no puede garantizar que recuerde hacer esa reescritura más tarde.
Lo que debería poder hacer en su lugar es rechazar cualquier conexión externa a 192.168.1.1:5000 en iptables INPUT que no sean las que provienen de 192.168.1.10 utilizando el
!
argumento anterior a la-s
especificación de la dirección de origen. Si utiliza el restablecimiento de TCP como mecanismo de rechazo (en-j REJECT --reject-with tcp-reset
lugar del destino predeterminado de ICMP inalcanzable), será en gran medida idéntico a la situación en la que nada escuchaba en esa dirección: combinación de puertos en lo que respecta al mundo exterior.fuente
Usaría openVPN para crear un túnel desde Router a RemoteGateway.
Luego, en el enrutador, agregaría una ruta:
route add -host RemoteTarget gw RemoteGateway-VPNaddress
use la regla simple de iptables donde quiera para limitar a qué puertos le permite llegar a Source.
fuente