Building a homelab - local DNS
This is a second post in a series of my experiences while Building a Homelab. The first post focusing on the history, hardware, and OS can be found here.
Having a number of networked devices at home presents some management overhead. You may find yourself asking, what was the IP address of that one laptop? or just getting plain old tired of looking at IP addresses. One method people often use to manage their network is to assign Domain Name System (DNS) names to their devices. Instead of constantly typing in 192.168.1.1
you could instead assign it the domain name router.home
. Entering router.home
into your browser then transparently brings you to the same webpage as 192.168.1.1
. This not only works for browsing the internet, services such as SSH, FTP, and other places where an IP address would normally be used can likely use the friendlier domain name instead.
So how can this be done? It’s actually quite simple given you have an always-on computer on the same network as the rest of your devices, a router with DNS serving capabilities, or even a DNS provider such as Cloudflare. This article will focus on the DIY solution of running a DNS server on an always on computer.
Before we get to how to set this up, let’s first explain what DNS is and how it works. Feel free to skip over this section if you’re already knowledgeable.
What is DNS?
DNS is a technology used to translate human-friendly domain names to IP addresses. For example, we can ask a DNS server what is the IP address for the domain google.com? The DNS server would then respond with the IP address for google.com
: 172.217.1.174
. DNS is used for almost every request your computer, phone, smart lightbulbs, and more when it communicates with the internet.
Anyone who runs a website is using DNS whether they know it or not. Usually the basic premise is that each domain name (eg. mysite.com
) will have a DNS record which points to an IP address. The IP address is the actual computer on the internet which traffic for mysite.com
will be sent to.
An example of DNS being used can be for jonsimpson.ca
. This site is hosted on a server that I pay for at DigitalOcean. That server has an IP address of 1.2.3.4
(a fictitious example). I use Cloudflare as the DNS provider for jonsimpson.ca
. Anytime a user’s browser wants to go to jonsimpson.ca
, it uses DNS to figure out that jonsimpson.ca
is located at 1.2.3.4
, then the user’s browser opens up a connection with the server at 1.2.3.4
to load this site.
This is quite a simplified definition of DNS as the system is distributed across the world, hierarchical, and involves hundreds of thousands, if not millions, of different entities. Cloudflare provides a more detailed explanation as to how DNS works, and Wikipedia has comprehensive coverage of multiple concerns relating to DNS. But what was explained earlier will provide enough context for this article.
Running a local DNS server
If there’s an always-on computer – whether that’s a spare computer or Raspberry Pi – a DNS server can run on it and provide DNS capabilities for the local network. Dnsmasq is a lightweight but powerful DNS server that has been around for a long time. Many hobbyists use Dnsmasq for their home environments since it’s quite simple to configure and get going. One minimal text file is all that’s needed for configuring a functional DNS service.
I chose to run Dnsmasq on my always-on server in a Docker container. When configuring Dnsmasq, for each device that I wanted to provide a domain name for, I added a line in the configuration mapping its IP address to the name I wanted to give it. For example, my router which lives at 192.168.1.1
was assigned router.home.mysite.com
, and my server which lives at 192.168.1.2
was assigned server.home.mysite.com
.
I then configured my router’s DHCP to tell all clients to use the DNS provided by the server (contact 192.168.1.2
for DNS), and configure some manually networked devices to explicitly use the DNS provided by the server. Now on all of my devices I can type in server.home.mysite.com
anywhere I would type 192.168.1.2
– so much nicer compared to having to type in an entire IP address.
nslookup
and dig
are both common command line tools to query the Domain Name System. They are often found already available on many Linux and Unix operating systems, or a straightforward install away. Using these tools can help with inspecting and debugging DNS setups. Here’s an example query using nslookup
to find google.com
:
$ nslookup google.com
Server: 192.168.1.2
Address: 192.168.1.2#53
Non-authoritative answer:
Name: google.com
Address: 172.217.1.174
The first Server
and Address
denote the DNS server that was used to find the IP address for google.com
. In this case, it was the Dnsmasq DNS server running on my home server. Name
and Address
at the bottom signify the actual response we’re interested in. In this case, 172.217.1.174
is the IP address I get whenever I go to google.com
.
The configuration
I use Docker as a way to simplify the configuration and running of different services. Specifically, I use <a href="https://docs.docker.com/compose/">docker-compose</a>
to define the Dnsmasq Docker image to use, which ports should be opened, and where to find its configuration. Here’s the docker-compose.yml
file I use:
All of these docker-compose.yml
options can be understood in more detail in Docker’s reference docs.
More importantly, here’s the dnsmasq.conf
file I use to actually configure Dnsmasq’s DNS capabilities:
I have my Ubiquity router handle providing DHCP for my network, therefore the no-dhcp-interface=eno1
is set here to not provide any DHCP services to the local network, as eno1
is the interface my server uses to connect to the network.
When Dnsmasq needs to find the DNS record for something that it doesn’t know, it performs a request to an upstream DNS server. server
is used for this and can be specified multiple times to provide redundancy in case one of these DNS servers are down. I’ve specified both the Google and Cloudflare DNS servers. In addition to this, the all-servers
option results in all defined server
entries being queried simultaneously. This has the benefit that one DNS server may respond quicker than the others, resulting a net-faster response to the DNS query.
The most important part of this dnsmasq.conf
configuration file are the last lines defined in the file that start with address=
. This is Dnsmasq’s way to declare DNS mappings. For example, any device on my network performing a request for server.home.mysite.com
will have 192.168.1.2
returned.
The really cool thing with DNS is that subdomains for any of these records return the same IP, unless declared explicitly otherwise. An example of this is blog.apps.home.mysite.com
doesn’t exist in the configuration file, but performing a DNS request for it will return 192.168.1.2
. This has the effect that “multiple services” can each have its own domain name, but all be served by the same IP address.
Conclusion
Hopefully this article gives a background about what DNS is, how it can be useful in a home environment, and how to setup and operate a Dnsmasq DNS server. A future post will build on top of the DNS functionality that has been setup here to provide multiple HTTP services running on separate domain names, all served by the same server, for the home network to use.