In a previous article, I went over some of the basic functions of ssh. In that article, I mentioned that simple remote shell access was not the most interesting thing you can do with ssh. I pointed out that remote command execution was more interesting than mundane remote shell access. In this article, I'll discuss something that I think is even more interesting than remote shell access or remote execution: tunneling.
Reasons for Tunneling
There are two primary reasons to use ssh for tunneling. Before I give those reasons, I'll describe what tunneling is.
Tunneling with ssh is the process of wrapping some network communication with the encrypted ssh protocol. Tunneling involves an ssh client connecting to an ssh server, just as in "regular cases." But when the ssh client connects to the server, the client specifies the source and the destination for the tunnel.
The destination is another bound network port; but this time, it's some other network server that the other end of the ssh tunnel can communicate with. If this seems a bit unclear, don't worry; I'll get into more detail shortly with an example. For now, you can just think of ssh tunneling as secure port forwarding.
You may be able to derive from this description one or both reasons I'm about to give for using ssh tunneling. The first reason I'll give for using ssh tunneling is to connect two networks that do not have open access to one another. As an example, suppose you have an imap server setup on your home LAN. Also suppose that you have a laptop and want to be able to connect to your home imap server regardless of where you are. You could just open access on your home imap server to the world, but that's a scary proposition. You could setup a VPN on your router, but that's probably overkill. Or, you could create an ssh tunnel from your laptop to your home network when you want imap access. I'll give an example of this in the next few paragraphs.
The second reason for using ssh tunneling is that it encrypts the network communication. In the imap example, an added benefit of using ssh is that the email data is encrypted. Your private communications with friends, family, and potential employers are secure as they travel over the tunnel on the internet. But be aware that communication before it hits the tunnel and after it leaves the tunnel are not encrypted.
There are two types of secure port forwarding using ssh: local forwards and remote forwards. For local forwards, the ssh client manages the source port. For remote forwards, the ssh server manages the source port. Whether you select a local or remote forward will depend on which system is able to initiate the connection, which has an ssh server running on it, and where you need the source of the tunnel.
Here is an example of a local forward. Continuing the imap connection, suppose that I have a laptop named "dink" and I want to access an imap server on a machine named "ezr." Why not just connect directly to "ezr?" If "ezr" is behind a firewall and you can't connect to port 143, then using ssh tunneling is a great alternative. Here is an ssh command that will allow you access to imap on "ezr":
The "-L" in the command specifies that this is a local forward. The "8143" specifies that I want to bind 127.0.0.1:8143 as the source of the tunnel. The "localhost:143" specifies where to forward traffic on the remote end of the tunnel. While I specified "localhost" on the remote end, I could have specified any address and port that the remote machine could communicate with. Finally, "ezr" is the machine I want to ssh into.
Before running this command, I ran this netstat command to see if anything on my laptop "dink" was listening on port 8143:
dink:~ jmjones$ netstat -an | grep 8143 dink:~ jmjones$
Nothing was listening. After creating the tunnel, I re-ran the same netstat command and saw different results:
dink:~ jmjones$ netstat -an | grep 8143 tcp4 0 0 127.0.0.1.8143 *.* LISTEN tcp6 0 0 ::1.8143
As you can see from the second netstat comand, something (my ssh client) is listening on port 8143 on 127.0.0.1 (the local loopback network device) on my laptop "dink." Any connection made to 127.0.0.1:8143 on "dink" will be forwarded to port localhost:143 on "ezr." After creating the tunnel, I just need to configure an account on my laptop's email client to look for an imap server at localhost:8143 and it will begin reading mail on "ezr."
Given the same machines, "ezr" and "dink," let's assume this time that I want the server "ezr" to use fetchmail and pull mail messages off of my ISP's pop3 server. The problem is that my ISP only allows machines that are connected to their network to access their pop3 servers. Since my laptop, "dink," is connected directly to my ISP and the server, "dink," is not, I could create a tunnel like this:
dink:~ jmjones$ ssh -R 8110:mail.myisp.com:110 ezr
The "-R" in the command specifies that this will be a reverse forward. The "8110" in the command specifies that the remote server will bind and listen on port 8110 as the source of the tunnel. The "mail.myisp.com:110" specifies where my laptop will forward any traffic that it receives from the tunnel. And "ezr" is the machine to ssh into.
Before running this ssh command from my laptop, I ran a netstat command on the server, "ezr," to show that nothing was listening on port 8110:
jmjones@ezr:~$ netstat -an | grep 8110 jmjones@ezr:~$
Nothing was listening. After running the ssh command on my laptop "dink," I ran the same netstat command on the server, "ezr":
jmjones@ezr:~$ netstat -an | grep 8110 tcp 0 0 127.0.0.1:8110 0.0.0.0:* LISTEN tcp6 0 0 ::1:8110 :::* LISTEN
After the tunnel is created, fetchmail can run on "ezr," pop messages off of localhost:8110, and the request will be forwarded to my ISP. Of course, the tunnel will only be active while the laptop has a connection to both the server "ezr" and the ISP's mail server.
Tunneling with ssh is an easy way to create secure data transmissions. It is also a convenient way of connecting two networks that aren't directly connected. It can become an irreplaceable tool once you figure out ways you can use it.
This article was first published on EnterpriseITPlanet.com.