Sometimes it is useful to have a DNS tunnel to circumvent too strict firewalls.
I already had installed and configured an iodine server on my AVM FRITZ!Box Fon WLAN 7270 v2 using Freetz and wanted to have an iodine client on my already rooted Sony Ericssons Xperia X10 mini. I started with looking for a suitable TUN Driver for my phone. Luckily I found one on the XDA developers forum. Next I started looking for a iodine client ported to Android. I found this one, but it didn’t work on my phone. So I decide to port iodine myself. This appeared to be not so simple, because the Android Linux is not a standard Linux. I had to change the source code on several places to make it work. I have sent a patch to the author of iodine, so maybe it will be part of the iodine package in the near future.
If you want to build iodine for Android yourself, you can follow these steps:
- Download and install the Android SDK
- Download and install the Android NDK
- Download and unpack iodine-0.6.0-rc1
- cd iodine-0.6.0-rc1/src
- make base64u.h base64u.c
- patch -p1 <…/iodine-0.6.0-rc1-android-3.patch
- …/ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk
If the compilation succeeded, you can now try the executable on your phone:
- adb push ./libs/armeabi/iodine /data/local/tmp
- adb shell
- su
- cd /data/local/tmp
- chmod 777 iodine
- ./iodine
It will not work from an SD card, because Android mounts SD cards non-executable!
I choose iodine over dns2tcp, because it is possible to route all traffic through the tunnel. To start the iodine client and to setup routing I created a shell script. If you want to use this script, you have to fill in your own server details. It depends on busybox provided by Titanium backup and it assumes that a tunnel will be created over WiFi (device wlan0).
To copy the TUN Driver and the startup script to your phone:
- adb push tun.ko /data/local/tmp
- adb push iodine.sh /data/local/tmp
You can now try to setup a DNS tunnel on your phone:
- adb shell
- su
- cd /data/local/tmp/
- chmod 777 iodine_route.sh
- iodine_route.sh
I use Script Manager to start the tunnel from my phone.
You can restore the default routing by disabling and enabling WiFi.
If you want to store iodine on a permanent location, you can re-mount your system partition read-write:
- mount -o remount,rw -t yaffs2 /dev/block/mtdblock<your block number> /system
- ../busybox cp /data/local/tmp/* /system/xbin
Tip: my hosting provider didn’t allowed me to set NS records for a sub-domain, that is why I used the FreeDNS service.
Fun facts:
- iod = IP over DNS
- DNS port number = 53 = atomic number of iodine
Download the patch, script and generic binary.
Update 19/5/2012: even easier now: MagicTunnel.
Update 6/7/2012: see here for my own DNS tunnel implementation.
Comments and questions are as always very welcome.