• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

doc/H03-May-2022-4737

man/H16-Jun-2014-369361

src/H16-Jun-2014-10,0877,121

tests/H16-Jun-2014-1,6781,201

CHANGELOGH A D16-Jun-20147.4 KiB167150

MakefileH A D16-Jun-20143.4 KiB10584

READMEH A D16-Jun-201418.1 KiB380292

TODOH A D16-Jun-2014228 136

README

1
2iodine - http://code.kryo.se/iodine
3
4***********************************
5
6This is a piece of software that lets you tunnel IPv4 data through a DNS
7server. This can be usable in different situations where internet access is
8firewalled, but DNS queries are allowed.
9
10
11COMPILING:
12
13Iodine has no configure script. There are two optional features for Linux
14(SELinux and systemd support) that will be enabled automatically if the
15relevant header files are found in /usr/include. (See script at ./src/osflags)
16
17Run 'make' to compile the server and client binaries.
18Run 'make install' to copy binaries and manpage to the destination directory.
19Run 'make test' to compile and run the unit tests. (Requires the check library)
20
21
22QUICKSTART:
23
24Try it out within your own LAN! Follow these simple steps:
25- On your server, run: ./iodined -f 10.0.0.1 test.com
26  (If you already use the 10.0.0.0 network, use another internal net like
27  172.16.0.0)
28- Enter a password
29- On the client, run: ./iodine -f -r 192.168.0.1 test.com
30  (Replace 192.168.0.1 with your server's ip address)
31- Enter the same password
32- Now the client has the tunnel ip 10.0.0.2 and the server has 10.0.0.1
33- Try pinging each other through the tunnel
34- Done! :)
35To actually use it through a relaying nameserver, see below.
36
37
38HOW TO USE:
39
40Note: server and client are required to speak the exact same protocol. In most
41cases, this means running the same iodine version. Unfortunately, implementing
42backward and forward protocol compatibility is usually not feasible.
43
44Server side:
45To use this tunnel, you need control over a real domain (like mydomain.com),
46and a server with a public IP address to run iodined on. If this server
47already runs a DNS program, change its listening port and then use iodined's
48-b option to let iodined forward the DNS requests. (Note that this procedure
49is not advised in production environments, because iodined's DNS forwarding
50is not completely transparent.)
51
52Then, delegate a subdomain (say, t1.mydomain.com) to the iodined server.
53If you use BIND for your domain, add two lines like these to the zone file:
54
55t1		IN	NS	t1ns.mydomain.com.		; note the dot!
56t1ns		IN	A	10.15.213.99
57
58The "NS" line is all that's needed to route queries for the "t1" subdomain
59to the "t1ns" server. We use a short name for the subdomain, to keep as much
60space as possible available for the data traffic. At the end of the "NS" line
61is the name of your iodined server. This can be any name, pointing anywhere,
62but in this case it's easily kept in the same zone file. It must be a name
63(not an IP address), and that name itself must have an A record (not a CNAME).
64
65If your iodined server has a dynamic IP, use a dynamic dns provider. Simply
66point the "NS" line to it, and leave the "A" line out:
67
68t1		IN	NS	myname.mydyndnsprovider.com.	; note the dot!
69
70Then reload or restart your nameserver program. Now any DNS queries for
71domains ending in t1.mydomain.com will be sent to your iodined server.
72
73Finally start iodined on your server. The first argument is the IP address
74inside the tunnel, which can be from any range that you don't use yet (for
75example 192.168.99.1), and the second argument is the assigned domain (in this
76case t1.mydomain.com). Using the -f option will keep iodined running in the
77foreground, which helps when testing. iodined will open a virtual interface
78("tun device"), and will also start listening for DNS queries on UDP port 53.
79Either enter a password on the commandline (-P pass) or after the server has
80started. Now everything is ready for the client.
81
82If there is a chance you'll be using an iodine tunnel from unexpected
83environments, start iodined with a -c option.
84
85Resulting commandline in this example situation:
86./iodined -f -c -P secretpassword 192.168.99.1 t1.mydomain.com
87
88Client side:
89All the setup is done, just start iodine. It takes one or two arguments, the
90first is the local relaying DNS server (optional) and the second is the domain
91you used (t1.mydomain.com). If you don't specify the first argument, the
92system's current DNS setting will be consulted.
93
94If DNS queries are allowed to any computer, you can directly give the iodined
95server's address as first argument (in the example: t1ns.mydomain.com or
9610.15.213.99). In that case, it may also happen that _any_ traffic is allowed
97to the DNS port (53 UDP) of any computer. Iodine will detect this, and switch
98to raw UDP tunneling if possible. To force DNS tunneling in any case, use the
99-r option (especially useful when testing within your own network).
100
101The client's tunnel interface will get an IP close to the server's (in this
102case 192.168.99.2 or .3 etc.) and a suitable MTU. Enter the same password as
103on the server either as commandline option or after the client has started.
104Using the -f option will keep the iodine client running in the foreground.
105
106Resulting commandline in this example situation:
107./iodine -f -P secretpassword t1.mydomain.com
108(add -r to force DNS tunneling even if raw UDP tunneling would be possible)
109
110From either side, you should now be able to ping the IP address on the other
111end of the tunnel. In this case, ping 192.168.99.1 from the iodine client, and
112192.168.99.2 or .3 etc. from the iodine server.
113
114
115MISC. INFO:
116
117IPv6:
118At the moment the iodined server only supports IPv4. The data inside the tunnel
119is IPv4 only.
120
121The client can use IPv4 or IPv6 nameservers to connect to iodined. The relay
122nameservers will translate between protocols automatically if needed. Use
123options -4 or -6 to force the client to use a specific IP version for its DNS
124queries. The client has to force IPv4 if it has dual-stack connectivity and
125the hostname handling the tunnel domain has both A and AAAA records.
126
127Routing:
128It is possible to route all traffic through the DNS tunnel. To do this, first
129add a host route to the nameserver used by iodine over the wired/wireless
130interface with the default gateway as gateway. Then replace the default
131gateway with the iodined server's IP address inside the DNS tunnel, and
132configure the server to do NAT.
133
134However, note that the tunneled data traffic is not encrypted at all, and can
135be read and changed by external parties relatively easily. For maximum
136security, run a VPN through the DNS tunnel (=double tunneling), or use secure
137shell (SSH) access, possibly with port forwarding. The latter can also be used
138for web browsing, when you run a web proxy (for example Privoxy) on your
139server.
140
141Testing:
142The iodined server replies to NS requests sent for subdomains of the tunnel
143domain. If your iodined subdomain is t1.mydomain.com, send a NS request for
144foo123.t1.mydomain.com to see if the delegation works. dig is a good tool
145for this:
146dig -t NS foo123.t1.mydomain.com
147
148Also, the iodined server will answer requests starting with 'z' for any of the
149supported request types, for example:
150dig -t TXT z456.t1.mydomain.com
151dig -t SRV z456.t1.mydomain.com
152dig -t CNAME z456.t1.mydomain.com
153The reply should look like garbled text in all these cases.
154
155Operational info:
156The DNS-response fragment size is normally autoprobed to get maximum bandwidth.
157To force a specific value (and speed things up), use the -m option.
158
159The DNS hostnames are normally used up to their maximum length, 255 characters.
160Some DNS relays have been found that answer full-length queries rather
161unreliably, giving widely varying (and mostly very bad) results of the
162fragment size autoprobe on repeated tries. In these cases, use the -M switch
163to reduce the DNS hostname length to for example 200 characters, which makes
164these DNS relays much more stable. This is also useful on some "de-optimizing"
165DNS relays that stuff the response with two full copies of the query, leaving
166very little space for downstream data (also not capable of EDNS0). The -M
167switch can trade some upstream bandwidth for downstream bandwidth. Note that
168the minimum -M value is about 100, since the protocol can split packets (1200
169bytes max) in only 16 fragments, requiring at least 75 real data bytes per
170fragment.
171
172The upstream data is sent gzipped encoded with Base32; or Base64 if the relay
173server supports mixed case and '+' in domain names; or Base64u if '_' is
174supported instead; or Base128 if high-byte-value characters are supported.
175This upstream encoding is autodetected. The DNS protocol allows one query per
176packet, and one query can be max 256 chars. Each domain name part can be max
17763 chars. So your domain name and subdomain should be as short as possible to
178allow maximum upstream throughput.
179
180Several DNS request types are supported, with the NULL and PRIVATE types
181expected to provide the largest downstream bandwidth. The PRIVATE type uses
182value 65399 in the private-use range. Other available types are TXT, SRV, MX,
183CNAME and A (returning CNAME), in decreasing bandwidth order.  Normally the
184"best" request type is autodetected and used. However, DNS relays may impose
185limits on for example NULL and TXT, making SRV or MX actually the best choice.
186This is not autodetected, but can be forced using the -T option.  It is
187advisable to try various alternatives especially when the autodetected request
188type provides a downstream fragment size of less than 200 bytes.
189
190Note that SRV, MX and A (returning CNAME) queries may/will cause additional
191lookups by "smart" caching nameservers to get an actual IP address, which may
192either slow down or fail completely.
193
194DNS responses for non-NULL/PRIVATE queries can be encoded with the same set of
195codecs as upstream data. This is normally also autodetected, but no fully
196exhaustive tests are done, so some problems may not be noticed when selecting
197more advanced codecs. In that case, you'll see failures/corruption in the
198fragment size autoprobe. In particular, several DNS relays have been found that
199change replies returning hostnames (SRV, MX, CNAME, A) to lowercase only when
200that hostname exceeds ca. 180 characters. In these and similar cases, use the
201-O option to try other downstream codecs; Base32 should always work.
202
203Normal operation now is for the server to _not_ answer a DNS request until
204the next DNS request has come in, a.k.a. being "lazy". This way, the server
205will always have a DNS request handy when new downstream data has to be sent.
206This greatly improves (interactive) performance and latency, and allows to
207slow down the quiescent ping requests to 4 second intervals by default, and
208possibly much slower. In fact, the main purpose of the pings now is to force
209a reply to the previous ping, and prevent DNS server timeouts (usually at
210least 5-10 seconds per RFC1035). Some DNS servers are more impatient and will
211give SERVFAIL errors (timeouts) in periods without tunneled data traffic. All
212data should still get through in these cases, but iodine will reduce the ping
213interval to 1 second anyway (-I1) to reduce the number of error messages. This
214may not help for very impatient DNS relays like dnsadvantage.com (ultradns),
215which time out in 1 second or even less. Yet data will still get trough, and
216you can ignore the SERVFAIL errors.
217
218If you are running on a local network without any DNS server in-between, try
219-I 50 (iodine and iodined close the connection after 60 seconds of silence).
220The only time you'll notice a slowdown, is when DNS reply packets go missing;
221the iodined server then has to wait for a new ping to re-send the data. You can
222speed this up by generating some upstream traffic (keypress, ping). If this
223happens often, check your network for bottlenecks and/or run with -I1.
224
225The delayed answering in lazy mode will cause some "carrier grade" commercial
226DNS relays to repeatedly re-send the same DNS query to the iodined server.
227If the DNS relay is actually implemented as a pool of parallel servers,
228duplicate requests may even arrive from multiple sources. This effect will
229only be visible in the network traffic at the iodined server, and will not
230affect the client's connection. Iodined will notice these duplicates, and send
231the same answer (when its time has come) to both the original query and the
232latest duplicate. After that, the full answer is cached for a short while.
233Delayed duplicates that arrive at the server even later, get a reply that the
234iodine client will ignore (if it ever arrives there).
235
236If you have problems, try inspecting the traffic with network monitoring tools
237like tcpdump or ethereal/wireshark, and make sure that the relaying DNS server
238has not cached the response. A cached error message could mean that you
239started the client before the server. The -D (and -DD) option on the server
240can also show received and sent queries.
241
242
243TIPS & TRICKS:
244
245If your port 53 is taken on a specific interface by an application that does
246not use it, use -p on iodined to specify an alternate port (like -p 5353) and
247use for instance iptables (on Linux) to forward the traffic:
248iptables -t nat -A PREROUTING -i eth0 -p udp --dport 53 -j DNAT --to :5353
249(Sent in by Tom Schouten)
250
251Iodined will reject data from clients that have not been active (data/pings)
252for more than 60 seconds. Similarly, iodine will exit when no downstream
253data has been received for 60 seconds. In case of a long network outage or
254similar, just restart iodine (re-login), possibly multiple times until you get
255your old IP address back. Once that's done, just wait a while, and you'll
256eventually see the tunneled TCP traffic continue to flow from where it left
257off before the outage.
258
259With the introduction of the downstream packet queue in the server, its memory
260usage has increased with several megabytes in the default configuration.
261For use in low-memory environments (e.g. running on your DSL router), you can
262decrease USERS and undefine OUTPACKETQ_LEN in user.h without any ill conse-
263quence, assuming at most one client will be connected at any time. A small
264DNSCACHE_LEN is still advised, preferably 2 or higher, however you can also
265undefine it to save a few more kilobytes.
266
267
268PERFORMANCE:
269
270This section tabulates some performance measurements. To view properly, use
271a fixed-width font like Courier.
272
273Measurements were done in protocol 00000502 in lazy mode; upstream encoding
274always Base128; iodine -M255; iodined -m1130. Network conditions were not
275extremely favorable; results are not benchmarks but a realistic indication of
276real-world performance that can be expected in similar situations.
277
278Upstream/downstream throughput was measured by scp'ing a file previously
279read from /dev/urandom (i.e. incompressible), and measuring size with
280"ls -l ; sleep 30 ; ls -l" on a separate non-tunneled connection. Given the
281large scp block size of 16 kB, this gives a resolution of 4.3 kbit/s, which
282explains why some values are exactly equal.
283Ping round-trip times measured with "ping -c100", presented are average rtt
284and mean deviation (indicating spread around the average), in milliseconds.
285
286
287Situation 1:
288Laptop  ->   Wifi AP   ->  Home server  ->  DSL provider  ->  Datacenter
289 iodine    DNS "relay"        bind9           DNS cache        iodined
290
291                        downstr.  upstream downstr.  ping-up       ping-down
292                        fragsize   kbit/s   kbit/s  avg +/-mdev   avg +/-mdev
293------------------------------------------------------------------------------
294
295iodine -> Wifi AP :53
296  -Tnull (= -Oraw)           982    43.6    131.0   28.0    4.6   26.8    3.4
297
298iodine -> Home server :53
299  -Tnull (= -Oraw)          1174    48.0    305.8   26.6    5.0   26.9    8.4
300
301iodine -> DSL provider :53
302  -Tnull (= -Oraw)          1174    56.7    367.0   20.6    3.1   21.2    4.4
303  -Ttxt -Obase32             730    56.7    174.7*
304  -Ttxt -Obase64             874    56.7    174.7
305  -Ttxt -Obase128           1018    56.7    174.7
306  -Ttxt -Oraw               1162    56.7    358.2
307  -Tsrv -Obase128            910    56.7    174.7
308  -Tcname -Obase32           151    56.7     43.6
309  -Tcname -Obase128          212    56.7     52.4
310
311iodine -> DSL provider :53
312  wired (no Wifi) -Tnull    1174    74.2    585.4   20.2    5.6   19.6    3.4
313
314 [174.7* : these all have 2frag/packet]
315
316
317Situation 2:
318Laptop  ->  Wifi+vpn / wired  ->  Home server
319 iodine                            iodined
320
321                        downstr.  upstream downstr.  ping-up       ping-down
322                        fragsize   kbit/s   kbit/s  avg +/-mdev   avg +/-mdev
323------------------------------------------------------------------------------
324
325wifi + openvpn  -Tnull      1186   166.0   1022.3    6.3    1.3    6.6    1.6
326
327wired  -Tnull               1186   677.2   2464.1    1.3    0.2    1.3    0.1
328
329
330Performance is strongly coupled to low ping times, as iodine requires
331confirmation for every data fragment before moving on to the next. Allowing
332multiple fragments in-flight like TCP could possibly increase performance,
333but it would likely cause serious overload for the intermediary DNS servers.
334The current protocol scales performance with DNS responsivity, since the
335DNS servers are on average handling at most one DNS request per client.
336
337
338PORTABILITY:
339
340iodine has been tested on Linux (arm, ia64, x86, AMD64 and SPARC64), FreeBSD
341(ia64, x86), OpenBSD (x86), NetBSD (x86), MacOS X (ppc and x86, with
342http://tuntaposx.sourceforge.net/). and Windows (with OpenVPN TAP32 driver, see
343win32 readme file).  It should be easy to port to other unix-like systems that
344has TUN/TAP tunneling support. Let us know if you get it to run on other
345platforms.
346
347
348THE NAME:
349
350The name iodine was chosen since it starts with IOD (IP Over DNS) and since
351iodine has atomic number 53, which happens to be the DNS port number.
352
353
354THANKS:
355
356- To kuxien for FreeBSD and OS X testing
357- To poplix for code audit
358
359
360AUTHORS & LICENSE:
361
362Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>, 2006-2009 Bjorn
363Andersson <flex@kryo.se>. Also major contributions by Anne Bezemer.
364
365Permission to use, copy, modify, and distribute this software for any purpose
366with or without fee is hereby granted, provided that the above copyright notice
367and this permission notice appear in all copies.
368
369THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
370REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
371FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
372INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
373LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
374OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
375PERFORMANCE OF THIS SOFTWARE.
376
377
378MD5 implementation by L. Peter Deutsch (license and source in src/md5.[ch])
379Copyright (C) 1999, 2000, 2002 Aladdin Enterprises.  All rights reserved.
380