kaashif's blog

Programming, software freedom and Unix


Iodine is cool

I know that sometimes, I’ve bene stuck in an airport or in a coffee shop without internet. That’s annoying in and of itself, but it’s even more annoying when there’s a WiFi hotspot nearby, but it requires you to pay £4/hour or something crazy like that.

You can still connect to the network, it’s just that whatever URL you

visit in your browser, you get redirected to the “pay for internet” page. Obviously, you can’t SSH tunnel somewhere, or use an ordinary HTTP proxy, those things are all blocked.

In desperation, I would ping google.com, since that’s what everyone does to check internet connectivity. There, I noticed something:

$ ping google.com
PING google.com (216.58.210.46) 56(84) bytes of data.

How did it know the IP of google.com? It must have resolved it using a DNS server, it’s not like I have a big list of sites in my /etc/hosts.

That means I can request information from a server, and get back information from on any server on the internet. All it would take is someone running a DNS server (or similar) putting some data in the records it sends back and I’ll have a way of communicating to the outside… without even logging into the hotspot.

Iodine - how to install and set up

I was ready to write a solution myself, but it already existed. Iodine! Here’s how to set it up.

First, set up an A record pointing to your public server and an NS record pointing to that A record. Basically set it up like the readme tells you to.

Now, on the server pointed to by the A record (assuming Debian):

$ sudo apt install iodine

Obviously that’s not going to do anything. On Debian, there is a config file at /etc/default/iodine. Fire up your editor and open it, and make the relevant variables look like this:

IODINED_ARGS="-c -d tap0 192.168.233.1/24 t1.mydomain.com"
IODINED_PASSWORD="mypassword"

Where t1.mydomain.com is an NS record, like in the README. Put in something secure for the password. Now, all you need to do is start it up:

$ sudo systemctl start iodined

And the server should be running. Check systemctl status iodined for any errors if you’re really paranoid.

The client

On the client, setup is just as easy. To make your life a bit easier, why not make iodine a service? Install iodine and edit /etc/systemd/system/iodineclient.service and put in the following:

[Unit]
Description=Iodine DNS proxy

[Service]
ExecStart=/usr/sbin/iodine -fP mypassword t1.mydomain.com

[Install]
WantedBy=multi-user.target

Now, just systemctl start iodineclient and wait a while for it to connect and you’ll be golden. You’ll get an IP of 192.168.233.2, if you used the same settings I did. The server it’s running from should be at 192.168.233.1, so you can run whatever web proxy you want there, and you’ll be able to access it so long as you can query DNS servers for t1.mydomain.com.

Setting up Squid

The whole point of this was to access the web from access points where all I have is DNS, so I need a web proxy. I chose Squid. Setting it up is really simple. On the server:

$ sudo apt install squid
$ echo 'http_access allow localnet' | sudo tee -a /etc/squid/squid.conf
$ sudo systemctl enable squid
$ sudo systemctl start squid

I know there are a lot of other things you can do with Squid, but with this, you can just fire up iodine and use 192.168.233.1 on port 3128 as your HTTP proxy and it’ll be like you paid that £400/second to access the internet, but your wallet will stay full.