Skip to content

Pi-hole: When Every Client Looks Like the Router

The Problem

You open Pi-hole's dashboard expecting a per-device breakdown, but one client — your router's IP — dwarfs everything else, and half your devices are invisible. Per-client blocking, allowlists, and "who is querying what" are all useless because Pi-hole can't see the real originating device.

There are actually two separate problems hiding here:

  1. Attribution — the router is proxying DNS, so every query arrives from the router's IP.
  2. Identification — the devices Pi-hole does see directly are all named iPhone, iPad, Android, etc., and there are ghost duplicates of each.

Part 1 — Fix attribution (stop the router proxying DNS)

When DHCP hands out the router as the DNS server, clients query the router's built-in resolver (dnsmasq), which forwards to Pi-hole. Pi-hole logs the query as coming from the router, not the device.

Fix (DHCP clients): hand out the Pi-hole IP directly as the DNS server. Either:

  • Set Pi-hole as the DHCP DNS server in the router (LAN → DHCP → DNS Server = <PIHOLE_IP>), and disable "advertise router's IP in addition to DNS" if your router offers it, or
  • Let Pi-hole run DHCP and disable the router's DHCP server.

Devices pick up the new resolver on their next lease renewal, so this is gradual — shorten the lease time or reconnect a device to hurry it. Enabling Pi-hole's Conditional Forwarding to the router fixes name lookups but not the proxy masking — only handing out Pi-hole directly does.

Static hosts need a manual pin

DHCP changes never touch machines with static network config — typically your servers. Those keep whatever resolver their config names, so they stay masked behind the router forever. Point each one at Pi-hole directly.

On a systemd-resolved + NetworkManager host (Fedora, modern Ubuntu), pin the LAN connection:

CONN="$(nmcli -g GENERAL.CONNECTION device show "$(ip -4 route show default | awk '{print $5; exit}')")"
nmcli con mod "$CONN" ipv4.dns "<PIHOLE_IP>"
nmcli con mod "$CONN" ipv4.ignore-auto-dns yes   # ignore DHCP-supplied resolvers
nmcli con mod "$CONN" ipv4.dns-search "lan"
nmcli con up "$CONN"
resolvectl status "$(ip -4 route show default | awk '{print $5; exit}')"   # DNS Servers should be PIHOLE_IP only

The change is written to the connection profile, so it survives reboot. Rollback is ipv4.ignore-auto-dns no + blank ipv4.dns + con up.

Tailscale note: on a host where Tailscale manages DNS (--accept-dns/CorpDNS), a local resolver of 100.100.100.100 fronts everything and forwards non-tailnet queries to the system base resolver. Pinning the base resolver (above) is enough — Tailscale then forwards to Pi-hole, sourced from the host's LAN IP, and attribution works. Do not set --accept-dns=false to force it; that disables MagicDNS name resolution.

Part 2 — Identify generic-named clients

Once devices query Pi-hole directly, many still show as generic names with ghost duplicates. That's Apple/Android randomized ("private") Wi-Fi MAC addresses: the device reports a generic hostname and re-rolls its MAC on rejoin, so each reincarnation is a new Pi-hole client. Three ways to tell them apart:

1. mDNS / Bonjour sweep — Apple devices broadcast their real name ("Alex's iPhone") over Continuity even behind a private MAC, when awake:

sudo apt install avahi-utils        # or: dnf install avahi-tools
avahi-browse -a -t -r -p | awk -F';' '/^=/{print $8"  ->  "$4}' | sort -u

This cleanly names always-on gear (speakers, printers, HomePods, hubs) but misses sleeping phones.

2. Query-pattern fingerprint — the reliable method, and it works for devices that have already left the network (their history is retained). Pull each client's top domains from Pi-hole's FTL database and read the identity signals: work MDM domains (manage.microsoft.com, Intune) → a work phone; a game or kids' video service → a child's tablet; your own self-hosted services → your personal devices.

3. MAC vendor — mostly a trap. A randomized MAC (the second hex digit of the first octet is 2, 6, A, or E) makes the vendor lookup a coincidental match. Only globally-administered MACs give a true vendor.

Presence vs. departure

To tell who is currently home, sort clients by last query time, not "last seen" — the latter is an ARP timestamp that stays current for absent devices. A stale last-query means the device has left or powered down.

Making names stick

Assigning a friendly name to a randomized-MAC device is futile — it re-rolls and becomes a ghost again. For durable names:

  1. On the device, turn off Private Wi-Fi Address for your home network (iOS: Settings → Wi-Fi → network → Private Wi-Fi Address → Off/Fixed).
  2. Add a DHCP reservation (MAC → fixed IP) on the router.
  3. Name the client in Pi-hole with a local DNS record (<IP> friendly-name) — Pi-hole shows the reverse-resolved name in the dashboard.

Always-on devices with real (non-randomized) MACs — printers, speakers, servers — can skip straight to steps 2–3.

Notes

  • Attribution and identification are independent: fix the router proxy first, or you're just naming the router.
  • The generic-name problem is by design (privacy). Turning off Private Wi-Fi Address per device is the only durable cure; weigh that against the privacy trade-off on devices you don't control.