If you’re still using SSH as just a telnet replacement, you are missing out on borrowing its secure encryption to carry many other network services through insecure Wi-Fi, and overly restrictive firewalls, from wherever you have a laptop or smartphone.
For the bulk of this article, we shall be looking at local port forwarding – the most common and the most useful type – to give secure, VPN-like connections. Why not just use a virtual private network? VPNs aren’t always available to you, and some corporate VPNs demand particular client software and configuration, but SSH
tunnels can always be created on the fly, as and when you need them.
Perhaps you have never read the SSH man page? No? Well, the options you should have been looking at are -L and -R, with a little attention to -N and -f.
Skipping lots of theory, we’ll take a practical approach and show you how to use SSH tunnelling in various common scenarios. Read on and find just what these magic switches to the ssh command can do for you, but beware – the power to run rings around firewalls should be used carefully!

Resources
SSH client with SSH daemon on the server
A server connected to the internet, preferably with a fixed IP address
Step by Step
Step 01
A different port
When you run a normal SSH session, it simply opens an encrypted connection from a spare port on your computer to port 22 on a remote device. For security reasons – many scripts are knocking on port 22 with well-known passwords – you can specify another port.
Step 02
Insecure access
However, inside this encrypted connection you can carry other traffic – hence SSH tunnelling. This means that however insecure your connection (eg cafe Wi-Fi), your traffic is as secure as the level of encryption used by SSH (ie good enough).
Step 03
Confidential mail
Tunnelling allows you to hide your unencrypted email traffic inside the SSH connection. The -L local-port:host:remote-port creates the tunnel, allowing SMTP (port 25) traffic from the mail-server to appear on (for example) port3909locally.
Step 04
Local config
Now just configure your email client to connect to port 3909 of the local machine. Localhost and 127.0.0.1 are synonymous, but you could also use the fully qualified domain name (FQDN) of your local machine. You can do the same for receiving mail via POP.

Step 05
Pick a number
Why port 3909? Port numbers below 1024 are for privileged services. No non-root users should be looking higher than this, but taking a peek at the popular ports in use by other software. Pick a free number such as 6555 or 3989 as your default.
Step 06
Two-lane tunnel
While outward-bound SMTP is occasionally blocked, if you’re tunnelling for security, best do the incoming POP mail with the same command. As you can see, multiple local tunnels can be expressed in the same ssh command, each with the -L switch.
Step 07
On the server
Before we go any further, best get a couple of things straight on our server. SSH in (without the tunnel this time), gain root privileges, and fire up your favourite editor to open /etc/ssh/sshd_config (or whatever your distro names the file).
Step 08
Security basics
As well as security settings like a port other than 22, and not allowing root login, here you should uncomment the protocol version 2 setting, so only the more secure protocol version 2 will be used. If both are listed, delete the ‘1’.
Step 09
Error check
Check you can log in on the new port from another terminal before you close this session! If there is a problem, check that you restarted the SSH server, and typed the correct port and username. If in doubt, return to default port setting.
Step 10
Keep yourself alive
While you can add ServerAliveInterval 60 to your ~/.ssh/config file, adding KeepAlive on the server will work when you connect from other devices or PCs – the ClientAlive directives will keep you connected during inactive periods, which is useful for reverse tunnels.
Step 11
Keeping track
Configs for local and reverse tunnels can also be added at the client end too – handy for keeping track of multiple connections over multiple ports, as well as enabling easier connections from shell scripts. RemoteForward = reverse tunnel.