Pi-hole

From ArchWiki

Pi-hole project is a DNS sinkhole that compiles a blocklist of domains from multiple third-party sources. Pi-hole uses pi-hole-ftlAUR (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 and a CLI interfaces.

Note: Pi-hole on Arch Linux is not officially supported by the Pi-hole project.

Overview

There are 2 versions of Pi-Hole available for Arch Linux:

  • #Pi-hole server - This is default and well-known Pi-Hole server that most users are looking for. It is designed to be used as a DNS server for other devices on the LAN.
  • #Pi-hole standalone - This is alternative lightweight Pi-Hole installation, designed for a mobile context. It is intended to be used on the same device (e.g. laptop), where no external and centralised Pi-Hole server is available. It also has no web interface and automatically updates.

Pi-hole server

Installation

Install the pi-hole-serverAUR package.

Configuration

FTL (Faster Than Light)

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:

  1. Daily data are stored in RAM and are captured in real-time within /run/log/pihole/pihole.log
  2. Historical data (i.e. over multiple days/weeks/months) are stored on the file system /etc/pihole/pihole-FTL.db written out at a user-specified interval.
Note: To disable logging, see #Disable query logging.

pihole-FTL.service is statically enabled; re/start it. For FTL configuration, see upstream documentation.

Note: Starting pihole-FTL.service is likely going to fail. See #Failed to start Pi-hole FTLDNS engine.

Web interface

Pi-hole has a very powerful, user friendly, but completely optional web interface. It allows not only to change settings, but analyse and visualise DNS queries performed by other devices.

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
[...]
Explicitly permit directories for php-fpm

For security reasons, one can optionally populate the PHP open_basedir directive however, the Pi-hole administration web interface will need access to following files and directories:

/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.log
/proc/meminfo
/proc/cpuinfo
/sys/class/thermal/thermal_zone0/temp
/tmp
Set-up lighttpd
Tip: Users can also run Nginx web server instead. See #Nginx instead of Lighttpd.

Install lighttpd and php-cgi.

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.

Note: As of upstream version 5.2.4, The built-in web interface (version 5.4) has minor compatibility issues with PHP version 8. Choose to ignore the errors, or see #PHP 8 web interface incompatibility... for a guide on installing and using PHP version 7 instead.

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 with the network should use Pi-Hole's IP address as their sole DNS server. To accomplish this, there are generally 2 methods to make it happen:

  1. In router's LAN DHCP settings, set Pi-Hole's IP address as the only DNS server available for connected devices.
  2. Manually configure each device to use Pi-Hole's IP address as their only DNS server.
Note: Some routers (or even ISPs) do not allow modifications to LAN DNS settings, so disabling the router's DHCP server and using Pi-Hole's built in DHCP server might be a solution.

More information about making other devices use Pi-Hole can be found at upstream documentation.

Tip: Pi-Hole hosting device can also make use of Pi-Hole. Just change DNS settings to only IP address 127.0.0.1.

Pi-hole standalone

Installation

Install the pi-hole-standaloneAUR package.

Configuration

Timer

The Pi-hole standalone package install a statically enabled timer (and relative service) 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

See #FTL (Faster Than Light).

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 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 server

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, edit cloudflared.yml file and change settings as per below:

/etc/cloudflared/cloudflared.yml
...
proxy-dns-port: 53000
proxy-dns-address: 127.0.0.1

Then restart [email protected]. Now use 127.0.0.1#53000 as the only DNS server entry in Pi-Hole.

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
Warning: Pi-hole will erase all statistics upon executing this command.

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 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 have to listen to all local interfaces:

pihole -a -i local

See more information in WireGuard#Client config.

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:

  1. Tracking domains
  2. Malware domains
  3. Piracy sites
  4. Fake news sites
  5. Phishing sites
Note: Pi-Hole blocklists must contain domains. Some blocklists might contain IP addresses of 127.0.0.1 and domain combination - this format is accepted by Pi-Hole.

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 zone 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

Tip: Check which process opened port 53 with: # 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 editing systemd-resolved configuration file:

/etc/systemd/resolved.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

Tango-inaccurate.pngThe factual accuracy of this article or section is disputed.Tango-inaccurate.png

Reason: This issue seems to pertain to DNS configuration. It might not be a good idea to instruct direct changes to /etc/resolv.conf. (Discuss in Talk:Pi-hole)

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 )'

PHP 8 web interface incompatibility...

Note: Since Pi-Hole web admin 5.9, PHP 8 incompatibility has been addressed.

As of upstream version 5.2.4, The built-in web interface (version 5.4) has compatibility issues with PHP version 8. In particular, when applying DNS related configurations in Settings > DNS tab, the webpage raises an error.

To address web interface issues after #Configuration, install packages php7, php7-cgi, php7-fpm and php7-sqlite. Then edit reference to php-cgi as follows:

/etc/lighttpd/lighttpd.conf
...
"bin-path" => "/usr/bin/php-cgi7 -d session.save_path=/run/pihole",
...
Warning: As stated in the configuration file, manual changes will be reset upon reinstallation or update.

Finally, restart lighttpd.service.

...but I need to stick with PHP 8 for my system

When trying to apply DNS settings through the Pi-hole's web interface (choosing to use PHP 8):

There was a problem applying settings.
Debugging information:
PHP error (2): Undefined array key "v6_2" in /srv/http/pihole/admin/scripts/pi-hole/php/savesettings.php:210

In order to solve this issue, I had to manually edit the "/srv/http/pihole/admin/scripts/pi-hole/php/savesettings.php" file at line "210" (according to the error message) from this :

foreach(["v4_1", "v4_2", "v6_1", "v6_2"] as $type)

to this (deleting both "v6_1" and "v6_2") :

foreach(["v4_1", "v4_2"] as $type)

Obviously this change is likely to be overwritten with each update.

See also