Network and DNSLocal DNSIntermediate90-120 minutesLab

Create a Secondary Pi-hole DNS Node and Test Resolver Resilience

Build an independent secondary Pi-hole resolver, align the settings that should match the primary, and test both resolvers before advertising them together to clients.

Last reviewed8/19/2026
Pi-hole core deploymentssecondary DNS and failoverresolver validationclient DNS behavior
Raspberry Pi OSPi-hole v6DNSBash

Expected Outcome

Two Pi-hole DNS resolvers that can each answer independently, with a documented client test proving the secondary remains usable when the primary resolver is unavailable.

Assumptions

  • A Raspberry Pi 3 or newer running a current Raspberry Pi OS release.

  • An existing primary Pi-hole resolver that is healthy before this Lab begins.

  • Console or SSH access with a user that can run `sudo` on both Pi-hole hosts.

  • A test client whose DNS settings can be changed without affecting the rest of the network.

  • A maintenance window if you intend to stop the primary Pi-hole service for an outage test.

Bill of Materials

  • Secondary Raspberry Pi with a reliable power supply and supported storage.

  • Network access to the official Pi-hole GitHub repository.

  • A record of the primary resolver's upstream DNS choices, local DNS records, allow/block policy, and DHCP role if Pi-hole provides DHCP.

  • A workstation with `dig` or an equivalent DNS query tool for direct resolver tests.

Build Steps

  1. Capture the primary and secondary network baseline

    Record the primary resolver address, secondary host address, default gateway, and current upstream DNS policy before installing or changing anything. The secondary must be able to resolve externally without depending on the primary Pi-hole; otherwise a primary outage also removes the secondary's upstream path.

    Manual or UI step

    • hostnamectl

    • ip -brief address

    • ip route

    Read-only command: verify target and scope

    cat /etc/resolv.conf
  2. Install prerequisites and retrieve the official Pi-hole installer source

    Install Git and DNS test utilities, then clone the official Pi-hole repository rather than piping a remote installer directly into a privileged shell. Record the exact Git commit you reviewed so the installation evidence identifies what was executed.

    Changes system state: review before running

    sudo apt update
    sudo apt install -y git dnsutils
    git clone --depth 1 https://github.com/pi-hole/pi-hole.git ~/Pi-hole
    git -C ~/Pi-hole rev-parse HEAD

    Manual or UI step

    • less "$HOME/Pi-hole/automated install/basic-install.sh"

  3. Install Pi-hole from the reviewed local script

    Run the locally reviewed installer and choose the interface, static address, and upstream resolver deliberately. Configure upstream resolvers that remain reachable when the primary Pi-hole is offline; do not point the secondary exclusively at the primary Pi-hole if resilience is the goal.

    Review before running: verify target, scope, and execution context

    sudo bash "$HOME/Pi-hole/automated install/basic-install.sh"

    Manual or UI step

    • pihole status

    • pihole version

  4. Align policy without copying live Pi-hole state directories

    Use Pi-hole's supported configuration and administration surfaces to reproduce only the settings that should match: upstream policy, adlists, allow/block entries, local DNS records, privacy settings, and any other intentional policy. Pi-hole v6 stores configuration in /etc/pihole/pihole.toml, but do not use a generic rsync --delete of /etc/pihole or /etc/dnsmasq.d as a synchronization strategy; those paths can contain node-specific and live service state.

    Manual or UI step

    • pihole status

    Read-only command: verify target and scope

    sudo ls -l /etc/pihole/pihole.toml
  5. Prove each resolver independently

    Query the primary and secondary explicitly from a test client. Direct queries establish that each resolver works on its own before client configuration introduces resolver-selection behavior.

    Read-only command: verify target and scope

    dig @<PRIMARY_PI_IP> example.com A +short
    dig @<SECONDARY_PI_IP> example.com A +short
    dig @<PRIMARY_PI_IP> pi.hole A +short
    dig @<SECONDARY_PI_IP> pi.hole A +short
  6. Test one client with both resolver addresses

    Configure only a disposable or low-impact test client to use both Pi-hole addresses. Do not assume clients will always use the first address until it fails; resolver selection and retry behavior vary by operating system and application. Generate several DNS lookups and confirm both Pi-hole dashboards or query logs reflect expected traffic before changing router-wide DHCP settings.

    Read-only command: verify target and scope

    dig example.com
    dig cloudflare.com
    dig github.com
  7. Run a controlled primary-outage test

    If the maintenance window allows it, temporarily stop Pi-hole DNS on the primary, then repeat direct and normal client lookups. The success criterion is not that every client instantly switches in a strict order; it is that the tested client can still resolve through the secondary and that you have observed the actual failover behavior of your client/network combination.

    Changes system state: review before running

    ssh <PRIMARY_ADMIN>@<PRIMARY_PI_IP> 'sudo systemctl stop pihole-FTL'
    dig @<SECONDARY_PI_IP> example.com A +short
    dig example.com
  8. Restore the primary and decide whether to advertise both resolvers

    Restore the primary service first. Only after direct tests and the controlled client test succeed should you update router or DHCP scope options to advertise both resolver addresses. Preserve the prior DHCP/DNS settings so the network-wide change has an immediate backout path.

    Changes system state: review before running

    ssh <PRIMARY_ADMIN>@<PRIMARY_PI_IP> 'sudo systemctl start pihole-FTL'
    dig @<PRIMARY_PI_IP> example.com A +short
    dig @<SECONDARY_PI_IP> example.com A +short

Validation

  • Confirm both Pi-hole services are healthy and independently answer direct DNS queries.

    Read-only command: verify target and scope

    dig @<PRIMARY_PI_IP> example.com A +short
    dig @<SECONDARY_PI_IP> example.com A +short
  • Confirm the secondary still resolves while the primary service is stopped during the approved outage test.

    Read-only command: verify target and scope

    dig @<SECONDARY_PI_IP> example.com A +short
  • After restoring the primary, confirm both resolvers are healthy before ending the maintenance window.

    Read-only command: verify target and scope

    dig @<PRIMARY_PI_IP> example.com A +short
    dig @<SECONDARY_PI_IP> example.com A +short

Troubleshooting

  • If the secondary answers local queries but not internet names, verify its configured upstream resolvers and routing. Do not make the secondary depend exclusively on the primary if the objective is primary-resolver outage resilience.

    Manual or UI step

    • ip route

    • pihole status

    Read-only command: verify target and scope

    dig @<SECONDARY_PI_IP> example.com
  • If a client does not switch as expected, verify the DNS addresses the client actually received and test each resolver explicitly. Client behavior can differ from a simple primary/secondary ordering assumption.

Cleanup or Rollback

  • Always restore the primary Pi-hole service after an outage test.

    Changes system state: review before running

    ssh <PRIMARY_ADMIN>@<PRIMARY_PI_IP> 'sudo systemctl start pihole-FTL'
  • If network-wide testing fails, restore the previous router or DHCP DNS options and remove any temporary DNS override from the test client. Leave the secondary unadvertised until the failure is understood.

Next Improvements

  • Document how policy changes will be kept aligned across the two Pi-hole nodes using supported administration/configuration methods.

  • Repeat the outage test from representative Windows, Linux, mobile, or appliance clients if their DNS behavior matters to your environment.

  • Add monitoring for resolver availability so a failed node is visible before the next maintenance event.

References

Keep Moving

Build on what you just completed

Continue with a related Lab or return to this build path for a different implementation.