IP tunnel over DNS HOWTO with Iodine


Why should I take iodine ?

Iodine is needed by the thyroid gland for the human body to synthetize some vitemins, it prevents stomach cancer, it ...

Seriously, Iodine is a small piece of software which permits to create IP tunnel over the DNS protocol, thus enabling Internet access in situations where the only allowed protocol is DNS (and that is quiet common). While Iodine is relatively simple to setup, the procedure is not straight-forward hence this HOWTO.

Also, Iodine is faster, more versatile and have more functionnalities than other DNS tunneling software (it has password protection, and allows up to 16 simultaneous connections). But you should not expect very high performances given the limitation of the DNS protocol.

What do I need ?

Here is the list of what you need to run Iodine:

  • A domain name, the shorter the better, as this name will be included in all the packet sent to the proxy (so a longer name will reduce the bandwith of your tunnel). In the following text I will call this domain domain.tld.
  • A configurable DNS server. This can be BIND installed on a private server or just the web interface of the registrar of your domain name if it offers enough option (you must be able to set A and NS record). The later is much easier, as running a DNS server can be trooblesome.
  • A private server where Iodine will be installed. This server must be different than the one running the DNS server (or it must have at least two different IP address). I will use as the IP for this server.
  • A client computer which will have access to Internet through the tunnel.

Where can I find iodine ?

You can find iodine in kelps or iodized salt... Or you can find Iodine from its home page, see below. The software is also bundled in numerous Linux distribution. Pay attention to the fact that it seems that the client and the server need to be running the same major version of Iodine.

The DNS Configuration

The point is that Iodine will pretend to be the DNS server for some domain name in order to create the tunnel. It would be possible to use Iodine directly on domain.tld but, depending on the TLD, there can be rules which will prevent you of doing so. The easiest way to proceed is to use a sub-domain, which I will call tunnel.domain.tld from now on (but remember that you want to keep to name short).

I will not give exact instructions in this paragraph about the setting of your DNS server, because it depends a lot on the registrar you are using, or the DNS software you are trying to configure (but in the latest case you should know how to proceed).

You must instruct your DNS server to tell that your private server (with IP is the DNS server for this sub-domain. For this, you need one more sub-domain, I will use dns.domain.tld, which will be the DNS domain. Then create an A record going from this sub-domain to the IP of your private server and a NS record indicating that the name server for the tunnel sub-domain is the dns sub-domain. For exemple, if you use BIND as your DNS server the records to add to the configuration of domain.tld are below:

dns IN A tunnel IN NS dns.domain.tld.

Mind the final dot in the target domain of the NS record which is mandatory for BIND and BIND-like DNS server.

Server side configuration

Installing Iodine


At this step you can check the proper installation of Iodine and your DNS configuration with the Iodine setup check, on Iodine home page (see the see links paragraph below).

Configuring NAT and IP masquerading

You need to enable packet forwarding in the kernel. This is done with this command (when you are root): echo 1 > /proc/sys/net/ipv4/ip_forward Note, that you cannot directly edit this file, you can only write data in it. Then this setting must be made persistant (to be still set at the next reboot), this is done by creating a setting for sysctl (also as root): echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/60-ipv4-forward.conf Or, you can edit the /etc/sysctl.conf file directly, especially if this command is already set in it or if the /etc/sysctl.d directory does not exist.

The next step is to enable NAT (network address translation) and IP masquerading in order for the client connecting to Iodine to have access to the Internet. We will assume that the primary network interface of your server (the one connected to the Internet) is called eth0 and that the interface created by Iodine is dns0, you should change these names according to your system in the following commands. Three rules must be issued for iptables th setup the NAT: iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE iptables -t filter -A FORWARD -i eth0 -o dns0 -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -t filter -A FORWARD -i dns0 -o eth0 -j ACCEPT There is many ways to make this setting permanent, depending on your system. You could add these commands to one of your init script, or use the iptables-save mechanism. The later is the easiest way on debian-like systems (and probably many others), where the /etc/network/interfaces configuration file is setup to read the the configuration for iptables from /etc/iptables.rules at startup. So you simply need to write this file with the current configuration of iptables: iptables-save > /etc/iptables.rules

Client side configuration


Usefull links

I did not discover all this alone. Most of the information here can be found in these web pages:


If you have comments about this web page, suggestions, corrections or anything you can send me an email.