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 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 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