I think what I am trying to do is called SSH Tunneling. I am a bit confused if this is actually what I want to do.

I want to setup a tunnel on port 1234 on Server A. Server A forwards all connections through port 1234 to Server B on port 5678. Is this possible to do with SSH?

Basically I want to access a secondary server on a local network through the primary server which is on a public network from my local computer without having to login to the primary server.

I also only want the tunnel to allow a non-root user to connect to the private server. It should be authenticated like normally when logging into SSH. Need to make sure this works for WinSCP too so that the client can access their account on the private box through the public IP address properly.


What @RolandW suggests is correct and will work if and only if server B on the private network is directly accessible from server A, i.e. if and only server B is not behind a firewall and a NATting router.

If either of these two assumptions is false, you will have to use a different solution. In this case, since B is not directly accessible from A, you will have to establish a reverse tunnel from B to A, and then you can access B from your home.

On server B,

  1. Add this line to /etc/rc.local

    su -c /home/your_name/bin/auto your_name
  2. Create an executable file called auto in /home/your_name/bin, called auto, with this content:

    /usr/lib/autossh/autossh -M 6321 -f -p 22 -2 -N -D  -R 8100:localhost:22 your_name_o_server_A@IP_address_of_server_A -i /path/to/cryptokey/of_server_A

    The command autossh is a very convenient utility which automatically restarts the ssh tunnel every time it goes down (power outage, reboots, whatever); to do so it uses a port (in my case, 6321) to check the status of the conection. You may very well use a different TCP port than 6321 (but larger than 1024!), just make sure it is open on server A.

    The command above assumes that you have enabled authentication through cryptographic keys, which you definitely should do.

  3. On server A, you will have to introduce the following line

    GatewayPorts yes

    in the file /etc/ssh/sshd_config. This demands sudo privileges.

  4. Lastly, you can connect from home as follows:

    ssh -YC -t -t -p 22 -i /path/to/cryptkey/of_server_A \
      your_name_o_server_A@IP_address_of_server_A        \
      "ssh -Y your_name_on_server_B@localhost -p 8100 -i /path/to/cryptkey/of-server_B" 

Of course it will be convenient to establish aliases to make the above call faster.


I am assuming that you want to get SSH access to Server B, which is on a private network connected to the (public) Server A. Server B runs an ssh daemon listening on port 5678.

To do this, you can create a port forwarding on the public server that forwards TCP packets arriving on port 1234 to server-b:5678. According to https://serverfault.com/questions/140622/how-can-i-port-forward-with-iptables this can be done on a Linux box running iptables (netfilter) using the following commands

iptables -t nat -A PREROUTING -p tcp -i <WAN interface> --dport 1234 -j DNAT --to-destination <server-b-IP>:5678
iptables -A FORWARD -p tcp -d <server-b-IP> --dport 5678 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

The first rule rewrites the destination address, the second allows the modified packet to be delivered to its destination. This assumes that Server B's default gateway is Server A.

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.