Maneira simples de criar um túnel de uma porta local para outra?

76

Eu tenho um servidor de desenvolvimento, que só é acessível a partir de 127.0.0.1:8000, não 192.168.1.x: 8000. Como um hack rápido, existe uma maneira de configurar algo para escutar em outra porta (por exemplo, 8001) para que, a partir da rede local, eu possa conectar 192.168.1.x: 8001 e encapsular o tráfego entre o cliente e o 127.0 .0.1: 8000?

waitinforatrain
fonte
4
O netcat pode fazer isso.
Andy

Respostas:

44

Usar ssh é a solução mais fácil.

ssh -g -L 8001: localhost: 8000 -f -N [email protected]

Isso encaminha a porta local 8001 em sua estação de trabalho para o endereço localhost na remote-server.com porta 8000.
-gsignifica permitir que outros clientes na minha rede se conectem à porta 8001 na minha estação de trabalho. Caso contrário, apenas clientes locais em sua estação de trabalho poderão se conectar à porta encaminhada.
-Nsignifica que tudo o que estou fazendo é encaminhar portas, não inicie um shell.
-fsignifica entrar em segundo plano depois de uma conexão e login SSH bem-sucedidos.
A porta 8001 permanecerá aberta para muitas conexões, até que o ssh morra ou seja morto. Se você estiver no Windows, o excelente cliente SSH PuTTY também poderá fazer isso. Use 8001 como a porta local e localhost: 8000 e o destino e adicione um encaminhamento de porta local nas configurações. Você pode adicioná-lo após uma conexão bem-sucedida com o PuTTY.

penguin359
fonte
4
O que [email protected]faz? Definitivamente, não é necessário o encaminhamento de porta, no entanto, o ssh exige que esse argumento, mais ainda, tente se conectar a ele. E ao definir essa opção traquina para nome de host que ela gera …port 22: Connection refused (não, eu não usei a porta 22) . A menos que esteja faltando alguma coisa, o comando claramente não funciona.
Hi-Angel
@ Hi-Angel [email protected]é apenas um exemplo e você não deve interpretar isso literalmente. É necessário substituí-lo por um nome de computador ao qual você deseja se conectar e seu nome de usuário neste computador. Esta informação é necessária para estabelecer a conexão ssh. Somente após o estabelecimento da conexão ssh, as portas podem ser encaminhadas por essa conexão.
Piotr Dobrogost
Se você quer a porta para estar disponível a partir de inicialização, em seguida, ver "autossh" em um serviço systemd usando o método acima - everythingcli.org/ssh-tunnelling-for-fun-and-profit-autossh
Richard Hollis
Eu também recebo "conexão recusada". E ainda não entendo por que o argumento [email protected] é necessário quando não há conexão SSH envolvida (de acordo com -N). Deve apenas encaminhar pacotes.
Alexander Taylor
2
@AlexanderTaylor -Nnão significa que não há conexão SSH. Simplesmente significa do not execute a remote command(veja a página de manual ). O <user>@<host>argumento é necessário, porque este faz abrir uma conexão SSH para <host>(o que para o caso de OP seria localhost), e encaminha a porta desejada através desse túnel SSH. É uma solução para o problema do OP, mas não a mais simples. Para encaminhar para localhost sem o uso de ssh, você pode usar socatou netcatcomo em StephaneChazelas e 's not-a-user respostas
94

Com socatno servidor:

socat tcp-listen:8001,reuseaddr,fork tcp:localhost:8000

Por padrão, socatescutará na porta TCP 8001 em qualquer endereço IPv4 ou IPv6 (se suportado) na máquina. Você pode restringi-lo ao IPv4 / 6 substituindo tcp-listenpor tcp4-listenou tcp6-listenou para um endereço local específico adicionando a ,bind=that-address.

O mesmo para o soquete de conexão ao qual você está executando o proxy, você pode usar qualquer endereço no lugar de localhoste substituir tcppor tcp4ou tcp6se desejar restringir a resolução do endereço aos endereços IPv4 ou IPv6.

Note-se que para o servidor escuta na porta 8000, a conexão aparecerá como provenientes do proxy (no caso de localhost, que será localhost), e não o cliente original. Você precisaria usar abordagens DNAT (mas que requerem privilégios de superusuário) para que o servidor possa saber quem é o cliente.

Stéphane Chazelas
fonte
1
Obrigado, isso é ótimo, pois você não precisa ter um servidor ssh local em execução.
jontro
Posso usar a mesma porta, mas com endereço diferente?
Amos
@amos, veja editar.
Stéphane Chazelas
Também seria possível encaminhar tráfego apenas de IPs específicos?
Phate 23/08/19
1
@Phate, consulte Diga ao socat para ouvir conexões de um único endereço IP (e as opções rangee tcpwrapna socatpágina de manual).
Stéphane Chazelas
46

Usar o tradicional ncé a solução mais fácil:

nc -l -p 8001 -c "nc 127.0.0.1 8000"

Esta versão do ncestá no netcat-traditionalpacote no Ubuntu. (Você precisa update-alternativesou chama nc.traditional.)

Observe que, ao contrário do ssh, isso não é criptografado. Lembre-se disso se você o usar fora de um host.

não usuário
fonte
2
alguém sabe o equivalente netcat-openbsd?
Sridhar Sarnobat
2
Analógica para netcata versão que está incluído no busybox: nc -v -lk -p 8001 -e /usr/bin/nc 127.0.0.1 8000. ( Descrição dos parâmetros )
Ivan Kolmychek 16/03
2
Funcionando, mas o nccomando termina após a primeira conexão remota. Adicione -kse você precisar mantê-lo em execução.
Sopalajo de Arrierez
Estou recebendo este erro: nc: cannot use -p and -lno CentOS 6.4. Existe uma solução alternativa?
9116 Nick Predey
Prefiro essa solução à ssh porque facilita o uso como root, quando é necessário encaminhar localmente uma porta privilegiada.
Christian
24

O OpenBSD netcat está disponível por padrão no Linux e também no OS X.

OSX:

mkfifo a
mkfifo b
nc 127.0.0.1 8000 < b > a &
nc -l 8001 < a > b &

Linux:

mkfifo backpipe
nc -l 12345 0<backpipe | nc www.google.com 80 1>backpipe

Uma alternativa que funciona no bash do OS X é usar um tubo bidirecional . Pode funcionar em outros Unixes:

nc 127.0.0.1 8000 <&1 | nc -l 8001 >&0
Mark A.
fonte
Eu não percebi no começo que você estava usando o openbsd netcat. Isso é melhor do que ter que instalar outro netcat a partir de um pacote Ubuntu.
RobertR
O exemplo do OpenBSD falhou no Ubuntu 15.04. Com os redirecionamentos de shell, o netcat falha ao abrir a porta para escuta, conforme visto por ss -tanou netstat -tan.
Justin C
⁺¹ FTR: a maneira alternativa funciona no Ubuntu
Hi-Angel
Eu não entendo sua solução. Você pode explicar isso?
Trismegistos
@trismegistos Nestes exemplos, o ouvinte e o cliente netcat redirecionam a entrada para alguns arquivos compartilhados (mkfifo pipes .. primeiro a sair) e usam esses arquivos compartilhados como sua origem / destino de entrada / saída, criando efetivamente um túnel. Normalmente, cliente / ouvinte são usados, mas algumas técnicas usam cliente + cliente / ouvinte + ouvinte- wiki.securityweekly.com/… e slideshare.net/amiable_indian/secrets-of-top-pentesters são leituras obrigatórias.
Info5ek
4

Citando um David Spillett 's resposta em ServerFault

O rinetd deve fazer o trabalho, e um binário do Windows pode ser obtido em http://www.boutell.com/rinetd/ (para quem procura a mesma coisa no Linux, o rinetd está nos repositórios padrão de praticamente todas as distribuições pode ser instalado com "apt-get install rinetd" ou "yum install rinetd" ou similar)

É um binário simples que pega um arquivo de configuração no formato

bindaddress bindport connectaddress connectport

Por exemplo:

192.168.1.1 8001 127.0.0.1 8000

ou

0.0.0.0 8001 127.0.0.1 8000

se você deseja vincular a porta de entrada a todas as interfaces.

psychowood
fonte
3
iptables -t nat -A PREROUTING -p tcp --dport <origin-port> -j REDIRECT --to-port <destination-port>

service iptables save
service iptables restart
Santanu Dey
fonte
Ao tentar me conectar dport, como nc -v localhost 2345estou recebendo Connection refused. Eu não sou muito bom em iptables, mas acho que o dport precisa ter um aplicativo de escuta.
Hi-Angel
E se a porta de origem estiver em uma interface diferente da porta de destino?
Trismegistos
0

Com base na resposta de Mark A. , tive que fazer um pequeno ajuste para que ele funcionasse no meu Mac (pelo menos no macOS Mojave versão 10.14.4)

mkfifo a
mkfifo b
nc 127.0.0.1 8000 < b > a &
nc -l 8001 < a > b &
printf "" > a

Essa declaração printf parece ser crucial. Caso contrário, o comando netcat para conectar-se à porta 8000 nunca tentará realmente se conectar, e o comando netcat para escutar na porta 8001 nunca escutará na porta 8001. Sem o printf, sempre que eu tentasse conectar-me à porta 8001, obteria Ligação recusada.

Minha suposição é que o netcat deve de alguma forma bloquear o stdin (talvez esteja tentando lê-lo por algum motivo) antes de realmente executar qualquer operação do soquete. Como tal, sem a instrução printf escrevendo para fifo a, o comando netcat nunca começará a escutar na porta 8001.

Nota: eu teria deixado uma resposta na postagem de Mark, mas ainda não tenho reputação.

Daniel K
fonte
0

Esta é uma nova maneira de encapsular duas portas udp no servidor: https://github.com/9crk/udpeer

udpeer 8001 8002

Testar:

nc -u xxxx.com 8001
nc -u xxxx.com 8002
9crk
fonte