One DNS Authority for a Segmented Lab, With Room Left for Red-Team Testing
Pi-hole as the resolver for every infrastructure segment, rolled out top-down, with three gotchas solved and offensive segments deliberately exempt.
Why
Even behind pfSense and VyOS, every DNS query that leaves the lab in plaintext tells the ISP which domains it touched, and HTTPS doesn't hide that. Different VMs were also resolving through different upstreams (some via pfSense, some hardcoded public resolvers), so there was no single place to see or control lab DNS.
Design
- Pi-hole on its own DNS segment is the resolver for infrastructure: pfSense, both hypervisors, server VMs
- pfSense's own system DNS points to Pi-hole
- Offensive segments are exempt. Forcing all DNS through one resolver kills rogue-DNS, DoH and DNS-tunneling exercises, so attacker and victim segments keep flexible DNS by design.
Rollout order
Top down, one test host at a time:
- pfSense system DNS → Pi-hole
- Hypervisor 1, hypervisor 2
- One test VM, verified in the Pi-hole query log
- The remaining server VMs
The Pi-hole query log was the verification: each client's address showing up next to its lookups.


Gotcha 1 — "Destination Host Unreachable" on a new segment
After creating the DNS segment, a VM on it couldn't reach its gateway. The VLAN was defined on VyOS and pfSense had a static route, but I hadn't added the VLAN to the switch trunk. Every layer needs to know about the segment.
I tested the path before moving the VM, with a temporary sub-interface:
sudo ip link add link <nic> name <nic>.<vid> type vlan id <vid>
sudo ip addr add <test-ip>/24 dev <nic>.<vid>
sudo ip link set <nic>.<vid> up
ping -c 3 <segment-gateway>
Gotcha 2 — Pi-hole ignored other segments
With Pi-hole's interface setting on "allow only local requests", queries from other segments were refused. Switching to respond only on the specific interface fixed it. Routed clients aren't "local" from Pi-hole's point of view.
Gotcha 3 — edits to resolv.conf that didn't stick
On Ubuntu-based hosts (EVE-NG here), /etc/resolv.conf is a stub generated by systemd-resolved. Editing it works until the next reload. The persistent fix is upstream DNS in the resolved/netplan config, not the stub file.
Lessons
- Segments exist in four places: switch, hypervisor bridge, router and firewall. Miss one and you get "unreachable".
- Centralize where it's infrastructure, and leave the attack surface flexible where that's the point.
- **Know who owns
/etc/resolv.conf** before editing it.
Sources: ISP Visibility in Lab Network (21 Feb 2026), Pi-hole DNS Setup (4 Mar 2026), VM Migration Strategy (5 Apr 2026)