How to safely use SSH to protect your information
SSH stands for Secure Shell. It was originally created as a safer method to access remote shells then current implementations at the time such as telnet. However you can use the secure channel that SSH provides for virtually any communication between two networked devices to add a higher level of confidentiality to your communications. Before we go any further with this article though it is important that we discuss some of the often overlooked technical aspects of SSH that can render it useless in the presence of decent hackers if you don’t really know what you’re doing.
Where SSH has failed us in terms of security and how we can fix it
When the SSH1 protocol first came out it was the most secure means to access remote terminals at it’s time. However, years passed and hackers missed good old plain text transmissions so they quickly discovered that through the use of MiTM (man in the middle) attacks they could snatch up the encryption keys being transmitted across the wire and read transmissions in plain text just like it was telnet. Thankfully the SSH2 protocol came out shortly after and fixed this mess, or at least it tried. The new problem with the arrival of SSH2 is that it was incompatible with SSH1 so it broke when trying to communicate with SSH1 servers. So for legacy reasons most clients to date still fall back on SSH1 if they detect that the server doesn’t support SSH2. Now clients falling back to SSH1 did absolutely nothing to fix the insecurity issue of the protocol as it was still being used. MiTM attacks still take advantage of this legacy feature today by tricking the client into using SSH1 by making it think the server doesn’t support SSH2.
Theirs still hope for SSH though. SSH2 has been around since 1996 and since then their has never been a working proof of concept of a way to decrypt a transmission in it. Theory says it’s entirely possible however i must reiterate, 13 years and nobody’s made even a proof of concept that they can do it. Most clients today have an option, that isn’t enabled by default for some reason, to force the connection to use SSH2 and SSH2 only. You accomplish this in the OpenSSH client by passing ‘-2′ as an argument. You can write this as an alias in .bashrc (or equivalent) so your shell will automatically enforce SSH2 connections only. You can do this with the following command:
echo "alias ssh='ssh -2'" >> ~/.bashrc
How can i use SSH to keep my information confidential?
First of all, i guess it’s worth noting that unless you can SSH or similar directly to the destination theirs no such thing as completely confidential information in an internet transmission. However by the end of this article you will have enough information to establish and maintain secure channel communications capable of providing 100% confidentiality in a wide open LAN regardless on any given protocol you choose to use. This will most notably be useful for people who don’t wish to shoot out their passwords in plain text over the air in public wi-fi hot spots, for students using college connections who don’t want nosy admins groping their packets, or the employee at work just trying to check his personal email with some privacy (during his break of course). This can also be used to sneak around annoying firewalls that restrict access to certain websites and services. Regardless of the case confidentiality on the internet can be a priceless tool at times.
Why not just use a VPN
As a matter of fact OpenSSH has built in support for VPN over SSH right out of the box and it’s relatively easy to set up. I’ll discuss VPN over OpenSSH in another article though. Anyways, setting up a VPN would be a great option as well and by all means i encourage you to set one up some time. However SSH is easy and most *nix boxes already have it installed and if it’s not already installed it’s a pretty painless procedure. So I’m aiming for out of the box confidentiality.
What you need
You’re going to need at least one of the following three requirements: 2 computers (one as the client you’d use and another as the tunneling server), a remote shell account or a router flashed with DD-WRT/OpenWRT. The main thing is to be able to establish an SSH connection with a box either outside of your current network or with the router itself. The way I achieve this on my home network is by establishing the SSH connection to the my router which is a custom FreeBSD server. However the easiest way to accomplish this would be with either a remote shell or with a router flashed with DD-WRT/OpenWRT.
For people wanting to go the DD-WRT/OpenWRT way and aren’t super comfortable with flashing their firmware I recommend they either pick up a Linksys WRT54GL (~$45 USD), which is a router designed for enthusiasts that’s pretty much made to be flashed (the appended L actually stands for linux rumor has it) and can be flashed in about 1 minute through the admin WebUI. You can even buy routers pre-flashed with DD-WRT/OpenWRT for a $10-15 added cost on average.
I have to re-iterate that the SSH server you want to connect to must either be on the edge of your network (router) or outside of it, otherwise the purpose is lost as no improved confidentiality is achieved due to your traffic still being forwarded in plain text across the local network.
Ok, i want to know how to tunnel already!
Ok, now the fun part. So you’re going to need to know the IP/web address of the SSH server you want to tunnel through and I’m going to assume you already know how to do this. If you don’t know how and you’re tunneling through your router you should look up how to set up DynDNS on the router which will give you a custom domain name. For this demo I’ll be tunneling through my router which has a local IP of 192.168.1.1, so whenever you see that IP just substitute it for the IP/Address that you wish to connect to. We’ll start the fun off by firing up our terminal of choice (windows users have no excuses this works in cygwin too) then entering the following command.
ssh -2NfD 4321 thetan@192.168.1.1
Now what this does is force the ssh client to use the SSH2 protocol (secure), tells the SSH server not to run a command (focus on connection tunneling instead), pushes the ssh client in the background and sets up a SOCKS 4/5 proxy on the local machine listening to port 4321 (can be any port greater then 1023, otherwise you have to run the ssh client as root) that will take all incoming traffic through the SOCKS proxy, encrypt it and push it through the secure channel. Now all you have to do is configure your client’s to talk through the local SOCKS proxy. Not all clients support SOCKS proxies but most major ones do.
To make Firefox connect to this local SOCKS proxy (in linux, i think it’s slightly different in windows) you’d open up Firefox, Navigate to Edit -> Preferences -> Advanced -> Network -> Settings, check ‘manual proxy configuration’, in the box that says SOCKS host type ‘127.0.0.1′ and for the port type ‘4321′ (or whatever port you used), click ok and viola you’re speaking alien to everyone else who doesn’t need to know.
What if i want to use a client that doesn’t support SOCKS?
Your favorite client for whatever doesn’t support SOCKS proxies, no problem. You can forward on a port by port basis as well. The process similar so I’m just going to jump in and show you the goods with a sample command. The following command you could use to keep prying eyes from reading your IRC conversations and nickserv/oper passwords. This would be useful if either the server or client you are connecting to/with doesn’t have built in support for SSL.
ssh -2fL 3337:irc.criticalsecurity.net:6667 Thetan@192.168.1.1 sleep 120
Now the above command forces the SSH client to use SSH2, pushes it in the background, and starts listening on port 3337 for TCP connections, found connections and associated data will be pushed through the secure channel to the SSHD host (192.168.1.1) and then forwarded to irc.criticalsecurity.net on port 6667. The sleep command is used to keep the ssh client open and listening for connections as ssh will die if no connections are found or programs are running.
What you would do to use this is instead of connecting to the remote IRC server directly you would have your IRC client connect to 127.0.0.1:3337 instead and no further configurations are required.
The same process applies to all other protocols on all other ports. In order to run multiple clients with this method you’d have to issue a similar port forward command through ssh with non conflicting local ports per command. So as you can tell using the dynamic forwarding method via the SOCKS proxy can be a lot less head ache prone.