I've wanted to set up a Pi-hole on my home network for a while but never found the time. Similarly, my old Mac mini has been laying around for a few years now, and I have meant to make use of it. After the recent announcement that MacOS Big Sur will not be compatible with my 2012 Mac mini, I have decided to turn my mini into an Ubuntu server and install PiHole.
As touched upon already, I re-purposed an old 2012 Mac Mini. The Mac has an i5-3210M processor, 8GB of RAM and a 500GB hard disk. Using a Mac mini that is a small form-factor allowed me to position it nicely underneath my router.
The first step was to grab Ubuntu server and follow the installation instructions from the official website. I used a USB stick as the installation media. To boot from the USB, hold down the
⌘ Command key when powering on the Mac to open up the boot menu.
After the initial installation, I updated everything before continuing any further.
apt update && apt upgrade -y
To keep the server up to date unattended-upgrades are used. Reports from unattended-upgrades get emailed using Postfix.
To install Postfix and initial config I ran the following:
apt install postfix mailutils cp /usr/share/postfix/main.cf.debian /etc/postfix/main.cf
I used SendGrid as a relay host and followed their documentation for configuring Postfix. Below was the configuration I added to
smtp_sasl_auth_enable = yes smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd smtp_sasl_security_options = noanonymous smtp_sasl_tls_security_options = noanonymous smtp_tls_security_level = encrypt header_size_limit = 4096000 relayhost = [smtp.sendgrid.net]:587
To authenticate against Sendgrid using an API key, I created
/etc/postfix/sasl_passwd to store the API key.
Ensure the password file had the correct ownership and before restarting postfix.
chmod 600 /etc/postfix/sasl_passwd postmap /etc/postfix/sasl_passwd systemctl restart postfix
Test Postfix by sending an email:
echo "Just testing postfix" | mail -s "[Test Email]" firstname.lastname@example.org
As mentioned before, to ensure the Ubuntu Server is always patched, I configured unattended-upgrades which installs updates without manual interaction.
apt-get install unattended-upgrades apt-listchanges
The frequency of updates I used was based upon this setup which was suitable for my needs.
/etc/apt/apt.conf.d/20auto-upgrades I set the following:
APT::Periodic::Update-Package-Lists "1"; APT::Periodic::Download-Upgradeable-Packages "1"; APT::Periodic::Unattended-Upgrade "3"; APT::Periodic::AutocleanInterval "9";
- I update the package lists daily. This is important because unattended-upgrades can fail if the sources are outdated.
- I also download the updates daily too rather than downloading them all in one go.
- Perform the installation every three days.
- Clean the package cache every nine days.
In the unattended-upgrades configuration file, I set the
Unattended-Upgrade::Mail property to my email address.
I also set automatic reboot and the time to reboot too:
Unattended-Upgrade::Automatic-Reboot "true"; Unattended-Upgrade::Automatic-Reboot-Time "02:00";
The inspiration for setting up Pi-Hole came from reading a blog post by Scott Helme, where he outlined the steps he undertook. Alongside, setting up Pi-Hole to filter out advertisements on my home network, I also set up DNS over HTTPS (DoH). DoH facilitates the secure transmission of DNS.
Cloudflared is used as a proxy to enable DNS over HTTPS. Pi-Hole has good documentation for installing Cloudflared. I installed cloudflared the "automatic" way outlined in the link above, below are the steps I undertook.
wget https://bin.equinox.io/c/VdrWdbjqyF/cloudflared-stable-linux-amd64.deb apt-get install ./cloudflared-stable-linux-amd64.deb cloudflared -v
To configure cloudflared, I used a config file to specify the upstream DNS location DoH requests should be routed.
mkdir /etc/cloudflared/ vi /etc/cloudflared/config.yml
config.yml file content points to CloudFlare's DNS servers.
proxy-dns: true proxy-dns-port: 5053 proxy-dns-upstream: - https://126.96.36.199/dns-query - https://188.8.131.52/dns-query #Uncomment following if you want to also want to use IPv6 for external DOH lookups #- https://[2606:4700:4700::1111]/dns-query #- https://[2606:4700:4700::1001]/dns-query
Once the config was in place, I installed cloudflared as a service:
cloudflared service install --legacy systemctl start cloudflared systemctl status cloudflared
To test DNS routed via cloudflared works you can run
dig @127.0.0.1 -p 5053 google.com
Installing Pi-Hole was trivial, I just ran the following command and proceeded through the install instructions:
curl -sSL https://install.pi-hole.net | bash
After the installation was complete, I updated a couple of configuration files to ensure Pi-Hole was routing DNS through the cloudflared service.
/etc/pihole/setupVars.conf remove the values for
PIHOLE_DNS_2. This stops Pi-hole from using the DNS configuration chosen when setting up Pi-hole.
... PIHOLE_DNS_1= PIHOLE_DNS_2= ...
I also created an additional configuration file for
dnsmasq to route DNS through the cloudflared service.
I then restarted the pihole-FTL service to use the updated config.
systemctl restart pihole-FTL systemctl status pihole-FTL
To enable all of my devices to utilise Pi-Hole, I chose to set the network DNS servers on my router so, all devices will be routed through Pi-Hole and DoH by default.
A few resources that I used during my setup that may also be of use:
- Install outgoing email from Debian/Ubuntu system through SendGrid
- Integrate Postfix with SendGrid
- Debian Unattended Upgrades Docs
- @roybotnik Unattended Upgrades Setup
- Install Cloudflared
- Install Pi-Hole
Have you installed and configured Pi-Hole? Do you have any feedback? Reach out and let's discuss.