Build your own DNS Recursor with PowerDNS in five minutes

First rule of DNS: Always keep in separted machines your authoritative and recursor DNS server.

Disclaimer: The below notes are made on a fresh centos7 server. This is not an openresolver, is just for personal use. You need to adjust your settings.



PowerDNS is an amazing product. Has two flavors, one for Authoritative NS and one for Recursor. I always use @KeesMonshouwer RPMs for two reasons:

a. Works perfectly
b. I trust his work


  • Installation

    Let’s start, by installing the pdns-recursor:

    # rpm -ivh https://www.monshouwer.eu/download/3rd_party/pdns-recursor/el7/x86_64/pdns-recursor-3.7.2-1.el7.MIND.x86_64.rpm
  • User/Group

    Verify that you have the pdns User/Group, if not create them:

    # grep pdns /etc/group
    # grep pdns /etc/passwd
    pdns-recursor:x:996:996:PowerDNS Recursor:/dev/null:/sbin/nologin
  • root hint

    Create the hint (root NS) zone:

    # dig NS . @a.root-servers.net. | grep -vE '^;|^$'  | sort -V > /etc/pdns-recursor/root.hint

    I prefer to use and work with the opennicproject cause it’s an amazing community open DNS project. They also provide their own gTLDs and the majority of them dont have any logs at all or they anonymize the dns logs. In the times we are living, I prefer my DNS queries NOT to be obtained and recorded by companies.

    I strongly suggest to participate to this amazing community project.

    So my root.hint file is the result of this:

    # dig . NS @ | grep -v '^;' | sort -u -V  > /etc/pdns-recursor/root.hint

    Dont forget to edit your /etc/pdns-recursor/recursor.conf so that you tell pdns where is your root hint file:

  • ACL

    As i mentioned above, I dont want (at the current moment) to create an openresolver. So I need to create an ACL.

    That can be done by two ways (combined or separated).

  • iptables

    The first one is via iptables. My iptables default policy is DROP, so I need to ACCEPT tcp/udp traffic from the networks I want to provide dns recursion. The below example are for a specific IP and a class C (/24) network

    # TCP
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 53 -s XXX.XXX.XXX.XXX -j ACCEPT
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 53 -s YYY.YYY.YYY.0/24 -j ACCEPT
    # UDP
    -A INPUT -p udp -m state --state NEW -m udp --dport 53 -s XXX.XXX.XXX.XXX -j ACCEPT
    -A INPUT -p udp -m state --state NEW -m udp --dport 53 -s YYY.YYY.YYY.0/24 -j ACCEPT

    Dont forget to restart your iptable service.

  • ACL in pdns

    The second way is by configure the allow-from pdns setting accordingly:

    # vim /etc/pdns-recursor/recursor.conf
    allow-from=, XXX.XXX.XXX.XXX, YYY.YYY.YYY.0/24
  • Listen IP address

    PowerDNS Recursor will start on your local IP address. To change it to your public IP, you need to edit the below entry:

    # vim /etc/pdns-recursor/recursor.conf
    local-address=, XXX.XXX.XXX.XXX

    At this point you are ready to start and use your own DNS recursor.

    # systemctl status pdns-recursor.service
    # systemctl enable pdns-recursor.service
  • Testing

    Before you exit your machine, you need to test your DNS server.

    # dig soa powerdns.com @

    and from a machine inside your ACL:

    # dig soa powerdns.com @XXX.XXX.XXX.XXX

    Everything must work just fine.

Add comment

Fill out the form below to add your own comments