How to configure DNS bind9 configuration in Ubuntu

 

Recently, I need to learn about DNS system. In fact, I have not considered about this system so far. To understand about this as the begineer. I will memorize how to configure simply.

 

1. Pre-requisite.

I have four servers with Ubuntu 16.04 in AWS. Each server has the Public IP address.

 

2. Installation of bind9 packages

 

In fact, I do not know anything at this time. I need some instructions. I will follow this instruction basically. At first I need to update hosts name.

# hostname ns1

hostname ns2

hostname ns3

And I will update repository and install the bind packages like below. I will repeate this step in each servers, ns2 and ns3 also.

# apt-get update

sudo apt-get install bind9 bind9utils bind9-doc

Installation is completed. I can see the directory and files under /etc/bind directory.

# ls /etc/bind
bind.keys  db.127  db.empty  db.root     named.conf.default-zones  named.conf.options  zones.rfc1918
db.0       db.255  db.local  named.conf  named.conf.local          rndc.key

 

3. Configuration Primary DNS Server

 

At first, I will edit "named.conf.options". In this file, I will add some options to work well as the DNS server. This configuration is not applied to only primary. I will edit all of servers. 

# For Caching DNS server

acl "trusted" {
        10.10.0.72;
        10.10.0.99;
        10.10.0.39;
}

options {
        directory "/var/cache/bind";

        recursion yes;
        allow-recursion { trusted; };
        listen-on port 53 { 10.10.0.72; };
        allow-transfer { 10.10.0.99; 10.10.0.39; }; 
        forwarders {
                8.8.8.8;
                8.8.4.4;
        };
};

# For Authoritative DNS servers

options { 
        directory "/var/cache/bind"; 

        recursion no;  
        listen-on port 53 { 10.10.0.72; }; 
        allow-transfer { 10.10.0.99; 10.10.0.39; }; 
};

In above, there is "acl" field. It is the represatative name for allow-recursion. "recursion yes" means enable the recurive query from other DNS servers which is defined in "allow-recursion". In this instrucion, It shows what the recursive query is.

In this instruction, it is more simple contexts comparing with "iterative request".

If I do not want to use this recursion, I can change to "recursion no;" In my case, my authoritative DNS servers will be end of step for Domain. So I will disable the recursion. "allow-transfer { 10.10.0.99; 10.10.0.39; };" means transfering zone file to listed DNS servers which are refered as slave servers. 

# Master DNS (Authoritative DNS) server

options {
        directory "/var/cache/bind";

        recursion no;
        listen-on port 53 { 10.10.0.72; };
        allow-transfer { 10.10.0.99; 10.10.0.39; };

        dnssec-validation auto;

        auth-nxdomain no;    # conform to RFC1035
        listen-on-v6 { any; };
};

# Slave DNS (Authoritative DNS) servers

options {
        directory "/var/cache/bind";

        recursion no;
        listen-on port 53 { 10.10.0.72; };

        dnssec-validation auto;

        auth-nxdomain no;    # conform to RFC1035
        listen-on-v6 { any; };
};

After these configurations, I can check the configuration is correct or not.

# service bind9 restart

# # named-checkconf named.conf.options

If I do not get any answer or failed message, It works correct. In above, I defined "allow-transfer" like "allow-transfer { 10.10.0.99; 10.10.0.39; };". This parameter is the global value. Therefore, it is applied for all of zone files. It need to be limited sometimes. In the instructionallow-transfer { none; }; is recommended.

# Master DNS (Authoritative DNS) server

options { 
        directory "/var/cache/bind"; 

        recursion no; 
        listen-on port 53 { 10.10.0.72; }; 
        allow-transfer { none };

        dnssec-validation auto; 

        auth-nxdomain no;    # conform to RFC1035 
        listen-on-v6 { any; }; 
}; 

# Slave DNS (Authoritative DNS) servers

options { 
        directory "/var/cache/bind"; 

        recursion no; 
        listen-on port 53 { 10.10.0.72; }; 

        dnssec-validation auto; 

        auth-nxdomain no;    # conform to RFC1035 
        listen-on-v6 { any; }; 
}; 

I will define "allow-transfer" in "named.conf.local" individually in every zone difinition. I will edit the "named.conf.local". It looks like below.

# Master DNS (Authoritative DNS) server

zone "dizigo.shop" {
    type master;
    file "/etc/bind/zones/db.dizigo.shop";
    allow-transfer { 10.10.0.99; 10.10.0.39; };
};
zone "10.10.in-addr.arpa" {
    type master;
    file "/etc/bind/zones/db.10.10";
    allow-transfer { 10.10.0.99; 10.10.0.39; };
};

# Slave DNS (Authoritative DNS) servers 

zone "dizigo.shop" {
    type slave;
    file "db.dizigo.shop";
    masters { 10.10.0.72; };
};
zone "10.10.in-addr.arpa" {
    type slave;
    file "db.10.10";
    masters { 10.10.0.72; };
};

In above, I defined "forward zone" and "reverse zone". (Please this does not mean zone file) I suppose the one of 10.10.0.0/16 ip addresses will be mapped with Domain. In this file, It show how many zone file are existed and the each properties. I wrote 2 types of configuration for master and slave. In this "master", I can define "allow-transfer { 10.10.0.99; 10.10.0.39; };" in each zone definition. (Even if I will explain later in this post) In "slave", I can define "masters" as the source.

I will locate the zone file under "/etc/bind/zones". If you do not have zone directory, I need to create before.

# mkdir -r /etc/bind/zones

After these configurations, I can check the configuration is correct or not.

# service bind9 restart

# named-checkconf named.conf.local

named-checkconf

 

3. Createing the Forward and reverse zone files.

 

Under the "/etc/bind" directory, there is the sample file for these.

# Forward zone file sample

root@ns1:/etc/bind# cat /etc/bind/db.local
$TTL    604800
@       IN      SOA     localhost. root.localhost. (
                              2         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
@       IN      NS      localhost.
@       IN      A       127.0.0.1
@       IN      AAAA    ::1

# Reverse zone file sample 

root@ns1:/etc/bind# cat /etc/bind/db.127
$TTL    604800
@       IN      SOA     localhost. root.localhost. (
                              1         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
@       IN      NS      localhost.
1.0.0   IN      PTR     localhost.

I will copy and edit this files for my zone file. This step is depends on your environments. It will be different from me

# cp db.local /etc/bind/zones/db.dizigo.shop

# cp db.127 /etc/bind/zones/db.10.10

Open the forward zone file and edit at first. It looks like below.

$TTL    60

@       IN      SOA     ns1.dizigo.shop admin.dizigo.shop. (

                              3         ; Serial

                         604800         ; Refresh

                          86400         ; Retry

                        2419200         ; Expire

                         604800 )       ; Negative Cache TTL

 

; name servers - NS records

       IN      NS      ns1.dizigo.shop.

       IN      NS      ns2.dizigo.shop.

       IN      NS      ns3.dizigo.shop.

 

; name servers - A records

ns1.dizigo.shop.       IN     A    10.10.0.72

ns2.dizigo.shop.       IN     A    10.10.0.99

ns3.dizigo.shop.       IN     A    10.10.0.39

 

; sample - A records

www.dizigo.shop.       IN     A    10.128.100.101

ftp.dizigo.shop.       IN     A    10.128.200.101 

I edit the TTL time for caching. If there is the caching DNS server in front of these authoritative DNS servers, the Caching server does not ask again during this time. I will adjust for 60 seconds. Serail number is increased. Every time, I edit zone file, I have to increase this number. This number is used for the slave servers to determince download zone file or not. I added all of name servers in end of SOA field.  For reverse zone file, it is similar with forward zone file. It looks like below.

$TTL    60
@       IN      SOA      ns1.dizigo.shop. admin.dizigo.shop. (
                              2         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL

; name servers - NS records
       IN      NS      ns1.dizigo.shop.
       IN      NS      ns2.dizigo.shop.
       IN      NS      ns3.dizigo.shop.

; PTR Records
72.0      IN   PTR  ns1.dizigo.shop.
99.0      IN   PTR  ns2.dizigo.shop.
39.0      IN   PTR  ns3.dizigo.shop.

Most of values are same. Add all of name servers end of SOA field, then add PTR records. After all of these, I can check my configuration.

# named-checkconf

# named-checkzone dizigo.shop ./zones/db.dizigo.shop

zone dizigo.shop/IN: loaded serial 3

OK

 

# named-checkzone 10.10.in-addr.arpa ./zones/db.10.10

zone 10.10.in-addr.arpa/IN: loaded serial 2

OK

If there are no errors, I will restart the daemon.

# service bind9 restart

 

4. Configuration Secondary(Slave) DNS Server

 

I will do these on ns2 and ns3 in my case. It is almost same as the master DNS server. I have already written above. For "named.conf.options",

# Slave DNS (Authoritative DNS) servers

options { 
        directory "/var/cache/bind"; 

        recursion no; 
        listen-on port 53 { 10.10.0.72; }; 

        dnssec-validation auto; 

        auth-nxdomain no;    # conform to RFC1035 
        listen-on-v6 { any; }; 
}; 

For "named.conf.local",

# Slave DNS (Authoritative DNS) servers 

zone "dizigo.shop" { 
    type slave; 
    file "db.dizigo.shop"; 
    masters { 10.10.0.72; }; 
}; 
zone "10.10.in-addr.arpa" { 
    type slave; 
    file "db.10.10"; 
    masters { 10.10.0.72; }; 
}; 

In this "named.conf.local", the file field is not a certain path. Now, I have slave DNS servers.

 

5. Verfication the Master and Slave DNS server.

 

Before I verify this. I need to download zone file from master to slave. On slaves, I run this command.

rndc reload
server reload successful


# ls -la /var/cache/bind/
total 24
drwxrwxr-x  2 root bind 4096 Sep 11 19:20 .
drwxr-xr-x 10 root root 4096 Sep 11 08:52 ..
-rw-r--r--  1 bind bind  411 Sep 11 19:12 db.10.10
-rw-r--r--  1 bind bind  420 Sep 11 19:12 db.dizigo.shop
-rw-r--r--  1 bind bind  821 Sep 11 19:20 managed-keys.bind
-rw-r--r--  1 bind bind  512 Sep 11 19:20 managed-keys.bind.jnl

In the /var/cache/bind/, I can see the zone file downloaded. Now I can Domain lookup from remote clients.

# dig +short ns2.dizigo.shop @54.180.126.68
10.10.0.99
# dig +short ns1.dizigo.shop @13.125.70.251
10.10.0.72

 

6. Create Caching DNS server without zone file (Only Forwarding caching DNS server)

 

Now, I create the Caching DNS server in front of Authoritative DNS servers. I will refere this instruction. Most of steps are similar with above. I have already written above. 

# For Caching DNS server

acl "trusted" { 
        10.10.0.72; 
        10.10.0.99; 
        10.10.0.39; 
} 

options { 
        directory "/var/cache/bind"; 

        recursion yes; 
        allow-recursion { trusted; }; 
        listen-on port 53 { 10.10.0.72; }; 
        allow-transfer { 10.10.0.99; 10.10.0.39; }; 
        forwarders { 
                8.8.8.8; 
                8.8.4.4; 
        }; 
};

In the instrucion, there is another term, "allow-query". This is same with "allow-recursion". So In my case I will use again in this post. I need to define "forwarders" which point to DNS server whiech handdle the recursive query. In my case, the authoritative DNS servers are listed in here

At this time, I want to make this Caching server to work as forwarder (This server does not response against the query reqeust itself). So I will add "forward only;" option. Final thing I need to edit is dnssec. In fact, I do not know what this is exactly. Anyway, this part make the server and client more secure. So, the my configuration of "named.conf.opiton" look like below.

acl trusted {

        10.10.0.37;

        178.128.21.101;

        49.174.202.137;

};

options {

        recursion yes;                 # enables resursive queries

        allow-recursion { trusted; };  # allows recursive queries from "trusted" clients

        listen-on port 53 { 10.10.0.37; };   # ns1 private IP address - listen on private network only

        allow-transfer { none; };      # disable zone transfers by default

        forwarders {

               10.10.0.99;

               10.10.0.72;

        };

        forward only;

        dnssec-enable yes;

        dnssec-validation yes;

        auth-nxdomain no;    # conform to RFC1035

        listen-on-v6 { any; };

};

After this configuration, I need to check the configuration with "named-checkconf" and restart bind

# named-checkconf

# service bind9 restart

 

7. Verfication of Caching server (Clean cached DB)

 

In this blog, there is the way to view cahce status. 

# Run Command

# rndc dumpdb -cache

 

# Log messages (Error)

Sep 13 14:38:25 cache kernel: [195574.027929] audit: type=1400 audit(1568385505.800:83): apparmor="DENIED" operation="mknod" profile="/usr/sbin/named" name="/named_dump.db" pid=25682 comm="named" requested_mask="c" denied_mask="c" fsuid=112 ouid=112
Sep 13 14:38:25 cache named[25678]: received control channel command 'dumpdb -cache'
Sep 13 14:38:25 cache named[25678]: could not open dump file 'named_dump.db': permission denied

This error happend due to permission of file location which is created by the command. Therefore, I need to re-define the path for the dump file in the configuration. Please read this instruction.

acl trusted {

        10.10.0.37;

        178.128.21.101;

        49.174.202.137;

};

options {

        recursion yes;                 # enables resursive queries

        allow-recursion { trusted; };  # allows recursive queries from "trusted" clients

        listen-on port 53 { 10.10.0.37; };   # ns1 private IP address - listen on private network only

        allow-transfer { none; };      # disable zone transfers by default

        forwarders {

               10.10.0.99;

               10.10.0.72;

        };

        forward only;

        dnssec-enable yes;

        dnssec-validation yes;

        dump-file "/var/cache/bind/dumps/named_dump.db";

        auth-nxdomain no;    # conform to RFC1035

        listen-on-v6 { any; };

};

"dump-file "/var/cache/bind/dumps/named_dump.db";" is added int the configuration. After then, check configuration and restart. (Please note that the file should be located under /var/cache/bind directory)

# Run Command

# rndc dumpdb -cache

 

# /var/cache/bind/dumps# ls
named_dump.db

I can see the file created. I can also read this file. The result look like below

# cat named_dump.db

;

; Start view _default

;

;

; Cache dump of view '_default' (cache _default)

;

$DATE 20190913145755

; authanswer

www.dizigo.shop.        56      IN A    10.128.100.101

;

; Address database dump

;

; [edns success/4096 timeout/1432 timeout/1232 timeout/512 timeout]

; [plain success/timeout]

;

;

; Unassociated entries

;

;       10.10.0.99 [srtt 232] [flags 00004000] [edns 1/0/0/0/0] [plain 0/0] [udpsize 512] [ttl 1796]

;       10.10.0.72 [srtt 29] [flags 00000000] [edns 0/0/0/0/0] [plain 0/0] [ttl 1796]

;

; Bad cache

;

;

; Start view _bind

;

;

; Cache dump of view '_bind' (cache _bind)

;

$DATE 20190913145755

;

; Address database dump

;

; [edns success/4096 timeout/1432 timeout/1232 timeout/512 timeout]

; [plain success/timeout]

;

;

; Unassociated entries

;

;

; Bad cache

;

; Dump complete

If I want to clean this db and caching. I can run like below. Flush and service restarted are necessary.

# rndc flush

# service bind9 restart

 

8. Create Caching DNS server with zone file (Delegating sub-domain)

 

Please note that I can not delegate other domain. I can only delegate sub-domain. For example, "some-name.origin-domain.com --> some-domain.com" is not possible.  "some-name.origin-domain.com --> some-name.sub-domain.origin-domain.com" is only possible

Because of above, I use another name "ozigo.shop". (So far, I used "dizigo.shop")

 

I will follow this instruction. Caching DNS server can have zone file and handle the query directly. For this, I will do some of changes. First I will remove "forward only;" and "forwarders". Therefore  "named.conf.option" is look like below

acl trusted {

        10.10.0.37;

        178.128.21.101;

        49.174.202.137;

};

options {

        recursion yes;                 # enables resursive queries

        allow-recursion { trusted; };  # allows recursive queries from "trusted" clients

        listen-on port 53 { 10.10.0.37; };   # ns1 private IP address - listen on private network only

        allow-transfer { none; };      # disable zone transfers by default

        dnssec-enable yes;

        dnssec-validation yes;

        dump-file "/var/cache/bind/dumps/named_dump.db";

        auth-nxdomain no;    # conform to RFC1035

        listen-on-v6 { any; };

};

And then, I need other configuration file and zone file, "named.conf.local" and "zone file included sub-domain"

# cat named.conf.local

zone "ozigo.shop" {

    type master;

    file "/etc/bind/zones/db.ozigo.shop";

};

I used "$ORIGIN" term to seperate zone between ozigo.shop and ns.ozigo.shop. The red text show how to delegate sub-domain reqursion. The request query for "ns.ozigo.shop" will be sent to "ns1.ns.ozigo.shop" which has 10.10.0.72 IP address.  The authoritative DNS which has zone file will be like below.

root@cache:/var/cache/bind/zones# cat db.crenet.com
$ORIGIN crenet.com.
$TTL    10
@       IN      SOA     crenet.com. admin.crenet.com. (
                              3         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
        IN      NS      ns1.crenet.com.
ns1.crenet.com. IN A 10.10.0.204

;
www.crenet.com. IN CNAME www.g.crenet.com.

$ORIGIN g.crenet.com.
@       IN      NS      ns1.g.crenet.com.
        IN      NS      ns2.g.crenet.com.
ns1.g.crenet.com. IN A 10.10.0.124
ns2.g.crenet.com. IN A 10.10.0.225

# cat zones/db.ns.ozigo.shop

$TTL    60

@       IN      SOA     ns1.ns.ozigo.shop. admin.ns.ozigo.shop. (

                              3         ; Serial

                         604800         ; Refresh

                          86400         ; Retry

                        2419200         ; Expire

                         604800 )       ; Negative Cache TTL

; name servers - NS records

       IN      NS      ns1.ns.ozigo.shop.

; name servers - A records

ns1.ns.ozigo.shop.       IN     A    10.10.0.72

; sample - A records

recursion.ns.ozigo.shop.  IN     A    200.200.200.200

My final goal is looking up "recursion.ozigo.shop". When I try to dig from remote client, the result should be like below.

# dig recursion.ns.ozigo.shop @54.180.154.199

; <<>> DiG 9.11.3-1ubuntu1.8-Ubuntu <<>> recursion.ns.ozigo.shop @54.180.154.199

;; global options: +cmd

;; Got answer:

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 46798

;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 2

;; OPT PSEUDOSECTION:

; EDNS: version: 0, flags:; udp: 4096

;; QUESTION SECTION:

;recursion.ns.ozigo.shop.       IN      A

;; ANSWER SECTION:

recursion.ns.ozigo.shop. 60     IN      A       200.200.200.200

;; AUTHORITY SECTION:

ns.ozigo.shop.          60      IN      NS      ns1.ns.ozigo.shop.

;; ADDITIONAL SECTION:

ns1.ns.ozigo.shop.      60      IN      A       10.10.0.72

;; Query time: 104 msec

;; SERVER: 54.180.154.199#53(54.180.154.199)

;; WHEN: Fri Sep 13 20:31:49 UTC 2019

;; MSG SIZE  rcvd: 102

 

9. TroubleShooting.

 

When I can meet some errors like below during checking zone file configuration in cache server.

# named-checkzone crenet.com db.crenet.com

zone crenet.com/IN: getaddrinfo(ns1.g.crenet.com) failed: Temporary failure in name resolution

zone crenet.com/IN: getaddrinfo(ns2.g.crenet.com) failed: Temporary failure in name resolution

zone crenet.com/IN: loaded serial 3

OK

In my case, I update /etc/resolv.conf file like below. I update the nameserver with my local private IP address.

# cat /etc/resolv.conf  

nameserver 10.10.0.204

 

Reference

 

[ 1 ] https://www.digitalocean.com/community/tutorials/how-to-configure-bind-as-a-private-network-dns-server-on-ubuntu-18-04

[ 2 ] https://kifarunix.com/configure-bind-as-slave-dns-server-on-ubuntu-18-04/

[ 3 ] https://help.fasthosts.co.uk/app/answers/detail/a_id/1276/~/what-is-recursive-dns-and-why-is-it-not-recommended%3F

[ 4 ] https://www.slashroot.in/difference-between-iterative-and-recursive-dns-query

[ 5 ] https://help.fasthosts.co.uk/app/answers/detail/a_id/1276/~/what-is-recursive-dns-and-why-is-it-not-recommended%3F

[ 6 ] https://www.digitalocean.com/community/tutorials/how-to-configure-bind-as-a-caching-or-forwarding-dns-server-on-ubuntu-14-04

[ 7 ] https://linuxconfig.org/how-to-view-and-clear-bind-dns-server-s-cache-on-linux 

[ 8 ] https://bugzilla.redhat.com/show_bug.cgi?id=112350

[ 9 ] http://www.zytrax.com/books/dns/ch9/delegate.html

 

+ Recent posts