Creating an authoritative-only DNS system for your domain

Most registrars they provide a DNS service when you purchase a domain name. But having your own DNS servers means more control to you. And if you are an aspiring sysadmin, you will find it fun and educational. We will be using [BIND 9](https://en.wikipedia.org/wiki/BIND) which is, by far the most popular DNS implementation.

## Prerequisites

We will need two systems (VMs or containers) preferably on different geographic locations and different providers. One will be the master and the other system, the slave. This guide works for recent Debian or Ubuntu systems.

Some assumptions:

* Master DNS:
* Hostname: **ns1.example.com**
* IP: **1.1.1.1**
* Slave DNS:
* Hostname: **ns2.example.com**
* IP: **2.2.2.2**
* Webserver:
* Hostname: **example.com** (*www.example.com* is an alias)
* IP: **3.3.3.3**
* Main mailserver:
* Hostname: **mx1.example.com** (*{mail,smtp,pop,imap,webmail}.example.com* are aliases)
* IP: **4.4.4.4**
* Backup mailserver:
* Hostname: **mx2.example.com**
* IP: **5.5.5.5**

## Preparations

### Setup the */etc/hosts* file

On master’s */etc/hosts*:

“`
1.1.1.1 ns1.example.com ns1
“`

On slave’s */etc/hosts*:

“`
2.2.2.2 ns2.example.com ns2
“`

### Installing BIND

**NOTE: all commands must be applied to both master and slave unless otherwise stated**

“`
apt-get -y install bind9 bind9utils
“`

Allow port 53:

“`
ufw allow 53
“`

### Configure the global options

Make the following changes in the */etc/bind/named.conf.options* of both servers:

“`
— /etc/bind/named.conf.options 2016-12-12 14:44:57.163515708 -0500
+++ /etc/bind/named.conf.options.new 2016-12-12 14:52:29.749268250 -0500
@@ -1,5 +1,7 @@
options {
directory “/var/cache/bind”;
+ recursion no;
+ allow-transfer { none; };

// If there is a firewall between you and nameservers you want
// to talk to, you may need to fix the firewall to allow multiple
“`

### Configure the local options

On master’s */etc/bind/named.conf.local*:

“`
— /etc/bind/named.conf.local 2016-12-12 20:06:27.000000000 +0000
+++ /etc/bind/named.conf.local.new 2016-12-12 20:07:03.000000000 +0000
@@ -6,3 +6,8 @@
// organization
//include “/etc/bind/zones.rfc1918”;

+zone “example.com” {
+ type master;
+ file “/etc/bind/db.example.com”;
+ allow-transfer { 2.2.2.2; };
+};
“`

On slave’s */etc/bind/named.conf.local*:

“`
— /etc/bind/named.conf.local 2016-11-01 13:02:24.000000000 -0400
+++ /etc/bind/named.conf.local.new 2016-12-12 15:09:47.445235343 -0500
@@ -6,3 +6,8 @@
// organization
//include “/etc/bind/zones.rfc1918”;

+zone “example.com” {
+ type slave;
+ file “db.example.com”;
+ masters { 1.1.1.1; };
+};
“`

### Create the zone file

On master server create the zone file (*/etc/bind/db.example.com*):

“`
$TTL 3600
@ IN SOA ns1.example.com. root.example.com. (
2016121201
7200
3600
1209600
180 )

; NS Records
@ 300 IN NS ns1.example.com.
@ 300 IN NS ns2.example.com.

; MX Records
@ 300 IN MX 10 mx1.example.com.
@ 300 IN MX 20 mx2.example.com.

; Address records
@ 300 IN A 3.3.3.3
ns1 300 IN A 1.1.1.1
ns2 300 IN A 2.2.2.2
mx1 300 IN A 4.4.4.4
mx1 300 IN A 5.5.5.5

; Alias (Canonical Name) records
www 300 IN CNAME example.com.
mail 300 IN CNAME mx1.example.com.
smtp 300 IN CNAME mx1.example.com.
imap 300 IN CNAME mx1.example.com.
pop 300 IN CNAME mx1.example.com.
webmail 300 IN CNAME mx1.example.com.

; TXT records
@ 300 IN TXT “v=spf1 a mx ?all”
“`

### Verify the global configuration

Run the `named-checkconf` command on both servers. If you get any errors you should fix them before proceeding.

### Verify the zone configuration

Run the following command on the master server:

“`
named-checkzone theo-andreou.org /etc/bind/db.example.com
zone example.com/IN: loaded serial 2016121201
OK
“`

If you get ‘OK’ then your setup is correct, otherwise you should fix it before proceeding.

### Restart bind and test your servers

“`
systemctl restart bind9.service
“`

Now test if your servers resolve your records.

The master:

“`
dig smtp.example.com @1.1.1.1

;; ANSWER SECTION:
smtp.example.com. 300 IN CNAME mx1.example.com.
mx1.example.com. 300 IN A 4.4.4.4

“`

The slave:

“`
dig smtp.example.com @2.2.2.2

;; ANSWER SECTION:
smtp.example.com. 300 IN CNAME mx1.example.com.
mx1.example.com. 300 IN A 4.4.4.4

“`

If you get any errors you can check your syslog file (*/var/log/syslog*).

## Finalizing

After you have tested that everything is OK, it is time to tell your registrar about the new servers. This is called *setting the [glue records](https://en.wikipedia.org/wiki/Domain_Name_System#Circular_dependencies_and_glue_records)* and you should consult the documentation of your registrar on how to do that. Ask support if you have any trouble.

References
———-
* https://www.digitalocean.com/community/tutorials/how-to-configure-bind-as-an-authoritative-only-dns-server-on-ubuntu-14-04

Leave a Reply

Your email address will not be published. Required fields are marked *