Creating CNAMEs on a Pi-Hole
During these odd times when we are forced to stay at home, I’m taking the opportunity to reorganize my home network a bit.
I recently got myself a RockPro64, a single board computer similar to a RaspberryPI, but with more computing power and a PCI express slot that makes it excellent as a home NAS.
I moved all the docker containers that I usually run on my desktop computer to the RockPro64, using Traefik 2 as ingress to send the traffic to the proper containers, initially using the path (example: rockpro64.local/firefly
sends the traffic to the Firefly III instance).
I quickly discovered that most containers don’t like path routing, and try to play with Traefik paths to redirect traffic while stripping the path didn’t help much. So I was looking for a way to use subdomains in order to route traffic, which would always expose containers on the root path of a domain, and solving all the issues I was having.
I run a PiHole in my home network, that does the DNS lookups for all the clients in the network (and filters ads and malicious domains while doing that, you should definitely get it if you don’t use it already), in addition to that I also use the PiHole as DHCP server for the network (just because the UI was nicer that most of the routers I’ve had so far).
The PiHole assignes a domain name to each of the clients in the form <clientname>.local
, so using it to create my domains seemed like the logical choice, but there is no option to do that on the UI.
Looking at the documentation about the PiHole, I found out that it uses dnsmasq under the hood to cache dns entries. Bingo!
Dnsmasq can be configured with additional domains, just go to the directory containing the service configuration files (usually /etc/dnsmasq
), create a new configuration file (they all are in the form NN-name.conf
, where NN is a double digit number, so they load in order, I named mine 50-cnames.conf
) and you can place the CNAMES in the file with this syntax
cname=subdomain1.clientnanme.local,clientnanme.local
cname=subdomain2.clientnanme.local,clientnanme.local
This creates two subdomains for clientname.local
. As CNAMEs, the two subdomains created will resolve to the exactly the same IP as clientname.local
, that’s what we need.
Last step after editing the file is issue a pihole restartdns
command to make sure that PiHole reads the new configuration.
Just for completeness, while this configuration works well for my needs, it has a weakness: the name of the target domain is hardcoded, so if the target client names changes, the dnsmasq configuration will require the same change, or else the cnames will point to an unexisting domain.