I struggled with the strange behavior of dhcpcd on my Raspberry Pi powered by Raspbian. The RPi does many things on my local network, including ad-blocking thanks to the pihole service.
I run pihole1 as a docker container, and it does its job perfectly well. Thanks to the port binding, I could bind port 53 (DNS) directly to the host and use its address as a DNS server.
I use a tool called dhcpcd to configure the static IP address for my Raspberry Pi. Also, in the configuration file
dhcpcd.conf, I can also change DNS. Here’s what I did.
interface wlan0 static ip_address=192.168.1.102/24 static routers=192.168.1.1 static domain_name_servers=127.0.0.1 220.127.116.11 18.104.22.168 interface eth0 static ip_address=192.168.1.2/24 static routers=192.168.1.1 static domain_name_servers=127.0.0.1 22.214.171.124 126.96.36.199
For both interfaces (wlan0 and eth0), I configured static IP addresses and DNS, using my local pihole service as a primary DNS. I didn’t want to rely only on my local instance because in case of any error or even docker image update, I’d end up without DNS. Unfortunately, despite the configuration, the system saw only one DNS – 127.0.0.1.
Here’s what I found in
# Generated by resolvconf nameserver 127.0.0.1
The same happened even if I reorder DNS in the configuration. Below change generated the same
# ... static domain_name_servers=188.8.131.52 127.0.0.1 184.108.40.206 # ...
I removed the 127.0.0.1 entirely from the configuration to test if it made any difference. After reboot,
resolv.conf presented a proper set of name servers.
# Generated by resolvconf nameserver 220.127.116.11 nameserver 18.104.22.168
Let’s form the problem: using localhost (127.0.0.1) address in the
domain_name_servers option in dhcpcd causes the rest of DNS to be ignored.
The resolv.conf.head file as a solution
After some research and reading docs, I stumbled upon a
resolv.conf.head file, which is a way to prepend an additional name server to the
I changed the configuration of dhcpcd to use public DNS only.
# ... static domain_name_servers=22.214.171.124 126.96.36.199 # ...
Subsequently, I created a
/etc/resolv.conf.head with the localhost address as a nameserver.
# resolv.conf.head nameserver 127.0.0.1
After reboot, it turned out that my localhost address defined in the additional header file was successfully added as the first nameserver in the
resolv.conf. Ultimately, it looks as follows:
# Generated by resolvconf nameserver 127.0.0.1 nameserver 188.8.131.52 nameserver 184.108.40.206
If you ever struggle with this crazy behavior, treat it like a potential solution. If you know the actual reason or have a better solution – please let me know.
pihole is a self-hosted adblocker that works as a proxy for DNS queries, blocking requests related to tracking, advertisements, and other untrustworthy resources. ↩︎