TCP-over-DNS tunnel software HOWTO

Q: How do I get free internet where I should have none?
A: Use tcp-over-dns tunnelling software.

We'll show you how.

How it works

DNS stands for "Domain Name System". The purpose of DNS is convert a domain name, such as "analogbit.com" to an ip address, such as "208.113.168.166". The interesting thing about DNS queries is that they are usually recursive queries. This means that if a server doesn't know the answer for a domain name, it is allowed to ask other servers for the answer. So while a firewall or restrictive ISP may filter regular internet traffic they probably overlooked DNS traffic.

tcp-over-dns diagramtcp-over-dns diagram

 

Hexdump of tcp-over-dns packetHexdump of tcp-over-dns packet

The tcp-over-dns client will encode data in an address and sends that out to the ISP's dns server. The ISP's dns server then realizes it cannot answer the question, so it forwards it onto the tcp-over-dns server. The tcp-over-dns server decodes the client's data from the address and encodes the server's data in the answer that is sent back to the client.

There are many things working against the efficiency of the tunnel. There are certain restrictions about what characters may be in a domain name (a-z, A-Z, 0-9, hyphen) so data is converted into the appropriate character set before transmission. The server's answer to a query also has many restricted characters, so it too must do the same thing with a different set of characters. Every query that is answered by the DNS server must also include the question in the response. The combination of these restrictions means the total data transmitted is not very efficient compared to the number of bytes actually sent.

Requirements
  1. An internet connection that has been intentionally crippled by the connection's administator. A candidate connection will filter normal internet traffic, but it will allow DNS queries through. You can tell if it will work if when you ping a server you can get its IP address but all ping/tcp/udp packets are lost.
  2. Server under your control where you are the root or administrator user. You need to be able to set up a server to listen on the DNS port (port 53). This can be a machine you are running at home, most (all?) ISPs do not filter dns traffic.
  3. A domain name that you can use to direct queries to your server.
  4. tcp-over-dns server and client software, as well as a functional Java Runtime Environment. It's free!

Step 1 - Set up the domain

First you need to point the domain to the location of your server. If you want to squeeze out a few more bytes per query, try to keep the domain name as short as possible. Ultimately we need two DNS records. One that says that there is a name server for *.dnstunnel.domain.com. The next record says where you can find the ip address of the aforementioned nameserver.

Method 1:

If you have direct access to the the DNS record you can add something like this to the bottom of it:

;set up the DNS tunnel
$ORIGIN dnstunnel.analogbit.com.
@ IN NS ns.analogbit.com.
ns IN A <server ip>

 

Method 2:

Okay, maybe I'm a cheapskate, I don't actually own a server where I can edit the DNS record directly. However I am in luck. Some of my users have brought http://freedns.afraid.org to my attention. You can use afraid.org with tcp-over-dns without even registering a domain name. Set up any two subdomains so they look like this.

freedns.afraid.org setupfreedns.afraid.org setup

Make sure you replace the A record with the ip address of your server. You can use various clients to update this A record automatically if you ip address changes. Read more about it on afraid.org's webpage.

Method 3:

Our hosting company lets us edit our DNS record through a web interface. You can do the same thing if this sort of functionality is provided to you.

Dreamhost DNS SetupDreamhost DNS Setup

Step 2 - Setup the server

Download and extract the tcp-over-dns software to the server machine you are using.

Choose a port on the server you want the client to be able to access. Currently, there is no authentication, so keep security in mind. This works on any OS that runs java, and both TCP and UDP traffic is tunnelled through, so really any application you wish to use should work. Please note that you need to have a program running and listening on the --forward-port. You will connect to this program through the DNS tunnel.

Some of the best choices are:

  • Proxy server (for basic web browsing)
  • An openssh server on linux (for controlling the server and also works as a proxy)
  • VPN server (your computer appears on the home network)
  • VNC server (for access to your desktop at home)

The best choices are either the SSH port (22) or a VPN port. I am primarily using this for SSH access with optional proxy support, so I will use port 22. VPN adds network overhead and since I don't have that much bandwidth I am going to go with SSH in this example.

As root/administrator, run the server:
java -jar tcp-over-dns-server.jar --domain dnstunnel.analogbit.com --forward-port 22

The above line causes the server to begin listening on the DNS port for client machines that it will tunnel traffic to port 22.

Step 3 - Set up the client

Download and extract the tcp-over-dns software to the client machine you are using.

Run the client:
java -jar tcp-over-dns-client.jar --domain dnstunnel.analogbit.com --listen-port 60022 --interval 100

This starts the client and it begins listening on port 60022 for data to tunnel to the server's port 22. With an interval of 100 milliseconds it sends 10 dns requests per second to the server (if you have access to a fast network you might want this as low as 5 or 10, but keep in mind it eats a lot of bandwidth in overhead).

Step 4 - Try it out

On the client, attempt to connect to the server.
ssh -C -p 60022 localhost

Or, if you want a proxy that you can use with web browsers or instant messengers:
ssh -C -p 60022 localhost -D 8080

Hopefully that worked. If not you can turn on higher levels of logging with the --log-level command line option, it may help. No data will be sent until a packet is received on the client end. There are some batch files and bash scripts included to make running the client/server a little easier.

Thats it!

Discussion Note:
Discussion for this utility has moved to the TCP-over-DNS forum.  

Comments

Low Connection Speed

I notice that the connection using DNS tunnel is very slow.

Usually I can download 500KB/s from my office. But when I apply this method I can only download around 3 KB/s.

Why the speed very different? Who to speed up the connection? Is there any DNS tunnel method that is faster?

Thanks.

Problems with the proxy command

This requires the 6.0+ JRE, so it won't work on most macs yet - they use 1.5.0_16 by default.  A workaround is to edit the example scripts to use /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home/bin/java instead of the version of java in the system path.

Also, I tried to start up a proxy using the -D 8080 example, but it still acts just like the other command, passing me through a normal SSH login to a shell on my server.  I don't want a shell, i want it to proxy http traffic :P

Then you are one step away

Then all that remains is to set your browser to use a proxy. They all have proxy options somewhere under your browser's networking settings or advanced settings.

(Set it to localhost:8080)

 

Similar issue

This might be more of a configuration issue with Firefox than anything else. I am running the client and server software. I assume it is working alright because when I

$ssh -C -p 6022 localhost -D 8080

I get a shell in my server. I then configured Firefox to use Proxys as follows:

HTTP Proxy: localhost port:8080

SOCKS Host: localhost port:8080

When i try to navigate to a website in Firefox, it simply remains blank. The client logs show the following:

001030.2 main: Sent: Packet[ClientID:54841 PacketID:0 Flags: NO_OP Data:8bytes ack:37 checksum:ok]

001030.2 main: Received: Packet[ClientID:54841 PacketID:0 Flags: NO_OP Data:0bytes ack:123 checksum:ok]

001030.3 main: Sent: Packet[ClientID:54841 PacketID:0 Flags: NO_OP Data:8bytes ack:37 checksum:ok]

001030.4 main: Received: Packet[ClientID:54841 PacketID:0 Flags: NO_OP Data:0bytes ack:123 checksum:ok]

001030.5 main: Sent: Packet[ClientID:54841 PacketID:0 Flags: NO_OP Data:8bytes ack:37 checksum:ok]

001030.5 main: Received: Packet[ClientID:54841 PacketID:0 Flags: NO_OP Data:0bytes ack:123 checksum:ok]

And the server logs show the following:

01165.7 DNS Serve /0.0.0.0:53: Received: Packet[ClientID:54841 PacketID:0 Flags: NO_OP Data:8bytes ack:48 checksum:ok]

001165.7 DNS Serve /0.0.0.0:53: Sent: Packet[ClientID:54841 PacketID:0 Flags: NO_OP Data:0bytes ack:134 checksum:ok]

001165.9 DNS Serve /0.0.0.0:53: Received: Packet[ClientID:54841 PacketID:0 Flags: NO_OP Data:8bytes ack:48 checksum:ok]

001165.9 DNS Serve /0.0.0.0:53: Sent: Packet[ClientID:54841 PacketID:0 Flags: NO_OP Data:0bytes ack:134 checksum:ok]

Any ideas on how I might get this to work?

Now the serverside

Now the serverside errors

===========================================

Z:\___tmp_TXP_shared2\server_TCP_over_DNS_09>java -jar tcp-over-dns-server.jar -
-domain test123.chickenkiller.com --forward-port 808 --forward-address 192.168.5
3.186 --mtu=400 --log-level 3
000000.0 main: tcp-over-dns-server starting up
000000.0 main: Hosting domain: test123.chickenkiller.com
000000.0 main: DNS listening on: /0.0.0.0:53
000000.0 main: Forwarding to: /192.168.53.186:808
000000.0 main: MTU: 400
000000.0 main: Log level: 3
045533.5 DNS Serve /0.0.0.0:53: New tcp client connection:254
045636.6 Client timeout: Client timeout (ClientID:254).
045636.6 TCP comm /192.168.53.186:2037: Local TCP socket closed.
055032.6 DNS Serve /0.0.0.0:53: New tcp client connection:227
055032.7 DNS Serve /0.0.0.0:53: New tcp client connection:138
055035.2 DNS Serve /0.0.0.0:53: New tcp client connection:103
055035.6 DNS Serve /0.0.0.0:53: New tcp client connection:208
055035.7 DNS Serve /0.0.0.0:53: New tcp client connection:35
055035.7 DNS Serve /0.0.0.0:53: New tcp client connection:112
055039.0 DNS Serve /0.0.0.0:53: TCP port communicator sender errored.
055039.1 DNS Serve /0.0.0.0:53: java.net.SocketException: Software caused connec
tion abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
at common.TCPPortCommunicator.sendPacket(TCPPortCommunicator.java:73)
at common.ConnectionState.onSlidingWindowCollectedPackets(ConnectionStat
e.java:144)
at common.SlidingWindow.moveFrontOfWindowToPid(SlidingWindow.java:159)
at common.SlidingWindowSet.packetReceived(SlidingWindowSet.java:34)
at common.ConnectionState.dnsPacketReceived(ConnectionState.java:41)
at server.Server.generateReply(Server.java:178)
at server.Server.serveUDP(Server.java:361)
at server.Server.access$1(Server.java:341)
at server.Server$1.run(Server.java:387)
055039.3 TCP comm /192.168.53.186:2055: Local TCP socket closed.
055043.4 TCP comm /192.168.53.186:2053: TCP port communicator receiver errored.
055043.4 TCP comm /192.168.53.186:2053: java.net.SocketException: Connection res
et
at java.net.SocketInputStream.read(Unknown Source)
at common.TCPPortCommunicator.run(TCPPortCommunicator.java:29)
Local TCP socket closed.
055048.2 DNS Serve /0.0.0.0:53: TCP port communicator sender errored.
055048.2 DNS Serve /0.0.0.0:53: java.net.SocketException: Software caused connec
tion abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
at common.TCPPortCommunicator.sendPacket(TCPPortCommunicator.java:73)
at common.ConnectionState.onSlidingWindowCollectedPackets(ConnectionStat
e.java:144)
at common.SlidingWindow.moveFrontOfWindowToPid(SlidingWindow.java:159)
at common.SlidingWindowSet.packetReceived(SlidingWindowSet.java:34)
at common.ConnectionState.dnsPacketReceived(ConnectionState.java:41)
at server.Server.generateReply(Server.java:178)
at server.Server.serveUDP(Server.java:361)
at server.Server.access$1(Server.java:341)
at server.Server$1.run(Server.java:387)
055071.9 DNS Serve /0.0.0.0:53: New tcp client connection:58
055072.9 DNS Serve /0.0.0.0:53: New tcp client connection:19
055078.1 Client timeout: Client timeout (ClientID:138).
055078.1 TCP comm /192.168.53.186:2051: Local TCP socket closed.
055085.1 Client timeout: Client timeout (ClientID:208).
055089.1 Client timeout: Client timeout (ClientID:103).
055118.2 Client timeout: Client timeout (ClientID:19).
055118.2 TCP comm /192.168.53.186:2063: Local TCP socket closed.
055198.3 Client timeout: Client timeout (ClientID:58).
055198.3 Client timeout: Client timeout (ClientID:112).
055198.3 Client timeout: Client timeout (ClientID:35).
========================================

Hope you can help analyzing this problem!

Thanks,Wolfgang

Forgot to add, it seems to be

Forgot to add, it seems to be when to much data is transfered, like loading a different web page and then a other one, all gets stuck with following error:

=============================================

000096.9 DNS Listener: Received error code from DNS server!SERVFAIL
000096.9 DNS Listener: Received error code from DNS server!SERVFAIL
000097.0 DNS Listener: Received error code from DNS server!SERVFAIL
000097.0 DNS Listener: Received dns response with truncated flag!
000097.0 DNS Listener: Received dns response with no answer!
000097.0 DNS Listener: Received dns response with truncated flag!
000097.0 DNS Listener: Received dns response with no answer!
000097.1 DNS Listener: Received error code from DNS server!SERVFAIL
000097.1 DNS Listener: Received error code from DNS server!SERVFAIL
000097.1 DNS Listener: Received error code from DNS server!SERVFAIL
000097.2 DNS Listener: Received dns response with truncated flag!
000097.2 DNS Listener: Received dns response with no answer!
000097.2 DNS Listener: Received error code from DNS server!SERVFAIL
000097.2 DNS Listener: Received error code from DNS server!SERVFAIL
000097.2 DNS Listener: Received error code from DNS server!SERVFAIL
000097.2 DNS Listener: Received error code from DNS server!SERVFAIL
000097.3 DNS Listener: Received error code from DNS server!SERVFAIL

===========================================

Tests have been done from different locations, so also different DNS server connected to client. So I assume it is not a specific DNS server causing this issues. The error message itself seems to be from dns-tunnel server...correct?

Thanks, Wolfgang

Have some issues to solve

Hi,

At first , great software! Have some issues to solve.

Use freeDNS and client and server is each installed on XP or Vista, latest java installed.

client and server connect

server is connected to CCproxy

Firefox is connected to client via http/https proxy setting

I can browse to Google, CNN etc , but in cmd you can see a lot of errors.

client_log=======================================

000128.5 DNS Listener: Received dns response with truncated flag!
000128.5 DNS Listener: Answer not TXT!
000128.6 DNS Listener: Received dns response with truncated flag!
000128.6 DNS Listener: Answer not TXT!
000128.8 DNS Listener: Received dns response with truncated flag!
000128.8 DNS Listener: Answer not TXT!
000128.9 DNS Listener: Received dns response with truncated flag!
000128.9 DNS Listener: Answer not TXT!
000129.1 main: TCP port communicator sender errored.
000129.1 main: java.net.SocketException: Software caused connection abort: socke
t write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
at common.TCPPortCommunicator.sendPacket(TCPPortCommunicator.java:73)
at common.ConnectionState.onSlidingWindowCollectedPackets(ConnectionStat
e.java:144)
at common.SlidingWindow.moveFrontOfWindowToPid(SlidingWindow.java:159)
at common.SlidingWindowSet.packetReceived(SlidingWindowSet.java:34)
at common.ConnectionState.dnsPacketReceived(ConnectionState.java:41)
at client.Client.update(Client.java:224)
at client.Client.loop(Client.java:188)
at client.Client.main(Client.java:73)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.simontuffs.onejar.Boot.run(Boot.java:306)
at com.simontuffs.onejar.Boot.main(Boot.java:159)
000129.5 TCP comm /127.0.0.1:808: Local TCP socket closed.
000129.5 DNS Listener: Received dns response with truncated flag!
000129.5 DNS Listener: Answer not TXT!
000131.3 TCP comm /127.0.0.1:808: TCP port communicator receiver errored.
000131.3 TCP comm /127.0.0.1:808: java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at common.TCPPortCommunicator.run(TCPPortCommunicator.java:29)
Local TCP socket closed.

=====================================

What does not work at all is to run a SSL tunnel http://barracudaserver.com/products/BarracudaDrive/ via the DNS tunnel. SSL tunnel client can not connect at all via tunnel, not directly to SSL server or via CCproxy, just errors on server side.

I used MTU 1500 and also 400, no change. Interval setting 2 to 20 no changes.

Any good ideas ?

Do you know DNScat ?  http://tadek.pietraszek.org/projects/DNScat/  As I use windows, I changed the script from DNScat to vbs script. Can connect from client to server via command window and send text in each direction, but have not managed in windows to convert the commandwindow to a socket/IP-port. I tried with Netcat, but seems to be I do not know netcat good enough to do so. That was the reason I found your solution. DNScat has also some good ideas for hiding....hey maybe both can be combind to make the perfect DNS tunnel :-)

Any help appreciated! Thanks, Wolfgang

 

im confused :D

this is the shot i made http://img58.imageshack.us/img58/4299/13520313.jpg

please mister help me to configure it ...im still newbie :D

dns records

This means your dns records are not set up properly. I rewrote the section on DNS setup. Let me know if you still can't get it to work.

DNS Listener: Received error code from DNS server!NXDOMAIN

Dear Tim,

When I start SSH for port 60022 on localhost , I am receiving follow messages

C:\tcp-over-dns>java -jar tcp-over-dns-client.jar --domain srv007.conntrust.com
--listen-port 60022 --listen-address 127.0.0.1 --interval 200 --mtu=1500
evel=3
000000,0 main: tcp-over-dns-client starting up
000000,0 main: Connecting to domain: srv007.conntrust.com
000000,0 main: Using dns server: 53:/192.168.1.1
000000,0 main: Interval: 200
000000,0 main: MTU: 1500
000000,0 main: Listening on: 60022:/127.0.0.1
000000,0 main: Log level: 3
000023,0 DNS Listener: Received error code from DNS server!NXDOMAIN
000026,0 DNS Listener: Received error code from DNS server!NXDOMAIN
000029,2 DNS Listener: Received error code from DNS server!NXDOMAIN

I verified NAMD SERVER but I not found problem.

Thanks for help.

Help, cant connect with tcp over dns

Hi, I´m having a lot of problems trying to connect to internet with tcp over dns, I only want to test it.

My server seems to be connected to the dns, and my client keeps trying to conect sending dns and receiving pings, In wireshark I only see a lot of packets of dns and icmp.

Please help =(

A Test Server

Im running a ssh server that you can use to test it. You can test it with

java -jar tcp-over-dns-client.jar --domain t.spirh.com --interval 20

then ssh into localhost:8080. You should get a ssh login prompt.

Did you get it to work? I

Did you get it to work?

I also have the same problem. I appreciate any help.

Thanks in advance