The quick way
Try it out within your own LAN! Follow these simple steps:
- On your server, run:
./iodined -fP test 10.0.0.1 test.asdf
(If you already use the 10.0.0.0 network, use another internal net like 172.16.0.0)
- On the client, run:
./iodine -fP test 192.168.0.1 test.asdf
(Replace 192.168.0.1 with the server's ip address)
- Now the client has the tunnel ip 10.0.0.2 and the server has 10.0.0.1
- Try pinging each other through the tunnel
- Done! :)
To use this tunnel, you need control over a real domain (like mytunnel.com), and a server with a static public IP number that does not yet run a DNS server. Then, delegate a subdomain (say, tunnel1.mytunnel.com) to the server. If you use BIND for the domain, add these lines to the zone file:
tunnel1host IN A 10.15.213.99 tunnel1 IN NS tunnel1host.mytunnel.com.
If you dont have a domain, it seems you can get a free subdomain with DNS control capable of NS records at http://freedns.afraid.org/
If you already have an A record (or a DynDNS name) to your server, you can use a CNAME to it instead of the A record above. Now any DNS querys for domains ending with tunnel1.mytunnnel.com will be sent to your server. Start iodined on the server. The first argument is the tunnel IP address (like 192.168.99.1) and the second is the assigned domain (in this case tunnel1.mytunnel.com). The -f argument will keep iodined running in the foreground, which helps when testing. iodined will start a virtual interface, and also start listening for DNS queries on UDP port 53. Either enter a password on the commandline (-P pass) or after the server has started. Now everything is ready for the client.
All the setup is done, just start iodine. It also takes two arguments, the first is the local relaying DNS server and the second is the domain used (tunnel1.mytunnnel.com). If DNS queries are allowed to any computer, you can use the tunnel endpoint (example: 10.15.213.99 or tunnel1host.mytunnel.com) as the first argument. The tunnel interface will get an IP close to the servers (in this case 192.168.99.2) and a suitable MTU. Enter the same password as on the server either by argument or after the client has started. Now you should be able to ping the other end of the tunnel from either side.
The normal case is to route all traffic through the DNS tunnel. To do this, first add a route to the nameserver you use with the default gateway as gateway. Then replace the default gateway with the servers IP address within the DNS tunnel, and configure the server to do NAT.
Some scripts to configure the client can be found at the TipsAndTricks page.
Try the automatic tunnel tester at http://code.kryo.se/iodine/check-it/
Do not worry that you can not ping the tunnel domain. You can only ping domains that point to hosts (via A or CNAME records), so this is normal.
The most common error is that the domain is not correctly configured, or that there is a firewall blocking the traffic. Send NS requests for subdomains of your tunnel domain to test that it works.
dig -t NS foo.tunnel.domain.com
if tunnel.domain.com is the domain used with iodined. Also add -DD to iodined arguments to see if any traffic arrives and is answered. When NS requests work, iodine should also work. You can also use network sniffers like tcpdump/tshark/wireshark to see if the traffic arrives.
To see what the DNS server has stored, first locate the server for your domain:
$ dig -t NS domain.com ; <<>> DiG 9.4.3-P3 <<>> -t NS domain.com ;; global options: printcmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51859 ;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 4 ;; QUESTION SECTION: ;domain.com. IN NS ;; ANSWER SECTION: domain.com. 86367 IN NS ns4.nameservx.com. domain.com. 86367 IN NS ns1.nameservx.com. domain.com. 86367 IN NS ns2.nameservx.com. domain.com. 86367 IN NS ns3.nameservx.com.
Here we see domain.com is handled by ns1.nameservx.com. Use dig to ask it about the tunnel domain:
$ dig @ns1.nameservx.com -t NS tunnel.domain.com ; <<>> DiG 9.4.3-P3 <<>> @ns1.nameservx.com -t NS tunnel.domain.com ; (1 server found) ;; global options: printcmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 28284 ;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0 ;; WARNING: recursion requested but not available ;; QUESTION SECTION: ;tunnel.domain.com. IN NS ;; AUTHORITY SECTION: tunnel.domain.com. 259200 IN NS tunnel1host.domain.com.
The right part of the single NS row here should be pointing to your server. You might also get an additional section, showing that host:
;; ADDITIONAL SECTION: tunnel1host.domain.com. 3600 IN A 220.127.116.114
Always use the latest version and ask for help in the IRC channel if you have any more problems.