Name that domain
10 July, 2014
Hello folks !
I recently reinstalled my home server, and during the process, I decided to
throw away the heavy
BIND nameserver from my application stack. I decided to
go with the light couple
This wasn't really "easy" to do so, as there are really few resources on the web explaining the step to get this working (If you're aware of one, please send me a link, I'll be glad to share it). So here is a full tutorial !
- create tinydns zone file
tinydnslisten on 127.0.0.1
- create the
ipfiles for dnscache
- create the
serversfile for dnscache containing
- Fire it up
The whole installation
First of all, I had to find out what were my needs. It seems stupid to say so, but I have the bad habit to dive into configuration, barely knowing what I'm trying to do. Here's what I wanted:
The DNS nameserver will be running on a machine with IP 10.0.0.1. My local network will be named domain.lan. I want all my machines to contact 10.0.0.1 to resolve URIs, and the server will provide authoritative answers for domain.lan, and forward everything else to some other servers.
How should we organise things then ?
Here's how I see it:
tinydnslistens on 127.0.0.1
tinydnsanswers queries related to *.domain.lan
dnscacheanswer queries from any address
dnscacheforwards queries related to *.domain.lan to ip 127.0.0.1
dnscacheforwards everything else to others DNS
dnscacheanswers on any address
Let's set this up then!
tinydns is fairly simple to use, and even more simple to configure. But it's
nothing you've ever seen before. You can configure tinydns from a single file:
─── cat /etc/tinydns/root/data Zdomain.lan:dns.domain.lan::contact.domain.lan &domain.lan::dns.domain.lan +domain.lan:10.0.0.1 +pc1.domain.lan:10.0.0.1 +pc2.domain.lan:10.0.0.2
That's a basic configuration file to use with
tinydns. It will resolve
pc1.domain.lan to ip
For more infos on the syntax, check the alpine wiki page.
Once your config file is created, you can generate the data that tinydns will
use. Remember to correctly set the
ROOT variable to define the directory where
tinydns will store it's data:
# ROOT=/var/cache/tinydns/ tinydns-data
As we said earlier, we want
tinydns to listen on the loopback interface. To do
so, we have to export the variable IP before running the binary.
# ROOT=/var/cache/tinydns/ IP=127.0.0.1 tinydns
And there you go ! Tinydns is listenning on address 127.0.0.1.
To check if it's correctly running, you can use
# cp /etc/resolv.conf.old /etc/resolv.conf.orig # cat <<EOF > /etc/resolv.conf nameserver 127.0.0.1 EOF # nslookup pc2.domain.lan Server: (null) Address 1: ::1 localhost Address 2: 127.0.0.1 dns.domain.lan Name: pc2.domain.lan Address 1: 10.0.0.g.2 # mv /etc/resolv.conf.orig /etc/resolv.conf
It works ! Don't use tinydns as a resolv.conf entry though. Because it's authoritative and ONLY serves our domain.lan zone, it would not be efficient...
No DNS server can answer all the queries, so in most case, if the DNS can't provide an answer, it will just forward the query to another depending on some internal rules.
That's how we're gonna set up
dnscache. Intercept queries from the local
network, forward every query for
tinydns, and everything to a
standard list of known root servers.
But first, we need to tell
dnscache to answer every query from local domain.
Let's say my current configuration is the following:
Network : 10.0.0.0 Netmask : 255.255.0.0 Gateway : 10.0.0.254 DNS : 10.0.0.1
We need to listen on
10.0.0.0/16 for DNS queries. To set this up, take a look
─── ls /etc/dnscache/ip 127 ─── wc 127 0 0 0 /etc/dnscache/ip/127
A single file named
127, which is totally empty... What does that mean ?
dnscache will read this directory and check the filenames to
know which IP address it should accept queries from.
The filename also act as a netmask, so in this case,
127 really means
Back to our configuration. We want
dnscache to accept queries from our local
10.0.0.0/16. Just create the corresponding file:
# :> /etc/dnscache/ip/10.0
And we're done !
Now, we need to tell
dnscache who will answer the queries it receives. This is
done in the
/etc/dnscache/servers/ directory. We can see that there is already
a file here:
─── ls /etc/dnscache/servers/ @ ─── cat /etc/dnscache/servers/@ 184.108.40.206 220.127.116.11 18.104.22.168 22.214.171.124 ...
This is a list of the root servers extracted from this list.
In this directory, each file represent a domain, and the content of this file is
the list of the servers to contact in order to resolve those names.
@" is a special name for the "fallback" entry.
In our case, we want
tinydns to resolve names from "domain.lan", and forward
everything else to the root servers in the "
@" file. To query
need to forward queries to
127.0.0.1. Here's how to do this:
# cat <<EOF > /etc/dnscache/servers/domain.lan 127.0.0.1 EOF
That's all. Pretty simple isn't it ?
It's now time to start dnscache. It needs (like
tinydns) two environment
ROOT for the configuration directory path, and
IP for the address
of the interface to listen on (note that you can use
0.0.0.0 to listen on all
# ROOT=/etc/dnscache IP=10.0.0.1 dnscache
You can now check if everything is working fine with
# cp /etc/resolv.conf.old /etc/resolv.conf.orig # cat <<EOF > /etc/resolv.conf nameserver 10.0.0.1 EOF # nslookup pc2.domain.lan Server: (null) Address 1: ::1 localhost Address 2: 127.0.0.1 dns.domain.lan Name: pc2.domain.lan Address 1: 10.0.0.g.2 # mv /etc/resolv.conf.orig /etc/resolv.conf
And there you are ! You can now specify the IP address of your server in the
resolv.conf on your local computers.