January 26th, 2005

hip

Geek diversion: tsocks

You're probably already familiar with ssh's portforwarding abilities — where ssh -L8000:somehost:80 otherhost will set up an encrypted tunnel where local connections to port 8000 will be tunneled through to otherhost and then connected to port 80 on somehost from there — and if you're like me you might even have a couple of shell scripts which establish ssh sessions that do nothing but tunnel (ssh -naxTfN -L3128:proxy:3128 somemachineatwork).

I found my list of forwarded ports was expanding a bit fast for my liking and was pleased to discover the -D option to OpenSSH. Invoking ssh -D portnum makes ssh act like a socks4 proxy, accepting socks proxy requests at the local end of the ssh session and tunneling them to the remote end where the requested connection is made. That way, I can point my web browser and IRC client and anything else socks-aware at the socks port I specify, and then they'll handle setting up tunnels to the multiple hosts I connect to, without requiring any additional software at the far end.

That's really handy and all, until you have an application that needs that sort of feature but doesn't speak socks — and that's where tsocks comes in. Tsocks is a transparent SOCKS proxy library that works via LD_PRELOAD. You preload libtsocks.so and your programs' TCP connections all magically end up going via the SOCKS proxy you've configured tsocks to use (or you can just use the included tsocks command to do the preload step for you).

So not only do you have ssh dynamically establishing tunnels for you, suddenly almost everything you have knows how to use them! There are a couple of gotchas, the big one being DNS not being proxied by default (since it's UDP), but it's a great way to get ssh tunnels that always Just Work even if you didn't think you needed the tunnel when you set up all your other tunnels.