2

I have a server in my home network (cannot port forward) and a VPS on the WAN. I need requests on a certain port, to, not from, the VPS to be forwarded to my home server. I have an SSH tunnel which works fine if I send the request to localhost on VPS. However I want requests forwarded to VPS's localhost from internet be sent to my home server through the tunnel. And it needs to be bi-directional.

I have seen this question, however it doesn't work for me. It is quite possible that I did something incorrectly.

My exact procedure:
On server a, my home server, I ran this command to set up the tunnel:

ssh -v -N -R 2222:localhost:22 root@server-b.com

I ran the following command on server b (VPS):

iptables -t nat -A PREROUTING -p tcp --dport 2223 -j DNAT --to-destination 127.0.0.1:2222

And tried to ssh from another machine:

ssh root@server-b.com -p 2223

I set GatewayPorts yes in sshd_config however I am still finding the same problem:
ssh: connect to host server-b.com port 2223: Connection refused.

  • 1
    It would be useful documenting in your own post exactly what was done – Rui F Ribeiro Mar 3 at 13:32
  • You might want to look at the GatewayPorts setting on the VPS server sshd_config. This can allow the remote port 2222 to bind to all IP addresses and so be visible without NATting. – Stephen Harris Mar 3 at 16:39
  • @StephenHarris I'll check that out. Thanks – Jachdich Mar 3 at 17:05
  • @StephenHarris sorry for the inactivity but it didn't work. I set GatewayPorts to yes however it is still not functioning. – Jachdich Mar 8 at 18:46
1

Set GatewayPorts yes and AllowTcpForwarding yes in sshd_config on server b. With GatewayPorts clientspecified explicitly mention IP 0.0.0.0 or * on server a to create reverse tunnel. So that sshd on server b accepts connections from public too:

ssh -NTR *:2222:localhost:22 root@server-b.com

Otherwise sshd listens on loopback interface only as is the case with GatewayPorts no.

Now ssh from another machine to port 2222:

ssh root@server-b.com -p 2222

You'll be logged in to server a after authentication.
No need to set up iptables forwarding. Btw, avoid user root for remote logins, if possible.


If you don't want to set GatewayPorts option, then you need to forward traffic from some other port, say 2223, to localhost:2222.

  • This can be done with iptables on server b:

    iptables -t nat -I PREROUTING -p tcp -m tcp --dport 2223 -j DNAT --to-destination 127.0.0.1:2222
    

    * REDIRECT works only for same interface

    But routing to loopback interface isn't allowed unless:

    echo 1 | sudo tee /proc/sys/net/ipv4/conf/all/route_localnet
    

    Now ssh from another machine to port 2223:

    ssh root@server-b.com -p 2223
    

Another option is to setup some minimal local forwarding server from port 2223 to 2222 using tools like ssh, socat, netcat, *inetd etc.

  • On server b, with socat:

    socat TCP-LISTEN:2223,fork TCP:127.0.0.1:2222
    
  • Or with netcat:

    nc -l -p 2223 -c "nc 127.0.0.1 2222"
    
  • Or with ssh:

    ssh -4gfNTL 2223:localhost:2222 localhost
    

Any of the above can be combined with reverse tunnel to do a double forwarding from server a in a single step:

ssh -TR *:2222:localhost:22 root@server-b.com "ssh -4gfNTL 2223:localhost:2222 localhost"
  • Thanks, I shall try this soon. About root, I've just been too lazy to make a normal user account. Probably should do that soon. – Jachdich Mar 25 at 6:36
  • OH MY GOD IT WORKS! I cannot thank you enough. I've been searching for this for months and it is everything I need. Thanks again – Jachdich Mar 25 at 18:08
  • You are welcome. I have extended the answer to include other possible options, including iptables if you want to go for that. – Irfan Latif Mar 25 at 21:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.