Tráfico UDP a través del túnel SSH

66

El título lo resume más o menos. Me gustaría enviar tráfico UDP a través de un túnel SSH. Específicamente, necesito poder enviar paquetes UDP a través del túnel y hacer que el servidor me los envíe al otro lado. Sé cómo hacerlo para conexiones TCP. ¿Es esto posible con UDP?

pesado
fuente

Respuestas:

36

Esta pequeña guía le dice cómo enviar tráfico UDP a través de SSH utilizando herramientas que vienen de manera estándar (ssh, nc, mkfifo) con la mayoría de los sistemas operativos tipo UNIX.

Realización de túneles UDP a través de una conexión SSH

Paso a paso Abra un puerto de reenvío TCP con su conexión SSH

En su máquina local (local), conéctese a la máquina distante (servidor) por SSH, con la opción adicional -L para que SSH con puerto TCP adelante:

local# ssh -L 6667:localhost:6667 server.foo.com

Esto permitirá que las conexiones TCP en el número de puerto 6667 de su máquina local se reenvíen al número de puerto 6667 en server.foo.com a través del canal seguro. Configure el reenvío de TCP a UDP en el servidor

En el servidor, abrimos una escucha en el puerto TCP 6667 que reenviará los datos al puerto UDP 53 de una IP especificada. Si desea reenviar DNS como yo, puede tomar la IP del primer servidor de nombres que encontrará en /etc/resolv.conf. Pero primero, necesitamos crear un fifo. El fifo es necesario para tener comunicaciones bidireccionales entre los dos canales. Una tubería de shell simple solo comunicaría la entrada estándar del proceso izquierdo al proceso estándar.

server# mkfifo /tmp/fifo
server# nc -l -p 6667 < /tmp/fifo | nc -u 192.168.1.1 53 > /tmp/fifo

Esto permitirá que el tráfico TCP en el puerto 6667 del servidor se reenvíe al tráfico UDP en el puerto 53 de 192.168.1.1 y que las respuestas regresen. Configure UDP hacia adelante TCP en su máquina

Ahora, tenemos que hacer lo contrario de lo que se hizo arriba en la máquina local. Necesita acceso privilegiado para enlazar el puerto UDP 53.

local# mkfifo /tmp/fifo
local# sudo nc -l -u -p 53 < /tmp/fifo | nc localhost 6667 > /tmp/fifo

Esto permitirá que el tráfico UDP en el puerto 53 de la máquina local se reenvíe al tráfico TCP en el puerto 6667 de la máquina local. Disfrute de su servidor DNS local :)

Como probablemente haya adivinado ahora, cuando se realice una consulta DNS en la máquina local, por ejemplo, en el puerto UDP local 53, se reenviará al puerto TCP local 6667, luego al puerto TCP 6667 del servidor, luego al servidor DNS del servidor , Puerto UDP 53 de 192.168.1.1. Para disfrutar de los servicios DNS en su máquina local, coloque la siguiente línea como primer servidor de nombres en su /etc/resolv.conf:

nameserver 127.0.0.1
John T
fuente
28
Esta solución no es segura. No se garantiza que las secuencias TCP conserven los límites del mensaje, por lo que un solo datagrama UDP puede dividirse en partes, rompiendo cualquier protocolo.
Juho Östman
2
También podría ser bueno usar el puerto 1153 en lugar del 6667 (del ejemplo man SSH), que es usado por IRC.
phil pirozhkov
1
@ JuhoÖstman Gracias por señalar esta trampa. Siendo consciente del problema ... ¿ha ejecutado accros una solución? ¿serían mensajes lo suficientemente pequeños como una manera de hacer que funcione?
humanityANDpeace
44
La solución sería anteponer una longitud a cada paquete antes de enviarlos a través de la secuencia TCP y reconstruir los paquetes originales a partir de eso. Sería fácil escribir un script C para hacer eso, pero no estoy seguro de si existe una solución fácilmente disponible. En la práctica, el TCP generalmente parece preservar los límites de los mensajes en este caso, pero pueden ocurrir fallas extrañas en cualquier momento.
Juho Östman
Me enfrenté a otro problema con esto: la tubería y el quince están amortiguadas para que se pierdan los límites del marco. Tantas tramas UDP se pueden concatenar en una trama TCP.
Julio Guerra
26

Este ejemplo (creo que la respuesta de John señala lo mismo en un lugar diferente), describe cómo acceder a los servicios UDP / DNS de otra máquina a través de una conexión TCP / SSH.

Reenviaremos el tráfico UDP / 53 local a TCP, luego el tráfico TCP con el mecanismo de reenvío de puertos de SSH a la otra máquina, luego TCP a UDP / 53 en el otro extremo.
Por lo general, puedes hacerlo con openvpn.
Pero aquí, lo haremos con herramientas más simples, solo openssh y netcat.

Al final de esa página, hay otro comentario con una referencia a ' socat',
Se realiza el mismo acceso UDP / DNS con,

Lado del servidor: socat tcp4-listen:5353,reuseaddr,fork UDP:nameserver:53
Lado del cliente:socat udp4-listen:53,reuseaddr,fork tcp:localhost:5353

Consulte los ejemplos de socat para obtener más información.

nik
fuente
3
Esta me parece mucho más útil que la respuesta aceptada. Necesitaba una redirección unidireccional de la transmisión de video (TS / UDP) ... ssh orig_strm_src socat udp4-listen:4003,reuseaddr,fork STDOUT| socat STDIN udp-sendto:localhost:4003
nhed
FWIW, he escrito una guía más detallada en mi página de inicio que describe cómo configurar socat sobre SSH para el reenvío UDP. Utiliza SNMP como ejemplo.
Peter V. Mørch
20

SSH (al menos OpenSSH) tiene soporte para VPN simples. Usando la opción -wo Tunnelen el sshcliente, puede crear un tundispositivo en ambos extremos, que puede usarse para reenviar cualquier tipo de tráfico IP. (Consulte también Tunnelen la página del manual de ssh_config(5)). Tenga en cuenta que esto requiere OpenSSH (y probablemente privilegios de root) en ambos extremos.

Gravedad
fuente
Esto requiere privilegios de root en la máquina remota incluso para la tunelización UDP de puertos no privilegiados y PermitRootLogin establecido en no 'no'. Demasiado.
phil pirozhkov
@grawity Gracias por señalar esta opción, que incluso cuando philpirozhkov señaló el inicio de sesión de root requerido. Me pregunto si puede haber una manera de engañarlo para que no necesite la raíz.
humanityANDpeace
44
@humanityANDpeace: puede crear previamente los dispositivos tun / tap y hacer que sean propiedad de un usuario específico, utilizando ip tuntap add.
Grawity
Hola @grawity. Me gusta su solución, pero no puedo hacer que funcione. Precreé el tundispositivo de la siguiente manera: sudo ip tuntap add mode tunpero cuando alguna vez utilicé la -wopción como esta: ssh $Server -w $portobtengo Tunnel device open failed. Could not request tunnel forwarding.¿Qué estoy haciendo mal?
Lucas Aimaretto
16

O simplemente puede usar ssf (que fue diseñado para manejar este caso de uso), con un comando simple:


Lado del cliente:

#>./ssfc -U 53:192.168.1.1:53 server.foo.com

Este comando redirige el puerto local 53 (dns) al puerto 53 192.168.1.1, a través de un túnel seguro entre localhost y server.foo.com.


Necesitará un servidor ssf (en lugar de - o al lado de - su servidor ssh):

#>./ssfs

Por cierto, tanto el lado del cliente como del servidor de ssf funcionan en Windows / Linux / Mac. Esta es una aplicación de usuario, por lo que no necesita tun / tap o VPN.

Para redirigir el puerto 53, necesitará privilegios administrativos, independientemente de la herramienta que esté utilizando.

Para obtener más información, detalles, casos de uso o descargas: https://securesocketfunneling.github.io/ssf/

ssf-developers
fuente
Sea cauteloso respondiendo con "aquí está mi producto", es un límite de spam. Sugiero leer y seguir las pautas del centro de ayuda .
heavyd
77
A lo sumo, es un enchufe descarado. De todos modos, la solución puede ajustarse a su solicitud. Por cierto, SSF es OpenSource y sin fines de lucro.
ssf-developers
11
@heavyd: Si publicara un montón de guiones hacky, sería aceptable, pero debido a que creó una herramienta madura de código abierto, ¿no? Responde la pregunta original perfectamente.
Synthead
Tengo que admitir de mala gana que esta es exactamente la herramienta que he estado buscando, incluso si era un enchufe descarado.
therealrootuser
9

No pude nctrabajar para SNMP, porque los clientes SNMP siguen eligiendo un nuevo puerto UDP de origen, y varios pueden estar activos a la vez.

En cambio, he escrito una publicación que describe cómo hacerlo socaten esta publicación de blog , utilizando SNMP como ejemplo. Esencialmente, usando dos terminales, comenzando con una descripción general:

visión de conjunto

Terminal uno:

client$ ssh -L 10000:localhost:10000 server
server$ socat -T10 TCP4-LISTEN:10000,fork UDP4:switch:161

Esto crea el reenvío SSH del puerto TCP 10000 y ejecuta socat en el servidor. Observe cómo la dirección IP del conmutador se menciona en la línea de comando socat como "conmutador".

Terminal dos:

client$ sudo socat UDP4-LISTEN:161,fork TCP4:localhost:10000

Eso configura socat en el cliente. Deberias hacer eso.

Peter V. Mørch
fuente
esto funcionó para mí :)
Paul Fenney
4

Una VPN es una mejor solución si tiene acceso a un puerto UDP.

Si solo tiene acceso al puerto TCP SSH, un túnel SSH es tan bueno como una VPN, al menos para hacer ping y realizar un seguimiento de paquetes.

Miguel
fuente