Test Ride
To get a feel for sods, its simple to try out:
git clone git://github.com/msantos/sods.git cd sods/sods ./configure make cd ../sdt ./configure make
Depending on your OS, you might need to adjust the Makefiles.
To test sods, you'll need to have an SSH server available somewhere and root privs on your test host. Start up the socket server:
$ sudo ./sods -d /tmp -L localhost:22 -vvv a.example.com
In another window, open an SSH session:
$ ssh -o ProxyCommand="./sdt -r 127.0.0.1 sshdns.a.example.com" 127.0.0.100
Real World SoDS
To use sods, you'll need a few things:
- A publicly addressable IP
- Something on which to run sods. The server doesn't need to be dedicated or high powered.
- A registered domain name
- A DNS server to host your domain
Well, that may seem to be waaaayyy too much bother, but it might not be as much work as it seems.
Publicly Available IP Address
You need an IP address that is reachable from the Internet or control of a device that can forward packets to your sods server.
The IP addresses the ISP assigns you tend to fall into 3 groups:
- the IP address is static and never (or rarely) changes
- the IP address changes infrequently, but the reverse lookup for the address is static
- the IP address and, consequently, the reverse address, changes frequently
You can work with any of these.
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:
OPTIONS="-D -L ssh.server1:22 -L ssh.server2:22 -L 65.55.21.250:22" DOMAIN="a.example.com"
/etc/init.d/sods:
#!/bin/sh /etc/rc.common # Copyright (C) 2006 OpenWrt.org START=50 BIN=sods DEFAULT=/etc/default/$BIN CHROOT_D=/var/chroot/sods start() { include /lib/network scan_interfaces config_load /var/state/network config_get ipaddr wan ipaddr [ -f $DEFAULT ] && . $DEFAULT [ ! -d $CHROOT_D ] && mkdir -p $CHROOT_D $BIN $OPTIONS -i $ipaddr $DOMAIN } stop() { killall 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 -o ProxyCommand="./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:
$ while [ "1" ]; do ssh -t -C -o ProxyCommand="./sdt sshdns.a.example.com" 127.0.0.100 "screen -drR sshdns"; done
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.