If there are any two services your school or workplace allows through their firewall, you can be almost sure they are HTTP and DNS. Unfortunately, HTTP access is usually filtered, and if your network admins are anything like mine, lots of useful, legitimate websites get blocked for no reason. I used to abuse the CONNECT method to establish a TCP connection to my SSH server and from there would tunnel traffic using SOCKS over the SSH connection to be able to browse properly again.

Unfortunately, recently they changed the firewall software and it now checks to see if traffic over CONNECT is using SSL, and if it is, it checks to see if there is a non self-signed certificate in use. If those conditions fail, the connection is blocked. This means that I could no longer connect to my SSH server. Running SSH over SSL using something like stunnel was also out, since I don’t own a signed certificate.

DNS tunneling

I wasn’t going to be beaten that easily. After remembering a few old Slashdot posts about DNS tunneling, I decided to look into it and compared a few pieces of software. The one I found to be most suitable was Iodine.

There’s a few drawbacks: it’s quite slow and it doesn’t seem to be able to co-exist with a real DNS server. But it works!

The first thing you need to do is to add an NS record to a subdomain of your main domain. Apparently it’s a good idea to make this as short as possible to give extra space for the data itself, so I chose The NS record should point to the address of the server you’re running Iodine on. For me that was simply

On the server, I ran these commands to install and start Iodine:

sudo apt-get install iodine
sudo iodined

The apt-get may need to be substituted with another package manager if you’re not on something Debian-based.

The second command starts Iodine in the background, using the subdomain Iodine creates a virtual network, so you also need to select an IP address for the server - in this case. The client’s IP address will be the next following the server’s - in this case. You should select an IP address within the private IPv4 network ranges that doesn’t conflict with any private networks your server and client is connected to.

On the client, I used these commands to install and start Iodine:

sudo apt-get install iodine
sudo iodine

Once this is complete, you’ll be able to connect to the server using the IP address you specified on the server. So to set up my SOCKS SSH tunnel, I ran the following command:

ssh -D1080

With luck, it should all be working!

If not I’d recommend checking the following things:

  • The DNS server Iodine is using is operating properly - when testing it locally I encountered issues with the local dnsmasq server that caches queries.

  • The firewall - I forgot to add the dns0 interface Iodine creates to the firewall configuration, this meant that Iodine said it was connected but all the packets were dropped.