Starting with CoreDNS
This post talks you through getting and setting up CoreDNS with a small zone file that it will serve. CoreDNS is a nameserver that is very flexible because it can chain different kinds of middleware. From the README:
CoreDNS aims to be a fast and flexible DNS server. The keyword here is flexible, with CoreDNS you are able to do what you want with your DNS data. And if not: write a middleware!
This post does not detail on how to use CoreDNS as a replacement for SkyDNS.
It assumes that you have installed a newish version of Go (1.5+).
Go get CoreDNS: go get github.com/miekg/coredns
and compile and install it:
cd $GOPATH/src/github.com/miekg/coredns
go install
coredns -version
should show something like: CoreDNS (untracked dev build)
.
Now, we are going to work with a little zonefile used for my atoom.net
(atom in English) domain,
just drop the contents of this in ~/atoom.net
$TTL 30M
$ORIGIN atoom.net.
@ IN SOA linode.atoom.net. miek.miek.nl. (
1282630061 ; Serial
4H ; Refresh
1H ; Retry
7D ; Expire
4H ) ; Negative Cache TTL
IN NS linode
IN NS ns-ext.nlnetlabs.nl.
IN A 139.162.196.78
IN AAAA 2a01:7e00::f03c:91ff:fef1:6735
IN HINFO "Please stop asking for ANY" "See draft-ietf-dnsop-refuse-any"
linode IN A 176.58.119.54
IN AAAA 2a01:7e00::f03c:91ff:feae:e74c
www IN CNAME linode
x64 IN A 139.162.196.78
IN AAAA 2a01:7e00::f03c:91ff:fef1:6735
Create a Corefile
with the following contents. We assume this file is also placed in my homedir:
atoom.net:53 {
file /home/miek/atoom.net
errors stdout
log stdout
}
And start coredns: sudo coredns -log stdout -conf ~/Corefile
, query it:
% dig @localhost atoom.net A +short
139.162.196.78
Pretty boring, let’s add DNSSEC, because that generates the most interesting outages.
We create a keypair and use it for signing:
% dnssec-keygen -r /dev/urandom \
-a ECDSAP256SHA256 atoom.net
Generating key pair.
Katoom.net.+013+21905
Amend our Corefile
and add the dnssec
directive, then restart:
atoom.net:53 {
file /home/miek/atoom.net
dnssec {
key file Katoom.net.+013+21905
}
errors stdout
log stdout
}
Using dig
again, we see an RRSIG popping up:
dig @localhost a atoom.net +dnssec +short
139.162.196.78
A 13 2 3600 20160505102551 20160427072551 21905 atoom.net. Xdebr6v7rsV+QO9...xnxaO6QgjVww...
Maybe you know about those pesky ANY queries, that generate large responses?
Testing this I see CoreDNS actually only includes the SOA record when responding to an ANY query. No sure if this is a bug or feature…
Let’s rewrite ANY queries to the more harmless HINFO type:
atoom.net:53 {
file /home/miek/atoom.net
dnssec {
key file Katoom.net.+013+21905
}
rewrite ANY HINFO
errors stdout
log stdout
}
And checking:
% dig @localhost ANY atoom.net +dnssec +short
"Please stop asking for ANY" "See draft-ietf-dnsop-refuse-any"
HINFO 13 2 3600 20160505104728 20160427074728 21905 atoom.net. 5exk2LXO...OxS0LN7Hqbw==
HINFO in all its glory.
Maybe just using it as an authoritative server isn’t enough? Let’s make CoreDNS a proxy for anything
that isn’t atoom.net
.
We need to push all queries through our stanza, so instead of listing
atoom.net
we use the root zone “.”. We are then forced to specify atoom.net
for the bits that
handle that zone. We end up with:
.:53 {
file /home/miek/atoom.net atoom.net
dnssec atoom.net {
key file Katoom.net.+013+21905
}
proxy . 8.8.8.8:53 [2001:4860:4860::8888]:53
errors stdout
rewrite ANY HINFO
log stdout
}
This routes atoom.net
to the file backend and everything else gets forwarded to Google. Now this
forwarding is slow, so you might want to add a caching layer as well.
.:53 {
file /home/miek/atoom.net atoom.net
dnssec atoom.net {
key file Katoom.net.+013+21905
}
proxy . 8.8.8.8:53 [2001:4860:4860::8888]:53
cache
errors stdout
rewrite ANY HINFO
log stdout
}
This will cache queries for atoom.net
as well, which should not be really needed. There is
currently no syntax that will allow you to say: “cache everything, except these zones”.