If you only have a single domain with a lone A record, you can skip this article.
When you have several domains with a complex setup, it becomes a pain to maintain, and if you’re hosting a site for someone you have to chase them down and make them change their domain records. You need a single source of truth that is easy to handle, and it’s called a self-hosted DNS server.
Nameservers
When you query DNS for blog.torq.pro this happens: 1
- it queries NS record of
proon the root servera.root-servers.net, gets a response witha0.pro.afilias-nst.info - queries
a0.pro.afilias-nst.infofor NS record oftorq.pro, gets backd.ns.buddyns.com - queries
d.ns.buddyns.comfor A record ofblog.torq.proand gets back116.203.246.233
Run each step yourself to get a feel for it:
dig @a.root-servers.net NS pro
dig @a0.pro.afilias-nst.info NS torq.pro
dig @d.ns.buddyns.com A blog.torq.pro
# Or run a trace
dig +trace blog.torq.pro
d.ns.buddyns.com is a secondary nameserver that queries torq.pro for DNS records and serves a copy. It’s important to understand that secondaries are optional – technically, I could set NS record for the domain to NS torq.pro. and avoid secondaries altogether, it’s just good practice to have them (for failure tolerance and geographical distribution).
When your DNS is managed by your registar, they’re running their own secondary nameservers for torq.pro. You’ll switch to using secondaries that listen to your server for changes instead.
Configuring Bind 9
Open Bind Configuration Reference Manual and follow along if you want a deeper understanding of what we’re doing.
Bind is the industry standard DNS server that everyone uses. It has a small footprint and is pretty easy to configure. Install it on your server:
sudo apt install bind9 # enables and runs the service by default
Relative and absolute domain names
Important note: in zone config files domain names can be absolute or relative. A name that ends with a dot, like site.example.com. is absolute. Otherwise the current origin domain will be appended to the name, so site becomes site.example.com., but site.example.com (no dot!) becomes site.example.com.example.com.. This is part of DNS spec, you can actually go to https://google.com./search?q=dns! A special symbol @ expands into the origin domain.
Create zone file
A DNS record has the following syntax (most of the parts can be omitted):
<domain> [IN] [TTL] <TYPE> <VALUE>
Now let’s create a zone for our domain. A zone contains DNS records for domain.tld and all its subdomains 2 . Create a file named /etc/bind/db.your-domain.com, I’ll use torq.pro as an example. Tweak it to your needs. While you’re experimenting, it helps to have low cache TTL, but if your zone rarely changes you should set it to a higher value.
$ORIGIN torq.pro. ; You domain name, mind the dot at the end!
$TTL 10m ; The default cache period for responses.
; Authority record.
; Replace torq.pro. with the domain of your DNS server. root.torq.pro is
; supposed to be the email of the person in charge of DNS (i.e. root@torq.pro).
@ IN SOA torq.pro. root.torq.pro. (
1 ; Serial, see explanation below
10m ; How often secondaries are supposed to refresh
1h ; How often they retry after failure
1w ; How long before your zone expires after sustained failure
10m ) ; Cache period for "domain missing" responses
; The nameservers for your domain. You will need to set up BuddyNS and change
; the nameservers in your domain registar settings to the same value.
@ NS l.ns.buddyns.com. ; Japan
@ NS c.ns.buddyns.com. ; Germany
@ NS i.ns.buddyns.com. ; CA, US
@ NS d.ns.buddyns.com. ; NY, US
; (you can pick your own selection of course)
@ A 116.203.246.233 ; A record for torq.pro
blog A 116.203.246.233 ; A record for blog.torq.pro
blog.torq.pro. A 116.203.246.233 ; Equivalent
blog 1h A 116.203.246.233 ; A record that is cached for 1 hour
www CNAME @ ; CNAME www.torq.pro => torq.pro
@ MX 10 mail ; Example MX record
@ MX 10 mail.torq.pro. ; Equivalent
@ TXT "v=spf1 a mx -all" ; Example TXT record for torq.pro
mail TXT "v=spf1 a mx -all" ; Example TXT record for mail.torq.pro
After you’re done, add the zone to /etc/bind/named.conf.local:
zone "torq.pro" {
type master;
file "/etc/bind/db.torq.pro";
};
And reload bind config (no need to restart):
sudo systemctl reload bind9
# Confirm that it works, query a few records that you added!
dig @localhost NS torq.pro
dig @localhost A blog.torq.pro
dig @localhost MX mail.torq.pro
Serial number
Whenever you update your zone, you have to increase the serial number in the SOA section for the changes to take place. So if you change the zone and don’t see the changes when querying the server, the first thing to do is make sure you increased the serial. This “feature” of DNS is a leftover from the olden days that we have to live with.
Set up BuddyNS
BuddyNS is a free secondary nameserver service (up to 300k queries/month). You can use any other free or paid option (another free one is https://dns.he.net).
Secondary nameservers regularly poll your dns server to request zone data and propagate any changes. When you reload bind config, it can send a NOTIFY request to secondaries to let them know to download zone data early.
Allow BuddyNS servers to query your zone data – put this in /etc/bind/named.conf.options inside the options { } section. You can also read their tutorial.
allow-transfer {
// buddyns.com
108.61.224.67; 116.203.6.3; 107.191.99.111; 185.22.172.112; 103.6.87.125;
192.184.93.99; 119.252.20.56; 31.220.30.73; 185.34.136.178; 185136.176.247;
45.77.29.133; 116.203.0.64; 167.88.161.228; 199.195.249.208; 104.244.78.122;
2001:19f0:6400:8642::3; 2a01:4f8:1c0c:8115::3;2604:180:2:4cf::3; 2a00:1838:20:2::cd5e:68e9;
2403:2500:4000::f3e; 2604:180:1:92a::3; 2401:1400:1:1201::1:7853:1a5;
2a04:bdc7:100:1b::3;2a00:dcc7:d3ff:88b2::1; 2a06:fdc0:fade:2f7::1; 2001:19f0:7001:381::3;
2a01:4f8:1c0c:8122::3; 2605:6400:20:d5e::3; 2605:6400:10:65::3;2605:6400:30:fd6e::3;
};
also-notify {
45.77.29.133; // buddyns Tokio
};
Reload bind config, and go to your domain registar configuration page to add the nameservers to your domain. This is what allows the query dig @a0.pro.afilias-nst.info NS torq.pro to return BuddyNS nameservers, telling DNS resolvers to query them for records. Read their tutorial on adding the nameservers. For consistency, add the exact same records that you set up in your zone file.
Now go to https://www.buddyns.com/activation/, enter your email, domain name and the public IP of the server running bind and finish the job.
Adding more zones
To add another zone, create a zone file /etc/bind/db.domain.tld, add it to /etc/bind/named.conf.local and reload bind config. Then add the domain to managed zones at https://www.buddyns.com/buddyboard/zones/. Then change the domain nameservers to BuddyNS at the domain registar. Done.
Now you have all your domains in one place. If you need to make any changes, just edit the zone (don’t forget to increment the serial) and run sudo systemctl reload bind9. No need to fiddle with registar config UIs and APIs or chase down domain owners. If your DNS server IP changes, there’s only one place that you need to update, set the new IP for the master server in BuddyNS.