How to setup a DNS server with PowerDNS on Raspberry Pi

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.

  • Patrick

    Thanks very much!! This has made my network setup much more organised.

  • bastb

    Thanks for this howto. Is there any reason why reverse lookups weren’t included?

    • Ben Hanna

      No, reverse lookups should work fine with it. I just didn’t bother to mention them.

  • Aldo Mendez Reyes

    Everithing works, much the same until I configure my own Zones, after that not even can be reached by nslookup

    • Ben Hanna

      Looks like I may have been missing a configuration line. Try running the following and restart the service. This tells PowerDNS to allow recursive DNS queries (, etc.) from IPs in your local network.

      sudo sed -i ‘s/allow-recursion=,’ /etc/powerdns/pdns.conf

  • root

    On your pdns.conf you also need to add to this line your network address.


    So that your network will be allowed to recurse domains which are not registered on the zone.

    • Ben Hanna

      Ah, thanks for that I must have overlooked it. The article has been updated to reflect that change.

  • Jose Warez

    One quick note, if you are having trouble connecting check out your router settings. I was able to do the nslookup locally, but if I went to another machine then I could not get it to work. I use DD-WRT and it was a quick change that had to be made.

  • wdh

    Firstly, let’s just get this out in the open – I’m probably out of my league trying to do this, but I’d like to figure it out! Anyway, I’d like to be able to configure the recursor to point back to the same DNS that my ISP uses when configured through DHCP. The DNS seems to be dynamic, but I can’t find any way to determine the DNS it uses, as, I’m thinking that’s the right DNS to recurse through. Make sense? Any idea how to find this name/address?

    • Per Lundberg

      Are you really sure it’s dynamic? That sounds quite uncommon to me (but it does occur). How about just picking one of their DNS:es and go with it, regardless of what the DHCP gives you? Have you tried with that?

  • Peter


    thanks for this tutorial. But i have a problem. When i run “sudo service pdns restart” i am getting this error

    Segmentation fault

    Restarting PowerDNS Authoritative Name Server: pdnsIllegal instruction



    Why? :)


  • Chris Young

    Very clear, very helpful tutorial. Tells you what to do and why you are doing it. Great stuff.

  • Chris Young

    In the line:

    sudo sed -i ‘s/allow-recursion=,’ /etc/powerdns/pdns.conf

    Should point out that needs to match the subnet identifier of your local network. Mine in for example.

  • Peter

    very good tutorial. I found it is missing the setting launch=bind

  • Peter

    you also need to add bind-config=/etc/powerdns/backbind.conf to pdns.conf

  • smartroad

    I have followed this, first changing the and then again without changing it and I end up with the same issue, when I run the ‘nslookup localhost” I don’t get my IP ( in my case) I get

    like I say I have followed this to the letter and it doesn’t seem to work, what have I got wrong?

  • dpstanfill

    I am getting an error ;; Got SERVFAIL reply from, trying next server
    ;; connection timed out; no servers could be reached.

    If I query outside my domain then it works

  • Per Lundberg

    Thank you! Very good blog post, especially for those of us with some experience of setting up DNS with other servers, e.g. Bind. Helped me to get going! :)

  • busterobservatory

    My config in raspberry with powerdns and webserver
    When I in my lan in another PC put in browser http://rpiarchive this address go to admin panel of router,
    Whats wrong, how can i fix this?

  • Ted Leahy

    I’m getting a similar error to dpstanfill:

    ;; Got SERVFAIL reply from, trying next server
    ;; Got SERVFAIL reply from, trying next server

    Server: localhost

    ** server can’t find SERVFAIL

    I’m also running an apache server on the raspberry pi, the IP address of which I mapped to Could this be causing the problem?

    Thanks in advance!

  • Phil Mordecai

    I have to admit I installed pdns a while ago, then did nothing with it, and only got around to really trying to set it up today. Even though this is a Raspeberry Pi-focussed tutorial, I am trying to run my installation on a machine running Peppermint Linux (which like Raspian on the Pi is Debian-based). I wish to use pdns as a slave to another DNS server running on a Windows 2003 host and have added slave=yes to pdns.conf and have defined the zone in bindbackend.conf.

    I have specified the IP address of my pdns host as a slave on the Windows server DNS so that it will accept zone transfer requests from this machine. However if I try to send a NOTIFY from the Windows server or restart pdns on the slave host and I check var/log/syslog I see the following error:-

    Initiating transfer of ‘mydomain.internal’ from remote ‘Windows server IP address’
    AXFR started for ‘mydomain.internal’, transaction started
    Unable to feed record during incoming AXFR of ‘mydomain.internal’: Unable to open temporary zonefile ‘/etc/powerdns/bind/mydomain/internal.bak.1498860937’: Permisson denied

    I’m assuming this is a permissions issue with the /etc/powerns/bin directory, but do not know what the rights should be, or how to change them.

    Any assistance would be appreciated.

    *update* Looks like the issue was with the rights to the /etc/powerdns/bind directory itself. I deleted the file I had originally created in /etc/powerdns/bind , went back up to /etc/powerdns and then ran “chmod o+w bind” and then restarted the service. This time there were no errors in /var/log/syslog and I have a shiny new zone file sitting in the /etc/powerdns/bind directory which I can now resolve from :o)

  • Amal

    The best tutorial in this domain with to-the-point instructions .

    But I have a couple of questions.

    What exactly is the mentioned here? Do I want to own it?

    If I use a dynamic dns on my Raspberry Pi,

    does the IP address must be changed to or something like that

    Does the A and CNAME records must be added to bottom of the zone file @ /etc/powerdns/bind/

    It would be very nice if you clarified these.

    Regards Amal