I’ll explain here how to redirect every DNS query your Linux system does through an SSH tunnel. I’ll be using this *wonderful* tool to make that trick:
$ sudo apt-get install socat
Screw yum and … worst! pacman :P (hw :*)
You’ll need an endpoint (server side) where your DNS queries will be rerouted. This will be the SSH tunnel endpoint. Now, how to do it:
Client Side
Start this command in the background. You can either use an init script or /etc/rc.local or whatever mechanism you like.
$ sudo socat udp-recvfrom:53,reuseaddr,bind=127.0.0.1,fork tcp:127.0.0.1:5377
So, we create an UDP socket on 127.0.0.1:53 (this is why you need root access), magically transform all traffic to TCP and sending it to 127.0.0.1:5377. This port (5377) can be whatever you want over 1024. It’s the local port of your SSH tunnel. Easy, UDP->TCP with a one liner :).
Then, start your SSH tunnel (-f -N makes SSH go to background and not execute remote command):
$ ssh -f -N -L 5377:localhost:5377 <server_addr>
Server Side
On your remote endpoint, simply redirect the TCP packet to a normal UDP datagram that will be sent to a DNS server:
$ sudo socat tcp4-listen:5377,reuseaddr,fork,backlog=50,bind=127.0.0.1 UDP:8.8.8.8:53
The example above is redirecting it to the famous Google DNS at 8.8.8.8. Feel free to use whatever DNS server you want.
The backlog=50 option is the size of listen(2) queue. Here 50. When you have thunderbird starting with 6 RSS feeds and 7 email accounts, trust me, there is a LOT of DNS queries sent through this tunnel.
Finally, change your /etc/resolv.conf. Put nameserver 127.0.0.1
VoilĂ !
Linux DNS query over TCP
I made a bit of research on how to make a Linux box use TCP instead of UDP for DNS resolution. The res_init() function (see resolver(5)) is part of the libc resolv component and reads the configuration file resolv.conf(5) to get default domain name, search order, name server address(es) and various options.
With the libc 2.14+, the RES_USEVC option support is added to res_init(). Just add options use-vc to the resolv.conf(5) file and TCP will be used by default for the entire system.
From there, it’s easier to reroute DNS traffic.
$ sudo ssh -f -N -L 53:8.8.8.8:53 <server_addr>
Cheers!
FIN
David
For anyone else using Archlinux <3
pacman -S socatty.