Securing Instiki with an SSH tunnel

I've been using a wiki a lot recently to keep track of my research. A wiki is the perfect tool for keeping track of all my notes, and the relationships between my ideas.

I've been using Instiki; the UI is clean and is built with familiar technology (it's written in Rails, and its early code was the app from which DHH extracted the Rails framework). As wikis go it takes a fairly low maintenance approach, and lets you concentrate on your content.

Being a Rails app, you can run it with a standard Ruby web server such as Webrick. I started out running it locally on my desktop. When I started working more on my laptop I needed access to the wiki there too, so I moved the app's folder into Dropbox and synchronised the database that way (it uses a local SQLite database). That worked fine until I accidentally started it on both machines at once, and I lost a page of data.

Clearly, I was going to have to host it properly.

There is a fork of Instiki that runs on Heroku. I'm sure it's awesome, but I'm often reluctant to use forks of apps that don't see a lot of use. You've no idea how long the fork will be maintained, and I don't fancy rolling my sleeves up when Heroku deprecate the stack that the port runs on.

So I decided to host it on my VPS. In theory all I'd need to do is to tar up my local instiki folder, copy it over to my server and untar it. After a quick bundle install I should be good to go, and indeed, I was.

I knocked up a quick init script to start/stop the app on bootup/shutdown, and all was well.

Instiki was running unprotected on port 2500. All was not well.

So, what about security?

You really don't want a private wiki listening on an open port. Not only is your data unprotected, but somebody might find a vulnerability in the wiki software and login to your server.

I had planned to filter port 2500 on my firewall, and configure Nginx to act as a proxy on port 80. This wouldn't prevent an attacker from accessing the wiki's home page, but I could secure it in Nginx with HTTP basic auth running over an SSL connection.

How conventional. And what a faff!

Instead, I've firewalled port 2500 on my server and connect to Instiki over an encrypted SSH connection. Better yet, it guarantees that only I can get at it, as only I can connect to my server with ssh!

So now I access Instiki in the browser by connecting to http://localhost:2500.

I've put the ssh command that sets this up in a script, and run it whenever I want access to the wiki. At some point I'll probably run it automatically whenever I start my laptop, but for now I'm happy with running it when I need it.

Here's the script:

$ cat bin/instiki-tunnel
#!/bin/sh

ssh -f my.server.com -L localhost:2500:my.server.com:2500 -N

This is what the ssh options are for:

  • -f – run in the background just before launching the command.
  • -L – forwards all connections to localhost on port 2500 to port 2500 on my.server.com, via an encrypted, authenticated SSH tunnel.
  • -N – prevents an actual command from being run on the server.

You've got to love SSH.

I love feedback and questions -- please say hello on Twitter or leave a comment.