Pi-hole
Pi-hole project is a DNS sinkhole that compiles a blocklist of domains from multiple third-party sources. Pi-hole uses pi-hole-ftlAUR (a dnsmasq fork) to seamlessly drop any and all requests for domains in its blocklist. Running it effectively deploys network-wide ad-blocking without the need to configure individual clients. The package comes with an optional web administration interface.
Overview
Two versions are available for Arch Linux:
- #Pi-hole server – This is the default and well-known Pi-hole server that most users are looking for. It provides a DNS server for other devices on the LAN.
- #Pi-hole standalone – This is an alternative lightweight Pi-hole installation, designed for a mobile context. It is intended to be used on the same device (e.g. a laptop), where no external and centralised Pi-hole server is available. It has no web interface, and automatically updates itself.
Pi-hole server
Installation
Install the pi-hole-serverAUR package.
Configuration
FTL (Faster Than Light)
Pi-hole's FTL is a DNS resolver/forwarder and a database-like wrapper/API that provides long-term storage of requests which users can query through the "long-term data" section of the WebGUI. Data are collected and stored in two places:
- Daily data are stored in RAM and are captured in real-time within
/run/log/pihole/pihole.log
- Historical data (several days/weeks/months) are stored on the file system
/etc/pihole/pihole-FTL.db
and written out at a user-specified interval.
- To disable logging, see #Disable query logging.
- Starting
pihole-FTL.service
is likely to fail. See #Failed to start Pi-hole FTLDNS engine.
pihole-FTL.service
is statically enabled; re/start it. For FTL configuration, see upstream documentation.
Web interface
Pi-hole has a powerful, user-friendly, but completely optional web interface. As well as changing settings, the user can analyse and visualise DNS queries handled by Pi-hole.
Set up PHP
Install php-sqlite (php will be installed automatically) and enable the relevant extensions detailed here:
/etc/php/php.ini
[...] extension=pdo_sqlite [...] extension=sockets [...] extension=sqlite3 [...]
Optional: read permissions for PHP
In php 7.0 and newer, the PHP open_basedir directive defaults to empty, meaning PHP can access every directory and file that can be read by the webserver's userid. For greater security, uncomment open_basedir
in /etc/php/php.ini
and add the list of directories and files accessed by the Pi-hole administration web interface. The list is quite long:
/srv/http/pihole /run/pihole-ftl/pihole-FTL.port /run/log/pihole/pihole.log /run/log/pihole-ftl/pihole-FTL.log /etc/pihole /etc/hosts /etc/hostname /etc/dnsmasq.d/02-pihole-dhcp.conf /etc/dnsmasq.d/03-pihole-wildcard.conf /etc/dnsmasq.d/04-pihole-static-dhcp.conf /var/log/lighttpd/error-pihole.log /proc/cpuinfo /proc/loadavg /proc/meminfo /sys/class/thermal/thermal_zone0/temp /tmp
The open_basedir
directive expects a colon-separated list:
/etc/php/php.ini
open_basedir = /srv/http/pihole:/run/pihole-ftl/pihole-FTL.port:/run/log/pihole/pihole.log:/run/log/pihole-ftl/pihole-FTL.log:/etc/pihole:/etc/hosts:/etc/hostname:/etc/dnsmasq.d/02-pihole-dhcp.conf:/etc/dnsmasq.d/03-pihole-wildcard.conf:/etc/dnsmasq.d/04-pihole-static-dhcp.conf:/var/log/lighttpd/error-pihole.log:/proc/loadavg:/proc/meminfo:/proc/cpuinfo:/sys/class/thermal/thermal_zone0/temp:/tmp
/var/log/lighttpd/error-pihole.log
with /var/log/nginx/error-pihole.log
and add env[PHP_ERROR_LOG] = /var/log/nginx/error-pihole.log
to /etc/php/php-fpm.d/www.conf
. Without specifying the environment variable PHP_ERROR_LOG
, the code will attempt to log to /var/log/apache2
. These changes resolve the logging permission error reported by the console when using nginx instead of lighttpd.Set-up lighttpd
Copy the package provided default configuration for Pi-hole:
# cp /usr/share/pihole/configs/lighttpd.example.conf /etc/lighttpd/lighttpd.conf
Enable lighttpd.service
and start it.
Update hosts file
filesystem ships with an empty /etc/hosts
file which is known to prevent Pi-hole from fetching block lists. One must append the following to this file to ensure correct operation, noting that ip.address.of.pihole should be the actual IP address of the machine running Pi-hole (e.g. 192.168.1.250) and myhostname should be the actual hostname of the machine running Pi-hole:
/etc/hosts
127.0.0.1 localhost ip.address.of.pihole pi.hole myhostname
For more, see Issue#1800.
Making devices use Pi-hole
To use Pi-hole, devices within the network should use Pi-hole's IP address as their sole DNS server. To accomplish this, there are generally two methods:
- In the router's LAN DHCP settings, set Pi-hole's IP address as the only DNS server available for connected devices.
- Manually configure each device to use Pi-hole's IP address as their only DNS server.
More information about making other devices use Pi-hole can be found at upstream documentation.
127.0.0.1
.Pi-hole standalone
Installation
Install the pi-hole-standaloneAUR package.
Configuration
Timer
The Pi-hole standalone package installs a statically enabled timer (and relative service) which will weekly update Pi-hole blacklisted servers list.
The default values can be changed via an edit to the service or it can be prevented from being executed by masking it.
Remember to manually start pi-hole-gravity.timer
or simply reboot after editing.
FTL
Usage
Change the computer's network settings so the only DNS server in use is 127.0.0.1
.
If using DHCP to lease IP addresses from an external router, append bind-interfaces
to /etc/dnsmasq.conf
for DNS queries to resolve.
Test DNS queries independently of network-configured nameserver in /etc/resolv.conf
using the drill
command of ldns package with drill @127.0.0.1 archlinux.org
.
Usage
Both standalone and server versions can be controlled via CLI, but only server version can be controlled via web interface.
Using web interface
Go to pi.hole or <Pi-hole IP address>/admin/
to access web interface.
Using CLI
Pi-hole DNS management
By default Pi-hole uses the Google DNS server. Change which DNS servers Pi-hole uses with:
$ pihole -a setdns ipaddress#port
Specify multiple DNS servers by separating their addresses with commas.
Forced update of ad-serving domains list
To update the blocked domain list, execute:
$ pihole -g
Temporarily disable Pi-hole
Pi-hole can be paused via CLI by executing:
$ pihole disable [time]
Leaving the value for time
blank, the disabling will be permanent until later manual reenabling.
time
can be expressed in seconds or minutes with syntax #s and #m. For example, to disable Pi-hole for 5 minutes:
$ pihole disable 5m
At any time, reenable Pi-hole by executing:
$ pihole enable
Tips and tricks
Password-protected web interface
To password-protect the Pi-hole web interface, run the following command and enter the password:
$ pihole -a -p
To disable the password protection, set a blank password.
Cloudflare DoH
Pi-hole can be configured to use Cloudflared to achieve DNS over HTTPS functionality.
To make Cloudflared work with Pi-hole, simply start cloudflared and configure pi-hole to use it as its DNS entry.
Using the suggested service file for cloudflared, that would be:
# systemctl start cloudflared $ pihole -a setdns 127.0.0.1#5300
Test that pi-hole is working with:
drill archlinux.org @127.0.0.1 -p 53
(notice that the port is the one bound to pi-hole, not the one bound to cloudflared).
Optimise for solid state drives
If Pi-hole is running on a solid state drive (SD card, SSD etc..) it is recommended to uncomment the DBINTERVAL
value and change it to at least 60.0
to minimize writes to the database:
/etc/pihole/pihole-FTL.conf
... ## Database Interval ## How often do we store queries in FTL's database -minutes-? ## See: https://docs.pi-hole.net/ftldns/database/ ## Options: number of minutes DBINTERVAL=60.0 ...
After changes have been performed, restart pihole-FTL.service
.
Disable query logging
Both daily and historic data collected by default contain query data that might be considered sensitive.
To disable the query database for historic data, set privacy level to the maximum Anonymous mode either in the web administration (Settings > Privacy) or in the configuration file /etc/pihole/pihole-FTL.conf
by editing the line:
PRIVACYLEVEL=3
To also disable the logging for daily data, use the following command:
$ pihole logging off
Use with VPN server
Pi-hole can be used by connected VPN clients.
OpenVPN
An OpenVPN server can be configured to advertise a Pi-hole instance to its clients. Add the following two lines to /etc/openvpn/server/server.conf
:
push "redirect-gateway def1 bypass-dhcp" push "dhcp-option DNS Pi-hole-IP"
If it still does not work, try creating a file /etc/dnsmasq.d/00-openvpn.conf
with the following content:
interface=tun0
It may be necessary to make dnsmasq
listen on tun0
.
WireGuard
WireGuard clients can be configured to use the Pi-hole DNS server. In the client configuration file, specify the following line:
DNS = Pi-hole-IP
In order for the DNS to be functional from the VPN, Pi-hole has to listen to all local interfaces:
pihole -a -i local
See more information in WireGuard#Client configuration.
Nginx instead of Lighttpd
This is unofficial, community-supported configuration. Make sure that PHP is set up (see #Set up PHP) and lighttpd server is inactive.
Install nginx-mainline and php-fpm.
Modify /etc/nginx/nginx.conf
to contain the following in the http section:
gzip on; gzip_min_length 1000; gzip_proxied expired no-cache no-store private auth; gzip_types text/plain application/xml application/json application/javascript application/octet-stream text/css; include /etc/nginx/conf.d/*.conf;
Copy the package provided default configuration for Pi-hole:
# mkdir /etc/nginx/conf.d # cp /usr/share/pihole/configs/nginx.example.conf /etc/nginx/conf.d/pihole.conf
Edit /etc/nginx/conf.d/pihole.conf
and change the fastcgi_pass
directive to the following:
fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
Optionally, set VIRTUAL_HOST
to the CNAME of Pi-hole if the intention is to run multiple virtual hosts on Nginx.
fastcgi_param VIRTUAL_HOST "pihole.example.com";
Since version 7.4 php-fpm is hardened by default and revokes read/write access on /usr
(and sub-directories).
Create an drop-in file for php-fpm
with the following content:
/etc/systemd/system/php-fpm.service.d/pihole.conf
[Service] ReadWritePaths = /srv/http/pihole ReadWritePaths = /run/pihole-ftl/pihole-FTL.port ReadWritePaths = /run/log/pihole/pihole.log ReadWritePaths = /run/log/pihole-ftl/pihole-FTL.log ReadWritePaths = /etc/pihole ReadWritePaths = /etc/hosts ReadWritePaths = /etc/hostname ReadWritePaths = /etc/dnsmasq.d/01-pihole.conf ReadWritePaths = /proc/meminfo ReadWritePaths = /proc/cpuinfo ReadWritePaths = /sys/class/thermal/thermal_zone0/temp ReadWritePaths = /tmp
Then start and enable nginx.service
and php-fpm.service
.
Additional blocklists
Pi-hole was intended to block ads, but it can also be used to block other unwanted content:
- Tracking domains
- Malware domains
- Piracy sites
- Fake news sites
- Phishing sites
There are many sources providing these blocklists. Some examples: firebog.net and oisd.nl.
Use Unbound as upstream DNS server
By default, Pi-hole forwards requests to upstream DNS servers, which might lead to privacy concerns. See upstream documentation for a guide on setting up Unbound locally to resolve DNS requests.
Troubleshooting
Odd behavior in the web interface after an upgrade
Some strange/unexplained rendering issues in the web GUI can often be fixed by clearing one's browser cache.
Data loss on reboot
Systems without a RTC such as some ARM devices will likely experience loss of data in the query log upon rebooting. When systems lacking a RTC boot, the time is set after the network and resolver come up. Aspects of Pi-hole can get started before this happens leading to the data loss. An incorrectly set RTC can also cause problems. See: Installation guide#Time and System time.
For devices lacking a RTC:
A hacky work-around for this is to use drop-in files against pihole-FTL.service
wherein a delay is built in calling /usr/bin/sleep x
in a ExecStartPre
statement. Note that the value of "x" in the sleep time depends on how long the specific hardware takes to establish the time sync.
Issue#11008 against systemd-timesyncd is currently preventing the use of the time-sync.target to automate this.
Failed to start Pi-hole FTLDNS engine
# lsof -i :53
.It might be that systemd-resolved.service
already occupied port 53, which is required for pihole-FTL.service
.
To resolve this, disable the stub listener by creating a drop-in snippet form systemd-resolved's configuration file:
/etc/systemd/resolved.conf.d/pi-hole.conf
[Resolve] DNSStubListener=no
Then restart systemd-resolved.service
and pihole-FTL.service
.
For more information, see resolved.conf(5).
Alternatively, tell dnsmasq to bind to each interface explicitly, instead of the wildcard 0.0.0.0:53
, by uncommenting the line bind-interfaces
in /etc/dnsmasq.conf
. This will avoid conflicting with systemd-resolved
which listens on 127.0.0.53:53
.
DNSMasq package conflict
Since Pi-hole-FTL 4.0, a private fork of dnsmasq is integrated in the FTL sub-project. The original dnsmasq package is now conflicting with pi-hole-ftlAUR and will be uninstalled when upgrading from a previous version. It is still possible to use the previous dnsmasq configuration files, just ensure that conf-dir=/etc/dnsmasq.d/,*.conf
in the original /etc/dnsmasq.conf
is not commented out.
Unknown status and changes not being saved
The issue, as seen in FS#63704, is with systemd-sysusers created user http
, which is created in expired state. To fix it, run:
# chage --expiredate -1 http
Slow loading times
If browsers report "Resolving host" or it just takes longer to load pages than usual, ensure that /etc/resolv.conf
looks exactly like this:
/etc/resolv.conf
nameserver 127.0.0.1
If it takes very long to load pages, it can be a problem with lsof
call in pihole script (/usr/bin/pihole)
called through php. Verify it while loading page with: ps -ef | grep lsof
. Kill it and if the page is displayed, replace lsof
call in pihole script (there is only one) with:
ss -lnp '( sport = 53 )'
Prevent DNS resolution issues for other virtual hosts
By default, the DNS service (pihole-FTL) will be bind to the 0.0.0.0 IP address :
# netstat -ltnp | grep 53
tcp 0 0 0.0.0.0:53 0.0.0.0:* LISTEN 2196/pihole-FTL tcp6 0 0 :::53 :::* LISTEN 2196/pihole-FTL
This will prevent any other virtual host onto the same machine hosting the pihole instance (such as docker containers) to get DNS resolution.[1][2]
In order to solve this, you need to create a config file in /etc/dnsmasq.d/
with the following content (where X.X.X.X
is the IP address of your pi-hole) :
/etc/dnsmasq.d/99-dns-bind.conf
listen-address=X.X.X.X bind-interfaces
Then, you need to restart the pihole-FTL.service
to apply changes.
Interface not up when pihole starts
If after booting domain name resolution does not work, and the journal shows an error message like:
pihole-FTL [...] FATAL ERROR in dnsmasq core: unknown interface wlo1
Then it might be that the interface name is wrong, or the interface is not up when pihole tries to run.
- Check the interface name with
ip a
. If it is wrong, setPIHOLE_INTERFACE
to the correct value in/etc/pihole/setupVars.conf
- If the interface is right, it may not be up when pihole is started (even if the systemd service depends on
After=network-online.target
). SetDELAY_STARTUP
in/etc/pihole/pihole-FTL.conf
to a value greater than 0 (expressed in seconds).
Reboot to verify the issue is fixed.
DNS cache evictions greater than zero
The cache size should be increased when this number is larger than zero. You can set the cache limit at /etc/dnsmasq.conf by uncommenting or adding the following setting with your desired number.
/etc/dnsmasq.conf
cache-size=12345
After changes have been performed restart pihole-FTL.service
A larger cache will consume more memory on your node, leaving less memory available for other caches of your Pi-hole. If you push this number to the extremes, it may even be that your Pi-hole gets short on memory and does not operate as expected.
You can not reduce the cache size below 150 when DNSSEC is enabled because the DNSSEC validation process uses the cache.