Estou tentando conectar pela internet a um serviço que está escutando em uma porta em uma máquina remota atrás de um roteador, por meio de um túnel ssh. Tenho privilégios de root na máquina local, máquina remota e acesso de administrador ao roteador. O firewall da máquina remota nega todas as conexões de entrada, exceto em sua porta ssh, digamos que seja 2222. A porta 2222 é encaminhada pelo roteador e o cliente ssh da máquina local também está usando essa porta. Consigo conectar da minha máquina local pela internet à máquina remota com ssh <my_user>@<router public ip>
, me dando um shell.
Até aqui tudo bem. Para montar o túnel, eu corro
ssh -D 5555 <my_user>@<router public ip>
e eu obtenho um shell na máquina remota como esperado. Na saída de sudo ss -tap | grep ssh
na máquina local eu posso ver o cliente ssh escutando na porta 5555 do host local, agindo como servidor SOCKS5, e a conexão estabelecida para o túnel:
LISTEN 0 0 127.0.0.1:5555 0.0.0.0:* users:(("ssh", pid=...))
ESTAB 0 0 <local machine private ip>:40632 <router public ip>:2222 users:(("ssh", pid=...))
40632 é a porta de saída aleatória usada pelo cliente ssh. Eu digo ao meu cliente de aplicativo para usar o servidor SOCKS5 em localhost:5555 e tentar conectar-se via túnel ao servidor de aplicativo por meio de sua GUI. Isso falha com um erro de entrada/saída na GUI, no terminal eu recebo
channel 3: open failed: connect failed: Connection refused
e no auth.log da máquina remota eu recebo
sshd[<pid>]: error: connect_to <router public ip> port 5555 failed
A mensagem 'channel 3', tendo lido muitas outras fontes sobre isso, geralmente é devido a não haver serviço escutando na porta 5555 na máquina remota. Suponho então que o sshd na máquina remota não pode passar os pacotes agora não criptografados. No meu caso, o serviço do aplicativo está escutando na porta remota 5555: posso ver isso na saída do ss e também consigo conectar a essa porta usando nc na máquina remota, produzindo uma conexão interna estabelecida na saída do ss.
Acho que a mensagem de erro relevante é a que vem do sshd da máquina remota. Isso me diz que o sshd está tentando se conectar à porta 5555 do endereço IP público do roteador, que não é encaminhada e, portanto, falha na conexão (eu verifiquei isso permitindo o encaminhamento dessa porta pelo roteador, mas isso não é uma solução para mim). Minha impressão é que o túnel está funcionando até a parte em que o sshd do remoto deve passar pacotes para a porta de destino no remoto.
O sshd na máquina remota não deveria tentar se conectar ao localhost:5555 da máquina remota em vez de usar o endereço IP público? O que eu posso ter configurado incorretamente aqui?
Ter que encaminhar 5555 pelo roteador prejudica o túnel, então tenho certeza de que configurei algo incorretamente. Mais uma coisa a mencionar é que quando faço tudo pela LAN, o túnel funciona. Como eu disse acima, uma conexão ssh simples pela internet também funciona. Também verifiquei se o firewall da máquina remota não está bloqueando nada, e não está (nenhum bloqueio em ufw.log).
Se eu esqueci de algum detalhe crucial necessário, por favor, me avise. Qualquer ideia sobre isso seria muito apreciada! Obrigado.
Acredito ter identificado o problema: você está usando -D (proxy SOCKS dinâmico) quando deveria usar -L (encaminhamento de porta local) para este caso de uso específico.
Eis o porquê:
O sinalizador -D cria um proxy SOCKS que tenta fazer conexões a partir da extremidade remota. Quando seu aplicativo se conecta por meio do proxy SOCKS, o servidor SSH remoto tenta estabelecer a conexão a partir de sua perspectiva, usando o IP público do roteador.
Isso explica por que você vê o erro sobre conexão ao IP público do roteador na porta 5555.
Então, no cliente local, você pode se conectar ao serviço remoto em localhost:5555
Esqueça tudo sobre porto local e coisas assim.
Execute
ssh -L 5555:<internal ip of the machine running nx>:5555 user@remote -p 2222
e diga ao seu cliente Nomachine para se conectar alocalhost:5555
.Porta local é a porta que o cliente Nomachine escuta, e não é relevante aqui. O relevante é que você quer
ssh
fazer o tunelamento do seu computador para um computador remoto, em uma porta definida. Para o nomachine,localhost
ele se torna o parceiro remoto; ele não vê que os pacotes são tunelados.