Intro
Inspired by the HTTPS-DNS project I started to look for another approach for doing encrypted dns-requests. The following solution should work with nearly all unixoid operatingsystems ( for Microsoft Windows see below ) and can easily be applied. It works absolutly transparently for the clients and servers.
Encrypting DNS-requests is usefull, because it
- prevents manipulation of dns-requests
- prevents recognizing of dns-requests
- prevents logging of dns-requests
Implementation
The whole concept is based on socat for udp <-> tcp and stunnel for TLS-encryption between the clients and the dns-server.
On the serverside we have a normal dns-server running like bind, which is reachable on port 53. Now we use stunnel to create a new TLS-server on port 5667. stunnel forwards the packets on the localhost to socat, which forwards them to bind. You have to use socat because dns requests use udp but stunnel just supports tcp. But with socat we can forward udp to tcp, back and forth again.
On the clientside we configure socat to forward udp packets from port 53 to stunnel as tcp and stunnel to forward them to the server on port 5667. We then configure ure client to use the localhost as dns server.
Client
If you want your client machine to make dns-requests over SSL you have to install socat and stunnel .
Modify your /etc/stunnel/stunnel.conf to this:
sslVersion = SSLv3 chroot = /var/run/stunnel setuid = stunnel setgid = stunnel pid = /stunnel.pid socket = l:TCP_NODELAY=1 socket = r:TCP_NODELAY=1 socket = l:SO_LINGER=1:1 socket = r:SO_LINGER=1:1 client = yes verify=0 [dns] accept = 5666 connect = IPOFDNSSERVER:TLS-DNS-PORT # !!!!!!!!!!!!!!!!modify this!!!!!!!!!!!!!! TIMEOUTidle = 1 TIMEOUTclose = 1 TIMEOUTbusy = 1
and start the stunnel-daemon. Now start socat:
$socat udp4-listen:53,reuseaddr,fork tcp:localhost:5666
That's it! Test it with:
dig @localhost www.google.de
Now all you have to do is make your system use the localhost as dns server. This is very distributionspecific, so look at the doc of your distro. To permanently use TLS-DNS, make stunnel and socat start at boot.
Running Servers
The following servers offers SSL-DNS:
- 62.141.58.13 Port: 5353
- 88.84.155.209 Port: 5667
Setup a Server
If you are running a dns server and want to extend it to support SSL-DNS you can do this pretty easy. This won't conflict with your existing dns-server in any way. It has been tested on debian lenny with bind9. I expect in the following that you correctly installed your dns server and it is reachable by port 53.
For the stunnel-server you have to create a key:
$openssl req -new -x509 -days 3650 -nodes -out dns.pem -keyout dns.pem
, move it to /etc/stunnel/ and change its permissions to 600. Now configure your stunnel.conf like this:
cert = /etc/stunnel/dns.pem sslVersion = SSLv3 chroot = /var/lib/stunnel4/ setuid = stunnel4 setgid = stunnel4 pid = /stunnel4.pid socket = l:TCP_NODELAY=1 socket = r:TCP_NODELAY=1 socket = l:SO_LINGER=1:1 socket = r:SO_LINGER=1:1 [dns] accept = 5667 connect = localhost:53
Start stunnel and your SSL-DNS server is up and running. You do not need socat at the server, because bind9 is able to handle TCP requests.
Your server offers now:
DNS - port 53 TLS-DNS - port 5667
Windows
You need to use socat windows-port and stunnel for Windows.
Modify your stunnel.conf (Start -> Programs -> stunnel -> Edit Stunnel.conf) to this:
sslVersion = SSLv3 socket = l:TCP_NODELAY=1 socket = r:TCP_NODELAY=1 socket = l:SO_LINGER=1:1 socket = r:SO_LINGER=1:1 client = yes verify=0 [dns] accept = 5666 connect = IPOFDNSSERVER:TLS-DNS-PORT # For example 88.84.155.209:5667 TIMEOUTidle = 1 TIMEOUTclose = 1 TIMEOUTbusy = 1
and start the stunnel-daemon (run stunnel). Now start socat:
$socat udp4-listen:53,reuseaddr,fork tcp:localhost:5666
Now you need to go to your control panel and edit the network configuration. Put 127.0.0.1 as your favourite DNS server. Make sure its working, check it by opening some websites and then closing stunnel. With stunnel closed you shouldn't be able to continue browsing.