When the machine that needs to be accessed by SSH is located behind a NAT router or a firewall that allows only connections that have been established by the internal machine, an SSH Tunnel is a simple way to accomplish that. It creates an outbound connection to a public server, through which SSH access can be tunneled.
For this example, lets think of a machine ‘client’ behind a regular NAT router in an office space and a server ‘server’ with a public IP accessible over the internet. On the machine ‘server’, the clients ssh public key is installed for the user ‘server-user’. On the ‘client’ machine, a ssh public key is installed, which ssh private key is stored on the ‘server’ machine. This of course works without public and private Keys as well.
From the client machine, issue the following:
client-user@client ~$ ssh -v -N -R 7000:localhost:22 server-user@server [...]
From the SSH manual page, edited for simplicity and relevance to this post. Please consult `man ssh` for further details:
-v: Be verbose. Its nice to add that in this case to see whats going on, as otherwise no output is given. -N: Do not execute a remote command, used here for port forwarding. -R: [bind_address:]port:host:hostport - Specifies that the given port on the remote (server) host is to be forwarded to the given host and port on the local side.
This opens up the port 7000 on ‘server’. If you connect to this port using ssh, you will be forwarded to port 22 on the ‘client’ machine. You can check for the open port on ‘server’ with:
server-user@server ~$ lsof -i -P | grep 7000 sshd 8331 root 7u IPv6 532052 0t0 TCP localhost:7000 (LISTEN) sshd 8331 root 8u IPv4 532053 0t0 TCP localhost:7000 (LISTEN)
Now you can connect to the ‘client’ machine by issuing the following command on ‘server’:
server-user@server ~$ ssh client-user@localhost -p 7000
As soon as somebody is logging into the ‘client’ machine, you will see output similar to the following in the clients ssh terminal:
debug1: channel 0: free: ::1, nchannels 1 debug1: client_input_channel_open: ctype forwarded-tcpip rchan 2 win 2097152 max 32768 debug1: client_request_forwarded_tcpip: listen localhost port 7000, originator ::1 port 59172 debug1: connect_next: host localhost ([127.0.0.1]:22) in progress, fd=4 debug1: channel 0: new [::1] debug1: confirm forwarded-tcpip debug1: channel 0: connected to localhost port 22
To stop the connection on the client, all you have to do is hit CRTL+C to stop the running ssh program.
This is only a temporary solution, perfect for non-recurring logins. For a more permanent solution, you might want to look for setting up OpenVPN.