Skip to main content.

Tunneling traffic through DNS

2014-07-16

Live demo in BSD Now Episode 046. | Originally written by TJ for bsdnow.tv | Last updated: 2014/11/01

NOTE: the author/maintainer of the tutorial(s) is no longer with the show, so the information below may be outdated or incorrect.

Public wifi is great, but sometimes there are annoying restrictions in place to prevent you from using it freely. You've probably been to an airport or coffee shop and seen the "Pay X dollars for an hour of wireless!" messages. They take over your entire browsing session, and the network refuses to load any of the websites you actually want to go to. Sometimes, however, you can bypass these annoyances without paying a dime! For this tutorial, we'll be relying on the (very likely) fact that the company who set up the network misconfigured it to allow DNS requests to pass through. Keep in mind that this is a last ditch effort to get free connectivity. It will be painfully slow for anything more than light web browsing. You will need the following things:

  • A remotely accessible server running SSH (a router is fine too)
  • A client machine (probably your laptop)
  • A domain name whose records you control, or an account at afraid.org

Once you're connected to the annoying network, a simple way to test is:

$ host bsdnow.tv

If you get a response like:

bsdnow.tv has address 65.39.148.220

then you can continue reading. If not, and they're also blocking DNS, this method won't work. In such a case, your best bet is likely to spoof your MAC address to be the same as one of the connected clients, then forcefully spam deauth packets and take over their session. That's not very nice though. The tool we'll be using today is called "iodine" and it's in FreeBSD ports, OpenBSD ports and NetBSD pkgsrc - all under the "net/" category. Install it however you like on both the server and your client machine. The next step is to set up the DNS records for your domain. To keep things organized, we'll be creating the following two subdomains:

  • risc.bsdnow.tv, with an A record of "1.2.3.4" (you'll want the real IP of your server)
  • bankai.bsdnow.tv, with an NS record of "risc.bsdnow.tv"

How you set those up will vary greatly depending on your provider, so you'll have to figure that one out on your own. Next, we'll start the server half of the utility. Be sure you allow incoming traffic on port 53 in your firewall. Running sshd on a port like 443 will also increase your chances of being able to successfully tunnel out of the restrictive network. Now, on your server, run:

# iodined -u _iodined -t /var/empty -c -f -D -P password 10.0.0.1 bankai.bsdnow.tv

Debug level 1 enabled, will stay in foreground.
Add more -D switches to set higher debug level.
Opened /dev/tun0
Setting IP of tun0 to 10.0.0.1
Adding route 10.0.0.1/27 to 10.0.0.1
add net 10.0.0.1: gateway 10.0.0.1
Setting MTU of tun0 to 1130
Opened UDP socket
Listening to dns for domain bankai.bsdnow.tv

In this example, we'll be creating the "tun0" interface with an IP address of 10.0.0.1, and we'll use "password" as the authentication. You should probably use a better password, but keep in mind that it will be visible in the process list. To check that the interface was created correctly, run:

# ifconfig tun0

tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> metric 0 mtu 1130
        options=80000<LINKSTATE>
        inet 10.0.0.1 --> 255.255.255.224 netmask 0xffffffe0 
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
        Opened by PID 42283

You'll also want to make sure your /etc/ssh/sshd_config file does not have the "ListenAddress" line set to your public IP. The server component of iodine can be run in tmux, or as a daemon via /etc/rc.conf (on FreeBSD), /etc/rc.conf.local (on OpenBSD) or via /etc/rc.local. See the man page for more options. Now, switch over to the client system and run the following:

# iodine -f -u _iodined -t /var/empty -P password bankai.bsdnow.tv

Opened /dev/tun0
Opened UDP socket
Sending DNS queries for bankai.bsdnow.tv to 8.8.8.8
Autodetecting DNS query type (use -T to override).
Using DNS type NULL queries
Version ok, both using protocol v 0x00000502. You are user #0
Setting IP of tun0 to 10.0.0.2
Adding route 10.0.0.2/27 to 10.0.0.2
add net 10.0.0.2: gateway 10.0.0.2
Setting MTU of tun0 to 1130
Server tunnel IP is 10.0.0.1
Testing raw UDP data to the server (skip with -r)
Server is at 1.2.3.4, trying raw login: OK
Sending raw traffic directly to 1.2.3.4
Connection setup complete, transmitting data.

At this point, the server console should display something similar to this:

IN   login raw, len 16, from user 0
IN   ping raw, from user 0
IN   pkt raw, total 62, from user 0
IN   pkt raw, total 116, from user 0

Also remember to allow incoming/outgoing traffic on the "tun0" interface in your firewall (on both the client and server) if you haven't already. The tunnel should now be set up between the two systems, using only DNS to communicate. A simple way to see if it's working is with SSH, like so:

$ ssh -C 10.0.0.1

tj@10.0.0.1's password: 

OpenBSD 5.6 (GENERIC) #0: Sat Nov 1 16:25:49 EDT 2014

Welcome to OpenBSD: The proactively secure Unix-like operating system.

Please use the sendbug(1) utility to report bugs in the system.
Before reporting a bug, please try to reproduce it with the latest
version of the code.  With bug reports, please try to ensure that
enough information to reproduce the problem is enclosed, and if a
known fix for it exists, include that as well.

$ 

We'll use the "-C" flag for compression, since every bit is precious in this case. To verify you're connected through the tunnel, we'll see what IP we're logged in from.

$ w

 9:16PM  up 61 days, 21:46, 3 users, load averages: 0.34, 0.24, 0.18
USER    TTY FROM              LOGIN@  IDLE WHAT
tj       p0 10.0.0.1          9:16PM     0 w 

If you've gotten this far, that means it's all working properly. You can disconnect and set up a SOCKS proxy with SSH, then tunnel all your traffic through that. See our stunnel tutorial and SSH chaining tutorial for more information and interesting ideas.

Latest News

Two Year Anniversary

2015-08-08

We're quickly approaching our two-year anniversary, which will be on episode 105. To celebrate, we've created a unique t-shirt design, available for purchase until the end of August. Shirts will be shipped out around September 1st. Most of the proceeds will support the show, and specifically allow us to buy...

New discussion segment

2015-01-17

We're thinking about adding a new segment to the show where we discuss a topic that the listeners suggest. It's meant to be informative like a tutorial, but more of a "free discussion" format. If you have any subjects you want us to explore, or even just a good name...

How did you get into BSD?

2014-11-26

We've got a fun idea for the holidays this year: just like we ask during the interviews, we want to hear how all the viewers and listeners first got into BSD. Email us your story, either written or a video version, and we'll read and play some of them for...

EuroBSDCon 2014

2014-09-18

As you might expect, both Allan and Kris will be at EuroBSDCon this year. They'll be busy hunting down various BSD developers and forcing them to do interviews, but don't hesitate to say hi if you're a listener!...


Episode 190: The Moore You Know

2017-04-19

VideoHD VideoMP3 AudioOGG AudioTorrent This episode was brought to you by OpenBSD 6.1 RELEASED Mailing list post We are pleased to announce the official release of OpenBSD 6.1. This is our 42nd release. New/extended platforms: New arm64 platform, using clang(1) as the base system compiler. The loongson platform now supports systems with Loongson 3A CPU and RS780E...

Episode 189 Codified Summer

2017-04-12

VideoHD VideoMP3 AudioOGG AudioTorrent This episode was brought to you by Headlines Google summer of code for BSDs FreeBSD FreeBSD's existing list of GSoC Ideas for potential students FreeBSD/Xen: import the grant-table bus_dma(9) handlers from OpenBSD Add support for usbdump file-format to wireshark and vusb-analyzer Write a new boot environment manager Basic smoke test of all base utilities Port...

Episode 188: And then the murders began

2017-04-05

Direct Download:VideoHD VideoMP3 AudioOGG AudioTorrent This episode was brought to you by Headlines DragonFly BSD 4.8 is released Improved kernel performance This release further localizes cache lines and reduces/removes cache ping-ponging on globals. For bulk builds on many-cores or multi-socket systems, we have around a 5% improvement, and certain subsystems such as namecache lookups and...

Episode 187: Catching up to BSD

2017-03-29

Direct Download:VideoHD VideoMP3 AudioOGG AudioTorrent This episode was brought to you by Headlines NetBSD 7.1 released This update represents a selected subset of fixes deemed important for security or stability reasons, as well as new features and enhancements. Kernel compat_linux(8): Fully support schedsetaffinity and schedgetaffinity, fixing, e.g., the Intel Math Kernel Library. DTrace: Avoid redefined symbol errors when...