by Paul Frields
SSH (Secure SHell) is well known to Linux administrators as the de facto method for connecting to other systems. SSH long ago supplanted other connection methods because it strongly encrypts the connection between the hosts, ensuring that passwords and any transmitted data are safe from prying eyes. On Fedora® and Red Hat® Enterprise Linux® systems, and many other Linux distributions, the OpenSSH suite provides the programs for this purpose. An administrator typically runs SSH to login to another system, often to run a shell on the remote host and issue commands. SSH, however, has many extra tricks up its sleeve beyond simply securing a connection.
Table of Contents
- Local Port Forwarding
- Remote Port Forwarding
If you are relatively new to using SSH, this article will show you some useful tools for securing communications other than simply logging in to a remote host. If you have a login on another system, you can use SSH to securely route other traffic in an almost endless variety of other situations. One of these capabilities is called port forwarding.
IP Networking for Newbies
In Internet Protocol (IP) networking, any connection between two hosts is made from a port number at one host’s IP address to a port number at the other host’s address. Ports range from 0-65535, and some numbers are usually claimed by particular services. For instance, port 80 is typically used by a web (HTTP) server, and port 22 is typically used by a SSH server. You can see a list of well-known port numbers in the
/etc/services file. Port numbers under 1024 are usually not available for users other than the administrator.
SSH port forwarding, essentially, is the art of causing a port from one host to appear on another, using a connection through SSH. Port forwarding can accomplish several goals at once, but one of the most compelling reasons to use the technique is that traffic to the forwarded port is encrypted.
When you forward a port locally, you make a port from the SSH server (the host to which you are connecting) available on your local machine (the host on which you’re running the ssh command). A port on the remote machine which would otherwise be unavailable to you for reasons of firewalling or other controls can be used just as if it was your local machine’s port. This port is presumably then available to other programs on your local host, outside the SSH session. That may seem a little confusing, but the following examples will hopefully give you a clearer understanding of how this technique works.
Imagine a situation where you need to conceal your web browsing traffic. Certainly many nefarious reasons for doing this come to mind immediately, but how about a legitimate one? Perhaps you are an on-site consultant and you don’t want your employer to know you’re Googling for an answer to a particularly difficult problem. Or maybe you’re visiting your company’s time registers from off-site.
If you have a remote host, say in your home office, that uses a squid web proxy, and is reachable by SSH, you can easily use local port forwarding to augment SSH with a secure proxy channel. Assume your remote host in the home office is known on the Internet as
fedora1.mydomain.com. Let’s assume your web proxy at your home office, the host called
proxy, uses port 1080; it need only be available to machines inside that network. Let’s further assume that you’re sitting inside the headquarters of IT sector giant example.com, at a host called
To set up port forwarding in this case, issue this command:
ssh -L 1080:proxy:1080
At this point, you can set your web browser to use the proxy, using the host
localhost) and port 1080. Your web browser connects to your local machine’s port 1080, but the connection is forwarded over the SSH session to
fedora1 in your home office, which connects to
proxy to make HTTP requests. Anyone at
example.com watching traffic will see only SSH traffic between
Observe Site Security Policies
Obviously, connections like this, as well as any network traffic, should be governed by Example.com’s IT security policies. Having secure, encrypted web browsing is nice, but having a job is good, too!
Let’s try another example. Say that you have a web-based administration tool that runs on your
codemonkey1 host in Example.com, using port 8888, but you wisely block access to this port for any hosts other than itself (as
localhost). Unfortunately, you’ve been working at an off-site example.com location for a few hours, when an urgent page comes in from your boss that requires immediate access to your web administration tool.
Fortunately, you can access SSH on that box, so no worries: local port forwarding to the rescue again! Issue the following command:
ssh -L 8888:localhost:8888
Note that the hostname
localhost in the command above indicates the way that
codemonkey1 refers to itself. If you now open up a web browser and point it at port 8888 on the system you’re using at the off-site, you’ll see your web-based administration tool, just as if you were back at the console in your own office.
Confusingly, you might type this in the web browser’s location bar as
http://localhost:8888, but in this case, the term
localhost is simply a way of telling the web browser to connect to the system on which it’s running. To recap, your host’s HTTP request connects to itself at port 8888, which is forwarded over the SSH session to
codemonkey1, which then connects to itself at port 8888.
When you forward a port remotely, you make a port on the client system available on the remote system. Like local forwarding, this technique allows you to work around security measures that might otherwise prevent an IP connection. However, since the port becomes available on the server side, a new vista of possibilities opens for networking, like the following example.
You may already know about vino, the slightly tweaked VNC server that allows one user to remotely view or assist with another user’s desktop. The vino server normally listens on port 5900 for a connection to the default X server. If you run multiple X servers (concurrent graphical logins), add the X display number to 5900 to find out the port number used, or simply use netstat -ltp and list the ports. A helpful friend or administrator can run the VNC client (vncviewer) to connect to the other desktop. But what if the server in question, and the user needing help, can’t be reached through normal means?
Imagine a friend of yours needs remote help, but is behind a router not under his control that prevents you from using SSH to login to his system. Your system
fedora1.mydomain.com, however, is not similarly disadvantaged.
First, set up an account for your friend on
fedora1, using a username and password you agree on over a relatively secure channel. (Your friend is free to change the password at first login using the passwd command or the appropriate graphical utility.) Then relay this command to your friend over IRC, instant messaging, email, or some other method:
ssh -R 5900:localhost:5900 email@example.com
In the command above, the first port number
5900 represents the port that will be opened on the remote host (
fedora1.mydomain.com. The hostname
localhost is the hostname your friend’s system calls itself. (Recall that if your friend has systems with ports he can reach, such as on a local or remote network, he can forward their ports remotely too!) The second port number
5900 is the port number on your friend’s system where his vino server is running.
Important: If your system has a process using port
5900, such as your own vino server, your friend will have to choose port
5901 for the first port number above.
You can now assist your friend by running the command vncviewer localhost. If your friend had to forward to port 5901 instead, use localhost:1 instead; for port 5902, use localhost:2; and so forth. Thus you can have several remote connections open at once to help a number of people at a time.
The flexibility of port forwarding goes far beyond the bounds of this article. Hopefully, though, these examples will spark your interest if you are starting to explore port forwarding.