Difference between revisions of "DNS Tunneling"
(→Linux) |
(→Tests) |
||
(64 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
A few years ago there was a proof-of-concept that it was possible to send and receive data packets over the Domain Name System (DNS). It utilizes the hostname for upstream data and the TXT-field for downstream data, and s smart queuing system to split and order the packets. The speed is not good, but it opens an alternate way to connect to the Internet. | A few years ago there was a proof-of-concept that it was possible to send and receive data packets over the Domain Name System (DNS). It utilizes the hostname for upstream data and the TXT-field for downstream data, and s smart queuing system to split and order the packets. The speed is not good, but it opens an alternate way to connect to the Internet. | ||
The method mentioned | The method mentioned in this tutorial is based on perl and works on Linux, Mac OS X, and Windows (via Cygwin). | ||
Document also known as ''Socks via SSH over DNS Tunnel'' and ''Socks via SSH over DNS''. | |||
== Technical Overview == | == Technical Overview == | ||
Line 14: | Line 16: | ||
The length of the entire hostname is limited to 255 octets/bytes [http://www.ops.ietf.org/lists/namedroppers/namedroppers.2003/msg00964.html]. And the TXT record has the same 255 bytes limit. It's now somewhat apparent that it should be possible to transmit and receive data using the hostname and TXT records respectively, if a system or encoder/decoder is placed in each end to create a connection. | The length of the entire hostname is limited to 255 octets/bytes [http://www.ops.ietf.org/lists/namedroppers/namedroppers.2003/msg00964.html]. And the TXT record has the same 255 bytes limit. It's now somewhat apparent that it should be possible to transmit and receive data using the hostname and TXT records respectively, if a system or encoder/decoder is placed in each end to create a connection. | ||
In addition, there is an experimental NULL record that allows 65535 octets (actual implementation is limited to 300 - 1200 octets) [http://tools.ietf.org/html/rfc1035]. See alternate ozymandns package for | In addition, there is an experimental NULL record that allows 65535 octets (actual implementation is limited to 300 - 1200 octets) [http://tools.ietf.org/html/rfc1035]. See alternate optimized ozymandns package below for version based on NULL records and estimating the optimal packet size. | ||
== | == Technical Details == | ||
Now, this DNS tunnel example is written in perl and includes a client and server. The fake DNS server runs on port 53 and will answer queries coming from the client (or anyone querying the hostname). A hostname has to be delegated to point to the server, e.g. the hostname of the server has to be the NS (record) for dtun.example.org. Thus any sub-domain query, e.g server.dtun.example.org, is forwarding (delegated) to the fake DNS server. | Now, this DNS tunnel example is written in perl and includes a client and server. The fake DNS server runs on port 53 and will answer queries coming from the client (or anyone querying the hostname). A hostname has to be delegated to point to the server, e.g. the hostname of the server has to be the NS (record) for dtun.example.org. Thus any sub-domain query, e.g server.dtun.example.org, is forwarding (delegated) to the fake DNS server. | ||
Line 33: | Line 35: | ||
lL9TM+NErSWeQPYVyKwB3uUT1fkcVI9E/WqnY1iFd2epHtyWrRD83nRvEsCOl9sMZamCw+UQQBTE | lL9TM+NErSWeQPYVyKwB3uUT1fkcVI9E/WqnY1iFd2epHtyWrRD83nRvEsCOl9sMZamCw+UQQBTE | ||
tcDKj8yXn3SAZBVdBCrEqowu9oVnVQ== | tcDKj8yXn3SAZBVdBCrEqowu9oVnVQ== | ||
== Requirments == | |||
These are the necessary services and tools: | |||
* Delegate a sub-domain to a fake name server | |||
* Host for fake server, ssh server and root privileges to run perl server on port 53 bind | |||
* Perl environment and required packages installed | |||
* Client machine to SSH into host server via DNS tunnel proxy | |||
== Delegating Zone == | == Delegating Zone == | ||
Line 50: | Line 61: | ||
The last example works fine for dynamic IP services like DynDNS and No-IP. | The last example works fine for dynamic IP services like DynDNS and No-IP. | ||
== Perl == | == Perl Setup == | ||
A quick tutorial on Perl and CPAN (Comprehensive Perl Archive Network): | A quick tutorial on Perl and CPAN (Comprehensive Perl Archive Network): | ||
Line 62: | Line 73: | ||
* Install modules: | * Install modules: | ||
** '''perl -MCPAN -e 'install MIME::Base32'''' | ** '''perl -MCPAN -e 'install MIME::Base32'''' | ||
** '''perl -MCPAN -e 'install Net::DNS'''' | |||
** '''perl -MCPAN -e 'install Digest::CRC'''' | |||
The server and client depends on a couple of modules, to install them: | The server and client depends on a couple of modules, to install them: | ||
Line 71: | Line 84: | ||
The fake server will answer queries and transmit data back. It should on a computer will full unlimited Internet access, meaning no outbound firewall blocking and minimum 512 kilobits/s upstream and downstream. The server is tested and confirmed working on Linux and Mac OS X. | The fake server will answer queries and transmit data back. It should on a computer will full unlimited Internet access, meaning no outbound firewall blocking and minimum 512 kilobits/s upstream and downstream. The server is tested and confirmed working on Linux and Mac OS X. | ||
The ''nomde.pl'' server requires root-privileges to bind to port 53. The port also has be reachable from the Internet. Make sure UDP and TCP port 53 is allowed inbound in the firewall and/or NAT configuration. Try [http://portforward.com/routers.htm portforward.com] or figure out the new iptables rule. | |||
=== Linux === | === Linux === | ||
The | The Linux set up is relatively easy. | ||
# Download the [http://www.doxpara.com/ozymandns_src_0. | # Download the [http://www.doxpara.com/ozymandns_src_0.1.tgz ozymandns_src_0.1.tgz] ([http://beta.ivancover.com/dnstunnel/ozymandns_src_0.1.tgz local mirror]) package from doxpara.com | ||
# Create a new directory and extract the archive | # Create a new directory and extract the archive | ||
# Start the server: | # Start the server: | ||
#* '''sudo ./nomde.pl -i 0.0.0.0 dtun.example.org | #* '''sudo ./nomde.pl -i 0.0.0.0 dtun.example.org''' | ||
# The server will create a new socket and listen on port 53 | # The server will create a new socket and listen on port 53 | ||
Line 91: | Line 106: | ||
# Download [http://developer.apple.com/tools/xcode/ Xcode] and install the package | # Download [http://developer.apple.com/tools/xcode/ Xcode] and install the package | ||
# Open Terminal and enter the perl CPAN shell | # Open Terminal and enter the perl CPAN shell | ||
#*''perl -MCPAN -e shell'' | |||
# Configure CPAN automatically or re-configure by ''o conf init'', press Enter on all the questions to fix the paths to e.g. make | # Configure CPAN automatically or re-configure by ''o conf init'', press Enter on all the questions to fix the paths to e.g. make | ||
# Install the perl modules mentioned above | # Install the perl modules mentioned above | ||
# Download the [http://www.doxpara.com/ozymandns_src_0. | #*''perl -MCPAN -e 'install Mime::Base32'' | ||
#*''perl -MCPAN -e 'install Net::DNS'' | |||
# Download the [http://www.doxpara.com/ozymandns_src_0.1.tgz ozymandns_src_0.1.tgz] ([http://beta.ivancover.com/dnstunnel/ozymandns_src_0.1.tgz local mirror]) package from doxpara.com | |||
# Create a new directory and extract the archive | # Create a new directory and extract the archive | ||
# Start the server: | # Start the server: | ||
#* '''sudo ./nomde.pl -i 0.0.0.0 dtun.example.org | #* '''sudo ./nomde.pl -i 0.0.0.0 dtun.example.org''' | ||
Of course change the hostname and install any missing modules, Mime/Base32.pm converts to module Mime::Base32. | Of course change the hostname and install any missing modules, Mime/Base32.pm converts to module Mime::Base32. | ||
=== Verify === | |||
An easy way to figure out if the server is ready is to manually query it. On Linux ''dig'' is handy and on Windows the ''nslookup'' utility does the job. | |||
* Linux / Mac OS X: | |||
** '''dig dtun.example.org''' | |||
** Alternatively specify name server to use '''dig @192.168.1.1 dtun.example.org''' | |||
The result should be: | |||
;; QUESTION SECTION: | |||
;dtun.example.org. IN A | |||
;; ANSWER SECTION: | |||
dtun.example.org. 3600 IN A 0.0.0.0 | |||
;; AUTHORITY SECTION: | |||
dtun.example.org. 10798 IN NS box.dyndns.org. | |||
;; ADDITIONAL SECTION: | |||
box.dyndns.org. 42 IN A 89.193.59.119 | |||
* Windows: | |||
** Open run => cmd.exe, and execute '''nslookup -q=ns dtun.example.org''' | |||
** Alternatively '''nslookup -q=ns dtun.example.org 192.168.1.1''' | |||
The result should look like: | |||
Server: UnKnown | |||
Address: 192.168.1.1 | |||
Non-authoritative answer: | |||
dtun.example.org nameserver = box.dyndns.org | |||
=== Loop Script === | |||
In case, or when, the server perl script crashes, this '''start.sh''' script will loop infinite and whenever the server is dead it will re-launch it automatically. | |||
#!/bin/sh | |||
while [ 1 ]; do | |||
ps -ef | grep -v grep | grep nomde | |||
# if not found - equals to 1, start it | |||
if [ $? -eq 1 ] | |||
then | |||
./nomde.pl -i 0.0.0.0 dtun.example.org | |||
else | |||
echo .eq 0 - daemon found - do nothing. | |||
fi | |||
done | |||
Fix the permissions, '''chmod +x start.sh''', and launch it with privileged rights, '''sudo ./start.sh'''. | |||
== Client == | |||
The client can run any computer with a perl environment (e.g. notebook, ultra-portable, etc) with a wired or wireless connection to the Internet connection. | |||
The method works behind a captive portal or payment portal as long as the DNS queries (A, TXT) are allowed through without being altered or blocked on the local router and DNS server. A normal hotspot practice is to not alter the DNS records but redirect HTTP traffic and deny access in the router firewall until the the user has been authorized. This still leaves DNS wide open and making a DNS tunnel possible. | |||
The client can run as a normal user as long as a SSH client is available. The SSH connection will be proxied using the ProxyCommand option in SSH by executing ''./droute.pl dtun.example.org''. | |||
The same '''module dependencies''' apply here as with the server, Mime::Base32 and Net::DNS mentioned in Perl Setup above is required. Make sure to re-configure Perl if make, gcc, etc is installed after wards. | |||
=== Linux === | |||
Client setup for Linux: | |||
# Download the [http://www.doxpara.com/ozymandns_src_0.1.tgz ozymandns_src_0.1.tgz] ([http://beta.ivancover.com/dnstunnel/ozymandns_src_0.1.tgz local mirror]) package to the client | |||
# Create a new directory and extract the archive | |||
# Start the proxy connection to the fake server and enable a local SOCKS 5 server on port 9999: | |||
#* '''ssh -o ProxyCommand="./droute.pl sshdns.dtun.example.org" -N -D 9999 -C jdoe@localhost''' | |||
# The SSH server will ask for the password of the user ''jdoe'' on the fake server (the connection is proxied, discard the localhost notation) | |||
The active queries over the DNS tunnel can be seen on the fake server terminal. Add a ''-v'' argument to the ssh command for verbose details. | |||
=== Mac OS X === | |||
Same goes for the client on Mac OS X, same as the server. Install Xcode and Perl modules. | |||
# Download the [http://www.doxpara.com/ozymandns_src_0.1.tgz ozymandns_src_0.1.tgz] ([http://beta.ivancover.com/dnstunnel/ozymandns_src_0.1.tgz local mirror]) package to the Mac | |||
# Create a new directory and extract the archive | |||
# Open Terminal and execute this command to start the proxy connection to the fake server and enable a local SOCKS 5 server on port 9999: | |||
#* '''ssh -o ProxyCommand="./droute.pl sshdns.dtun.example.org" -N -D 9999 -C jdoe@localhost''' | |||
# The SSH server will ask for the password of the user ''jdoe'' on the fake server (the connection is proxied) | |||
Watch the server terminal to see the queries being answered. Verbose output can be enabled by adding ''-v'' to the command. | |||
=== Windows === | |||
It's possible to set up a listening SOCKS proxy on Windows by using the Cygwin UNIX environment emulator. The SOCKS proxy, once set up, is available for the rest of the system. | |||
# Download the [http://www.cygwin.com/ Cygwin] installer (on the right side) | |||
# Or alternatively, download this Cygwin pre-installed and configured package (not available yet) | |||
# Pick a nearby mirror and add these these packages (and dependencies) to the installation: | |||
#* '''make''' under Devel | |||
#* '''gcc''' under Devel | |||
#* '''perl''' under Interpreters | |||
#* '''openssh''' under Net | |||
#* '''wget''' under Net | |||
#* '''perl''' under Perl | |||
#* and maybe '''unzip''', '''nano''' | |||
# Once installed, open a Cygwin command-prompt via one of the shortcuts | |||
# Download the [http://www.doxpara.com/ozymandns_src_0.1.tgz ozymandns_src_0.1.tgz] ([http://beta.ivancover.com/dnstunnel/ozymandns_src_0.1.tgz local mirror]) package to the local Cygwin /home/<user> directory | |||
# Create a new directory and extract the archive, '''tar xzvf ozymandns_src_0.1.tgz''' | |||
# Start the proxy connection to the fake server and enable SOCKS server on port 9999: | |||
#* '''ssh -o ProxyCommand="./droute.pl sshdns.dtun.example.org" -N -D 9999 -C jdoe@localhost''' | |||
# Type the password for the jdoe user on the fake server, omit the localhost notation, the connection is proxied over the DNS tunnel. | |||
Add a ''-v'' argument for verbose output. On the server, ''nomde.pl'' will show the constant stream of queries it receives and answers as quick as possible. | |||
=== Start script === | |||
To make it easier to launch and initialize the DNS tunnel, create a little '''start.sh''' script: | |||
#!/bin/sh | |||
ssh -o ProxyCommand="/home/jdoe/ozymandns/droute.pl sshdns.dtun.example.org" -N -D 9999 -C -v jdoe@localhost | |||
On Windows create this '''dns-tunnel.bat''' batch script to start a Cywin shell and execute the start.sh script: | |||
@echo off | |||
C: | |||
chdir C:\cygwin\bin | |||
bash --login -i /home/Administrator/ozymandns/start.sh | |||
pause | |||
== Optimized Fork == | |||
In the DNS specifications, there is a NULL RDATA record (like TXT, CNAME, etc) with a teoretical limit of 65535 bytes (64 KBytes). But in practical use the various name servers restrict the size from 200 to 3000 bytes. | |||
Try this optimized version by [http://cyberphob1a.wordpress.com/2008/02/11/speeding-up-dns-tunneling/ cyberphob1a] ([http://cyberphob1a.wordpress.com/2008/03/08/dns-tunneling-updated-source/ download page]) to increase the data received in each packet a.k.a. better throughput. Rename the original and extract the new client and server. | |||
* [http://beta.ivancover.com/dnstunnel/ozymandns_forkzip.zip ozymandns_forkzip.zip] | |||
The client will calculate the largest packet size supported by the local DNS servers (relays). | |||
Resolving through: | |||
UP: 192.168.1.1 | |||
DN: 192.168.1.1 | |||
Nullsize: | |||
Downstream Packetsize: 465 | |||
Upstream Packetsize: 110 | |||
The server machine also requires a small edit to the RR.pm perl module. Open '''/System/Library/Perl/Extras/5.8.8/darwin-thread-multi-2level/Net/DNS/RR.pm''' on Mac or '''/usr/local/lib/perl/5.8.8/Net/DNS/RR.pm''' on Linux. | |||
In RR.pm, find new_from_hash(), around line 464, change it from: | |||
( $self->{lc $key} = $val ) =~ s/\.+$// if defined $val; | |||
to | |||
( $self->{lc $key} = $val ) = $val; | |||
Start the client the normal way: | |||
* '''ssh -o ProxyCommand="./droute.pl sshdns.dtun.example.org" -N -D 9999 -C jdoe@localhost''' | |||
== Tunneling == | |||
Now, the tunnel should be set up and working. The SOCKS 5 server is available via 127.0.0.1 (localhost) and port 9999. | |||
=== Firefox === | |||
A classic example is to tunnel Firefox web traffic through a SOCKS proxy. The configuration is simple and easy to turn on and off. | |||
Open ''Options'' and under the ''Advanced'' tab pick ''Network'' and ''Settings''. Enable ''Manual Proxy Configuration'', in the ''SOCKS proxy'' field enter '''127.0.0.1''' and ''port'' '''9999'''. Select '''SOCKS v5'''. | |||
Another thing to configure is DNS resolving over SOCKS, in the address bar enter ''about:config'' and accept the warning. In the ''Filter'' field at the top enter '''socks''' and look for ''network.proxy.socks_remote_dns'', double click it to set it to '''true'''. | |||
Try to browse a webpage, e.g. [http://www.google.com google.com]. The page should load slowly but surely. | |||
To speed things up a bit, try: | |||
* Disable the loading of images | |||
* Disabling Javascript | |||
* Disabling Java | |||
* Installing AdBlock Plus + Filterset.G | |||
I found this [http://www.ghacks.net/2008/07/13/optimize-firefox-for-low-traffic-volumes/ guide to optimize firefox for low bandwidth carriers]. | |||
=== Windows Proxifier === | |||
There are a few applications that intercept traffic at application level and send it to a SOCKS proxy, i.e. SocksCap and Humming Bird. | |||
* Download the last freely available version, [http://beta.ivancover.com/dnstunnel/SocksCap_v240.rar SocksCap 2.40]. | |||
* Extract the content to ''c:\Program Files\SocksCap\'' and start '''sc32.exe'''. | |||
* Now, drag any TCP or UDP enabled application to the the SocksCap Control window and either pick ''New application profile'' or ''Run Socksified'' from the menu. | |||
* The application will now start from SocksCap Control like a debugger and intercept the traffic. | |||
== Notes == | |||
* Any one can query the fake name server once the hostname (e.g. dtun.example.org) is known and potentially execute arbitrary commands as root if an exploit is found. | |||
* The server and client will sometimes crash the SSH tunnel. Try to set up a auto re-launch script and password-less login. | |||
== Tests == | |||
The best and coolest way to test the set up, is to find a wireless captive portal or a provider charging for wireless Internet. | |||
Below is a list of verified wireless networks I tried. These are located in Norway. | |||
{| class="wikitable" border="0" width="750" | |||
! Picture | |||
! Info | |||
|- | |||
| rowspan="8" align="center"| [[Image:Dns tunnel telenor mobile wlan.jpg|150px]] | |||
|'''SSID:''' Telenor Mobile WLAN | |||
|- | |||
|'''Provider:''' Choice Clarion Hotels | |||
|- | |||
|'''Operator:''' Telenor Communications - Redirect to https://portal.wlan.telenor.no | |||
|- | |||
|'''Plan:''' 49 NOK/day | |||
|- | |||
|'''DNS servers:''' 10.10.0.1 | |||
|- | |||
|'''Recursive:''' Yes | |||
|- | |||
|'''Downstream:''' 345 | |||
|- | |||
|'''Upstream:''' 110 | |||
|} | |||
{| class="wikitable" border="0" width="750" | |||
! Picture | |||
! Info | |||
|- | |||
| rowspan="8" align="center"| [[Image:Dns tunnel telenor.jpg|150px]] | |||
|'''SSID:''' telenor | |||
|- | |||
|'''Provider:''' Public area, city centre | |||
|- | |||
|'''Operator:''' Telenor Communications - Redirect to https://portal.wlan.telenor.no | |||
|- | |||
|'''Plan:''' 49 NOK/day | |||
|- | |||
|'''DNS servers:''' 130.67.15.198, 130.67.60.68 | |||
|- | |||
|'''Recursive:''' Yes | |||
|- | |||
|'''Downstream:''' 465 | |||
|- | |||
|'''Upstream:''' 110 | |||
|} | |||
{| class="wikitable" border="0" width="750" | |||
! Picture | |||
! Info | |||
|- | |||
| rowspan="9" align="center"| [[Image:Dns tunnel bbox.jpg|150px]] | |||
|'''SSID:''' www.b-box.no | |||
|- | |||
|'''Provider:''' Nettbuss, TIMEkspress - NOR-WAY Bussekspress | |||
|- | |||
|'''Operator:''' bBox - Redirect to https://login.b-box.no | |||
|- | |||
|'''Plan:''' 29 NOK/day | |||
|- | |||
|'''DNS servers:''' 208.67.222.222, 208.67.220.220 (OpenDNS) | |||
|- | |||
|'''Recursive:''' Yes | |||
|- | |||
|'''Downstream:''' 465 | |||
|- | |||
|'''Upstream:''' 110 | |||
|- | |||
|'''Hack for portal:''' http://login.b-box.no/ccard/ccmailto.txt | |||
|} | |||
== References == | |||
* [http://dnstunnel.de/ DNS tunnel guide] | |||
* [http://cyberphob1a.wordpress.com/2008/02/10/dns-tunneling-part-i/ cyberphob1a - DNS Tunneling] | |||
* [http://cyberphob1a.wordpress.com/2008/02/11/speeding-up-dns-tunneling/ cyberphob1a - Speeding up DNS tunneling] | |||
* [http://cyberphob1a.wordpress.com/2008/03/08/dns-tunneling-updated-source/ cyberphob1a - DNS Tunneling - Updated Source] | |||
* [http://macapper.com/2007/05/22/advanced-os-x-secure-tunneling-via-ssh/ Advanced OS X secure tunneling via SSH] |
Latest revision as of 08:23, 16 September 2009
A few years ago there was a proof-of-concept that it was possible to send and receive data packets over the Domain Name System (DNS). It utilizes the hostname for upstream data and the TXT-field for downstream data, and s smart queuing system to split and order the packets. The speed is not good, but it opens an alternate way to connect to the Internet.
The method mentioned in this tutorial is based on perl and works on Linux, Mac OS X, and Windows (via Cygwin).
Document also known as Socks via SSH over DNS Tunnel and Socks via SSH over DNS.
Technical Overview
The DNS system is hierarchy structured, beginning with the 13 root servers for top-level-domains (TLD) i.e., com, net, org, down to the domain name, i.e. example.org, and then sub-domains, i.e. group.example.org. Each sub-domain can be delegated to another domain server at a different location.
Each domain is configured in a zone file, each zone file contains different types of records, i.e. A for address record, CNAME for alias to an A record, MX for the mail exchange server, NS for the zone's name server, TXT for plain text description. The interesting records here is the NS and TXT records. Entries ending with a dot means end of domain, while no dot means add $ORIGIN to entry.
example.org. IN NS ns1.nameserver.com. example.org. IN TXT "Example.org sample domain"
The length of the entire hostname is limited to 255 octets/bytes [1]. And the TXT record has the same 255 bytes limit. It's now somewhat apparent that it should be possible to transmit and receive data using the hostname and TXT records respectively, if a system or encoder/decoder is placed in each end to create a connection.
In addition, there is an experimental NULL record that allows 65535 octets (actual implementation is limited to 300 - 1200 octets) [2]. See alternate optimized ozymandns package below for version based on NULL records and estimating the optimal packet size.
Technical Details
Now, this DNS tunnel example is written in perl and includes a client and server. The fake DNS server runs on port 53 and will answer queries coming from the client (or anyone querying the hostname). A hostname has to be delegated to point to the server, e.g. the hostname of the server has to be the NS (record) for dtun.example.org. Thus any sub-domain query, e.g server.dtun.example.org, is forwarding (delegated) to the fake DNS server.
An upstream A record for a packet looks like this:
d6hsa2ar4hyinvdhgdv7nucwf5zkp3motntq3fmvn52kphqfn72kzyg24zui.6tuapj3frb6coby nav6zdvosvogvmvxouxfzebun3ga.17000-0.id-59037.up.sshdns.dns-inet.x-pec.com. 0 IN A 64.0.0.0
And a downstream NULL record looks like this:
8I8U4DiYSnstLODBg9GLva9NGo2TyE373SUAAS3snFWWf0jovz81s+foQO9KzBjxi8LslpxQiIYJ tafNvOw5TKtunYFqPoo0SIoytoFiJ4nzK4G4DTm0KMBpB2snO/+cVCIVH9VGVCHQGl7mufDxTVk7 RaGRBByTF+ia8tw0VOFLHp8SfnXeLdI5HZtqLF5kT3RzmWKa1w7awg+XI+xaGhQrA/aCtJa1p1B9 lL9TM+NErSWeQPYVyKwB3uUT1fkcVI9E/WqnY1iFd2epHtyWrRD83nRvEsCOl9sMZamCw+UQQBTE tcDKj8yXn3SAZBVdBCrEqowu9oVnVQ==
Requirments
These are the necessary services and tools:
- Delegate a sub-domain to a fake name server
- Host for fake server, ssh server and root privileges to run perl server on port 53 bind
- Perl environment and required packages installed
- Client machine to SSH into host server via DNS tunnel proxy
Delegating Zone
Since a fake name server server will handle all the sub-domain query traffic, the main name server for the domain (e.g. ns1.nameserver.com for example.org) has to have a NS record for the sub-domain (e.g. dtun.example.org) pointing to the address of the fake server.
A normal configuration would be this:
dtun.example.org. IN NS ns-dtun.example.org. ns-dtun.example.org IN A 89.193.59.119
The first line specifies the new name server for dtun.example.org (and everything under that sub-domain). The second line simply defines the static IP address of the fake server.
An alternate configuration if the hostname for the fake server is already known:
dtun.example.org. IN NS box.dyndns.org.
The last example works fine for dynamic IP services like DynDNS and No-IP.
Perl Setup
A quick tutorial on Perl and CPAN (Comprehensive Perl Archive Network):
- Enter the CPAN shell:
- perl -MCPAN -e shell
- To re-configure the environment:
- o conf init
- Upgrade CPAN:
- perl -MCPAN -e 'install Bundle::CPAN'
- Install modules:
- perl -MCPAN -e 'install MIME::Base32'
- perl -MCPAN -e 'install Net::DNS'
- perl -MCPAN -e 'install Digest::CRC'
The server and client depends on a couple of modules, to install them:
perl -MCPAN -e 'install MIME::Base32' perl -MCPAN -e 'install Net::DNS' perl -MCPAN -e 'install Digest::CRC' # For optimized version
Fake Name Server
The fake server will answer queries and transmit data back. It should on a computer will full unlimited Internet access, meaning no outbound firewall blocking and minimum 512 kilobits/s upstream and downstream. The server is tested and confirmed working on Linux and Mac OS X.
The nomde.pl server requires root-privileges to bind to port 53. The port also has be reachable from the Internet. Make sure UDP and TCP port 53 is allowed inbound in the firewall and/or NAT configuration. Try portforward.com or figure out the new iptables rule.
Linux
The Linux set up is relatively easy.
- Download the ozymandns_src_0.1.tgz (local mirror) package from doxpara.com
- Create a new directory and extract the archive
- Start the server:
- sudo ./nomde.pl -i 0.0.0.0 dtun.example.org
- The server will create a new socket and listen on port 53
Make sure to replace the hostname with your own. If any perl errors is reported, make sure the modules listed is installed, Mime/Base32.pm converts to module Mime::Base32.
Mac OS X
Mac OS X already has a perl installed by default but lacks the build and compile tools. The Xcode development enviroment includes all the necessary utilities and is freely available on Apple's website (registration required).
Make sure to re-run the cpan configuration after Xcode is installed. The path to make and other tools will then be correctly set up.
- Download Xcode and install the package
- Open Terminal and enter the perl CPAN shell
- perl -MCPAN -e shell
- Configure CPAN automatically or re-configure by o conf init, press Enter on all the questions to fix the paths to e.g. make
- Install the perl modules mentioned above
- perl -MCPAN -e 'install Mime::Base32
- perl -MCPAN -e 'install Net::DNS
- Download the ozymandns_src_0.1.tgz (local mirror) package from doxpara.com
- Create a new directory and extract the archive
- Start the server:
- sudo ./nomde.pl -i 0.0.0.0 dtun.example.org
Of course change the hostname and install any missing modules, Mime/Base32.pm converts to module Mime::Base32.
Verify
An easy way to figure out if the server is ready is to manually query it. On Linux dig is handy and on Windows the nslookup utility does the job.
- Linux / Mac OS X:
- dig dtun.example.org
- Alternatively specify name server to use dig @192.168.1.1 dtun.example.org
The result should be:
;; QUESTION SECTION: ;dtun.example.org. IN A ;; ANSWER SECTION: dtun.example.org. 3600 IN A 0.0.0.0 ;; AUTHORITY SECTION: dtun.example.org. 10798 IN NS box.dyndns.org. ;; ADDITIONAL SECTION: box.dyndns.org. 42 IN A 89.193.59.119
- Windows:
- Open run => cmd.exe, and execute nslookup -q=ns dtun.example.org
- Alternatively nslookup -q=ns dtun.example.org 192.168.1.1
The result should look like:
Server: UnKnown Address: 192.168.1.1 Non-authoritative answer: dtun.example.org nameserver = box.dyndns.org
Loop Script
In case, or when, the server perl script crashes, this start.sh script will loop infinite and whenever the server is dead it will re-launch it automatically.
#!/bin/sh while [ 1 ]; do ps -ef | grep -v grep | grep nomde # if not found - equals to 1, start it if [ $? -eq 1 ] then ./nomde.pl -i 0.0.0.0 dtun.example.org else echo .eq 0 - daemon found - do nothing. fi done
Fix the permissions, chmod +x start.sh, and launch it with privileged rights, sudo ./start.sh.
Client
The client can run any computer with a perl environment (e.g. notebook, ultra-portable, etc) with a wired or wireless connection to the Internet connection.
The method works behind a captive portal or payment portal as long as the DNS queries (A, TXT) are allowed through without being altered or blocked on the local router and DNS server. A normal hotspot practice is to not alter the DNS records but redirect HTTP traffic and deny access in the router firewall until the the user has been authorized. This still leaves DNS wide open and making a DNS tunnel possible.
The client can run as a normal user as long as a SSH client is available. The SSH connection will be proxied using the ProxyCommand option in SSH by executing ./droute.pl dtun.example.org.
The same module dependencies apply here as with the server, Mime::Base32 and Net::DNS mentioned in Perl Setup above is required. Make sure to re-configure Perl if make, gcc, etc is installed after wards.
Linux
Client setup for Linux:
- Download the ozymandns_src_0.1.tgz (local mirror) package to the client
- Create a new directory and extract the archive
- Start the proxy connection to the fake server and enable a local SOCKS 5 server on port 9999:
- ssh -o ProxyCommand="./droute.pl sshdns.dtun.example.org" -N -D 9999 -C jdoe@localhost
- The SSH server will ask for the password of the user jdoe on the fake server (the connection is proxied, discard the localhost notation)
The active queries over the DNS tunnel can be seen on the fake server terminal. Add a -v argument to the ssh command for verbose details.
Mac OS X
Same goes for the client on Mac OS X, same as the server. Install Xcode and Perl modules.
- Download the ozymandns_src_0.1.tgz (local mirror) package to the Mac
- Create a new directory and extract the archive
- Open Terminal and execute this command to start the proxy connection to the fake server and enable a local SOCKS 5 server on port 9999:
- ssh -o ProxyCommand="./droute.pl sshdns.dtun.example.org" -N -D 9999 -C jdoe@localhost
- The SSH server will ask for the password of the user jdoe on the fake server (the connection is proxied)
Watch the server terminal to see the queries being answered. Verbose output can be enabled by adding -v to the command.
Windows
It's possible to set up a listening SOCKS proxy on Windows by using the Cygwin UNIX environment emulator. The SOCKS proxy, once set up, is available for the rest of the system.
- Download the Cygwin installer (on the right side)
- Or alternatively, download this Cygwin pre-installed and configured package (not available yet)
- Pick a nearby mirror and add these these packages (and dependencies) to the installation:
- make under Devel
- gcc under Devel
- perl under Interpreters
- openssh under Net
- wget under Net
- perl under Perl
- and maybe unzip, nano
- Once installed, open a Cygwin command-prompt via one of the shortcuts
- Download the ozymandns_src_0.1.tgz (local mirror) package to the local Cygwin /home/<user> directory
- Create a new directory and extract the archive, tar xzvf ozymandns_src_0.1.tgz
- Start the proxy connection to the fake server and enable SOCKS server on port 9999:
- ssh -o ProxyCommand="./droute.pl sshdns.dtun.example.org" -N -D 9999 -C jdoe@localhost
- Type the password for the jdoe user on the fake server, omit the localhost notation, the connection is proxied over the DNS tunnel.
Add a -v argument for verbose output. On the server, nomde.pl will show the constant stream of queries it receives and answers as quick as possible.
Start script
To make it easier to launch and initialize the DNS tunnel, create a little start.sh script:
#!/bin/sh ssh -o ProxyCommand="/home/jdoe/ozymandns/droute.pl sshdns.dtun.example.org" -N -D 9999 -C -v jdoe@localhost
On Windows create this dns-tunnel.bat batch script to start a Cywin shell and execute the start.sh script:
@echo off C: chdir C:\cygwin\bin bash --login -i /home/Administrator/ozymandns/start.sh pause
Optimized Fork
In the DNS specifications, there is a NULL RDATA record (like TXT, CNAME, etc) with a teoretical limit of 65535 bytes (64 KBytes). But in practical use the various name servers restrict the size from 200 to 3000 bytes.
Try this optimized version by cyberphob1a (download page) to increase the data received in each packet a.k.a. better throughput. Rename the original and extract the new client and server.
The client will calculate the largest packet size supported by the local DNS servers (relays).
Resolving through: UP: 192.168.1.1 DN: 192.168.1.1 Nullsize: Downstream Packetsize: 465 Upstream Packetsize: 110
The server machine also requires a small edit to the RR.pm perl module. Open /System/Library/Perl/Extras/5.8.8/darwin-thread-multi-2level/Net/DNS/RR.pm on Mac or /usr/local/lib/perl/5.8.8/Net/DNS/RR.pm on Linux.
In RR.pm, find new_from_hash(), around line 464, change it from:
( $self->{lc $key} = $val ) =~ s/\.+$// if defined $val;
to
( $self->{lc $key} = $val ) = $val;
Start the client the normal way:
- ssh -o ProxyCommand="./droute.pl sshdns.dtun.example.org" -N -D 9999 -C jdoe@localhost
Tunneling
Now, the tunnel should be set up and working. The SOCKS 5 server is available via 127.0.0.1 (localhost) and port 9999.
Firefox
A classic example is to tunnel Firefox web traffic through a SOCKS proxy. The configuration is simple and easy to turn on and off.
Open Options and under the Advanced tab pick Network and Settings. Enable Manual Proxy Configuration, in the SOCKS proxy field enter 127.0.0.1 and port 9999. Select SOCKS v5.
Another thing to configure is DNS resolving over SOCKS, in the address bar enter about:config and accept the warning. In the Filter field at the top enter socks and look for network.proxy.socks_remote_dns, double click it to set it to true.
Try to browse a webpage, e.g. google.com. The page should load slowly but surely.
To speed things up a bit, try:
- Disable the loading of images
- Disabling Javascript
- Disabling Java
- Installing AdBlock Plus + Filterset.G
I found this guide to optimize firefox for low bandwidth carriers.
Windows Proxifier
There are a few applications that intercept traffic at application level and send it to a SOCKS proxy, i.e. SocksCap and Humming Bird.
- Download the last freely available version, SocksCap 2.40.
- Extract the content to c:\Program Files\SocksCap\ and start sc32.exe.
- Now, drag any TCP or UDP enabled application to the the SocksCap Control window and either pick New application profile or Run Socksified from the menu.
- The application will now start from SocksCap Control like a debugger and intercept the traffic.
Notes
- Any one can query the fake name server once the hostname (e.g. dtun.example.org) is known and potentially execute arbitrary commands as root if an exploit is found.
- The server and client will sometimes crash the SSH tunnel. Try to set up a auto re-launch script and password-less login.
Tests
The best and coolest way to test the set up, is to find a wireless captive portal or a provider charging for wireless Internet.
Below is a list of verified wireless networks I tried. These are located in Norway.
Picture | Info |
---|---|
SSID: Telenor Mobile WLAN | |
Provider: Choice Clarion Hotels | |
Operator: Telenor Communications - Redirect to https://portal.wlan.telenor.no | |
Plan: 49 NOK/day | |
DNS servers: 10.10.0.1 | |
Recursive: Yes | |
Downstream: 345 | |
Upstream: 110 |
Picture | Info |
---|---|
SSID: telenor | |
Provider: Public area, city centre | |
Operator: Telenor Communications - Redirect to https://portal.wlan.telenor.no | |
Plan: 49 NOK/day | |
DNS servers: 130.67.15.198, 130.67.60.68 | |
Recursive: Yes | |
Downstream: 465 | |
Upstream: 110 |
Picture | Info |
---|---|
SSID: www.b-box.no | |
Provider: Nettbuss, TIMEkspress - NOR-WAY Bussekspress | |
Operator: bBox - Redirect to https://login.b-box.no | |
Plan: 29 NOK/day | |
DNS servers: 208.67.222.222, 208.67.220.220 (OpenDNS) | |
Recursive: Yes | |
Downstream: 465 | |
Upstream: 110 | |
Hack for portal: http://login.b-box.no/ccard/ccmailto.txt |