Browse the internet with only DNS queries

Posted by

You’re outside with no mobile internet. You’ve found an unsecured WiFi connection, like a hotel lobby or airport. But once again, it is behind a paywall, or it requires an SMS confirmation even though you’ve just landed and have no SIM card. You want to get to Facebook or Gmail but all you can get is the “Sign In” page.

This article is for educational purposes only. Unauthorized use of a computer is a crime in many jurisdictions.


If you can still access DNS on your computer using these networks, then you can get internet. The trick here is to prepare your own sneaky DNS server (a DNS proxy, if you will). Your computer and the sneaky DNS will send to each other normal DNS queries and responses, which actually encodes a smuggled internet connection.

I followed an existing guide by Andreas Gohr here:

My experience with this method:

This is not a guide itself but merely some comments on what I had trouble with when using the guide linked above, so follow that guide instead and read this if you get any problems.

Luckily I already had a domain from GoDaddy with DNS options, and a Linode VPS as my SSH endpoint and the DNS proxy itself.

I added a new NameServer record for my domain in GoDaddy’s DNS manager:

I made an entry for the name too:


On my linode server, I downloaded the fixed up OzymanDNS scripts found in the guide above. I installed perl and a couple of missing modules:

# apt-get install perl
# cpan App:cpanminus
# cpanm Net::DNS
# cpanm MIME:Base32

However I ran into some minor problems. The script was so old that I had to remove the “qw ( RFC )” bit from line 12 of to make it compatible with the latest MIME::Base32.

Then I had to add the group “nobody” to my linode for the script’s privilege dropping:

# groupadd nobody

Finally, the instructions are a bit misleading in the dnstunneld.wrapper file. On the line:

DNSHOST=""           # change this to your DNS name

You should be changing to the domain name that your DNS is resolving, not the domain name of the DNS server itself, eg to and not in my case.

I followed the rest of the instructions and it finally worked. If you run into problems, try running the daemon script directly without the service and wrapper to find out what’s wrong (like I had to do):

# ./dnstunneld -i

Finally, on my Linux client, I also downloaded the modified OzymanDNS scripts linked in the guide above, installed perl and relevant modules, removed the problematic “qw ( RFC )” part from, moved dnstunnel to /usr/local/bin/, and ran:

$ ssh -D 8080 -C -o ProxyCommand="dnstunnelc" linode

This created the SOCKS proxy on my local computer via SSH on port 8080, which itself is through a DNS tunnel! I then configured Firefox (or any popular browser) to use this socks proxy. Search Google for an up-to-date guide on how to do this:


I can now browse the entire world wide web… using only DNS queries!

So far I have tried a couple of free WiFi hotspots at local cafes without logging in. The proxy all works, but remember that those hotspots were completely free in the first place, but at least this is proof of concept that it works.

This method also works at hotel WiFi hotspots that I’ve come across, without needing to log in.

So far, when it is connected, the experience is rightfully slow. It’ll do OK in emergency-esque situations where you need to send an important email or check your itinerary, but don’t think about video streaming or even loading images.

After using tcpdump I realize that I never send/receive packets directly to/from my DNS server. I’m no DNS expert but it seems like all the traffic is relayed via a public DNS server. Use this wisely since it puts strain on those servers, typically used to handle your occasional small DNS queries and not your entire internet traffic.

In addition, the connection breaks every now and then with “corrupt packet” errors which I have yet to investigate.

My DNS server is now closed to avoid violating Linode’s TOS.

Leave a Reply

Your email address will not be published. Required fields are marked *