Power-Hole is a simple Docker Compose stack featuring PowerDNS, PowerDNS-Admin and Pi-hole for a quick & easy DNS setup.
Note
This project is intended to meet my personal requirements and thus fulfill a very specific need (see more below).
PowerDNS is a suite of various pieces of software which provide an authoritative and a recursive DNS server as well as a load balancer.
PowerDNS-Admin is a web interface to make simple the management of PowerDNS thanks to the REST API the latter provides.
Finally Pi-hole is a DNS sinkhole which primary goal is to provide network-wide ad blocking.
The aim of this project is to supply an easy way to deploy and manage a stack of DNS services featuring:
- 👮 Your own DNS zones, with the authoritative server
- 🚀 Fast speeds, with local DNS caching
- 🛡️ Secure network, blocking unwanted content
- 🚫 Privacy, with your own recursive server
- 🔒 Secure access, with HTTPS and authentication
- ☁️ Lightweight, the stack can run on a Raspberry Pi
See below the top level parts of this README:
Only Docker and Compose are required by Power-Hole to deploy the stack, the following versions are the minimal requirements:
Tool | Version |
---|---|
Docker | 23 |
Compose | 2+ |
Note
I will not detail how to set up this project without Docker, but understanding the stack below you might be able to install and configure each component separately.
The docker-compose.yml
file defines 8 services:
- The authoritative DNS server and its database
- The admin web interface and its database
- The recursive server, for domain resolution
- Pi-hole, the DNS sinkhole and the server to forward its requests
- Nginx, the reverse proxy, to handle SSL
In a nutshell, to resolve a domain, Pi-hole receive the DNS request and decide whether to block it or not, if the domain is authorized the request is passed to the forwarder.
The forwarder will then pass the request to the authoritative server, if the latter does not manage the domain, the request is sent to the recursive server to be resolved.
Fetch the code from the repository and enter the folder.
git clone https://github.com/noxPHX/Power-Hole.git && cd Power-Hole
To properly work, Power-Hole needs to have some secrets defined:
- db_password.txt, the PowerDNS authoritative server database password
- admin_db_password.txt, the PowerDNS-Admin database password
- db_uri.txt the PowerDNS-Admin link to the database
- api_key.txt, the PowerDNS authoritative server REST API key
- pdns_admin_secret_key.txt, the PowerDNS-Admin internal secret key
Warning
Be sure to set the same string for the admin_db_password.txt and within the db_uri.txt
Here is some inspiration to help you randomly create these secrets, feel free to set them as you please.
cd secrets
date +%s | sha256sum | base64 | head -c 32 > db_password.txt
openssl rand -base64 32 > admin_db_password.txt
echo "postgresql://powerhole_admin:$(cat admin_db_password.txt)@powerhole-pdns-admin-db/powerhole_admin" > db_uri.txt
dd if=/dev/urandom bs=1 count=32 2>/dev/null | base64 | tr -d / > api_key.txt
cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 32 > pdns_admin_secret_key.txt
Warning
No new line must be present in the db_uri.txt file, consider truncating it: truncate -s -1 db_uri.txt
The stack comes with a nginx container which needs a certificate and its private key as well as Diffie-Hellman parameters.
If needed, you can quickly generate a self-signed certificate as shown below:
openssl req -x509 -newkey rsa:2048 -nodes -keyout ssl/privkey.pem -out ssl/fullchain.pem -days 365 -subj '/CN=localhost' -addext "subjectAltName=DNS:pdns.local.intra,DNS:pihole.local.intra,IP:127.0.0.1,IP:0.0.0.0"
Regarding the D-H parameters you can generate them as follows:
openssl dhparam -out ssl/dhparams.pem 2048
Consider using a valid certificate for running in production.
Finally, apply correct ownership (www-data has id 33)
chown -R $USER:33 ssl/
chmod 640 ssl/privkey.pem
The only thing you might want to change are the domain names for the admin interface and Pi-hole.
You can change them in the *.conf
files under the nginx
folder.
If you want to fine tune even more the different services, you can have a look at their respective documentation:
- PowerDNS Authoritative settings page
- PowerDNS Recursor settings page
- PowerDNS-Admin GitHub
- Pi-hole GitHub
- Postgres environment variables
When you are ready, these commands will suffice to build the images and run the services.
Important
You must ensure that no other service is running on port 53 (eg systemd-resolved) otherwise you can change the port to bind.
./build.sh
docker compose up -d
The docker compose build
command can not be used here because I need to use Docker's build time secrets which are currently not supported by Compose.
Also, to support ARM devices (my personal setup runs on a Raspberry Pi 4) the PowerDNS-Admin image must be built locally, which can by the way take quite some times.
For these reasons, a convenient script replace the build command here.
You can access PowerDNS-Admin at https://localhost
as it's the default server, from there you can create the DNS entry (default is pihole.local.intra) to access Pi-hole.
The first time you access it, you will be asked for the PDNS API URL
, here you can specify http://powerhole-pdns-authoritative:8081
.
The PDNS VERSION
parameter depends on the version installed by the package manager but at the time it is 4.4.2
.
The PDNS API KEY
should be the same as the one generated earlier.
Finally, change the DNS server of your devices to the host and port on which you deployed the stack.
Depending on your ISP, you might even be able to change it on your router's settings directly.
This repository is to fulfill my personal's needs and major changes from pull requests might not be welcome.
However, if you ever find an issue please feel free to report it and I will be glad to solve it.