dns
Setting Up Your Own DNS Server
Today I went through the process of setting up my own DNS server. As I’m hosting websites behind DSL I was getting sick of switching /etc/hosts files every time I was within my own network (only Cable prevents the need for this) and originally intended to set up an internal-only DNS server which would fall back to OpenDNS for any records it didn’t know … this would solve the issue.
There are also a few bragging rights in being able to say you host your own DNS server.
Rather than retracing my steps and placing them all here, follow this tutorial for the internal server. However this tutorial omits an important detail: make sure you also add an ‘@’ A record which points to your IP address, or it won’t resolve.
Once I had this all up and running and I had finally got my head around the way BIND9′s config files worked, I decided to take the next step: opening up the server for external use. I followed this tutorial to modify my existing configuration to allow external requests. And here’s the second note: make sure you move the ‘include “/etc/bind/named.conf.default-zones”‘ directive from ‘/etc/bind/named.conf’ into the end of your ‘internal’ view in ‘/etc/bind/named.conf.local’. Why? Because if you’re using views you can’t define a zone outside of a view, and that’s just what ‘named.conf.default-zones’ will do if it’s included from the main file.
Finally, in the above tutorial it talks about including your external zone file in the internal one to prevent modifying so many files every time you update your DNS records, however that means you’re overloading the records which just doesn’t feel right to me. I’ve taken it one step further to make it nice, simple and clean. My folder structure looks like this:
/etc/bind/
|-zones/
|-base/
|-internal/
|-external/
The philosophy here is to put all of the DNS record declarations in the base files except for anything unique to the view. Therefore, ‘base/example.com.db’ would look similar to this:
1 $TTL 8H 2 @ IN SOA ns1.example.com. admin.example.com. ( 3 2010122005 4 28800 5 3600 6 604800 7 38400 8 ); 9 10 example.com. IN NS ns1.example.com. 11 example.com. IN MX 10 mail 12 13 www IN CNAME @ 14 imap IN CNAME mail 15 pop IN CNAME mail 16 pop3 IN CNAME mail 17 smtp IN CNAME mail
Here we have a very generic definition. Nothing is unique to being internal or external (don’t worry about line 10, this still resolves internally).
Next, the ‘internal/example.com.db’ file:
1 $include "/etc/bind/zones/base/example.com.db" 2 3 mail IN A 192.168.0.43 4 ns1 IN A 192.168.0.43 5 @ IN A 192.168.0.43
Now this is beautiful in its simplicity. We are importing the base definition and then adding on the A records pointing to the web server’s IP so that when you’re within the network you can resolve correctly.
Finally, the ‘external/example.com.db’ file:
1 $include "/etc/bind/zones/base/example.com.db" 2 3 example.com. IN NS ns0.xname.org. 4 5 mail IN A 123.123.123.123 6 ns1 IN A 123.123.123.123 7 @ IN A 123.123.123.123
Again, extremely simple. Identical in fact, apart from the extra nameserver declarations which aren’t necessary internally. Externally you need a fallback and Xname is as good as any (as referenced in the above tutorial).
So how do you use all of these files? Very simply. All you do is include the ‘file “/etc/bind/zones/internal/example.com.db”‘ declaration (with the obvious modification for the external view) within ‘/etc/bind/named.conf.local’, and those simple files will import the base declaration for you. If you ever need to open up a new subdomain or change an MX record, all you need to do is edit the base declaration (remembering to update the serial number at the top) and the changes will take effect both internally and externally.
See what I mean by Beauty in Simplicity?
About Nik Rolls
My Projects
Mail Divination
A web app I made to detect your IMAP/POP/SMTP server settings on the fly, saving you mucking around trying to find them yourself.
Follow Me Elsewhere