Pages

Wednesday, December 30, 2009

SoDS provides a covert method of bypassing firewall restrictions, obscuring traffic analysis and hiding your data by tunnelling it over DNS. SoDS was intended to be small, resource efficient, reasonably portable with few dependencies (at least on Unix) as well as taking basic precautions against misuse.

The IP address must be able to receive UDP packets on port 53 and send packets from port 53. If your ISP blocks port 53 (DNS), then you'll have to look around for another ISP, use a hosted service or maybe piggyback off of a friend.

A SoDS Server

You'll need sods to be running any time you might need it. SoDS doesn't require much in the way of resources, so I suggest using a low powered server that you can leave running all the time. The SoDS server might be the same device that you use for your gateway.
I use a Linksys WRT54gl as my home router and sods server. But any small, lower power device will do: I've also used a Linksys NSLU2, and, more recently, a Sheeva Plug.

A Registered Domain Name

If you're even thinking about setting this up, you probably already own a domain or two.

Another DNS Server

Finally, you will need another DNS server to delegate your domain name. This could be a DNS server you run on another IP address, a service provided by your registrar or one of the many free DNS services on the internet (there are a bunch, any of them should work, google for them).

Assuming your domain name is example.com with an IP address of 10.10.10.10, here is what you would have to set up.

If you have a static IP address (or one that doesn't change too frequently to be inconvenient), delegate a name server for a subdomain (in this example, "a"):

example.com. IN A 10.10.10.10
a IN NS example.com.

Some ISP's will change your IP, but maintain a consistent reverse DNS lookup for your IP address (something like a DHCP name). You can use this by setting a CNAME.

For example, if your IP address always resolves to:

macaddr-00-00-aa-bb-cc-dd.home.isp.com

You could set up your DNS entry as follows:

a.example.com. IN CNAME macaddr-00-00-aa-bb-cc-dd.home.isp.com.

Finally, if your ISP gives you a dynamic IP address, you can use one of the dynamic DNS services. Many of these services are free and will provide a consistent reverse DNS entry that you can exploit as with the previous example.

Set Up Your SoDS Server

Set up your sods server and point it to whatever SSH or tcp servers you're interested in. These servers don't have to be publicly exposed; they could be running somewhere behind your firewall.

SoDS is configured from the command line, but its easy to wrap it in a script for system startup. Here is an example for OpenWRT:
/etc/default/sods:

Accessing Your DNS Tunnel

So next time you are enjoying a venti americano in your local coffee shop, you may think to pause from chatting with the cute barista to fire up your laptop or other mobile device and login to IRC. We're geeks, it happens.

$ ssh -oProxyCommand="./sdt sshdns.a.example.com"127.0.0.100

Since UDP is innately unreliable, for best results, wrap the ssh command in a script that reconnects on failure. On the server side, if you are using ssh, running everything within a GNU screen session provides seamless access to your console, in case your connection drops. See the example scripts for more details, but basically, all you need to do is use a named GNU screen session on your ssh server:

SoDS Client

sdt will try not to overwhelm the local DNS server and will back off. Some DNS servers throttle chatty clients.

To add some reliability to the protocol, both the client and server track sent packets and will re-send if they are lost.

If you are having problems connecting, run with multiple "-v" switches to see what's going on. It'll fill your screen with debug messages but will eventually stop. To control the number of debug messages displayed, use the "-V" switch (it defaults to 100).

You can bounce your connection off of other DNS servers, beside your local DNS server, if they support recursion by using the "-r" flag. To see which servers sdt knows about, run:

sdt -v -h

To use a particular recursive server, choose it by name:

sdt -r google

To pick a random server, run:

sdt -r random

sods supports tunnelling using TXT, CNAME and NULL records. The default is TXT records. I've found that some ISP's re-write TXT records and many DNS servers in the wild do not support NULL records at all. Using CNAME's seems to work with most networks.

NULL records have the lowest encoding overhead and the specification allows for a large packet size, reducing overhead further. Since sods does not support TCP, large packets aren't supported.

If you are on a mobile device, you probably want to conserve your battery. sdt polls for data at regular intervals by sending a request to the local DNS server to flush any pending data from your SoDS server.

You can control this polling (without much effect on latency) by using the "-b" option. Every time data is received polling ramps up and slowly decays as no new data is recieved.

If you happen to be on linux, powertop is a great tool for fine tuning the polling intervals.

Files can be transferred securely over DNS by using sftp, see the "sdftp" script in the examples. If you're brave, you can also run a fuse filesystem using sshfs.

Yeah, sorry about that, the configure script isn't very smart. You can either install the openssl dev package (apt-get install libssl-dev) or just remove the "-DHAVE_SSL" and "-lcrypto" in the Makefile (SSL isn't a hard requirement for sdt).

To compiles sods for the WRT54GL, you'll need a cross compiler. I used the OpenWRT SDK:

http://wiki.openwrt.org/oldwiki/BuildingPackagesHowTo

It's sort of a pain to set up, so I put a compiled version of sods on github:

http://github.com/downloads/msantos/sods/sods-mips-wrt54gl.bz2

It's compiled for Kamikaze, hopefully it will work with newer versions. If you have to compile your own, it's easier to do it by hand, rather than using the Makefile:

thank you for your quick reply! unfortunately i still get the same error (User defined signal 1). im pretty new to compiling (ive only been using the automated make command so far), could you give me some suggestions as to how to compile it for tomato?

Awesome. About the bind error: you probably have another dns server (like dnsmasq) listening on port 53 on all interfaces. dnsmasq only needs to be listening on the LAN side and sods only needs to listen on the WAN side.

I start dnsmasq with the --bind-interfaces option and then start sods with -i $external_ip_address

Just add a sods (or nobody) user to /etc/passwd and a sods group to /etc/group. Also make sure the chroot directory exists (by default /var/chroot/sods). sods changes to an unprivileged user after startup.

if anyone else who wants to run sods on tomato is reading this, i found out you can't "forward" port 53 to the router with the webui (even though it says it's forwarded), you have to do it manually with iptables.

also, tomato rewrites iptables every time you change any settings or reboot, so you have to put this script in the webui (administration->scripts->firewall):

> I managed to get it running for one service (SSH) like this:> > server: sods -L 127.0.0.1:22 tun.mydom.com> client: sdt -t CNAME sshdns.tun.mydom.com> > What I would like to do now is run it for two services (HTTPS and SSH). If> I got it right, I have to use the "-L" switch several times:> > sods -L 127.0.0.1:22 -L 127.0.0.1:443 tun.mydom.com

Yup, that's right!

> But: how do I tell the client (sdt) which service to use?

Use the "-s" switch to sdt and the session number. The sessions arenumbered starting from 0, from left to right. So in your example, toconnect to port 22 you would use:

sdt -s 0 -t CNAME sshdns.tun.mydom.com

And to connect to port 443:

sdt -s 1 -t CNAME sshdns.tun.mydom.com

> If I have only one service (https), is it possible to omit the "ssndns"> prefix? Or is it always necessary?

No, you can use any prefix. I just use a single character to keep thebyte count down, something like s.tun.mydom.com.

> What do the client options "-D" and "-s" do? I read the client's help,> but I do not understand it.

-s: chooses the session to use (a session is the destination IP/port you want to proxy). Session 0 is the default.

-D: dynamic forwarding

"-D" is experimental. It lets the client tell the server which IPaddress/port it wants to go to. I'm thinking of setting up a service ona virutal machine somewhere so people won't have to through the hassleof installing sods and all the DNS entries.

The C version of sods doesn't support dynamic forwarding yet. The version(in Erlang) that does is here:

https://github.com/msantos/seds

> Sorry for these dumb questions.

Those were great questions, thanks for taking the time to put themtogether! And let me know if you run into any other problems.

thank you for your quick and detailed reply. I shortened down "sshdns" to a single character. Using the "-s" parameter and the session numbers also work as you explained, I can now use multiple services. :-)

For some reason which I haven't quite worked out yet, sdt on android is a bit flakey, so the first thing to try is rebooting your phone (I know, lame).

Here are some things you can try:

1. It looks as if the end to end connection to your sods server is good since you're seeing packets. Can you run sods in debug mode (sods -vvv) and paste the output here or email it to me? Feel free to sanitize the domain names.

2. Try specifying the IP of the dns server to rule out any problems in between (from an open network):

sdt -r x.x.x.x

3. And to rule out problems with Android, have you tested the tunnel on something besides the phone? What version of Android are you using?

I've used another IP over DNS program (not on the phone) and I found it best to set the "DNS Server" to be the actual server itself, rather than a real DNS server. When I do this with SDT I get a lot more packets through than going via google DNS but I get the same error.