Private Domain with Technitium

To use friendly names instead of IPs. Set up a Private Domain with Technitium. We set up a Domain Name Server ns1 and configure it to handle our domain, example.com or mylab.lan. Options for later: DHCP, a cluster with at least ns1 and ns2 for redundancy, and add ad-blocking if that's needed.

Share
Private Domain with Technitium
Photo by U. Storsberg / Unsplash

At some point you would like to have friendly names for all the things on your home network instead of dealing with IP addresses. There are many ways to do it, but one of the most common approaches is to create a private domain.

A Private Domain

A private domain is simply a domain name that you like to use on your internal network, and it is not visible from the outside world. You can create a private domain by running local DNS and DHCP services and pointing your internal devices at them. You can use a Firewall for this like pfSense or OpenSense or an Ad-blocker like AdGuard Home or Pi-hole.

If AdGuard Home and Pi-hole are ad-blockers with some DNS functionality attached. AdGuard Home and Pi-hole are a DNS forwarder and can be a pseudo-resolver for custom local DNS names, but it’s not a real recursive DNS resolver without the addition of some additional software like unbound to do the recursive resolving and by adding even more apps they can be synchronized.

Why using Technitium

Technitium is a full fledge DNS that has clustering out of the box. It can be expanded to do DHCP (not clustered yet) and ad-blocking.

Why not usin a Firewall or an Ad-blocker with DNS/DHCP extensions.

The ultimate goal is to have the Firewall doing firewalling, DNS as DNS, DHCP as DHCP and Ad-blockers to block adds. As this brings some complexity we can compromise and combine some actions.
That said, the firewall should be left doing just that because it is essential for the security of our entire network.
We can then use a cluster of DNS servers to handle both DNS/DHCP and ad-blocking as its all about DNS anyhow.

A Private Domain Name

This can be an actual domain name, but that’s not necessary, and it can be problematic if you are planning to use that same domain name for anything public-facing. Consider using a subdomain like lab.example.com.

You can use whatever domain name you want, including the TLD (the last part of the domain name). However, there are some standards, or at least conventions, that we tend to follow. Common TLDs for private networks includ:
.intranet and the newer .internal, .private, .corp, .home or .lan.

ℹ️
There are some names that are not recommended to use, like:
.local, because that is reserved for multicast DNS, or mDNS.
Using .local as a private top-level domain conflicts with mDNS and may cause problems for users.
– Multicast DNS RFC 6762, Appendix G
ℹ️
A strange one is .home.arpa, it will work, but it’s not in common use.
– Proposed as a standard in IETF’s RFC 8375.

Using a Local DNS Resolver

For typical home networks, the router will serve as the nameserver.

  • The router isn’t really mapping names to IPs (known as resolving).
    It’s typically just a DNS forwarder.
  • A DNS forwarder forwards queries to full-fledged DNS resolvers, and then it caches the results it gets back for faster look up next time.

Once you have a private domain name, you need a local DNS resolver to resolve those local addresses, because there is no upstream nameserver that know anything about your mylab.lan domain. You need something locally that can map these names to actual network IP addresses.

  • The most basic solution is to create an /etc/hosts file with all the local names on each machine that needs them.
  • You might have AdGuard Home or the older Pi-hole Ad Blocker that can run DNSmasq for local DNS and even a DHCP server.
  • On firewalls like pfSense and OpenSense you can run DNS and DHCP as well as Ad Blocking it you like.

A better solution is to use a DNS Server like my old favorite bind9 DNS server.

👉
DNS is a vital service for your network, not a add-on.

I started my homelab in the 90s running my own bind9 instance, which was the same me and my sysadmins used for our customers. Later I had a cluster of Pi-holes using Unbound. But, recently I changed to Technitium,

If AdGuard Home and Pi-hole are ad-blockers with some DNS functionality attached. They are DNS forwarders and can be a pseudo-resolver for custom local DNS names, but it’s not a real recursive DNS resolver (one which can recursively query DNS servers until it discovers the IP address) without the addition of some additional software like unbound to do the recursive resolving and by adding more apps they can be syncroniced.

Technitium is a self-contained package that does all of this, and it is a DNS server with ad-blocking capability attached.

The clarity of the GUIs of AdGuard Home, Pi-hole and Technitium are similar.

Install Technitium

Install using a LXC

As my virtualization clusters are TrueNAS and Proxmox the LXC/CT route is a easy choice as it's supported on both by KVM/QEMU.
For a production environment you probably want to use a proper VM for added security and separation. Anyway, remember hardening the VM/LXC.

I will use a Alpine 3.24 LXC, 1 Core 512 MB RAM, 512 MB SWAP

Update and Install Dependencies

Alpine Linux requires dotnet dependencies to run the Technitium binary. Run:

apk update && apk upgrade
apk add bash curl icu-libs krb5-libs libgcc libintl libssl3 libstdc++ zlib wget

Run the Official Installation Script

Execute the self-contained installer script:

The secure way is to read the code before running it. Instead of running the curl -sSL <downlaod-link> | bash we do it in two steps. Read the code please.

wget https://download.technitium.com/dns/install.sh 
bash install.sh

Instead, of the proposed: curl -sSL https://download.technitium.com/dns/install.sh | bash

The installer will automatically download the assemblies, create a system daemon named systemd-dns, and expose ports 53 (DNS) and 5380 (Web UI).

Set up Technitium

To proceed with the DNS configuration, login to the DNS server web console using the server's IP address and port 5380. Point your browser to the IP of your VM/CT http://192.0.2.253:5380/ to initialize the Technitium server.

The first login is admin:admin and you automatically need to change the password before you can continue. Create a new password for admin. Later add your real users.

The Dashboard

Once you have it up and running, you can reach the dashboard.

Now, create a new secure password, the DNS server is like the key to the Castle

Make sure that your internal network clients can all reach the DNS server on UDP/TCP port 53 (DNS) as well as UDP 67 (DHCP). You may need to do some port mapping in Docker or configure some firewall rules depending on your internal network setup.

For the rest of this post, our private subnet is 192.0.2.0/24, with 192.0.2.1 as our router and 192.0.2.253 as our Primary and 192.0.2.254 for our Secondary DNS server. Replace with your prefered subnet.

HTTPS Options

To enable HTTPS you go to SettingsWeb Services and set the following:

Set up a forward zone

The next thing to do is set up your forward zone which maps names to IP addresses. Go to the Zones tab.

Click the Add Zone button and fill out the form to set up your zone: mylab.lan.

Adding the Primary Zone

Use the default Primary Zone type. Once you create the zone, it gets some default records, like :

mylab.lan

Edit the SOA record

Once you have created the primary zone, you will see only one NS record and an SOA record. Edit the SOA record and enter a valid email address as the Responsible Person: on which you can receive emails and save the record.

Primary Name Server: ns1
Responsible Person: [email protected]

Edit the SOA record to look like this.

Clusterd NS records

The clustering will generate the NS records to all the Technitium servers.

Non-clusterd NS records
  • Add NS records for all of the secondary name servers that you have planned. You do not need to enter any glue address for adding the NS records.
  • Add A records for all the name servers based on the list of name servers you prepared before starting the configuration. Each NS record's domain name must have a corresponding A record in the zone. If your name servers have IPv6 address, add AAAA records too for them corresponding to each NS record.

Add or Import Other Records

Add all the other records for the primary zone manually by referring at your existing DNS provider's panel or importing them OptionsImport Zone.

Add DNS entries for your systems

Let’s add a couple of records for systems on our network. Click the Add Record. Here I’m adding a record for my pve-1 server and mapping it to 192.0.2.41.

Adding a Record

An A record is the standard record to map a name to an IP address.

Using the option to create a reverse PTR record.

A PTR record maps an IP address to a name. This is a less obvious, but helpful in a few situations.

  • For public DNS servers: this is one way that services like email check that the IP address trying to send the email is part of a valid domain.
  • Being able to display friendly names instead of IP addresses when using troubleshooting tools like traceroute.
  • Give Technitium permission to create the reverse zone, as it doesn’t exist yet.

Once add the record will be seen in the zone

And in the zone list we can see that the reverse zone is created as 2.0.192.in-addr.arpa, it's the subnet 192.0.2.0 expressed in reverse order.

If we look in that zone we can see the PTR record that was created for pve-1, with a name of 41 for the last part of its IP address.

Going back to our forward zone mylab.lan, we can continue adding A records for all of our infrastructure hosts.

CNAME

A CNAME is an alias to another name. Suppose you also want to refer to your NAS 192.0.2.40 as both nas.mylab.lan and storage.mylab.lan.

That’s all there is setting up your private DNS domain’s zones. Now any client which uses this DNS server as its nameserver will be able to resolve names like srv-42.mylab.lan to their IP addresses.

Technitium is also a full-fledged DNS resolver, it can figure out the address of any other domain name you ask about as well. We didn’t have to configure any upstream DNS nameservers, unlike with a DNS forwarder where you need to tell it to forward to a specific nameserver like Cloudflare (1.1.1.1).

Once you added all the records, the primary zone is ready for the next step.

How to Query the Logs

Please install the Query Logs (Sqlite) DNS App or any other DNS app that supports query logging feature from the Apps section.

Go to Apps and hit the App Store button to install Query Logs (Sqlite) then hit Install next to the name of thr app to install it.

  • Logs all incoming DNS requests and their responses in a Sqlite database that can be queried from the DNS Server web console.
  • Warning! If you set enableVacuum to true in the configuration, the app will run the VACUUM command after deletion of records which will increase disk IO and may cause the app to not respond for a while. Its recommended to enable this feature periodically, only for a while as needed, to trim the db file size on disk.

Decrease disk writes

Logging is required during the initial setup phase to ensure the system functions as intended. Once the system is stable, logging can be reduced or disabled. If you choose to modify logging behavior, make sure you fully understand the implications before doing so.

To save your disk from a lot of writes we can use the In-Memory Stats feature and still have a semi useful Dashboard. Activate it by going to SettingsLogging and the section Stats check the Enable In-Memory Stats.

Alternatively, in the Enable Logging To section, you can disable all logging, including error logs and audit logs.


Once you have added all the records, the primary zone is ready for the next step.


Option – Set up a DNS cluster

For added stability we always need at least two DNS Servers on our network.
To add a cluster we need to create a second DNS Server, ns2 and create the cluster.

Create the cluster

The cluster management is handled on the AdministrationCluster tab.
On ns1 Create the cluster and on ns2 you join the cluster.


Option – Set up DHCP

This is an option, but a very useful option to have.

We like the DHCP server to provide three functions for us:

  1. Making sure that hosts get the IP addresses we’ve assigned to them in our DNS zone. Yes you can do this manually on each host, but having it centrally managed in DHCP is more convenient and easier to change in the future.
  2. Making sure that all of our network devices use our new DNS server as their name server. Similarly, we can do this on each device but managing it via DHCP is far more convenient.
  3. Updating our DNS records as devices come and go from the network.
⚠️
Disable all other DHCP Servers on the network, like those built into routers or OS installs, Alpine don't have this issue, but Ubuntu do.
⚠️
DHCP is not integrated into the cluster yet!

There are many ways to provide DHCP service on your network.

  • You can use your router’s built-in DHCP service.
  • Run the ISC DHCP server to complement the BIND 9 DNS server
  • Run the new Kea DHCP server to complement the BIND 9 DNS server

The main reason to use Technitium for DHCP is that it integrates DHCP with DNS right out of the box, ensuring that the two stay in sync and that your private domain records are always up to date

And all is controlled from a single plane-of-glass in the Thechnitium GUI.

Set up a DHCP Scope

Go to the DHCPScopes tab. By default, Technitium creates a scope, the subnet 192.168.1.0. Delete it and add your own subnet/subnets.

Add the scope for the 192.0.2.0 subnet by clicking the Add Scope -button.
Define the new scope using the form presented to you.

Creating a DHCP Scope

  1. First the scope needs a name, and then
  2. Define the range of IPs we’d like the DHCP server to lease out we reserve for:
    .1 the router, .253 the Primary and .254 the Secondary DNS server.
    So, e.g., 192.0.2.2.250 or rather 192.0.2.50.250 for more fixed IPs
  3. Enable the Ping Check, it's an additional safeguard to avoid introducing IP conflicts to your network if you have fixed IPs in the range.

For the Domain Name, and the Domain Search List we use mylab.lan . The Domain Search List, will be given to the clients so they know which domains to search if they have just a short name e.g. srv-42.

ℹ️
To automatically add any DHCP entry to the DNS server: enable the DNS Updates checkbox. This way the DHCP server will update any DNS records as clients come on and off the network.

Entries for non-local IP-Addresses

Specify the router so that our clients will know how to route non-local network traffic, and we specify the DNS servers. You can leave the default Use This DNS Server checked, but to give it a backup uncheck it and specify the IP address of this DNS server as the primary, and then a public one like Cloudflare’s 1.1.1.1 as the secondary. This just gives clients a backup if all our DNS servers are down.

Exclusions

The IP address range/ranges that must be excluded or not assigned dynamically to any client by the DHCP server e.g., a range for fixed IP servers or a VPN IP range.

Reserved leases

The last section is where you can define reserved leases. It is important to define a reserved lease for any machine you entered as an A record in the DNS zone, so here we’ll define reserved leases for srv-42 and mynas. This means they’ll get the same IP address every time, and their IP address won’t ever be used for another machine.

Click the Save button, and you should see the new scope in the list of scopes.

Once you create the scope, it is enabled automatically. If a different DHCP server is detected, Technitium refuses to start its own DHCP server to avoid multiple DHCP servers on the network.
Success is indicated by that the Enable button is replaced with a Disable button.

Test your DHCP Clients

Now you can go to any DHCP client on your network and release and renew its DHCP lease, and it should pick up a lease from our new DHCP server. You can confirm this on the DHCPLeases tab of the Technitium interface.

The Leases Tab

Here you will see all leases handled by Technitium. You can turn any lease from Dynamik to Reserved by hitting the 3 dots dropdown menu. Or delete it.

IP Reservations

You should add all your infrastructure devices into the Reserved Leases section.

Define DNS records and DHCP reserved leases for all servers at a minimum, as well as any other devices which need to be found by IP address, for example security cameras are added to the recording software via IP, not name.

DHCP and DNS co-operation

When a new client receives a DHCP lease, they also receive DNS entries. In a lab this is great as servers and services are generated and deleted all the time.

Edit Host Names in DHCP

If you want to chain a DHCP generated name you edit the DHCP → Scope → Edit and go to Reserveved Leases section where you change them. Having several devices called iPhone.mylab.lan is not correct, Rename adding the users name.


Option – Set up Ad-Blocking

This is optional as the main focus is to have DNS for the lab network.

A Technitium instance can also give you Ad Blocking in addition to DNS and DHCP service. Setting that up is really easy.

Go to SettingsBlocking -tab and add your favorite Blocking List from the Allow/Block List URLs and the Quick Add dropdown. Hagezi and Steven Black are industry standard what comes to block lists.


List of Apps

Advanced Blocking

Blocks domain names using block lists and regex block lists. Supports creating groups based on client's IP address or subnet to enforce different block lists and regex block lists for each group.

Advanced Forwarding

Provides advanced, bulk conditional forwarding options. Supports creating groups based on client's IP address or subnet to enable different conditional forwarding configuration for each group. Supports AdGuard Upstreams config files.

Auto PTR

Allows creating APP records in primary and forwarder zones that can return automatically generated response for a PTR request for both IPv4 and IPv6.

Block Page

Serves a block page from a built-in web server that can be displayed to the end user when a website is blocked by the DNS server.

Default Records

Allows setting one or more default records for configured local zones.

DNS64

Enables DNS64 function for both authoritative and recursive resolver responses for use by IPv6 only clients. Will cause connectivity issues for some websites without having NAT64 in place.

DNS Block List (DNSBL)

Allows creating APP records in primary and forwarder zones that can return A or TXT records based on the DNS Block Lists (DNSBL) configured. The implementation is based on RFC 5782.

DNS Rebinding Protection

Protects from DNS rebinding attacks using configured private domains and networks.

Drop Requests

Drops incoming DNS requests that match list of blocked networks or blocked questions.

Failover

Allows creating APP records in primary and forwarder zones that can return A or AAAA records, or CNAME record based on the health status of the servers. The app supports email alerts and web hooks to relay the health status.

Filter AAAA

Allows filtering AAAA records by returning NO DATA response when A records for the same domain name are available. This allows clients with dual-stack (IPv4 and IPv6) Internet connection to prefer using IPv4 to connect to websites and use IPv6 only when a website has no IPv4 support.

Geo Continent

Allows creating APP records in primary and forwarder zones that can return A or AAAA records, or CNAME record based on the continent or Autonomous System Number (ASN) the client queries from using MaxMind GeoIP2 Country database. Supports EDNS Client Subnet (ECS). This app requires MaxMind GeoIP2 database and includes the GeoLite2 version for trial.

Geo Country

Allows creating APP records in primary and forwarder zones that can return A or AAAA records, or CNAME record based on the country or Autonomous System Number (ASN) the client queries from using MaxMind GeoIP2 Country database. Supports EDNS Client Subnet (ECS). This app requires MaxMind GeoIP2 database and includes the GeoLite2 version for trial.

Geo Distance

Allows creating APP records in primary and forwarder zones that can return A or AAAA records, or CNAME record of the server located geographically closest to the client using MaxMind GeoIP2 City database. Supports EDNS Client Subnet (ECS). This app requires MaxMind GeoIP2 database and includes the GeoLite2 version for trial.

Log Exporter

Allows exporting query logs to third party sinks. It supports exporting to File, HTTP endpoint, and Syslog (UDP, TCP, TLS, and Local protocols).

No Data

Allows creating APP records in Conditional Forwarder zones to return NO DATA response for requests that match the configured query type (QTYPE) to prevent them from being forwarded.

NX Domain Override

Overrides NX Domain response with custom A/AAAA record response for configured domain names.

Query Logs (MySQL)

Logs all incoming DNS requests and their responses in a MySQL/MariaDB database that can be queried from the DNS Server web console.

Query Logs (PostgreSQL)

Logs all incoming DNS requests and their responses in a PostgreSQL database that can be queried from the DNS Server web console.

Query Logs (Sqlite)

Logs all incoming DNS requests and their responses in a Sqlite database that can be queried from the DNS Server web console.

Query Logs (SQL Server)

Logs all incoming DNS requests and their responses in a Microsoft SQL Server database that can be queried from the DNS Server web console.

Split Horizon

Allows creating APP records in primary and forwarder zones that can return different set of A or AAAA records, or CNAME record for clients querying over public, private, or other specified networks.

Enables Address Translation of IP addresses in a DNS response for A & AAAA type request based on the client's network address or configured domain names, and the configured 1:1 translation.

Weighted Round Robin

Allows creating APP records in primary and forwarder zones that can return A or AAAA records, or CNAME record using weighted round-robin load balancing.

What Is My Dns

Allows creating APP records in primary and forwarder zones that can return the IP address of the user's DNS Server for A, AAAA, and TXT queries.

Wild IP

Allows creating APP records in primary and forwarder zones that can return the IP address embedded in the subdomain name for A and AAAA queries. It works similar to sslip.io.

Zone Alias

Allows configuring aliases for any zone (internal or external) such that they all return the same set of records.


And now we have

  • A private DNS for our domain mylab.lan
  • Defined our hosts in our DNS zone
  • Secured DNS by a cluster – option
  • The DHCP server make sure that: – option
    • all clients point to the right nameserver
    • DNS knows about everyone on the network.
  • Ad-Blocking – option


References

About IPs [1] Technitium [2] RFC 6762 [3] RFC 8375 [4] Bind 9 [5]


  1. IPv4 Address Blocks for Documentation are by RFC 5737:
    TEST-NET-1 = 192.0.2.0/24, -2 = 198.51.100.0/24, -3 = 203.0.113.0/24 ↩︎

  2. Technitium DNS server has 30+ contributors homepage and on GitHub ↩︎

  3. Proposed Standard: Multicast DNS RFC 6762 ↩︎

  4. Proposed Standard: Special-Use Domain '.home.arpa' RFC 8375 ↩︎

  5. The industry standard DNS Bind 9, ISC DHCP, KEA DHCP and the GUI Stork. All provided by the Internet Systems Consortiom homepage ↩︎