ssh-ecurity — Part 6: Walled in? Tunnel out!
To reiterate what I said in the last installment, I'm a luddite and an erudite command line user. In fact, I still read the lion's share of my email using OpenVMS mail — a strict text based email agent; unfortunately, many of the people I correspond with do not. Sometimes, I am sent graphical attachments, or files which must be opened and processed with a tool that does not exist on OpenVMS. When these emails arrive, I simply move the email message, along with its attachment(s), in OpenVMS mail to a special folder which I have configured to be served via POP. I can then view the message's attachments using Evolution Mail on my Ubuntu Linux laptop or the MacOS X Mail application both which are configured to use my OpenVMS server as the POP server. I can reply back to these messages as well because the OpenVMS SMTP server is configured to relay inside network emails.Out on-the-road, however, this practice is thwarted by a number of obstacles. One being the POP and SMTP servers. Both have been configured, for security reasons, only to serve email to email clients on the inside network. Let's, for the sake of this discussion, define this network as 192.168.1.0/24. For the same reason, security, the SMTP server is also configured for the same inside network. So, as you can see, right off the bat, accessing either of these servers from outside of the inside 192.168.1.0/24 network is prohibited.
There's another issue. Many home internet service providers (ISPs) have, in recent years, started to firewall (block) certain ports on their networks. The same occurs when connecting to networks on-the-road. One of the common ports blocked, and for good reason which I'll discuss in just moment, is outbound port 25. Port 25 is the designated port number for SMTP — email. Why is it that they have blocked it? Many of the ISPs, in a attempt to make their customers good denizens of the internet, have blocked port 25 in an effort to thwart the widespread proliferation of SPAM. SPAM — We all know what it is, so I see no need to define it herein, and we all hate it! By blocking port 25, these ISPs have limited the ability of rogue SMTP connections to other SMTP servers on the world wide internet. If you are their customer, you either use your ISP's SMTP server or you opt for one of the web browser based email systems. If you choose to use your ISP's server, any SPAM you originate will be traceable to you! When you do, and your high-speed internet provider traces it to you, you will have violated your terms and conditions of using their service and you may find yourself back on that old 33.6K modem dialup connection you loathe so well.
Out on-the-road, the block on port 25 isn't of that much concern to me. I'm content to login with ssh and use my text-based OpenVMS mail as I have for close to three decades. However, my wife often borrows the laptop to check on her email, and she is more comfortable with the Mac OS X email application and its Universal Access features. Of course, comfort or not, I simply do not allow anything outside of the 192.168.1.0/24 inside network to access my email SMTP or POP servers. So, does this leave my wife pining for her email fix? Not at all! Using X11 Forwarding, could the email client on her machine back home be forwarded to the laptop out on-the-road? Perhaps, however, there's a even craftier solution... ssh tunneling.
There's a feature of ssh which allows almost any protocol, not just X11, to be used like X11 Forwarding and it is called ssh tunneling. It is, in my humble opinion, one of the best features of ssh. It's powerful and, for some reason, so misunderstood or confusing that most people don't bother to use it or learn how it can be used. Let's see if the following can make it clearer.
Be it known that there are two types of tunneling provided in ssh: local and remote. For the remainder of this blog entry, I will focus on the local tunneling aspects of ssh. Next installment, I will delve further into tunneling and discuss remote tunneling.
When local tunneling with ssh, any application you would use to connects to some remote client using host.domain.com:port-number or IP-address:port-number will have that host and port replaced with localhost:port-number. When you use ssh local tunneling, you specify that a port on your local (client) host is to be forwarded to some remote host and an associated port on the remote (server) host. ssh allocates a listener socket on the local (client) side with the port you've specified. Now, when you use your application, connecting through localhost:port-number, ssh creates a connection from this port on your local host and forwards, over the secure channel, all of the application data to a connection the ssh server makes to the server host and port on the remote host. The server on the remote host sees this connection as a localhost connection too, if you've specified localhost.
The syntax for the ssh command is fairly universal for local tunneling. The switch that signifies local tunneling is
-L
and the argument to the switch is local-port:remote-host:remote-port
.Let's see what this looks like when using ssh local tunneling to forward port 25 — SMTP — to the remote server. First things first, let's issue the ssh command and authenticate to the remote system.
ubuntu$ ssh -L 25:localhost:25 username@openvms
username@openvms's password:
Now, let's have a look at what this looks like to TCP/IP. On the client side, before connection of the client application, there is a port 25 now in LISTEN state on the localhost.
ubuntu$ netstat -tnlp
maxosx% netstat -an -p tcp
Proto Recv-Q Send-Q Local Address Foreign Address State
⋮ ⋮ ⋮ ⋮ ⋮ ⋮
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN
⋮ ⋮ ⋮ ⋮ ⋮ ⋮
tcp6 0 0 ::1:25 :::* LISTEN
⋮ ⋮ ⋮ ⋮ ⋮ ⋮
On the remote side, there is nothing shown, yet! Now, connect the client application (the mail program) with the SMTP server configured to be localhost:25 and the remote shows: (I did this on OpenVMS because it is more straight-forward to view what is actually happening.)
OPENVMS$ TCPIP SHOW DEVICE/PORT=25
Port Remote
Device_socket Type Local Remote Service Host
bg184 STREAM 25 0 SMTP * ⇐ normal SMTP server
bg777 STREAM 25 51452 SMTP 127.0.0.1 ⇐ created via ssh tunnel
bg779 STREAM 51452 25 127.0.0.1 ⇐ created via ssh tunnel
OPENVMS$ SHOW DEVICE/FULL bg777
Device BG777:, device type unknown, is online, mounted, record-oriented
device, network device, mailbox device.
Error count 0 Operations completed 8
Owner process "MX SMTP Server" Owner UIC [SYSMGTGRP,SYSTEM]
Owner process ID 00009D0B Dev Prot S:RWPL,O:RWPL,G:RWPL,W:RWPL
Reference count 1 Default buffer size 256
OPENVMS$ SHOW DEVICE/FULL bg779
Device BG779:, device type unknown, is online, mounted, record-oriented
device, network device, mailbox device.
Error count 0 Operations completed 5
Owner process "TCPIP$SSH_BG781" Owner UIC [TCPIP$AUX,TCPIP$SSH]
Owner process ID 00009D0F Dev Prot S:RWPL,O:RWPL,G:RWPL,W:RWPL
Reference count 1 Default buffer size 256
OPENVMS$
The first command output shows the socket devices created for the ssh tunneling of port 25. It shows two devices with the ethereal port number 51452. The second two commands display the bg devices (the TCPIP Services for OpenVMS socket device designation). The first socket is associated with the SMTP server on the system. You can see its local socket designation is 25 and the remote is localhost:51452. The second socket is associated with the TCPIP$SSH server process. Its local socket is 51452 and it is communicating with the SMTP server. The remote socket designation is localhost:25. The TCPIP$SSH process handles the data exchange to and from port 25 on the remote host.
So, there is now a way to connect from a remote email client to the SMTP server. Firewall or not, we can access port 25. Also, because the access to the SMTP server appears to come from the localhost, the inside net restriction doesn't come into play. In addition, it's all securely encrypted!
Now, you may have noted that SMTP is for sending your email. How do you get it? Simple. Tunnel the port for your POP (port 110) or IMAP (port 143) server as well. The following command, assuming POP, will allow two-way secure email traffic.
$ ssh -L25:localhost:25 -L110:localhost:110 username@myhost.mydomain.com
username@myhost.mydomain.com's password:
Also, note that ports 25, 110 and 143 are considered privileged ports. In order to establish tunnels to these on your local system, you need to be root or you need to be setup to use sudo. Taking this into consideration, the command would be:
$ sudo ssh -L25:localhost:25 -L110:localhost:110 username@myhost.mydomain.com
[sudo] password for username:
username@myhost.mydomain.com's password:
If you can't get the privilege (ie. sudo) to setup ports 25 and 110 or 143 locally, you can use other port numbers which are less restricted; however, you will need to configure your local email client with the appropriate port designations in order for this to function.
Please don't come away from this discussion thinking that this is only useful to access your email &mdash far from it! I use ssh local tunneling to access several MySQL databases over the internet. Using the MySQL Query Browser, I can mine the databases securely over an ssh tunnel on port 3306. No password is passed in plain text in the query and all of the data, as some of is is sensitive, is also securely encrypted.
On several web sites with web-based management functions (think CMS — Content Management System — such as Joomla, Drupal, vBulletin, etc.) I have set people up to tunnel to their sites. Thus, everyday web access still continues to function through http://www.sitedomain.com but any of their privileged login functions now require them to first connect and tunnel their web site to localhost:80. The web server (Apache in this case) is configured to only serve up pages associated with the management functions to requests and referrals from localhost. This drives the script-kiddies mad! It also keeps them at bay!