Index ¦ Archives ¦ Atom

How to tunnel data over DNS

A while ago I wrote a post on tunneling data over DNS that was a technical explanation of what's going on. This post is a tutorial on how to setup a DNS tunnel with iodine.

I'm using DNS Made Easy as my main DNS provider, Debian on an EC2 for the DNS server, and Arch Linux and Windows as the client. I haven't tried this on other setups but it should be more or less the same.

Setting up the server

Start a t2.micro EC21 running Debian, updated all the packages and reboot2.

sudo apt-get update && sudo apt-get dist-upgrade && sudo reboot

Then install iodine

sudo apt-get install iodine

Setup the domain name to use for the tunnel, in my case I used I created a sub-domain and delegated it to a DNS servers called

In DNS Made easy go to NS Records and hit the Add button.

Adding an NS Record

Next we need to setup the A record for the name server we have specified.

Adding an A Record

Then on the EC2 server

sudo iodined -f -c
  • -f Keeps iodined running on the forground, it's not nessacery but it makes it easier to stop and start.
  • is the local network that iodine will create. Use an address that is not on your LAN.
  • -c Disables checking of the client IP address, you will only need it if your DNS queries are getting routed through a cluster of DNS servers and so your traffic will be coming from diffrent IP addresses.
  • is the domain to use as a tunnel.

Check your server is working with iodine check tool

Arch Linux Client

On the client (Arch Linux)

sudo pacman -S iodine
sudo iodine -f

Now if you run ip addr you should see a new network connection

[michael@ezreal ~]$ sudo ip addr
# ...
4: dns0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1130 qdisc fq_codel state UNKNOWN group default qlen 500
    inet scope global dns0
       valid_lft forever preferred_lft forever
[michael@ezreal ~]$ ping -c 4
PING ( 56(84) bytes of data.
64 bytes from icmp_seq=1 ttl=64 time=346 ms
64 bytes from icmp_seq=2 ttl=64 time=334 ms
64 bytes from icmp_seq=3 ttl=64 time=346 ms
64 bytes from icmp_seq=4 ttl=64 time=338 ms

--- ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3001ms
rtt min/avg/max/mdev = 334.381/341.482/346.673/5.310 ms

Congratulations, you now have a tunnel through DNS.

Windows Client

First we need to install the Install the TAP32 driver. To do this download the OpenVPN installer3 and when you get to Choose Components step, you only need to pick TAP Virtual Ethernet Adapter.

Installing openVPN TAP adapter

The rest is more or less the same as Linux, download the latest binary, extract them, open a command prompt as administrator and run iodine c:\Users\Michael\Downloads\iodine-0.7.0-windows\64bit\iodine.exe -f

Making it a service

Of course if you're planning on using it from a hotel WiFi for example you might not be able to SSH in and start iodine so you will want your tunnel available all the time.

sudo nano /etc/default/iodine

Setup your iodine config4

# Default settings for iodine. This file is sourced from
# /etc/init.d/iodined
sudo systemctl enable iodined.service
sudo systemctl restart iodined.service

Encryption and routing

Now you have a DNS tunnel between you and your server, but it doesn't mean that all your traffic will magically flow through it, nor is your traffic private5. The recommended way is to either setup a VPN or SSH Tunnel6.

On Linux it's pretty simple ssh -D 8080 admin@ -i aws-key.pem

On Windows it's pretty much the same, except we will use Putty and under Connection > SSH > Tunnels and Dynamic port forwarding on port 8080.

Putty Tunnel Settings)

Then in Firefox go to Options > Advanced > Network > Connection Settings > Manual proxy configuration and enter the SOCKS proxy details.

Firefox Proxy Settings

I found the network to be painfully slow, but it's a fun little experment.

  1. Also if you are using Amazon, make sure you open ports TCP 22, TCP 53 and UDP 53 in the security groups settings. 

  2. A reboot is not strictly necessary, but when I ran the updates it installed a new kernel so I wanted to reboot for the kernel update. 

  3. The documentation says it needs to be the 32 bit version of OpenVPN but I used the 64 bit version and it worked fine. 

  4. To generate a password I recommend sudo dd if=/dev/random bs=1 count=18 2>/dev/null | base64

  5. Tunneling data through DNS might be stealthy but iodine does not provide encryption be default. 

  6. Yes a tunnel with in a tunnel. 

Creative Commons License
Content on this site is licensed under a Creative Commons Attribution 4.0 International License.
Built using Pelican. Based on a theme by Giulio Fidente on github.