Iodine is a nifty little program to tunnel IPv4 packets over DNS (53 is the atomic number of Iodine..*arf*). It can be handy in those situations where DNS queries are allowed out from a network, but not much else.

The setup: One local FreeBSD box (the client), one Ubuntu Feisty box (the server) and control over your own domain.

We start off by installing iodine on our FreeBSD machine, there is a port available for it:

[root@akagi ~]# portinstall iodine

Unfortunately iodine isn’t available in the Ubuntu package repositories, but we can just nick the Debian package and use that instead. The server is an amd64 machine, so you’d need to fetch the right package for your architecture. Install using

wget http://ftp.ie.debian.org/debian/pool/main/i/iodine/iodine_0.4.0-3_amd64.deb
dpkg -i iodine_0.4.0-3_amd64.deb

apt spat out some post-install errors due to version string mismatches - these are safe to ignore.

The next step is to delegate control of a domain to our server. This will cause all queries for the domain iotunneldom.spoofedpacket.net to go to our server iotunnel.spoofedpacket.net, where our iodine daemon lies in wait.

iotunnel        300     IN      A     88.198.67.243
...
iotunneldom     300     IN      NS    iotunnel.spoofedpacket.net.

Now, we start the server. The iodine daemon accepts udp/53 requests and creates a tunnel interface (dns0) for the IPv4-in-DNS packets. Make sure you have the tun device available, lsmod should confirm this.

root@longcat:~# iodined -P iminurdns 192.168.0.1 iotunneldom.spoofedpacket.net
Opened dns0
Setting IP of dns0 to 192.168.0.1
Setting MTU of dns0 to 1024
Opened UDP socket
Listening to dns for domain iotunneldom.spoofedpacket.net
Detaching from terminal...

-P specifies the password to use. The first argument is the tunnel endpoint address, choose an addressing scheme that doesn’t overlap with anything you already have - private space is a good choice. The second argument is the domain we setup earlier.

You should end up with an interface like this:

root@longcat:~# ifconfig dns0
dns0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:192.168.0.1  P-t-P:192.168.0.1  Mask:255.255.255.0
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1024  Metric:1
          RX packets:2 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:500
          RX bytes:168 (168.0 b)  TX bytes:168 (168.0 b)

Start up the client and point it at our tunnel server. Again, you’ll need some kind of tunnel device available - the generic FreeBSD kernel has one by default:

[root@akagi ~]# iodine iotunnel.spoofedpacket.net iotunneldom.spoofedpacket.net
Enter password on stdin:
iminurdns
Opened /dev/tun0
Opened UDP socket
Retrying version check...
Version ok, both running 0x00000400. You are user #1
Setting IP of tun0 to 192.168.0.3
Adding route 192.168.0.3/24 to 192.168.0.3
add net 192.168.0.3: gateway 192.168.0.3
Setting MTU of tun0 to 1024
Sending queries for iotunneldom.spoofedpacket.net to iotunnel.spoofedpacket.net
Detaching from terminal...

The client will then have the following interface (tun0) available:

[root@akagi ~]# ifconfig tun0
tun0: flags=8051 mtu 1024
        inet 192.168.0.3 --> 192.168.0.3 netmask 0xffffff00
        Opened by PID 61357

Now lets pass some traffic through it, test out the tunnel by pinging the remote end:

[root@akagi ~]# ping 192.168.0.1
PING 192.168.0.1 (192.168.0.1): 56 data bytes
64 bytes from 192.168.0.1: icmp_seq=0 ttl=64 time=57.382 ms

So, iodine is relatively straightforward to setup. Once you’ve got your tunnel, there are many uses you can put it to - Run a web proxy on the server, do some port forwarding or simply route all your traffic down it. There is also the potential to obfuscate your traffic, as all anyone would see is udp/53 queries.

One Response to “Everyone needs a little Iodine..”

  1. Taromaru says:

    Excellent entry, thanks for such verbose comments :)

Leave a Reply