I read your article How can I
keep my email safe from sniffing? about keeping your email and most
importantly email passwords safe whenever you use a public WiFi hotspot. My
problem is that I also have websites on my own server that I need to visit
which require a user name and password. Unfortunately, they are not https
encrypted which implies that those user names and passwords could be sniffed
and stolen. Is there a similar solution to keep this type of web access
safe?
Yes, indeed.
I'll warn you, though, this gets pretty geeky.
Become a Patron of Ask Leo! and go ad-free!
I have several websites on my servers, and some of them are definitely not
for the public. A good example might be the MovableType administrative
interface that I use to publish Ask Leo! and other sites. This, and my other
administrative sites require a user name and password.
Unfortunately these are all unencrypted http, not https, connections. If I
access those sites in a public place such as my local coffee house's free WiFi
hotspot, someone else could sniff my traffic and extract the user name and
password I use.
Now, I could run around and set up https for each of these sites, purchasing
a certificate for each, or installing a "self signed" certificate on each. But
since I've already done "SSH tunneling" for email, it wasn't much of a stretch
to expand on that to encrypt the web traffic as well.
There are two steps:
-
Creating the tunnel
-
Setting up fake DNS
We'll look at both here.
Creating the tunnel
up fake DNS"
As with the email tunnel discussed in that earlier article, you must have
SSH (Secure SHell) access to your server. If you do not (and if you don't know,
you probably don't), you can stop reading now. Check with your ISP if you like,
to see if you can get it, but this technique relies on SSH being available on
your server.
Start by getting the free SSH client and tools called PuTTY. Get the ZIP file that contains all the tools,
because we'll be using more than just the PuTTY client.
One of the tools is called "plink". In a command shell, run the
following:
plink -v -L 80:webserver:80 -2 you@webserver -N -pw
yourpassword
Where:
- -v: verbose - optional, but it will show you what plink is
doing setting up the tunnel, and as long as the tunnel is active. - -L 80:webserver:80: defines a tunnel of port 80 on your
local machine to go to port 80 on the webserver. Port 80 is the port used for
http connections. You would replace "webserver" with the name or IP address of
your web server. (For reasons we'll see shortly, IP address is actually
preferred.) - -2: force ssh v2 protocol only. Optional, but slightly
more secure. Use it unless your remote server doesn't support it. - you@webserver: your ssh login account name @ your web
server. - -N: no shell. Normally plink will also open up an
interactive shell. For our purposes here we don't need one. - -pw yourpassword: your password for your ssh login account
name. You can also leave this off to be prompted instead.
Leave plink running once it connects.
You now have a tunnel. Go to your browser and enter http://localhost as the URL; you should
see some activity on the plink line and you should get the default page that
your server offers up.
And the communication between your machine and your server went over an
encrypted SSH connection.
Now to get to specific sites you care about.
Setting up fake DNS
If the default website you just viewed is sufficient, then you're done.
However it's more likely you actually have several websites defined on your
server, only some of which need to be tunneled.
The tunnel we've just set up is only used when you attempt to view a web
page from "localhost", meaning IP address 127.0.0.1. The result is we need to
make your website "look like" it's at 127.0.0.1 by faking DNS.
Locate your "hosts" file; typically it's
c:\windows\system32\drivers\etc\hosts. Edit hosts using notepad or some other
text editor, and add the following line:
127.0.0.1 webserver
Where "webserver" is the domain hosted on your server that you want to
tunnel to. It's common for that to be a subdomain; something like
"admin.example.com", but you can tunnel to any domain.
This is where we run into a chicken and egg problem. If your hosts file
fakes DNS to make "webserver" appear as if it's at 127.0.0.1, then the plink
line used to establish the tunnel can't use "webserver" as the server it's
attempting to tunnel to. The solution is to in plink use either use a different
domain that resolves to the same server, or just use the IP address of your
server.
If you have several domains on the same server that you want to tunnel to
(as I do), then just add additional entries to the host file:
127.0.0.1 mt.example.com
127.0.0.1 admin.example.com
Only domains listed are tunneled, so if you need to tunnel both
"example.com" and "www.example.com", you'll need to list both. Any domains not
listed in the hosts file are not tunneled.
The steps, in summary
So next time you visit your local WiFi hotspot and need to access the sites
you're concerned about, you:
-
Establish an SSH tunnel between your local machine and your server using
plink. -
Fake the DNS for each of the domains you wish to tunnel, either by editing
your hosts file, or perhaps copying in a pre-edited version of the hosts
file. -
Surf away, securely!
Important: when you are done, CTRL+C to abort plink, and then don't
forget to remove the fake DNS entries from your hosts file.