I run Pi-Hole at home to filter and block ad traffic, is a fantastic piece of of software that helps me to keep me and my son away from unwanted ads. It can be run on a VM or even better a Docker container. If you are not doing it yet I encourage you to visit Pi-Hole homepage and take a look at the project and donate or contribute in GitHub to keep it running.
For the last year and a half or so I have been running pi-hole on a CentOS 7 virtual machine, it’s been working great but I wanted to move it outside of my ESXi host and separate it from my lab workloads. Many people use a Raspberry Pi to run it and my original intention was exactly that and use Portainer to manage the container like I was doing on CentOS, however I had a GIGABYTE GB-BXBT-2807 mini PC laying around. This little fella used to be my media center, is a NUC-like machine with a dual-core Intel Celeron N2807 CPU, 8GB of RAM and a 60GB SSD. It has enough room not only for Pi-Hole but also for other workloads I am planning to run to support my home network.
I decided to move from CentOS to Fedora Server so I installed version 33. Fedora 33 comes with a caveat, since it uses cgroupvs2 Docker does not work. But that is not the end of the world because it has Podman available instead, I’ve used it in the past for testing purposes but never to run any serious workloads at home, there are ways to install Docker in Fedora 33 but I decided to use the default option and try run Pi-Hole on it.
If you have never heard about Podman, or Pod Manager, it is a daemonless container engine for OCI Conainers on Linux originally developed by Red Hat as an open source project and intended to replace Docker in the Fedora/CentOS/RHEL ecosystem.
Prepare the server
Install Fedora 33 in a virtual machine or like in my case in a physical system, is up to you to decide the type of installation but for me minimal installation is more than enough to keep the system and its attack surface as small as possible.
After the OS is installed run
dnf update to get latest Fedora updates and install Podman.
sudo dnf update -y sudo dnf install -y podman
Next we need to adjust Fedora network configuration. By default Fedora Server comes with NetworkManager to manage networking and
systemd-resolved service enabled, we will maintain NetworkManager but will configure static
ipv4 addressing, FirewallD DNS servers using
nmcli tool and disable
Set an static IP address
Modify your existing connection with
nmcli, my connection is
ens192 but you should run
nmcli connection to get a list of the existing connections and use the appropiate one.
sudo nmcli connection modify ens192 ipv4.method manual sudo nmcli connection modify ens192 ipv4.addresses 192.168.1.94/24 sudo nmcli connection modify ens192 ipv4.gateway 192.168.1.1
Configure DNS and stop and disable
sudo nmcli connection modify ens192 ipv4.dns "22.214.171.124 126.96.36.199" sudo systemctl disable systemd-resolved sudo systemctl stop systemd-resolved sudo unlink /etc/resolv.conf sudo systemctl restart NetworkManager
sudo firewall-cmd --zone=FedoraServer --add-port=80/tcp sudo firewall-cmd --zone=FedoraServer --add-port=443/tcp sudo firewall-cmd --zone=FedoraServer --add-port=53/tcp sudo firewall-cmd --zone=FedoraServer --add-port=53/udp sudo firewall-cmd --zone=FedoraServer --add-port=67/udp sudo firewall-cmd --permanent --zone=FedoraServer --add-port=53/udp sudo firewall-cmd --permanent --zone=FedoraServer --add-port=53/tcp sudo firewall-cmd --permanent --zone=FedoraServer --add-port=443/tcp sudo firewall-cmd --permanent --zone=FedoraServer --add-port=67/udp sudo firewall-cmd --permanent --zone=FedoraServer --add-port=80/tcp
Pi-Hole will need two container volumes to persist data, we can create them with
podman in the same way as with
sudo podman volume create pihole_pihole sudo podman volume create pihole_dnsmasq
pihole container image.
sudo podman pull pihole/pihole
pihole container to test that it works.
podman run --name=pihole \ --hostname=pi-hole \ --cap-add=NET_ADMIN \ --dns=127.0.0.1 \ --dns=188.8.131.52 \ -e TZ=Europe/Madrid \ -e SERVERIP=192.168.1.20 \ -e WEBPASSWORD=my_pihole_password \ -e DNS1=184.108.40.206 \ -e DNS2=220.127.116.11 \ -e DNSSEC=true \ -e CONDITIONAL_FORWARDING=true \ -e CONDITIONAL_FORWARDING_IP=192.168.1.1 \ -e CONDITIONAL_FORWARDING_DOMAIN=lan \ -e TEMPERATUREUNIT=c \ -v pihole_pihole:/etc/pihole:Z \ -v pihole_dnsmasq:/etc/dnsmasq.d:Z \ -p 80:80/tcp \ -p 443:443/tcp \ -p 67:67/udp \ -p 53:53/tcp \ -p 53:53/udp \ pihole/pihole
You can verify that container running with
sudo podman ps.
$ sudo podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3c0f7b90e121 docker.io/pihole/pihole:latest 2 weeks ago Up 2 weeks ago 0.0.0.0:53->53/tcp, 0.0.0.0:53->53/udp, 0.0.0.0:67->67/udp, 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp pihole
Configure Pi-Hole as systemd service
We have verified that Pi-Hole can be run as a Podman container, however if the server gets down or we reboot it for whatever reason we will need to run the container manually again. In CentOS with Docker I had this solved by using Portainer, however since Portainer needs to be run as privileged container cannot be run with Podman. Instead I decided to create a SystemD service that will be automatically run during server startup.
Create your service unit file in
/etc/systemd/system, I named mine
[Unit] Description=Pi-Hole Podman Container After=firewalld.service [Service] ExecStart=/usr/bin/podman run --name=pihole --hostname=pi-hole --cap-add=NET_ADMIN --dns=127.0.0.1 --dns=18.104.22.168 -e TZ=Europe/Madrid -e SERVERIP=192.168.1.20 -e WEBPASSWORD=my_pihole_password -e DNS1=22.214.171.124 -e DNS2=126.96.36.199 -e DNSSEC=true -e CONDITIONAL_FORWARDING=true -e CONDITIONAL_FORWARDING_IP=192.168.1.1 -e CONDITIONAL_FORWARDING_DOMAIN=lan -e TEMPERATUREUNIT=c -v pihole_pihole:/etc/pihole:Z -v pihole_dnsmasq:/etc/dnsmasq.d:Z -p 80:80/tcp -p 443:443/tcp -p 67:67/udp -p 53:53/tcp -p 53:53/udp pihole/pihole ExecStop=/usr/bin/podman stop -t 2 pihole ExecStopPost=/usr/bin/podman rm pihole [Install] WantedBy=multi-user.target
After creating the service unit file and before staring the service configure SELinux to allow
systemd to load containers.
setsebool -P container_manage_cgroup on
Enable and start the new service and reboot to verify it runs at boot.
sudo systemctl enable pi-hole.service sudo systemctl start pi-hole.service
Access yoour Pi-Hole at
http://pi_hole_ip/admin, login and see the magic happen :)
FInally I installed
cockpit-podman package to keep track of this and future podman containers from Cockpit.
Please left any comments about your usage of pi-hole, experience with podman, etc.