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:
- Attribution — the router is proxying DNS, so every query arrives from the router's IP.
- 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:
- On the device, turn off Private Wi-Fi Address for your home network (iOS: Settings → Wi-Fi → network → Private Wi-Fi Address → Off/Fixed).
- Add a DHCP reservation (MAC → fixed IP) on the router.
- 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.