Sick of always typing in IP addresses for machines on your network? In this tutorial I'm going to show you how to setup a home DNS server using your Raspberry Pi. For this tutorial we will assume that you are starting out with a fresh copy of Raspbian.

Installing PowerDNS

For running a DNS server on Linux there are couple different programs you could use such as Bind9 or djbdns. But in this particular case we're going to use one called PowerDNS. While Bind9 is easily the most widely used it can also be heavier on resources and more complex to set up. I chose PowerDNS because it's a lot lighter, does just as good a job, and has support for many different configuration backends (MySQL, SQLite, LDAP).

Thankfully PowerDNS is included in Debian repositories. Note there's also pdns-recursor package which separately provides DNS caching but we're not going to install that because it's currently unavailable in the Raspbian repositories. So we're just going to go ahead and install the DNS server.

sudo apt-get install pdns-server

For this tutorial we're just going to use the Bind9 backend that gets installed with PowerDNS by default. This backend basically allows us to write our zone configurations using Bind9's syntax since PowerDNS knows how to read them. Thus, if you were moving off of Bind9 you could still use your old zone files or if you wanted to move to Bind9 later on then your zone files would already be in the correct format.

Configuring a recursor

Before we start setting up our zone file we need to configure our recursor. The recursor is the DNS server that will handle queries which our DNS server doesn't have zone configurations for (,, etc.). So in the next command we're going to use sed to set the recursor in /etc/powerdns/pdns.conf to Google's Public DNS (

sudo sed -i 's/# recursor=/recursor=' /etc/powerdns/pdns.conf
sudo sed -i 's/allow-recursion=,\/24/g' /etc/powerdns/pdns.conf

Now that recursor has been configured we're going to restart the pdns service and also install dnsutils so we can test it.

sudo service pdns restart
sudo apt-get install dnsutils

To confirm that recursion against our DNS server we'll execute the following query for against it.

nslookup localhost

If you get a list of names and addresses back then everything is configured and working properly.

Configuring a zone

So now we'll move onto configuring our own zone. You can think of a zone as basically your domain name ( With Bind9, you generally have a configuration file that declares all of your zones and then the actual records for those zones are stored in separate files. PowerDNS uses /etc/powerdns/bindbackend.conf as it's main configuration file for Bind9. So let's open that up and we'll create a zone like the following.

zone "" {
        type master;
        file "/etc/powerdns/bind/";
        allow-update { none; };

You'll want to replace with whatever you want your domain to be. Note that if you're just doing this for your home internal network then you don't need to actually own the domain you use. So you can effectively call it whatever you want (home.lan,, example.lan, etc.). Now you'll notice we made a reference to a file called /etc/powerdns/bind/, this is where our DNS records for will go. First we'll create the /etc/powerdns/bind folder.

sudo mkdir /etc/powerdns/bind

Next let's go ahead and create /etc/powerdns/bind/ with the following.

$ORIGIN     ; base for unqualified names
$TTL 1h                 ; default time-to-live
@                       IN      SOA (
                                1; serial
                                1d; refresh
                                2h; retry
                                4w; expire
                                1h; minimum time-to-live
                        IN      NS      ns
                        IN      A
ns                      IN      A

In this zone file we've setup a couple of basic things. Note that is the IP address of my server, substitute it with whatever the IP is of the server you've installed it on. The first record is the SOA (Start Of Authority) record. This tells the DNS server what the primary data source is for the zone and how it should propagate. After that we setup an NS (nameserver) record. The job of this record is to point to our authoritative DNS server for the zone, which happens to be this server. We then have an A record for the zone itself so that -> And then after that I have another A record so that ->

Now if we restart PowerDNS and use nslookup we can verify that it's working correctly.

sudo service pdns restart
nslookup localhost

A successful response should return the IP that you mapped to (in my case it would be

Adding a new record

The basic zone and the DNS server are all setup at this point so in order to add a new record we can append a line like this to the zone file.

webserver               IN      A

Most of the time there are two types of records you'll be adding. As we've already seen an A record always maps to an IP. A CNAME record is used when want to map an alias to another record. For example look at the following.

webserver               IN      A
www                     IN      CNAME   webserver

What I've done there is map -> and then mapped -> It's essential to learn to use CNAME records effectively because if the IP for had changed and I had used two A records then I'd have to update both records. However, using an A and a CNAME I'd only have to update the IP for

After you're done adding your records just restart the pdns service to bring in the changes.

Now all you have to do in order to start making use of your DNS server is to just set the DNS of your workstation to your new DNS server's IP.


comments powered by Disqus