Problem
The information presented here is obsolete. Take a look at
Iodine.
You’re sitting in an airport or in a cafe, and people want your money for Internet access. They do allow DNS traffic, though.
If the ISP allows DNS traffic to any DNS server (and not just their own), you might consider running OpenVPN on UDP port 53 (thanks to Norman Rasmussen for this suggestion). If they don’t, however, NSTX comes to the rescue. NSTX is a hack to tunnel IP traffic over DNS. NSTX (IP-over-DNS) seems cool, but you cannot get it to work. You’ve downloaded the latest version, maybe because you saw it mentioned on Slashdot. You’ve looked at the nstx project page and the freshmeat page. You even tried reading some confusing documentation. Maybe you gave up and tried OzymanDNS. But curiousity got the better of you. You really want to use this.
Once you’ve followed these instructions, you basically have a remote proxy, providing you with access to the Internet. Communication between you and the remote proxy is over NSTX.
If DNS traffic does not work, but ICMP traffic (i.e., ping) works, try ICMPTX: IP-over-ICMP. Note that these instructions play nicely with ICMPTX. You can run both on one proxy.
Keywords
nstx, ip-over-DNS, tunnel, firewall piercing, ifconfig, route, tun/tap, tun0.
Solution
You need several things to get going:
- a DNS server that you can configure, (we’ll call this ns.example.com
- another server, one not running DNS. We’re going to assume the IP address of this machine is 1.2.3.4. The reason you cannot run DNS on the same machine, is that you’re going to run nstx on this machine. Nstx must run on port 53, like DNS.
- a crippled Internet connection, i.e., one that only allows you to issue DNS queries.
Configure a new DNS subdomain
Let’s assume you’re running the domain “example.com”. The nameserver for this domain is, as mentioned before, “ns.example.com”. Configure “ns.example.com” by adding a subdomain, “tunnel.example.com”. You do this by appending the following DNS records at the end of the zone file for “example.com”:
;
; subdomain for IP-over-DNS tunnelling
;
$ORIGIN tunnel.example.com.
@ IN NS ns.tunnel.example.com.
ns IN A 1.2.3.4
In other words. We configured 1.2.3.4 to be the name server for a new subdomain “tunnel.example.com”.
Install and configure the bogus DNS server
On the machine 1.2.3.4, make sure your kernel supports the TUN/TAP network device. If you installed a standard 2.6 kernel image, it does. You may have to manually /sbin/modprobe tun. Install the nstx Debian package:
# apt-get install nstx
Edit /etc/default/nstx and set NSTX_DOMAIN to “tunnel.example.com” and set start_nstxd to “yes”. Finally, set ifup_tun0 to “yes”. In /etc/network/interfaces, define a new interface tun0, as follows:
iface tun0 inet static
address 10.0.0.1
netmask 255.0.0.0
Now start the server by running:
# /etc/init.d/nstxd restart
If you’re not running Debian, you can skip all that and just download the code, compile it manually, and start the server by hand and then configure the tun0 network device:
# nstxd tunnel.example.com
# /sbin/modprobe tun
# /sbin/ifconfig tun0 up 10.0.0.1 netmask 255.255.255.0
Whether you’re running Debian or not, after running the nstx server, make sure you now have a tun0 device:
# /sbin/ifconfig tun0
tun0 Link encap:UNSPEC HWaddr XX-XX-XX-XX-XX-XX-XX-XX-XX-XX-XX-XX-XX-XX-XX-XX
inet addr:10.0.0.1 P-t-P:10.0.0.1 Mask:255.0.0.0
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
RX packets:50 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:10
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
Now you need to enable forwarding on this server. I use iptables to implement masquerading. There are many HOWTOs about this (a simple one, for example). On Debian, the configuration file for iptables is in /var/lib/iptables/active. The relevant bit is:
*nat
:PREROUTING ACCEPT [6:1596]
:POSTROUTING ACCEPT [1:76]
:OUTPUT ACCEPT [1:76]
-A POSTROUTING -s 10.0.0.0/8 -j MASQUERADE
COMMIT
Restart iptables:
/etc/init.d/iptables restart
and enable forwarding:
echo 1 > /proc/sys/net/ipv4/ip_forward
You can make sure this is permanent by editing /etc/sysctl.conf:
net/ipv4/ip_forward=1
Configure the client
Make sure the kernel on the client machine also supports the TUN/TAP network device. If you installed a standard 2.6 kernel image, it does. You may have to manually /sbin/modprobe tun. Install the nstx Debian package:
# apt-get install nstx
Edit /etc/default/nstx and set NSTX_DOMAIN to “tunnel.example.com” and set start_nstxcd to “yes”. Finally, set ifup_tun0 to “yes”. In /etc/network/interfaces, define a new interface tun0, as follows:
iface tun0 inet static
address 10.0.0.2
netmask 255.0.0.0
mtu 500 # optional, may solve ssh problems
Marc Merlin points out that you may you want to add something like (below the mtu line)
post-up route del default; route add -net default gw 10.0.0.1
Many thanks to Marc, also for pointing out the mtu option to solve potential ssh issues.
Alright, now you’re sitting at an airport or in a cafe, and you have internet access and they want your money before allowing you on the Internet. However, you noticed that you can issue DNS queries.
Assuming you got an IP address through DHCP, you should now know the IP address of the DNS server they want you to use. Your /etc/resolv.conf will contain at least one “nameserver” entry. Make sure you use the first nameserver entry in /etc/resolv.conf and remove the others. For the sake of this example, let’s call the first and remaining nameserver 66.77.88.99. Edit /etc/default/nstx and change set NSTX_DNS_SERVER to “66.77.88.99″. The latest nstx Debian package obviates this manual step as follows:
NSTX_DNS_SERVER=`grep nameserver /etc/resolv.conf |head -1|awk '{print $2}'`
That is, it simply sets NSTX_DNS_SERVER to the IP address of the first nameserver entry in/etc/resolv.conf.
Now, (re)start the nstx client:
# /etc/init.d/nstxcd restart
If you don’t have Debian, start the client manually:
# nstxcd tunnel.example.com 66.77.88.99
# /sbin/modprobe tun
# /sbin/ifconfig tun0 up 10.0.0.2 netmask 255.255.255.0
Make sure you now have a tun0 device:
# /sbin/ifconfig tun0
tun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
inet addr:10.0.0.2 P-t-P:10.0.0.2 Mask:255.0.0.0
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
By running /sbin/route -n, figure out what your gateway is. It’s the record with the “UG” Flags field. For example:
# /sbin/route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 wlan0
0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 wlan0
OK. So “192.168.1.1″ is our gateway. Assuming your wireless network device is called “wlan0″ (but it might well be “eth1″, or whatever), run:
# /sbin/route del default
# /sbin/route add -host 66.77.88.99 gw 192.168.1.1 dev wlan0
# /sbin/route add default gw 10.0.0.1 tun0
Notice that “192.168.1.1″ is the IP address of the gateway we learned by running “/sbin/route -n”. Similarly, “66.77.88.99″ is the nameserver from /etc/resolv.conf. Make sure you plug in the correct IP address in both cases.
You should now be all set. All DNS traffic is going straight to 66.77.88.99. All other traffic will be tunnelled through 1.2.3.4, via DNS.
iodine lets you tunnel IPv4 data through a DNS server. This can be usable in different situations where internet access is firewalled, but DNS queries are allowed.
It runs on Linux, Mac OS X, FreeBSD, NetBSD, OpenBSD and Windows and needs a TUN/TAP device. The bandwidth is asymmetrical with limited upstream and up to 1 Mbit/s downstream.
Compared to other DNS tunnel implementations, iodine offers:
Higher performance
iodine uses the NULL type that allows the downstream data to be sent without encoding. Each DNS reply can contain over a kilobyte of compressed payload data.
Portability
iodine runs on many different UNIX-like systems as well as on Win32. Tunnels can be set up between two hosts no matter their endianness or operating system.
Security
iodine uses challenge-response login secured by MD5 hash. It also filters out any packets not coming from the IP used when logging in.
Less setup
iodine handles setting IP number on interfaces automatically, and up to 16 users can share one server at the same time. Packet size is automatically probed for maximum downstream throughput.
See the README, the CHANGELOG and the man page
Wiki, bug tracker, source browser and more is available at our trac page. iodine is released under the ISC license.
Test your DNS setup here: http://code.kryo.se/iodine/check-it/
We have a mailing list: iodine-users at lists.wpkg.org. You can send to it without joining. Archive is at: http://lists.wpkg.org/mailman/listinfo/iodine-users. Thanks to Tomasz Chmielewski for hosting it.
We are probably idling in #iodine on ircnet if you want to talk. However, please dont just ask a question and leave if you get no reply for 2 minutes, it may take some time before we see it.
iodine-0.6.0-rc1-win32
http://dnstunnel.de/
Did you ever sit at the airport or at a cafe and there was a unencrypted wireless access point nearby, but whenever you wanted to visit a site their website would pop up asking for a fee to use the internet through their AccessPoint (aka. Captive Portal)?
Well, I did, several times. But in most cases you are able to look up arbitrary hostnames, ie. google.com. That is because if you cannot resolve a host name your browser won't display any site. So these providers usually allow to look up hostnames to then filter whether they are allowed to access the site or not. In the latter case, their pay-to-get-access site pops up.
But you can use the fact that you can resolve arbitrary hostnames to gain free connection to the internet. Not a very fast one, though, but still a free internet connection.
The Idea
The Idea is to tunnel all outgoing traffic through DNS. Yes, you heard right, through DNS, the Domain Name System, used to translate human-readable hostnames to numerical IP addresses and vice versa.
To understand how this'll work, you need a little knowledge of DNS. The DNS system has quite a lot of so-called types of records, such as A for address record, NS for nameserver record, CNAME for canonical name record etc. The most commonly used record is the A record. To let the hostname example.com point to 192.0.34.166 you'd set up the following in your DNS server's config:
example.com. IN A 192.0.34.166
Usually, such entries are stored at your provider's nameserver and you don't have any/full control over them (most likely if you bought a rather cheap webhosting package). But to allow DNS tunneling to work, there has to be a little bit more advanced setup.
What we'll do is delegate all requests to a certain subdomain (or, subzone) to another nameserver. That means: People want to look up your IP, get to your ISP's nameserver and will be redirected to your own nameserver which can then answer the request. For this, of course, you'll need a server running the client where you can become root.
Keep in mind: All requests to a certain subdomain are relayed to your host, which then answers them. And you won't look up ordinary hostnames, I tell you. Hope you got the idea.
Technical Setup
To delegate all requests to sub.example.com to ns.anothernameserver.com, you first have to delegate all requests to that server (NS record, line 1) and then send a so-called GLUE record (that is, glued to the record before because it's most likely the asking server will need this info as well) with your server's IP (line 2, A record).
sub.example.com. IN NS ns.anothernameserver.com.
ns.anothernameserver.com. IN A 192.0.34.166
If you just have a DynDNS account and no static IP, you'd set up the delegation using a CNAME record. As mentioned above, CNAME is a canonical name (speak: an alias). So when a server gets back a CNAME instead of an A record (IP address) he continues to look up this hostname. That brings us to the following:
sub.example.com. IN NS ns.extern.example.com.
ns.extern.example.com. IN CNAME foo.bar.dyndns.org.
The Fake Server
The fake server you can set up at your server to tunnel all the traffic through is a little program called OzymanDNS, written in Perl (Client and Server together 642 SLOC) by DNS guru Dan Kaminsky. The tool is split in four files, two of them being a file upload/download tool using DNS. Nice examples, but rather uninteresting for our approach.
The script nomde.pl is the server. Since the server binds to port 53 UDP on your server (which is a privileged port) you must be root to start the server. Also, make sure port 53 UDP is reachable from the outside (consider running nmap -v -sU host from a remote machine). You will usually want to start it as follows:
sudo ./nomde.pl -i 0.0.0.0 server.example.com
Here, the server will only listen to DNS requests for all subdomains of server.example.com. That way, people who don't know that exact address cannot use the service on your server.
The Client
The OzymanDNS client is just a perl script which encodes and transfers everything it receives on STDIN to it's destination, via DNS requests. Replys are written to STDOUT.
So this isn't particularly useful as a standalone program. But it was designed to be used together with SSH. And with SSH this works great. SSH has a config option, ProxyCommand, which lets you use OzymanDNS's droute.pl client to tunnel the SSH traffic. The command to connect to your server would look like this:
ssh -o ProxyCommand="./droute.pl sshdns.server.example.com" user@localhost
Note two things:
Add a sshdns. in front of the hostname you specified the server to listen to and
Since your connection will already have been tunneled through DNS (and thus has come out at your host already) there is no need to login as user@server.example.com (because that already is localhost)
Once the connection is established (you'll probably have to enter your password) you have a shell! The connection is a little bit droppy sometimes and has not got the best latency, but it is still good keeping in mind that connections to the internet are not allowed at this Cafe/Airport/....
Tunneling
Once you verified that the connection is actually working, you can set up a tunnel so that you may not only have shell, but complete web acces, can fetch mails using POP, etc., etc...
For this, I recommend to read my tutorial on How to Tunnel Everything through SSH.
Don't forget: It may provide great performance increases to use SSH's -C ("compress data") switch!
Communication between the Servers
So, now how might the servers communicate with each other, not being directly able to establish a connection?, you might ask now.
Well, since all subdomain resolve requests are delegatet (ie., relayed) to your host, you can include arbitrary data in the hostname which your server then can interpret and execute/relay.
The bytes you want to send to the server (upstream) will be encoded using Base32 (if you know what Base64 is, Base32 is just the same except there is no case sensivitiy, for EXAMPLE.COM ist just the same as example.com). After the data, there is a unique ID (since some DNS requests may take longer than others and the UDP protocol has no methods to check this) and either one of the keywords up or down, indicating whether the traffic's up- or downstream. Here is what an example request could look like (transferring something to the server):
ntez375sy2qk7jsg2og3eswo2jujscb3r43as6m6hl2ws
xobm7h2olu4tmaq.lyazbf2e2rdynrd3fldvdy2w3tifi
gy2csrx3cqczxyhnxygor72a7fx47uo.nwqy4oa3v5rx6
6b4aek5krzkdm5btgz6jbiwd57ubnohnknpcuybg7py.6
3026-0.id-32227.up.sshdns.feh.dnstunnel.de
The server's response comes as a DNS TXT record. A TXT record can hold arbitrary ASCII data and can hold uppercase letters as well as lowercase letters and numbers (some other characters, as well). So the responses come Base64 encoded. Such a response might look like the following one:
695-8859.id-39201.down.sshdns.feh.dnstunnel.de. 0 IN TXT
"AAAAlAgfAAAAgQDKrd3sFmf8aLX6FdU8ThUy3SRWGhotR6EsAavqHgBzH2khqsQHQjEf355jS7cT
G+4a8kAmFVQ4mpEEJeBE6IyDWbAQ9a0rgOKcsaWwJ7GdngGm9jpvReXX7S/2oqAIUFCn0M8="
"MHw9tR0kkDVZB7RCfCOpjfHrir7yuiCbt7FpyX8AAAABBQAAAAAAAAAA"
That is, in rough outlines, how tunneling via DNS works.
Security Issues
There are a few security issues you'll have to think about before letting the server run permanently:
As soon as some people guess which subdomain you use to tunnel DNS they can send arbitrary commands to the server. I haven't reviewed the code for too long, but there might be the possiblity of a bug which could be exploited to gain access to your system. But that ist just a unlikely hypothesis.
The software still is very experimental and crashes every now and then (see below for a workaround).
Consider that the server puts a high load on your system while actively surfing.
I own a Server but my ISP doesn't allow me to change (the relevant) DNS settings
Well, that is the reason I created this website. I offer to set up a subdomain for you which delegates all requests (see above) to your fake nameserver.I cannot handle the mass of requests coming in; doing the communication and (manually!) setting up the records is just too much.
Therefore, I advise you to check at free DNS providers first, for example:
http://free.editdns.net/
http://freedns.afraid.org/
If you're willing to pay a little money (like 5 EUR) you could just as well register a domain name at INWX, which is the provider I use for hosting the DNS of this domain.
If you have no whatsoever means to do the setup on your own write me an email at <request AT dnstunnel.de>. You should include your full name, your server's static IP or DynDNS hostname and the desired subdomain name (name.dnstunnel.de; I encourage you to keep this secret for your own security). Be prepared to wait a few days or even weeks until I get around to setting up the records!
Legal Warning
Circumventing the AP's access controls (that includes DNS tunneling) is most probably considered to be a crime, depending on the country you live in. I am not responsible for whatever you do with your tunnel. I am just providing two simple entries in my ISP's DNS server to let a hostname point to your server's IP.
Helper Script
Here are two little helper scripts that'll allow you to automatically start OzymanDNS on system boot through initd. This is my /etc/init.d/ozymandns file:
#!/bin/sh
# Written by Julius Plenz
set -e
case "$1" in
start)
echo -n "Starting ozymandns listener..."
screen -d -m /usr/local/bin/ozymandns-listener
echo "."
;;
stop)
echo -n "Stopping ozymandns listener..."
kill `cat /var/run/ozymandns.pid`
echo "."
;;
restart)
/etc/init.d/ozymandns stop
/etc/init.d/ozymandns start
;;
reload|force-reload)
echo "cannot do that"
echo "."
;;
*)
echo "Usage: /etc/init.d/$NAME {start|stop|restart}"
exit 1
;;
esac
exit 0
Of course, you'll have to make the script executable. Then I'd suggest to put two links to automatically start and terminate the server on bootup/shutdown:
~# cd /etc/rc0.d/; ln -s ../init.d/ozymandns K15ozymandns
~# cd /etc/rc2.d/; ln -s ../init.d/ozymandns S99ozymandns
The program called from the init script (/usr/local/bin/ozymandns-listener) looks like this:
#!/bin/sh
REPLYIP=0.0.0.0
DNSHOST=name.dnstunnel.de
echo $$ > /var/run/ozymandns.pid
while [[ -e /var/run/ozymandns.pid ]] ; do
cd /usr/local/bin/
nomde.pl -i $REPLYIP $DNSHOST >/dev/null 2>&1
done
Note: This script again assumes you have installed the nomde.pl server in /usr/local/bin/ as well.
Example Video
I made an example video: DNS Tunneling Example Video (1:30, 20MB)
Documentation
There are a few other documents on the net explaining how DNS tunneling works. Some of these documents describe how DNS tunneling works with nstx, which is a different application, but basically also does the same as OzymanDNS.
Quick tunneling IP over DNS guide at digitalsec.es
NSTX (IP-over-DNS) HOWTO at thomer.com
Public Access to TOR via DNS at afs.eecs.harvard.edu
PPP over SSH over DNS Howto at ecs.soton.ac.uk
Dan Kaminsky's PowerPoint Slides at doxpara.com
Counter-measurements against DNS tunneling at daemon.be/maarten
2006-2011 Julius Plenz <julius * dnstunnel.de>
评论