I want PiHole and BIND on the same host, and I'm not alone, and everyone seems to be asking the same question : how the fuck the configuration of pihole should be.
Préliminary information
- ubuntu version : 24.something (server).
- pihole version : 6.1.something.
- Both services run on a host named : lenopi.
I. The desired behavior
Pihole's IP is the default DNS serveur for my home network. DHCP advertise its address. Every host which needs to resolve a name must query the pihole.
The host machine (lenopi) runs a BIND server.
Pihole uses the BIND resolver as upstream.
Meaning that :
- The Pihole does caching and filtering. When queried, if the domain is in block list, it'll return 0.0.0.0. If it's in its cache, it'll return the host address. If it's unknown it'll forward the request to BIND.
- BIND works in a recursive manner. Either it knows about the domain (locally defined), and it can reply with the Authoritative flag (aa) or it'll ask somewhere else (recursively) until it gets the answer, or fails.
II. The IP config on the host
Host Lenopi has 1 physical interface, with its IP address. I suppose you're SSHing to it. Which, btw, is not a very good idea when you want to mess with its interfaces. You've been warned.
A secondary address must be added.
For example : 192.168.0.26 and 192.168.0.27 as secondary.
192.168.0.254 is the gateway (router & default route).
III. The setup
III.a Define the secondary address
Content of /etc/netplan/50-cloud-init.yaml
:
network:
version: 2
ethernets:
eno1:
dhcp4: no
addresses:
- 192.168.0.26/24
- 192.168.0.27/24
routes:
- to: default
via: 192.168.0.254
nameservers:
addresses:
- 127.0.0.1
dhcp6: no
dhcp is off per pihole installation rules.
Apply the config :
sudo netplan generate
sudo netplan apply
Test :
ip addr
Output :
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 ...
...
2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ...
inet 192.168.0.26/24 brd 192.168.0.255 scope global eno1
inet 192.168.0.27/24 brd 192.168.0.255 scope global secondary eno1
Both addresses should be pingable.
III.b Install BIND
I won't explain how to install BIND, it's documented everywhere. Just don't forget that your server listens to the secondary address defined above, port 53 (default). So the conf file looks like this :
options {
directory "/var/cache/bind";
// Listen (bind) on the secondary
listen-on { 192.168.0.27; };
// 127.0.0.1, the pihole IP and all the hosts on the network can query
allow-query { localhost; 192.168.0.26; 192.168.0.0/24; };
recursion yes;
// Recommended
dnssec-validation auto;
// Cache negative answers for performance
auth-nxdomain no;
// don't need to listen to an IPv6 address
listen-on-v6 { none; };
};
Nota bene : I allow all my hosts to bypass filtering and use BIND as a nameserver. Maybe you don't want this. It's useful for debugging from a PC though (dig @bind or dig @pihole).
Please test the BIND process. Check if a firewall is not messing with it for example, and that it can resolv addresses. You can use dig for that purpose :
dig www.mit.edu @192.168.0.27
; <<>> DiG 9.18.30-0ubuntu0.24.04.2-Ubuntu <<>> www.mit.edu @192.168.0.27
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 46623
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 093c1af4416dcc1001000000682d2dcd354fef0344a4cd75 (good)
;; QUESTION SECTION:
;www.mit.edu. IN A
;; ANSWER SECTION:
www.mit.edu. 1800 IN CNAME www.mit.edu.edgekey.net.
www.mit.edu.edgekey.net. 60 IN CNAME e9566.dscb.akamaiedge.net.
e9566.dscb.akamaiedge.net. 20 IN A 104.85.29.3
;; Query time: 32 msec
;; SERVER: 192.168.0.27#53(192.168.0.27) (UDP)
;; WHEN: Wed May 21 03:35:09 CEST 2025
;; MSG SIZE rcvd: 160
Query time should become smaller if you run the same query 2 or 3 times because it'll be cached. When cached the time will be 0. Try several hosts. If you have defined some zones, check the hosts in those domains.
Let's assume that your BIND is up and running, and can survive reboots.
III.c Pihole config
Create the config file for dnsmasq :
/etc/dnsmasq.d/50-slt-custom.conf
With content :
listen-address=127.0.0.1
listen-address=192.168.0.26
bind-interfaces
The bind-interfaces MUST be the LAST statement.
Now, login to the pihole dashboard.
On the left pane, under SYSTEM open Settings > All settings
On top of the page click on the [Miscellaneous] button.
That opens the "misc." settings.
Scroll down until : misc.etc_dnsmasq_d
Check Enable.

Now, from the left, select DNS (still in the Settings). And configure as follow :

- No upstream selected from the list.
- 192.168.0.26, or your secondary IP address where BIND listens.
- Note that my pihole is not accessible from the internet, so it uses the default Allow only local requests.
sudo systemctl restart pihole-FTL.service && sudo pihole -t
Check that pihole works :
dig www.mit.edu @192.168.0.26
; <<>> DiG 9.18.30-0ubuntu0.24.04.2-Ubuntu <<>> www.mit.edu @192.168.0.26
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 14873
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; EDE: 3 (Stale Answer)
;; QUESTION SECTION:
;www.mit.edu. IN A
;; ANSWER SECTION:
www.mit.edu. 1217 IN CNAME www.mit.edu.edgekey.net.
www.mit.edu.edgekey.net. 35 IN CNAME e9566.dscb.akamaiedge.net.
e9566.dscb.akamaiedge.net. 0 IN A 104.85.29.3
;; Query time: 0 msec
;; SERVER: 192.168.0.26#53(192.168.0.26) (UDP)
;; WHEN: Wed May 21 03:44:52 CEST 2025
;; MSG SIZE rcvd: 138
You can follow what's happening with :
sudo tail -f /var/log/pihole/pihole.log /var/log/named/bind.log
For example :
dig www.sdf.org @192.168.0.26
==> /var/log/pihole/pihole.log <==
May 21 03:53:36 dnsmasq[24278]: query[A] www.sdf.org from 192.168.0.2
May 21 03:53:36 dnsmasq[24278]: forwarded www.sdf.org to 192.168.0.27
==> /var/log/named/bind.log <==
21-May-2025 03:53:36.474 queries: info: client @0x71e05402cad8 192.168.0.26#45150 (www.sdf.org): query: www.sdf.org IN A +E(0)K (192.168.0.27)
==> /var/log/pihole/pihole.log <==
May 21 03:53:36 dnsmasq[24278]: reply www.sdf.org is 209.160.32.194
Good luck.
From there, it might be interesting to play with the cache size and ttl on both pihole and BIND. Which one should forget the entry faster ?