Note: this post is another technical one, so if you are a member of my immediate family, you probably won’t find it of much interest. If “ports” make you think of boats (rather than the numbers 80 and 22), then why don’t you mosey on over to my christmas photos?
I frequently have trouble communicating between systems which are separated by different private LANs. This often happens when you have your computer on a home wireless network which is separated from the rest of the internet via a router and firewall. Fortunately, SSH tunnels can be used to link these machines together, provided you know which ports need to be interfaced and you have a common server which both machines can reach. Here is how.
Remote Access with SSH
Normally SSH is used to remotely log into servers in order to run commands or copy files. However, SSH can also be used to create “tunnels” between two servers. These tunnels are particularly useful for two reasons: they are encrypted and you can make network traffic going to one system magically appear at the end of the tunnel.
There are two basic kinds of SSH tunnels: remote and local. In all cases you create a tunnel that connects one port number on a remote server to a port on the local machine where you run the command.
Note: The commands here are primarily geared towards computers running linux or mac os x, although widows users can do the same if they install cygwin.
Remote Tunnels are used to forward all traffic from some remote port back to your own system. You would do this if you want to run a web server or some other service on your own machine, but the remote server can’t reach it because of your router. In effect, you are creating a listener on the remote machine which will accept the webpage requests, and forward them to your own computer.
You can create a remote tunnel with the following command:
ssh -R *:8080:localhost:80 email@example.com -N ## run this on home ## -R = remote tunnel ## 8080 = port on remote machine that will accept traffic ## 80 = port on local machine to forward traffic to ## -N = creates the ssh connection without opening an interactive shell ## -f = (optional) use this to make the command create the tunnel ## and return immediately.
This will make it so that all requests on the remoteserver.com to port 8080 are redirected to home port 80 (the default web server port). However, the remote tunnel only makes it so users on remoteserver.com itself are able to utilize the port forward. Thus localhost:8080 tunnels correctly from that server, but remoteserver.com:8080 will not go through the tunnel. To let a third user access the website, we need to also create a local tunnel.
Local Tunnels let you make a port on your own machine actually send traffic to a port on a remote machine. Often you need to combine a remote and a local tunnel if you want a user within a second private LAN to reach your machine.
ssh -L 8888:localhost:8080 remoteserver.com -N ## run this on work ## -L = create a local tunnel ## 8888 = the port on the local machine for the tunnel entrance ## 8080 = the port on the remote machine
This will make it so that from the perspective of users on work, requests to localhost:8888 are forwarded to remoteserver.com:8080. This in turn is connected to the original tunnel, creating the full tunnel back to home.
These kinds of tunnels can be very useful for connecting systems separated by routers and firewalls. Depending on the application you are trying to reach, you will need to use a different port number. Here is a good list of commonly used port numbers.
Of course there are some security implications here and your company IT people may not like these tunnels much. In effect, this lets you connect any two machines, even if they are supposed to be separated by secure VPNs. Of course, since only one port is being opened, and the commands generally aren’t left running for a long time, it shouldn’t be an issue.