Content managements systems like the one we're using for the web site (Drupal) need to provide a privileged administration interface which you usually want to access securely. Due to the insecure nature of the Internet, it's reasonable to assume your traffic may be intercepted at some point. So how do you prevent that?

Up until recently, we used SSL. You could access the web site from both:

Unfortunately, as the site grew in complexity this created a range of subtle but annoying paper-cut type problems.

For example, I configured the site to use a content filter which translates local urls (e.g., /lamp) into absolute urls (e.g., http://www.turnkeylinux.org/lamp ). This is necessary for links and images in blog posts to work correctly in RSS feeds and email updates (e.g., such as those provided by FeedBurner). We didn't want to do that by hand because we were using FCKeditor and IMCE which create local links by default and it wasn't any fun to have to translate every single link into an absolute URL by hand.

The problem is that Drupal cache saves pages AFTER the content filter, so guess what happens to links in pages you access via SSL? The situation could be a mix-up of http and https links which would be potentially confusing to both human visitors and search engines.

More importantly while in theory SSL should have protected our administration credentials in practice it didn't.

Drupal, along with many other web applications doesn't support secure SSL cookies. That means even if you login via SSL your cookie is still transmitted over the clear when you access the site, say accidentally, via HTTP. In a perfect world that might never happen but in practice it's quite a frequent mistake.

An attacker that can intercept your traffic can then intercept the cookie containing your session key and use that to access the site with your privileges.

So using SSL in this way doesn't really add that much security.

OTOH, session keys are temporary where passwords have much longer lifetimes so you still don't want to transmit your password in the clear.

Alternative: access the site through an SSH tunnel

So perhaps somewhat unintuitively, after considering our options we decided to turn off SSL and access the web site through an SSH tunnel which serves as a poor man's VPN.

That sounds a bit complicated but it really isn't.

From my ~/.ssh/config:

host tkl
DynamicForward 1081

Then when I ssh to tkl, which is the VPS which hosts the web site, this creates a virtual socks proxy bound to 127.0.0.1:1081. Constructing the tunnel in this way can be a bit of a hassle but you can set that up to happen automatically (future post).

We then configure SwitchProxy FireFox extension to make it easy to switch to browsing within the tunnel.

Configuration tips:

disable the SwitchProxy toolbar (Views->Toolbars)

added my staging server test.turnkeylinux.org to "No proxy for..."

And then to switch into the tunnel: Tools->SwitchProxy->tkl

A nice bonus is that in our case this setup seems to be noticeably snappier than using SSL.

WOW, I did not know drupal has this brutal security problem! Did you report it? I think, this is really a major concern - I expect a modern framework to handle cookies securely, Drupal should do it like this!

However, your described configuration is something I also use frequently - but it happens, even if I am not totally sunk in a stressful situation, that I make accidentally connections to the "wrong" site - so I recommend to instruct your CMS to only accept admin logins from 127.0.0.1, so you can only admin via the tunnel.

You can set your cookies to be secure by adding ini_set('session.cookie_secure', 1); to your settings.php file. You should also add ini_set('session.cookie_httponly', 1); to stop javascript from accessing your cookies as well. However, please be aware that a site that uses both http and https will never be secure. If a ssl site still accepts http connections, then a man-in-the-middle can simply strip the https and redirect all your requests to http to obtain the plain text versions. So it's basically all or nothing with ssl.