Configure CoreDNS as basic DNS server on your Local Area Network at home

Audun Nes
2 min readAug 18, 2022

I use libvirt to create virtual machines on my home server, and when using NAT networking, libvirt can use dnsmasq to register DNS entries for the virtual machines, and both the host machine and the guest networks can utilize this.

Red Hat, Inc., CC BY-SA 3.0 <https://creativecommons.org/licenses/by-sa/3.0>, via Wikimedia Commons

Recently I switched to bridge networking where each virtual machine is getting an IP address directly on my LAN. Hence I needed to find a simple way to manage DNS lookups without setting up a full blown and complicated DNS server. Since I have no prior experience with managing DNS servers, I chose to install CoreDNS and configure it to use /etc/hosts as its “database”. The downside is that I will have to manually add IP addresses to /etc/hosts. The upside is that CoreDNS reads this file dynamically.

So all I need to do is:

  • Install CoreDNS
  • Configure CoreDNS to use /etc/hosts
  • Configure CoreDNS to run as a systemd service on my host server.
  • Configure the virtual machines to use my CoreDNS server as the primary DNS.

Install CoreDNS

COREDNS_VERSION=1.9.3curl -LO https://github.com/coredns/coredns/releases/download/v$COREDNS_VERSION/coredns_$COREDNS_VERSION_linux_amd64.tgztar zxvf coredns_$COREDNS_VERSION_linux_amd64.tgzchmod +x corednssudo mv coredns /usr/binrm zxvf coredns_$COREDNS_VERSION_linux_amd64.tgz

Configure CoreDNS

Most of the configuration was found in the Arch Linux wiki: https://wiki.archlinux.org/title/CoreDNS#Configuration

mkdir -p /etc/coredns

Create a file called /etc/coredns/Corefile with the following configuration:

.:53 {
bind 10.0.1.74
bufsize 1232
acl {
allow net 10.0.0.1/23
block
}
hosts {
reload 0
fallthrough
}
cache {
success 4096
denial 1024
prefetch 512
}
errors
log
}

The “bind 10.0.1.74” tells CoreDNS to bind to IP address 10.0.1.74 on my host server where I installed CoreDNS.

The “allow net 10.0.0.1/23” is the CIDR range I will allow DNS lookup requests. This range is my LAN’s CIDR range with IP addresses from 10.0.0.0 through 10.0.1.255.

Configure CoreDNS to run as a systemd service

useradd coredns -s /sbin/nologin -c 'coredns user'touch /usr/lib/systemd/system/coredns.servicechmod +x /usr/lib/systemd/system/coredns.service

The file /usr/lib/systemd/system/coredns.service has the following content:

[Unit]
Description=CoreDNS DNS server
Documentation=https://coredns.io
After=network.target

[Service]
PermissionsStartOnly=true
LimitNOFILE=1048576
LimitNPROC=512
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
NoNewPrivileges=true
User=coredns
WorkingDirectory=/home/coredns
ExecStart=/bin/bash -c '/usr/bin/coredns -conf=/etc/coredns/Corefile'
ExecReload=/bin/kill -SIGUSR1 $MAINPID
Restart=on-failure

[Install]
WantedBy=multi-user.target

Enable and start the service:

systemctl enable coredns
systemctl start coredns

Allow network traffic to reach the DNS server at port 53:

firewall-cmd --permanent --zone=public --add-port=53/tcp
firewall-cmd --permanent --zone=public --add-port=53/udp
firewall-cmd --reload

Configure the VMs to use CoreDNS as the primary DNS

On each of my virtual machines, I have configured the nameservers like this:

#!/bin/bash
nmcli con mod "System eth0" ipv4.dns "10.0.1.74 10.0.0.1 8.8.8.8"
systemctl restart NetworkManager

What this does is that it configures the eth0 device to use my host server with IP 10.0.1.74 as the primary nameserver, my LAN router with IP 10.0.0.1 as the secondary nameserver and finally Google’s public DNS 8.8.8.8 as the tertiary nameserver for the eth0 network interface.

--

--

Audun Nes

Lead Cloud Engineer/Site Reliability Engineer from Copenhagen, Denmark. GitHub: https://github.com/avnes