# Starting with CoreDNS


This post talks you through getting and setting up [CoreDNS](https://github.com/miekg/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](https://github.com/skynetservices/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:

~~~ bash
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`

~~~ bind
$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:

~~~ txt
atoom.net:53 {
    file /home/miek/atoom.net
    errors stdout
    log stdout
}
~~~

And start coredns: `sudo coredns -log stdout -conf ~/Corefile`, query it:

~~~ bash
% dig @localhost atoom.net A +short
139.162.196.78
~~~

Pretty boring, let's add DNSSEC, because that generates [the most interesting
outages](https://ianix.com/pub/dnssec-outages.html).

We create a keypair and use it for signing:

~~~ bash
% 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](https://github.com/miekg/coredns/issues/4):

~~~ txt
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](https://blog.cloudflare.com/deprecating-dns-any-meta-query-type/), 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:

~~~ txt
atoom.net:53 {
    file /home/miek/atoom.net
    dnssec {
        key file Katoom.net.+013+21905
    }
    rewrite ANY HINFO
    errors stdout
    log stdout
}
~~~

And checking:

~~~ bash
% 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:

~~~ txt
.: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.

~~~ txt
.: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".

