Wednesday, August 31, 2005

SSH HTTP Proxy Setup

SSHirking work - part 1 tech

A little while ago I mentioned that I've been tunnelling my web traffic out of work and through my home connection. That post inspired a firestorm of public interest (one person emailed me about it). Here's the beginning of how to implement such a setup yourself. When it's working your boss won't be able to snoop on which websites you're visiting, or block them, or really tell anything about your internet traffic apart from how much of it there is (and that it's strangely hidden).

First, the big picture. I've explained the idea behind ports at least a couple of times. We're going to take our browser's web traffic — the stuff going out through port 80 — and send it through an encrypted tunnel to a PC at home that's running a proxy server. The proxy server will make an unencrypted request for the webpage we're trying to access (using our home connection) and send the data back through the encrypted tunnel.

We're going to need a few things. We'll need a PC that's at home and turned on at whatever times the link should be available. And we're going to need to make some assumptions. So this is going to be a Windows tutorial. All the software required is free and open source, though, and you could certainly accomplish this setup under OS X or Linux. In fact, in some regards it'd probably be quite a bit easier. But Linux users don't need my help setting up a proxy server, and Mac users are used to being ignored. If anybody with a Mac really wants this functionality, just let me know. I'll be happy to dig up the relevant links.

Finally, I'm going to assume you know how to open up ports on Windows firewall (or at least turn it off) if you're running a version of XP that has it installed. Same thing with ZoneAlarm, or whatever other software firewall you might be running. I can't account for everything, people!

So let's get started. In this post we'll take care of the software that supports the encrypted tunnel. This is the hard, but not that hard, part.

We're going to use SSH for this, a technology that on its face is a secure replacement for telnet, but also provides the ability to redirect ports on a client machine to arbitrary ports on any machine accessible to the server. This'll make sense later -- for now, just trust me as I tell you how to install OpenSSH for Windows. Start by downloading the binary installer from that site, then unzipping and running it.

Here's the first important decision. What port should we run this thing on? SSH usually runs on port 22 — but we're going to have to make it publicly accessible. Script kiddies scan IP blocks for SSH servers (among other things). SSH servers make for ripe targets because they generally indicate a system more interesting than a typical grandmother's email box, and because if it can be accessed a large new class of exploits can be run against the machine. Don't be scared — none of this is very likely to happen. But it's worth thinking about.

A bigger consideration is your firewall at work. Your workplace might block unknown ports for security reasons, or productivity reasons, or just to be mean. Unless you have a job-related reason for using port 22 it might not be available. To get around this, you could run your server on port 80 — that's pretty well guaranteed to work, so long as you can access the web. But it might also attract attention, in this case from your ISP. Broadband providers generally don't like folks hosting websites on their home computers. Cablemodem ISPs tend to be the biggest jerks about this. So while port 80 might be more foolproof for work, it also might bring up bureacratic hassles with your internet provider. Decide accordingly.

UPDATE: Thanks to a reader in comments who points out that port 443 is almost always open (for SSL-enabled websites), is commonly used for encrypted traffic, and less likely to attract script-kiddy attention.

So, run the OpenSSH installer. Accept all the defaults. If you need to use a port beside 22, edit c:\program files\openssh\etc\sshd_config in a text editor like Notepad, remove the hash (#) mark from in front of the line that reads "# port 22", change the port number appropriately, and save the file.

Now we've got to set up a user for this SSH server. We'll do this by adding one to your windows machine. Make sure you're logged in as an administrator, right click on "My Computer" and choose "Manage". Expand "Local Users And Groups", right-click on "Users" and choose "New User". Enter a username — I'll assume "sshuser", but you can use whatever you'd like — and enter a good password (I'm fond of this generator for producing them). You'll probably want to uncheck "User must change password at next logon", and if I were you I'd go ahead and check the boxes next to "User cannot change password" and "Password never expires".

One last thing. Click on "Start", go to "Run" and type "cmd". Now type this in:

cd \Program Files\OpenSSH\bin
mkgroup -l >> ..\etc\group
mkpasswd -l -u sshuser >> ..\etc\passwd

That sets up OpenSSH to use the user account we just created

Finally, go to the Control Panel, then select "Administrative Tools", then "Services". Find "OpenSSH Server" and go to its properties (you can doubleclick on its name to get to them). Make sure "Startup Type" is "Automatic", then click the "Start" button.

Congratulations. Your computer is now an SSH server. Why don't you try connecting to it? Download PuTTY and run it. Click the SSH radio button, enter "localhost" into the "Host Name" box (assuming you're running this on the same machine onto which you just installed OpenSSH). The port box should read "22" — if you installed the server on a different port, enter that number instead. Then click the "Open" button. You should get a one-time warning about the server's key, then be able to log in using the sshuser name and password.

And bang! You'll get a command line prompt. Very exciting. Alright, maybe not. But trust me, this is good. If for some reason you can't get to this point, leave a message in comments and I'll try to help you fiogure it out.

There's only one more step to getting this SSH server up and running: open it up to the world. So if you're behind a router, go to portforward.com and look up instructions on how to forward whatever port you're using (22, 80, or whatever) to the server machine. You'll need to look up the server's IP as well — portforward.com should have instructions, but the short version is start|run, "cmd.exe" then "ipconfig".

If everything's gone right, you've got a working SSH server that's accessible from the internet. When you're at the office you'll have to use your internet IP to access the machine. You can find that out here; alternately, it might be a good idea to register for a dynamic DNS service (be sure to install the updater software) so that you don't have to worry about the IP expiring.

This is a useful thing to have in its own right, but it's going to be really useful once we install Privoxy, configure the SSH tunnel and modify your browser's proxy settings to use it. But we'll get to all that in the next post. For now, take heart in the knowledge that the worst is over.


===========================

When last we left our hero — that'd be you — he had a functioning SSH server running on his Windows machine. You've poked a hole in your firewall and/or router, and maybe you've signed up for a dynamic DNS service. That, or you at least have an IP address. The bare minimum is the same: to proceed from here, you ought to be able to connect to your OpenSSH server with PuTTY when you're away from home.

The remaining tasks are pretty easy:

  1. Install Privoxy on the server
  2. Set up the SSH tunnel using PuTTY
  3. Configure your web browser to use the SSH tunnel

So: Privoxy. You can download it here — you'll want the most recent Win32 release. Run it and use the default configuration. It should start up the Privoxy console. Everything is pretty well ready to go with the default settings. You can hit the "X" on the console, but retain the shiny new blue P in your system tray. You've now got an HTTP proxy server running on your machine — one that, it's worth noting, will only accept requests from the local machine. But that's okay, because (counterintuitively) that's exactly where they'll be coming from.

Alright. Let's get this SSH tunnel going. From your non-home location (let's just call it work), start up PuTTY and enter the information necessary to connect to your SSH server. But don't connect yet. In the menu tree on the left, navigate to Connection | SSH | Tunnels. You should see this dialog:

PuTTY configuration screen

Enter the information as you see it here (if you can't see the image, see here), then click "Add". Let me explain what this all means.

SSH allows you to forward ports between the client machine (on which you're running PuTTY) and the server machine (on which you installed OpenSSH and Privoxy). In this case it's a Local port — that's what the radio button is set to, and it means that traffic that comes into the relevant port (specific in the "Source Port" textbox) on the client machine will be encrypted, sent to the OpenSSH server, and then sent from there to the address specified in the "Destination" textbox. If the "Remote" radio button was specified it would work in exactly the opposite direction, with traffic getting collected at the server and sent out through the client.

One more thing. You might already know this, but that "127.0.0.1:8118" has two parts: the IP address and the port number. 127.0.0.1 is a special IP address, called "loopback" or "localhost" that always refers to the current machine. The colon followed by "8118" specifies the port number. So: this tunnel will collect traffic coming into the client on port 8118; it'll then be sent through the SSH tunnel; and the server will decrypt it and send it to 127.0.0.1:8118 — port 8118 on itself. Which happens to be the default port on which Privoxy listens.

You might want to go back to the startup PuTTY screen, enter some text in the box under "Saved Sessions" and click "Save" — this'll let you reload the settings quickly in the future. Every time you want to use this tunnel, you'll have to open PuTTY, reload (or reenter) these settings, then connect and log into your SSH server as normal. It's important to note that the tunnel won't be set up until the login is complete — otherwise this would be a pretty huge security hole. And, as a result, you'll have to keep that PuTTY window open for as long as you're using the proxy setup each day. It's not that irritating, I promise.

Alright, last step. With the tunnel established, set up your browser to use an HTTP proxy. In Firefox this is under Tools | Options | General | Connection Settings. In Internet Explorer it's under Tools | Internet Options | Connections | LAN Settings | Advanced. Either way, set your HTTP proxy to point to 127.0.0.1, port 8118.

That's it! Start browsing. If you'd like to and feel up to it, download Ethereal to see what's going across the wire — all of your web traffic should be encrypted.

I should mention a few details. First, you'll probably notice that this system is a little slower than proxy-free web browsing. That's to be expected — your connection at home is assymetric, meaning that you have more available download capacity than upload capacity. Normally this works out fine, because receiving a webpage or a file or streamed audio takes more bandwidth than does asking for it. But our setup turns this on its head, because all traffic will have to be shoved back up through your home internet connection. It shouldn't be too irritatingly slow, but it will be a noticeable difference.

Second, you might occasionally see Privoxy assert itself. The most obvious way is in big, bold error pages that come up when Privoxy can't access a website. Usually refreshing the page will solve this problem. By default Privoxy also filters some ads. If you'd like to turn this capability off, consult its documentation. I've found it to be a pretty unobtrusive feature.

Finally, if you're using Firefox, I'd recommend installing SwitchProxy, an extension that lets you easily change which proxy you're using to browse (configuration is pretty intuitive; use the same settings as those outlined above). SwitchProxy comes in handy when you're about to start a high-bandwidth transaction -- a file download, for example, or streaming audio from an internet radio station. Just switch the proxy off, then start the transfer. It won't go through the tunnel, and consequently won't eat up the tunnel's limited bandwidth. As soon as the connection is initiated you can turn the proxy back on. The just-started transfer will remain outside the secure tunnel (and, of course, be visible to the public).

That pretty well wraps things up. Folks on your network at work won't be able to see what you're accessing. From a network perspective, it'll look like you're browsing from home. The SSH tunnel will be visible, but its contents will be encrypted. Odds are that no one will bother you about it. If they do, I'd suggest making up a line about your personal webmail not supporting SSL — that's plausible enough. Do keep in mind, though, that a record of your browsing activities will still exist on your hard drive. If you're really worried about it, be sure to clear out your browser's cache and history before heading home each night.

There are a few more useful things you can do now that you've got this SSH tunnel set up, the most notable being remote control of your computer at home with an application called VNC. I'll try to write something up on that later — it's very straightforward. In general, whatever other network services are available from home but not work, can be made available — with a couple of noteworthy exceptions. First, SSH only tunnels TCP, the slower-and-steadier of the internet's two packet types (UDP is its speedier, unreliable sibling). The tunnel's slow, so you wouldn't want to use it for playing Quake anyway. But the lack of UDP support rules out some streaming applications, like iTunes on the PC (Mac users can use iTunes without needing UDP by forwarding TCP port 3689). More notably, despite Windows filesharing working over TCP, it can't be redirected over SSH (at least not easily). If you need to get to windows shares on your home network, you'll want a real VPN solution, like OpenVPN. Unfortunately the OpenVPN tutorial I did a while ago is now outdated (it should still work for a single user, but it'll probably be a bit slow). If there's any interest, I'll write up a new one.

As before, let me know in comments if you have any trouble with the above instructions. Besides newfound guilt over dereliction of your official duties, I mean.

UPDATE: I forgot to mention that many apps besides web browsers can use HTTP proxies. Most obvious is your IM client — if you'd like secure IM traffic, check out its connection settings and configure it to use an HTTP proxy using the same settings as you did for your web browser.

No comments: