Author: Alessandro Marchioro - Written and Published on 2024-08-11 14:08

High Performance local DNS for your homelab/local network

Hi everyone!

Today we're having a look at how we can build a local, high performance local DNS for your homelab or local network using coredns, which is the default implementation for DNS queries of Kubernetes.

Let's get started!

Prerequisites

We need an always on server, or virtual machine, with DNS service disabled due to it having conflicts with the following coredns installation.

We also need docker and docker-compose installed, which you can find an official guide for your operating system here: click here.

The setup

Let's make a directory under /srv/services, called coredns, like so, and create a new file called docker-compose.yml:

# /srv/services/coredns/docker-compose.yml
services:
    coredns:
        build: .
        container_name: coredns
        restart: unless-stopped
        expose:
            - '53'
            - '53/udp'
        ports:
            - '53:53'
            - '53:53/udp'
        network_mode: 'host'
        volumes:
            - './config:/etc/coredns'

Now we need to create a file called Dockerfile in the same directory, with the following content:

FROM coredns/coredns:latest

EXPOSE 53 53/udp
VOLUME ["/etc/coredns"]
ENTRYPOINT ["/coredns"]
CMD ["-conf", "/etc/coredns/Corefile"]

Once we have both of those saved, let's configure our DNS settings and initial records!

Create a config directory under the project folder, and then create two files: Corefile and localdomain.local.hosts (you will use a different file name ending with .hosts, based on your domain name; in case of a domain called localdomain.local, use localdomain.local.hosts)

Corefile content:

. {
    log
    errors
    cache

    auto
    reload 10s
    hosts /etc/coredns/localdomain.local.hosts localdomain.local {
        fallthrough
    }
    forward . 1.1.1.1 8.8.8.8
}

localdomain.local.hosts content (here you will save your DNS records associations!), for example:

10.0.0.100        localdomain.local
10.0.0.100        dns.localdomain.local dns

10.0.0.50         workstation.localdomain.local workstation

(10.0.0.100 is the IP of the DNS server, 10.0.0.50 is the IP of my workstation as an example)

Run the service

After that, to run it do the usual magic tricks for running docker as follows:

docker compose pull
docker compose build
docker compose up -d

And here it goes! Now we have a fully serviceable and easy, local, high performance DNS service at our disposal!

How to use your new shiny DNS server

You can do it in two main ways:

Conclusions

What an easy setup! With that, you have covered the basics of coredns, which has tons of plugins for setting up the DNS service exactly the way you like it!

It's possible to do custom filtering, DNS blockage, Ad blocking and so on, you just need to watch the documentation and go accordingly :)

I hope it helped someone as it always has helped me in my work and homelab projects!


If you fancy see what I'm working on, have a look at my GitHub or write me an email!