It is no secret to power Internet users that DNS resolution is one of the factors that mostly affect the performance of our Internet browsing, and sometimes even a very fast broadband can become a pain if a poor DNS service is used. DNS -which stands for “Domain Name System“- is a protocol which makes use of a networked database, plus a particular set of services for querying that database, with the main function of translating human friendly, symbolic hostnames such as “www.google.com”, into the numerical addresses or IP‘s of the machines hosting a website or service accessible from the Internet or, generally speaking, a typical network. Fast DNS servers, usually, make for a better user experience thanks to a faster Internet browsing, even with today’s fast broadband services. With today’s media-rich websites, social networks and content mashups, in fact, each time a web page is downloaded chances are that the page contains references to images or other content hosted on several different hosts, and therefore accessible from different hostnames / domain names. While sometimes developers may make this happen in purpose so that browsers can benefit from parallel downloading (see Steve Souders‘ famous 14 rules for faster loading web sites), since each hostname requires a trip to the DNS server, already just a few different hostnames can negatively affect the overall page loading time if a low performing DNS server is used.

ISP’s usually offer their own free DNS together with their Internet connectivity service; this is what most people normally use, and in many cases this may be just OK. However, the DNS service offered by ISP’s is often poor when it comes to performance. Luckily, nowadays there are quite a few alternative, more specialised DNS services which are also freely available and that usually offer either improved performance (thanks to smarter caching and a generally better setup/design) or additional features that go beyond the simple DNS resolution but that make use of DNS -most importantly, improved security with filters at DNS level that prevent users from reaching known malicious sites, protecting them against phishing and other threats . Some of these free services only promise to deliver better performance, such as Google Public DNS and DNS Advantage by UltraDNS, while others – such as Norton DNS or Comodo Secure DNS focus mainly on the security benefits of having an active filtering at DNS level.

Then, among the more popular ones, there is also OpenDNS, that does it all. This was likely the first specialised DNS service and remained basically the only one of its kind for a while, until several others spotted the significant potential of services based on DNS as well as new revenue opportunities. OpenDNS and others offer most of their services for free, while making money with “premium” services with additional features, as well as through NXDOMAIN hijacking: when a request is made for an unresolvable domain name, the browser won’t show the usual, expected error message; instead, as OpenDNS intercepts and processes the requests, it detects that the domain name cannot be resolved (or that the actual website isn’t loading at the time) and by default redirects the user to their OpenDNS Guide page with search results based on the mistyped or wrong domain name… plus some lovely ads, of course. This is a somewhat clever trick that makes them some decent money and therefore it shouldn’t surprise that others have copied it, competitors as well as many ISP’s who can’t miss the opportunity to make some more money the easy way. However this approach by ISP’s has often been criticised, since while OpenDNS makes it pretty clear how they make money out of their free DNS service, most others do not.

Out of the several DNS services around these days, OpenDNS still remains the most feature-rich of them all. Not only it still offers the best DNS performance in many locations (as is the case for me in London, UK), it also offers quite many other features that can be particularly useful when managing a network of computers or if you have small kids, thanks to security filtering and parental control. I recommend you to create an account (it’s free!) and configure the appropriate settings for your network(s) through their excellent dashboard, if you are interested in these features.

Regardless of which DNS server you use, it is still possible to improve your DNS experience, thus your Internet browsing, a further bit by setting up a local DNS server to use as a cache. Some may argue that most operating systems and browsers already cache DNS query results locally, but while this is true, I have found that a local DNS server used as a cache still helps improve things, especially, of course, if this cache can also be shared with other clients in the same network (at home I use a local DNS cache as well as a caching proxy, Squid, to improve the overall browsing performance of my home clients).

Setting up a local DNS server is pretty easy and quick on Unix systems, provided you are familiar with the terminal. Here we’ll see how to do this on Snow Leopard, but it shouldn’t be too different on other Unix flavours once you have installed the DNS server we are going to use, BIND, with your package manager of choice (for Windows desktops, there was once upon a time a simple DNS server called TreeWalk DNS, but the project seems to have been abandoned years ago and the website is currently listed as malicious by Norton for some reason).

BIND is already installed on Mac OS X, although it is switched off by default. For starters, to prevent users on remote systems form being able to access and control our local BIND server, we need to make sure that a secret key is used to explicitly grant privileges to a host. BIND requires a daemon called named to be running on the system, while the utility rndc will take care of the administration of this daemon with commands that will only work if the keys specified in the two configuration files /etc/named.conf and /etc/rndc.conf match.

It is possible to automate this little configuration and create a key file by executing the command

sudo rndc-confgen -a

Since BIND expects the key to be in /etc while the command above creates the key in /private/etc (at least on Snow Leopard 10.6.5), you can either

sudo mv /private/etc/rndc.key /etc/rndc.key

or

sudo vim /etc/named.conf

and change the line include “/etc/rndc.key”; to include “/private/etc/rndc.key”;

Update: as reader David Glover reminds me in the comments, there is no need to move the file /private/etc/rndc.key to /etc/rndc.key since /etc is already a symlink to /private/etc; I can’t remember why I had done that while getting BIND to work on my system, but you should be able to safely skip that step. Thanks David.

Next, we need to tell BIND which DNS servers it has to forward to any queries that it cannot answer directly either because they resolve yet locally unknown domain names or because the cached results have expired.

Open the file /etc/named.conf as sudo (unless you have it opened already from the previous step) with vim or your favourite editor, and add the following lines to the options section:

forwarders { 208.67.222.222; 208.67.220.220; };

In this example, I am using OpenDNS’ servers, but you can use Norton’s public DNS (198.153.192.1, 198.153.194.1), Google Public DNS (8.8.8.8, 8.8.4.4), UltraDNS (156.154.70.1, 156.154.71.1) or whichever other DNS servers you prefer or that work best for you.

Now, depending on the version of OS X you are using, you may need or not to create the following – just skip this if you already have the folder /System/Library/StartupItems/BIND.

sudo mkdir -p /System/Library/StartupItems/BIND sudo nano /System/Library/StartupItems/BIND/BIND

Copy the following lines in the file you’ve just created (unless it was already there), and save.

#!/bin/sh . /etc/rc.common if [ "${DNSSERVER}" = "-YES-" ]; then /usr/sbin/named fi

Then make it executable

sudo chmod +x /System/Library/StartupItems/BIND/BIND

In the same folder, create the file

sudo vim /System/Library/StartupItems/BIND/StartupParameters.plist

and copy the following lines in it:

{ Description = "DNS Server"; Provides = ("DNS Server"); OrderPreference = "None"; Messages = { start = "Starting BIND…"; stop = "Stopping BIND…"; }; }

By default, the DNS server is set not to start at boot. Let’s change that by opening the file

sudo vim /etc/hostconfig

and changing the content so that it contains the line

DNSSERVER=-YES-

Save, then either reboot or load BIND manually for the current session with

sudo /System/Library/StartupItems/BIND/BIND

At this stage BIND should be up and running, but it is not used yet. You will need to go to System Preferences > Network > Advanced > DNS, and replace all the current DNS servers with the only 127.0.0.1 so that your local DNS server is used instead. To make sure this is working as expected, type in your terminal

scutil --dns

You should see an output similar to this:

DNS configuration resolver #1 domain : config nameserver[0] : 127.0.0.1 order : 200000 ....

Another thing that may be useful to know is how to flush the DNS cache should you need to do so for any reason:

sudo rndc -p 54 flush && dscacheutil -flushcache

You should now have and be using a local DNS cache and your Internet browsing should feel faster. Please let me know in the comments if this is the case for you as well or whether you see different results.