IP over DNS – Iodine

Heute möchte ich euch das kleine Tool „Iodine“ vorstellen. Mit diesem Programm könnt ihr IP-Traffic zwischen zwei Rechnern über das DNS-Protokoll übertragen. Das kann in manchen Situationen nutzvoll sein, z.B. falls man hinter einer restriktiven Firewall sitzt.

Die Einrichtung von Iodine

Die Einrichtung nicht nicht besonders schwer. Als Voraussetzung wird nicht viel benötigt, außer ein „/dev/tun“ Device auf dem Server, um eine virtuelle Netzwerkschnittstelle zu erzeugen.

Als erstes lädt man sich den Sourcecode herunter und kompiliert diesen mit den bekannten Schritten:

mkdir /tmp/iodine
cd /tmp/iodine
wget http://code.kryo.se/iodine/iodine-0.7.0.tar.gz -O iodine.tgz
tar xfv iodine.tgz
mv iodine-* src
cd src
make

Nun hat man ein neues Verzeichnis namens „bin“:

$ pwd
/tmp/iodine/src
$ ls bin/
insgesamt 288K
drwxr-xr-x 2 gehaxelt users   80 28. Aug 02:09 .
drwxr-xr-x 7 gehaxelt users  260 28. Aug 02:09 ..
-rwxr-xr-x 1 gehaxelt users 139K 28. Aug 02:09 iodine
-rwxr-xr-x 1 gehaxelt users 147K 28. Aug 02:09 iodined

Die erste Datei ist der Client und die letztere der Server (Daemon).

Falls man möchte, kann man noch ein

sudo make install

ausführen, um die beiden Dateien im System zu verankern. Das habe ich hier nicht gemacht.

Die Nutzung von Iodine

Zunächst müssen wir auf einem Server den Iodine-Dienst starten.

sudo iodined -f -P "GeheimesPW" 10.50.0.1 google.com 

Die Parameter bedeuten:

  • -f : Im Vordergrund laufen
  • -P : Passwort für die Verbindung setzen (Keine Verschlüsselung, nur Authentifzierung)
  • 10.50.0.1 : Subnetz für das VPN
  • google.com : Domain die wir „abrufen“

Das Programm müssen wir mit Rootrechten ausführen, da es sich an den UDP Port 53 bindet. Ihr solltet also sicherstellen, das dort nicht bereits ein Nameserver o.ä. läuft und das der Port von außen erreichbar ist (Firewall!).

Den Client führen wir lokal aus:

> sudo iodine -f -r -P "GeheimesPW" SERVERIP google.com
Opened dns0
Opened IPv4 UDP socket
Sending DNS queries for google.com to SERVERIP
Autodetecting DNS query type (use -T to override).
Using DNS type NULL queries
Version ok, both using protocol v 0x00000502. You are user #0
Setting IP of dns0 to 10.50.0.2
Setting MTU of dns0 to 1130
Server tunnel IP is 10.50.0.1
Skipping raw mode
Using EDNS0 extension
Switching upstream to codec Base128
Server switched upstream to codec Base128
No alternative downstream codec available, using default (Raw)
Switching to lazy mode for low-latency
Server switched to lazy mode
Autoprobing max downstream fragment size... (skip with -m fragsize)
768 ok.. 1152 ok.. ...1344 not ok.. ...1248 not ok.. ...1200 not ok.. 1176 ok.. ...1188 not ok.. will use 1176-2=1174
Setting downstream fragment size to max 1174...
Connection setup complete, transmitting data

Die Parameter sind die folgenden:

  • -f : Wieder im Vordergrund
  • -r : Testen, ob direkte UDP-Verbindung zum Server möglich ist (ohne DNS-Relay)
  • -P : Passwort vom Server
  • SERVERIP : Die IP des Servers auf dem der Iodine-Daemon läuft
  • google.com : Die oben konfigurierte Domain

Wir sollten nun eine zusätzliche Netzwerkschnittstelle sehen:

$ ip a 
[snip]
4: dns0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1130 qdisc pfifo_fast state UNKNOWN group default qlen 500
    link/none 
    inet 10.50.0.2/27 scope global dns0
       valid_lft forever preferred_lft forever

Nun sollte es möglich sein, den Server über diese IP-over-DNS Verbindung zu pingen:

> ping -c 5 10.50.0.1
PING 10.50.0.1 (10.50.0.1) 56(84) bytes of data.
64 bytes from 10.50.0.1: icmp_seq=1 ttl=64 time=126 ms
64 bytes from 10.50.0.1: icmp_seq=2 ttl=64 time=127 ms
64 bytes from 10.50.0.1: icmp_seq=3 ttl=64 time=128 ms
64 bytes from 10.50.0.1: icmp_seq=4 ttl=64 time=126 ms
64 bytes from 10.50.0.1: icmp_seq=5 ttl=64 time=134 ms

--- 10.50.0.1 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4000ms
rtt min/avg/max/mdev = 126.827/128.975/134.496/2.886 ms

Bedenkt bitte, das Iodine den „DNS“-Traffic nicht verschlüsselt und daher die Daten mitgelesen werden können.

Erweiterte Nutzung

Zuletzt noch ein kleiner Tipp wie man effektiv ohne viel Aufwand Traffic mit Hilfe eines SOCKS-Proxy verschlüsselt überträgt. Dazu können wir ganz einfach unseren SSH-Client nutzen um einen entsprechenden Tunnel zwischen unserem PC und dem Server aufzubauen.

ssh -n -N -D 1080 user@10.50.0.1

Die Parameter sind die folgenden:

  • -n : Kein Lesen von der Standardeingabe
  • -N : Keine Kommandos ausführen
  • -D Port : Socks-Tunnel auf Port [Port] öffnen
  • user@10.50.0.1 : Benutzername und VPN-IP des Iodine-Servers

Danach kann man im Browser localhost:1080 als Socks(5)-Proxy konfigurieren und sollte dann den Traffic verschlüsselt über die Iodine-Verbindung übertragen bekommen.

~ Sebastian