Building a Reliable Home Network with OpenWrt and Pi-hole

Published November 02, 2026 • Updated November 02, 2026

A well-configured home network should provide reliable connectivity, centralised DNS resolution, automatic hostname discovery and a sensible separation between local network services and external DNS resolution.

My setup uses a GL.iNet Beryl 7 (GL-MT3600BE), based on OpenWrt, as the primary router and DHCP server, with Pi-hole providing DNS resolution and network-wide filtering.

The objective is to have a single, consistent source of truth for local device addresses, while allowing Pi-hole to handle DNS requests from all network clients. The router should manage device registration through DHCP, Pi-hole should resolve local names by consulting the router, and all other DNS requests should continue through Pi-hole’s configured upstream DNS services.

This article documents the network configuration, the DNS architecture, the problems encountered and the changes made to get the components working together.

1. Network architecture

The network uses the following arrangement.

Component Address Responsibility
Beryl 7 router 192.168.1.1 Gateway, DHCP and local DNS
Pi-hole 192.168.1.2 DNS resolution and filtering
Dell laptop 192.168.1.101 Desktop/client
servo 192.168.1.10 Raspberry Pi home server
other 192.168.1.12 Additional home server

The local network uses the 192.168.1.0/24 subnet.

The responsibilities are deliberately separated.

Beryl 7 handles DHCP. It allocates IP addresses to clients, maintains DHCP leases and registers client hostnames with its integrated DNS service.

Pi-hole handles DNS for network clients. It filters DNS requests, resolves externally hosted domain names using its configured upstream services and forwards local hostname queries to Beryl.

This distinction is important. Pi-hole does not automatically know which IP addresses Beryl has assigned to DHCP clients. Without additional configuration, Pi-hole cannot necessarily resolve local device names, even though the router knows about those devices.

Pi-hole’s conditional forwarding, now called reverse-server configuration in Pi-hole 6, provides the mechanism to bridge that gap.

Beryl remains the only DHCP server. Pi-hole remains the DNS resolver advertised to network clients.

2. The original problem: two interfaces, one hostname

The initial problem appeared on my Raspberry Pi server. The machine had both Ethernet and Wi-Fi enabled. Both interfaces were connected to the same network and independently obtained DHCP leases. The output of ip a showed:

eth0:
    MAC: ..:..:..:..:..:24
    IP:  192.168.1.10

wlan0:
    MAC: ..:..:..:..:..:25
    IP:  192.168.1.11

Both interfaces were advertising the same machine hostname, but they had different MAC addresses and IP addresses.

From the router’s perspective, these were two separate DHCP clients.

This created an ambiguous hostname-to-IP association. The router could associate with the Wi-Fi address rather than the Ethernet address, despite Ethernet being connected and intended as the primary interface.

Consequently, connecting using the hostname could resolve to the Wi-Fi address, while connecting explicitly using the IP worked correctly.

Disabling Wi-Fi on the server

Since this machine is a home server with a wired Ethernet connection, there was no reason to maintain the wireless interface.

NetworkManager is used by a Pi 5 installed with Pi OS (Lite), so Wi-Fi was disabled with:

sudo nmcli radio wifi off

This disables the wireless radio through NetworkManager and persists its software-blocked state.

I also removed the previous DHCP client entries from the Beryl interface so that old registrations would not continue to cause confusion.

For a permanent server configuration, it is also sensible to create a DHCP reservation against the Ethernet MAC address. This ensures it retains the same IP address without requiring a statically configured address on the Linux machine itself.

3. Understanding the DNS problem

With Wi-Fi disabled, Ethernet was working correctly, but hostname resolution remained unreliable.

The important distinction was between DHCP and DNS.

DHCP assigns an IP address to a network interface. The DHCP server can also learn the client’s hostname and associate it with the assigned address.

DNS provides the mechanism for translating that hostname into an IP address.

Beryl 7 uses dnsmasq, which combines DHCP and DNS functionality. This allows it to maintain local DNS information based on DHCP leases.

Pi-hole, however, has its own DNS service. It does not automatically import the DHCP leases held by Beryl.

My desktop used 192.168.1.2 which meant DNS queries were going to Pi-hole rather than directly to Beryl.

Pi-hole did not initially have a working route for resolving the local device names through Beryl.

This explained why connecting using an IP address worked while hostname-based SSH connections failed.

An additional complication: /etc/hosts

During troubleshooting, I discovered that the desktop also had manually configured hostname entries in /etc/hosts.

These entries were left over from earlier configuration and were pointing to an obsolete address.

The output from systemd-resolved included:

Data from: synthetic

This was an indication that the response was being synthesised locally rather than obtained from the configured DNS server.

The entries in /etc/hosts were commented out to allow the system to use the central DNS infrastructure.

This is an important lesson: local hosts-file entries can override the central DNS infrastructure and make troubleshooting considerably more confusing.

For this network, I wanted hostname management to happen centrally through DHCP and DNS rather than through individual client hosts files.

4. Choosing a local DNS domain: .lan versus .home.arpa

Another issue was the local DNS domain.

The initial configuration used .lan, which is commonly used in home networks.

However, .lan is not an officially reserved special-use domain. There is a possibility of namespace collisions with externally registered domains. The alternative is .home.arpa.

RFC 8375, published by the IETF in May 2018, specifically reserves home.arpa for residential home networks.

This makes it the more appropriate choice for a modern home network.

The advantages include:

A resulting hostname looks like servo.home.arpa

The intention is still to use short names when connecting like ssh servo. The operating system’s DNS search domain makes this possible by automatically appending home.arpa to an unqualified hostname.

The full hostname and the short hostname therefore refer to the same device.

5. Configuring Beryl 7 / OpenWrt

Beryl 7 provides a graphical administration interface, with access to the underlying OpenWrt LuCI interface.

The relevant configuration is under:

Network → DHCP and DNS → General Settings

The important fields are:

Setting Configuration
Domain required Enabled
Authoritative Enabled
Local server /home.arpa/
Local domain home.arpa

The two domain settings serve different purposes.

Local server

This controls which DNS domain dnsmasq considers local.

The initial configuration was: /lan/

This meant dnsmasq was treating .lan as its local DNS domain.

It was changed to: /home.arpa/

This tells dnsmasq to handle queries for that domain locally rather than forwarding them to an upstream DNS server.

Local domain

This defines the local domain suffix used when registering DHCP hostnames and providing domain information to clients.

It was configured as: home.arpa

This allows DHCP hostnames to be associated with their fully qualified names.

For example, a DHCP client identifying itself as servo can be resolved as: servo.home.arpa

The client can also receive the local DNS search suffix through DHCP.

The important point is that both settings need to agree. Having the local domain set to home.arpa while the local server still specifies /lan/ creates an inconsistent configuration.

Underlying dnsmasq configuration

These LuCI settings correspond to the relevant dnsmasq configuration in OpenWrt.

The expected configuration is:

config dnsmasq
    option local '/home.arpa/'
    option domain 'home.arpa'

The configuration can be inspected over SSH to Beryl:

uci show dhcp.@dnsmasq[0] | grep -E 'domain|local|expandhosts'

After changing the configuration through LuCI, the DNS service applies the changes.

It can also be restarted manually using:

/etc/init.d/dnsmasq restart

The OpenWrt dnsmasq documentation describes how the local and domain options work together to provide local DNS resolution for DHCP clients.

6. Configuring Pi-hole

Pi-hole needs to know that Beryl is responsible for local DNS resolution. This is configured using conditional forwarding, which Pi-hole 6 now refers to as reverse-server configuration.

There are two important settings.

Local DNS domain

Under Pi-hole’s DNS configuration:

dns.domain.name = home.arpa
dns.domain.local = true

The local domain is now home.arpa.

Enabling the local-domain setting tells Pi-hole that this domain is local and should not be sent to ordinary upstream DNS servers.

A matching reverse-server entry allows Pi-hole to forward the local queries to Beryl instead.

Conditional forwarding

The configuration is:

true,192.168.1.0/24,192.168.1.1,home.arpa

The individual fields have the following meanings:

Field Value Purpose
Enabled true Enables the forwarding rule
Network 192.168.1.0/24 Defines the local network
Server 192.168.1.1 Identifies Beryl as the DNS server
Domain home.arpa Defines the local DNS domain

The fourth field is particularly important.

Initially, conditional forwarding had been configured with the network range and Beryl’s address, but without the local domain suffix.

Adding home.arpa completed the association between the local network, the DHCP/DNS server and the domain that Pi-hole should forward.

In Pi-hole 6, this configuration corresponds to dns.revServers.

The relevant configuration can be inspected with:

pihole-FTL --config dns.revServers

The important architectural distinction is that Pi-hole does not need to maintain its own independent list of local DHCP clients. It can ask Beryl to resolve names from the DHCP lease information.

This is especially useful as the network grows. New devices can join and obtain names automatically without requiring a manual Pi-hole DNS record for every device.

7. How the complete DNS resolution process works

With the router and Pi-hole configured consistently, the resolution process is straightforward.

Suppose I run: ssh servo

The operating system first attempts to resolve the hostname.

The client has been configured with the DNS search domain: home.arpa

It can therefore resolve the short name using: servo.home.arpa

The DNS query is sent to Pi-hole.

Pi-hole recognises that home.arpa is a local domain and that the matching conditional-forwarding rule directs these queries to 192.168.1.1

Beryl receives the query and looks up the hostname using its local dnsmasq information, including DHCP lease registrations.

It returns: servo.home.arpa -> 192.168.1.10

Pi-hole returns the answer to the client, which can then establish its SSH connection.

External DNS requests follow a different path.

For example: ping www.example.com

The query is sent to Pi-hole, which processes it using its configured upstream DNS services and filtering rules.

It is not necessary to involve Beryl in normal external DNS resolution.

This gives the network a clean division of responsibility:

This is the intended benefit of conditional forwarding: local device information remains authoritative on the router, while Pi-hole remains the central DNS service for clients.

8. Testing and troubleshooting

A significant part of getting this configuration working was testing each component independently.

It is important not to assume that a successful query against one DNS server means the entire chain is working.

Test Beryl directly

The first test is to query Beryl without involving Pi-hole:

dig @192.168.1.1 servo
dig @192.168.1.1 servo.lan
dig @192.168.1.1 servo.home.arpa

Before changing Beryl’s local domain, the results were:

servo              -> 192.168.1.10
servo.lan          -> 192.168.1.10
servo.home.arpa    -> NXDOMAIN

This established that Beryl knew the device but was publishing it under the old .lan domain.

After changing the Local server setting to /home.arpa/, the result became: servo.home.arpa -> 192.168.1.10

This confirmed that Beryl was now registering the hostname in the intended domain.

Test Pi-hole directly

Next, query Pi-hole:

dig @192.168.1.2 servo.home.arpa

The expected response is:

servo.home.arpa. IN A 192.168.1.10

This was confirmed working.

The result demonstrated that Pi-hole was successfully forwarding the local hostname query to Beryl and returning the correct address.

Test multiple devices

The same tests should be applied to other DHCP clients:

dig @192.168.52.1 other.home.arpa
dig @192.168.52.2 other.home.arpa

Both should return the same address.

This is important because the intended configuration is a general solution for all DHCP clients, not just a manually configured record for servo.

Test the client resolver

The final step is to test hostname resolution through the operating system rather than querying Pi-hole directly.

On Ubuntu, systemd-resolved provides useful diagnostic commands:

resolvectl status
resolvectl query servo.home.arpa
getent hosts servo

The expected DNS configuration is:

DNS Servers: 192.168.1.2
DNS Domain: home.arpa

The first confirms that Pi-hole is being used as the DNS server. The second confirms that the client has the correct search domain.

The third checks the operating system’s normal name-resolution mechanism.

9. DHCP search domains and why flushing DNS caches was not enough

One additional issue appeared after migrating from .lan to .home.arpa.

The client desktop had previously received the search domain: lan

This was visible in: resolvectl status

Changing the router and Pi-hole configuration does not automatically change the DNS search domain already held by every connected client.

This is where DHCP configuration becomes relevant again.

The client needs to obtain the updated search domain from Beryl. This normally happens when it obtains a fresh DHCP configuration.

Running: sudo resolvectl flush-caches only clears the DNS cache.

It does not renew the DHCP lease, change the DNS search domain or fetch new DHCP options.

On a NetworkManager-managed Ubuntu system, the active connection can be identified with:

nmcli connection show --active

The connection can be renewed by disconnecting and reconnecting it:

CON=$(nmcli -g GENERAL.CONNECTION device show wlp0s20f3)
sudo nmcli connection down "$CON"
sudo nmcli connection up "$CON"

This briefly interrupts the connection but obtains fresh DHCP configuration.

Then check: resolvectl status

The desired result is:

DNS Servers: 192.168.1.2
DNS Domain: home.arpa

Finally:

sudo resolvectl flush-caches
getent hosts servo
ssh servo

This last client-side search-domain check is essential when using short hostnames. Fully qualified names can resolve correctly even when the client has not yet obtained the correct search suffix.

10. Final configuration summary

The intended configuration is as follows.

Beryl 7 / OpenWrt

Setting Value
LAN address 192.168.1.1
LAN subnet 192.168.1.0/24
DHCP server Enabled
DHCP authoritative Enabled, Beryl is the only DHCP server
Local server /home.arpa/
Local domain home.arpa
Local DNS dnsmasq

Pi-hole

Setting Value
IP address 192.168.1.2
Local DNS domain home.arpa
Local domain enabled Yes
Conditional forwarding Enabled
Network range 192.168.1.0/24
Forwarding server 192.168.1.1
Forwarding domain home.arpa

Conditional forwarding: true,192.168.1.0/24,192.168.1.1,home.arpa

Network clients

Setting Value
DNS server 192.168.1.2
DNS search domain home.arpa
DHCP server 192.168.1.1

Clients should obtain their configuration through DHCP rather than requiring individual DNS configuration.

11. Conclusion

The main lesson from this exercise is that DHCP and DNS are related services, but they are not interchangeable.

The router knows which devices have obtained DHCP leases. Pi-hole provides DNS resolution to the clients, but it needs a mechanism to obtain the router’s local hostname information.

Conditional forwarding provides that mechanism.

The other important lesson was ensuring that the local domain is consistent across the entire network. Beryl, Pi-hole and the client DNS search configuration must agree. Changing only one component can result in DNS queries being sent to the wrong place or the wrong domain being searched.

The final architecture provides several advantages:

The goal is to have a network where devices can be added, removed or assigned new DHCP addresses without requiring corresponding manual DNS changes.

For a home network containing several servers, Raspberry Pis, desktops, virtual machines, IoT devices and other services, this is a considerably more maintainable approach than relying on individual hosts files or manually maintained DNS records.

References


Appendix

DHCP Renewal, Client Refresh and Safe Remote Administration

An important lesson from this exercise was that changing router DHCP or DNS settings does not automatically update the configuration held by existing clients.

This became apparent when servo failed to resolve after the migration to home.arpa. Rebooting the machine caused it to renew its DHCP configuration and announce its hostname again. Beryl then registered the hostname correctly, allowing Pi-hole to resolve it through conditional forwarding.

Temporary DHCP lease reduction

A useful administration technique is to temporarily reduce DHCP lease duration when making network-wide changes.

Situation Suggested lease
Normal operation 24 hours
Configuration migration 5–15 minutes
Short-term troubleshooting 2–5 minutes

Shorter leases allow obsolete DHCP configuration to expire sooner, but do not force existing clients to renew immediately. The new lease duration generally takes effect when clients next contact the DHCP server.

Once the migration is complete and clients have refreshed their configuration, restore the normal lease duration.

Refresh DHCP without rebooting

A full reboot is often the simplest approach, particularly for servers, but is not always necessary.

On Linux systems using NetworkManager, identify the active connection:

nmcli connection show --active

For a locally administered machine, the connection can be restarted with:

sudo nmcli connection down "<connection-name>"
sudo nmcli connection up "<connection-name>"

This obtains fresh DHCP configuration, including the IP address, gateway, DNS servers and search domain.

Important: Never casually run these commands interactively over SSH on a remotely administered machine.

The connection down command will disconnect the network interface carrying the SSH session. Your SSH connection will terminate, and the shell may not survive long enough to execute the subsequent connection up command.

Simply joining the commands with && does not make this safe.

Safer remote administration using systemd-run

When remotely refreshing a network connection, schedule the reconnection independently of the SSH session using systemd.

Check that the connection is configured to reconnect automatically:

nmcli -g connection.autoconnect connection show "<connection-name>"

Then schedule the disconnect and reconnect operation:

sudo systemd-run --unit=nm-reconnect --on-active=30s \
  /bin/sh -c 'nmcli connection down "<connection-name>"; sleep 5; nmcli connection up "<connection-name>"'

This approach:

  1. Creates a system-level scheduled operation.
  2. Waits 30 seconds, allowing time to prepare for the interruption.
  3. Disconnects the NetworkManager connection.
  4. Waits five seconds.
  5. Attempts to reconnect the same connection.

Because systemd manages the scheduled operation independently of the SSH session, it continues running even after the remote terminal disconnects.

After allowing time for reconnection, establish a new SSH session and verify connectivity.

The operation can be inspected using:

sudo journalctl -u nm-reconnect.service

Remote administration precaution: This method reduces the risk of losing access but cannot guarantee recovery if the connection profile is incorrect, the DHCP server is unavailable, or the network fails to reconnect. Where possible, retain local console or out-of-band access before making changes to remote networking.

Also note that reconnecting may result in a different DHCP address unless the device has a reservation.

Other useful practices:

Practical takeaway

For future network migrations, the recommended sequence is to back up configurations, temporarily reduce lease duration if appropriate, make the router and DNS changes, renew or reconnect affected clients, verify hostname resolution, and restore normal lease settings.

For remotely administered systems, always arrange an independent reconnection mechanism before deliberately taking down the network interface carrying your management session.

The central principle is that changing the network infrastructure and refreshing the configuration held by existing clients are two separate tasks. Both must be completed for changes to take effect consistently across the LAN.