Setting up coredns and Zone Files
Published on
Updated on
Domain names are the easiest way for a reverse proxy to split up services in a homelab. Since I’m going full docker-compose in my homelab, I decided to use coredns
.
The server I’m hosting my services on runs Ubuntu 18.04 at the time of writing. This verison of Ubuntu comes packaged with their own DNS resolver systemd-resolved
which runs on port 53. Therefore in order to stop this, we need to edit /etc/systemd/resolved.conf
:
DNS=127.0.0.1
FallbackDNS=
Domains=~.
DNSStubListener=no
You might be wondering about the ~.
option in Domains. From the Arch Wiki, “Without the Domains=~.
option, systemd-resolved might use the per-link DNS servers.”
You also need to remove the already existing /etc/resolv.conf
file.
sudo rm /etc/resolv.conf
Now to setup coredns
I used the following docker-compose snippet:
coredns:
image: coredns/coredns
command: -conf coredns-config/Corefile
ports:
- 53:53/udp
volumes:
- /Volumes/coredns/coredns-config:/coredns-config/
Noticed that I mounted the configuration directory in a volume. coredns
is managed by a configuration file. This would be located under /Volumes/coredns/coredns-config/Corefile
in the host system.
Let’s say we own the domain example.com and want subdomains of that to point to different to our server. To do that, we need to define a zonefile for that domain name. We will save that under /Volumes/coredns/coredns-config/homelab.db
in our host system. Every other domain we will either pass to a public DNS server like Google’s 8.8.8.8
or you can even use a PiHole.
Example Corefile:
example.com:53 {
file /coredns-config/homelab.db
log
errors
}
.:53 {
log
errors
forward . 8.8.8.8
cache
}
I do recommend that whatever domain you do use for your homelab is one you own. Otherwise you might name conflict with a public service that you would want to access in the future.
The cache
directive will cache results from the other DNS provider for quicker delivery at a later point.
The zonefile homelab.db
could look like the following:
$TTL 3600
$ORIGIN example.com.
@ IN SOA ns.example.com. contact.example.com. (
2019121301 ; serial
1d ; refresh
2h ; retry
4w ; expire
1h ; nxdomain ttl
)
IN NS ns.example.com.
@ IN A 192.168.1.10
* IN A 192.168.1.10
@ IN A 10.10.100.10
* IN A 10.10.100.10
In the zone file, @
means whatever the value of $ORIGIN
is and *
is a wildcard meaning any subdomain. You can assign a local LAN address first and then a VPN ip address if you have one set up to access services remotely.
The serial number needs only to be unique across SOA entries, and is conventionally the date and hour in which the entry was modified.
I have this setup since all my services are on one physical machine. If you want to split it up through many different machines, specify it by adding the subdomains in place of the *
or @
.
After the Corefile
and homelab.db
are made, the DNS server is all ready to be up and running. Just execute docker-compose up -d coredns
and the DNS server will start happily responding to requests.
A good way to verify it works is to request an A
record from your site and an external site.
dig @serverip example.com A
dig @serverip google.com A