Tráfego UDP através do túnel SSH

66

O título resume bastante. Gostaria de enviar tráfego UDP através de um túnel SSH. Especificamente, preciso ser capaz de enviar pacotes UDP pelo túnel e ter o servidor para enviá-los de volta para mim do outro lado. Eu sei como fazer isso para conexões TCP. Isso é possível com o UDP?

pesado
fonte

Respostas:

36

Este pequeno guia mostra como enviar tráfego UDP via SSH usando ferramentas que são padrão (ssh, nc, mkfifo) com a maioria dos sistemas operacionais do tipo UNIX.

Executando o tunelamento UDP através de uma conexão SSH

Passo a passo Abra uma porta de encaminhamento TCP com sua conexão SSH

Na sua máquina local (local), conecte-se à máquina distante (servidor) pelo SSH, com a opção -L adicional para que o SSH com encaminhamento de porta TCP:

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

Isso permitirá que as conexões TCP na porta 6667 da sua máquina local sejam encaminhadas para a porta 6667 em server.foo.com através do canal seguro. Configure o encaminhamento de TCP para UDP no servidor

No servidor, abrimos um ouvinte na porta TCP 6667 que encaminhará os dados para a porta UDP 53 de um IP especificado. Se você deseja fazer o encaminhamento de DNS como eu, pode pegar o IP do primeiro servidor de nomes que encontrará em /etc/resolv.conf. Mas primeiro, precisamos criar um fifo. O fifo é necessário para ter comunicação bidirecional entre os dois canais. Um pipe de shell simples comunicaria apenas a entrada padrão 'saída padrão para processo direito' do processo esquerdo.

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

Isso permitirá que o tráfego TCP na porta 6667 do servidor seja encaminhado para o tráfego UDP na porta 53.1 192.168.1.1 e as respostas retornem. Configure o encaminhamento UDP para TCP na sua máquina

Agora, precisamos fazer o oposto do que foi feito na parte superior da máquina local. Você precisa de acesso privilegiado para ligar a porta UDP 53.

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

Isso permitirá que o tráfego UDP na porta 53 da máquina local seja encaminhado para o tráfego TCP na porta 6667 da máquina local. Aproveite o servidor DNS local :)

Como você provavelmente já adivinhou agora, quando uma consulta DNS será realizada na máquina local, por exemplo, na porta UDP local 53, ela será encaminhada para a porta TCP local 6667, para a porta TCP do servidor 6667 e para o servidor DNS do servidor. , Porta UDP 53 de 192.168.1.1. Para aproveitar os serviços DNS em sua máquina local, coloque a seguinte linha como primeiro servidor de nomes em seu /etc/resolv.conf:

nameserver 127.0.0.1
John T
fonte
28
Esta solução não é segura. Não é garantido que os fluxos TCP preservem os limites das mensagens; portanto, um único datagrama UDP pode ser dividido em partes, quebrando qualquer protocolo.
Juho Östman 8/08
2
Também pode ser bom usar a porta 1153 em vez da 6667 (do exemplo SSH man), que é usada pelo IRC.
phil Pirozhkov
11
@ JuhoÖstman Obrigado por apontar esta armadilha. Estar ciente do problema ... você executou uma solução? mensagens pequenas o suficiente seriam uma maneira de fazer com que funcionasse?
humanityANDpeace
4
A solução seria acrescentar um comprimento a cada pacote antes de serem enviados pelo fluxo TCP e reconstruir os pacotes originais a partir dele. Seria fácil escrever um script C para fazer isso, mas não tenho certeza se existe uma solução prontamente disponível. Na prática, o TCP geralmente parece preservar os limites das mensagens nesse caso, mas falhas estranhas podem ocorrer a qualquer momento.
Juho Östman
Eu enfrentei outro problema com isso: o pipe e o fifo são armazenados em buffer, perdendo os limites do quadro. Muitos quadros UDP podem ser concatenados em um quadro TCP.
Julio Guerra
26

Este exemplo (acho que a resposta de John aponta a mesma coisa para outro local) descreve como acessar os serviços UDP / DNS de outra máquina através de uma conexão TCP / SSH.

Encaminharemos o tráfego UDP / 53 local para o TCP, depois o tráfego TCP com o mecanismo de encaminhamento de porta do SSH para a outra máquina e, em seguida, o TCP para o UDP / 53 na outra extremidade.
Normalmente, você pode fazer isso com o openvpn.
Mas aqui, faremos isso com ferramentas mais simples, apenas openssh e netcat.

No final dessa página, há outro comentário com uma referência a ' socat',
O mesmo acesso UDP / DNS é feito com,

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

Consulte exemplos sociais para mais.

nik
fonte
3
Este parece muito mais útil para mim do que a resposta aceita. Eu precisava de um redirecionamento unidirecional de fluxo de vídeo (TS / UDP) ... ssh orig_strm_src socat udp4-listen:4003,reuseaddr,fork STDOUT| socat STDIN udp-sendto:localhost:4003
nhed
FWIW, escrevi um guia mais detalhado em minha página inicial, descrevendo como configurar o socat sobre SSH para encaminhamento de UDP. Ele usa o SNMP como exemplo.
Peter V. Mørch
20

O SSH (pelo menos o OpenSSH) tem suporte para VPNs simples. Usando a opção -wou Tunnelno sshcliente, você pode criar um tundispositivo nas duas extremidades, que pode ser usado para encaminhar qualquer tipo de tráfego IP. (Veja também Tunnelna página de manual de ssh_config(5).) Observe que isso requer o OpenSSH (e provavelmente privilégios de root) nas duas extremidades.

gravidade
fonte
Isso requer privilégios de root na máquina remota, mesmo para o encapsulamento UDP de portas não privilegiadas e o PermitRootLogin definido como não 'não'. Que pena.
phil pirozhkov
@ grrawity Obrigado por apontar esta opção, que mesmo quando indicado por philpirozhkov, é necessário o login root. Gostaria de saber se pode haver uma maneira de enganá-lo para não precisar da raiz?
HumanANDpeace
4
@humanityANDpeace: Você pode pré-criar os dispositivos tun / tap e torná-los propriedade de um usuário específico, usando ip tuntap add.
grawity
Olá, @grawity. Gosto da sua solução, mas não consigo fazê-la funcionar. Eu pré-recriei o tundispositivo da seguinte maneira: sudo ip tuntap add mode tunmas sempre que uso a -wopção assim: ssh $Server -w $porteu entendi Tunnel device open failed. Could not request tunnel forwarding.O que estou fazendo de errado?
Lucas Aimaretto 13/08/18
16

Ou você pode simplesmente usar ssf (que foi projetado para lidar com este caso de uso), com um comando simples:


Lado do cliente:

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

Este comando redireciona a porta local 53 (dns) para a porta 192.168.1.1 53, através de um túnel seguro entre localhost e server.foo.com.


Você precisará de um servidor ssf (em vez de - ou ao lado de - seu servidor ssh):

#>./ssfs

A propósito, o cliente e o servidor do ssf funcionam no Windows / Linux / Mac. Este é um aplicativo da área de usuário, portanto você não precisa de tun / tap ou VPN.

Para redirecionar a porta 53, você precisará de privilégios administrativos - independentemente da ferramenta que está usando.

Para obter mais informações, detalhes, caso de uso ou download: https://securesocketfunneling.github.io/ssf/

desenvolvedores ssf
fonte
Por favor, seja cauteloso ao responder com "aqui está o meu produto", é um spam limite. Sugiro ler e seguir as diretrizes da Central de Ajuda .
heavyd
7
No máximo, é um plugue sem vergonha. De qualquer forma, a solução pode atender ao seu pedido. A propósito, o SSF é OpenSource e sem fins lucrativos.
Ssf-developers
11
@heavyd: Se ele publicasse um monte de scripts hacky, seria aceitável, mas porque ele criou uma ferramenta de código aberto madura, não é? Responde perfeitamente à pergunta original.
Synthead
Eu tenho que admitir de má vontade que esta é exatamente a ferramenta que eu estava procurando, mesmo que fosse um plugue sem vergonha.
Therealrootuser 27/08/16
9

Não pude nctrabalhar no SNMP, porque os clientes SNMP continuam escolhendo uma nova porta UDP de origem e vários podem estar ativos ao mesmo tempo.

Em vez disso, escrevi uma postagem descrevendo como fazê-la socatnesta postagem de blog , usando o SNMP como exemplo. Essencialmente, usando dois terminais, começando com uma visão geral:

visão global

Terminal um:

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

Isso cria o encaminhamento SSH da porta TCP 10000 e executa socat no servidor. Observe como o endereço IP do comutador é mencionado na linha de comando socat como "comutador".

Terminal dois:

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

Isso configura o socat no cliente. Isso deve resolver.

Peter V. Mørch
fonte
Isso funcionou para mim :)
Paul Fenney
4

Uma VPN é uma solução melhor se você tiver acesso a uma porta UDP.

Se você tiver acesso apenas à porta TCP SSH, um túnel SSH será tão bom quanto uma VPN, pelo menos para retorno de ping e pacote.

Michael
fonte