See my other guides for SSL certificates on Pi-hole v6:
Pi-hole v6 introduces changes to its web server:
- Embedded Web Server – Pi-hole no longer relies on
lighttpd
. - TLS Configuration – Certificates must be in PEM format containing both the private key and certificate.
By default, Pi-hole v6 provides a self-signed SSL certificate, but you can create your own self-signed certificate for Pi-hole that specifies your desired hostnames, fully qualified domain names (FQDN), and IP addresses for your Pi-hole server using openssl.
Although self-signed certificates can be used to secure connections between a client device and a server, Using a service like Let's Encrypt for TLS certificates is a better security practice because it provides publicly trusted and automatically renewed certificates, ensuring that browsers and other applications recognize them without warnings or manual trust setup.
Benefits of Let's Encrypt:
- Automatic Trust – Certificates are signed by a widely trusted CA, eliminating security warnings.
- Automated Renewals – Avoids expired certificates by using tools like
acme.sh
orcertbot
. - Less Manual Work – No need to manually generate keys, CSRs, or distribute CA certs.
Why Would You Still Use Self-Signed Certificates?
For some use cases, self-signed certificates or an internal CA may still be necessary:
- Air-Gapped Networks – No external internet access to use Let's Encrypt.
- Experimental Setups – Quick testing where setting up Let's Encrypt isn’t feasible.
Install openssl
:
sudo apt update && sudo apt install openssl -y # For Debian/Ubuntu
sudo yum install openssl -y # For RHEL/CentOS
sudo dnf install openssl -y # For Fedora
openssl
is installed on the same machine that Pi-hole is installed on, but this is not a requirement -openssl
can be installed on a machine that is not running Pi-hole;tls.pem
just needs to be copied to/etc/pihole
on the target mahcine running Pi-hole.- All shell commands are executed from the home directory (e.g.,
/home/your_user
or~/
). - Your client browser is Chrome in Windows
- Pros: All future certificates are trusted once you install the CA cert.
- Cons: Requires setting up a CA.
Summary: Set up a CA, sign certificates for each server, and install only one CA certificate instead of trusting multiple self-signed certificates.
mkdir -p ~/crt && cd ~/crt
The CA will be used to sign server certificates.
openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -nodes -days 3650 -keyout homelabCA.key -out homelabCA.crt -subj "/C=US/O=My Homelab CA/CN=MyHomelabCA"
x509
: Generates a self-signed certificate (for a CA).newkey ec
: Creates a new EC key.pkeyopt ec_paramgen_curve:prime256v1
: Uses P-256 curve.nodes
: Skips password protection (optional).-days 3650
: Valid for 10 years.keyout homelabCA.key
: Saves the private key.out homelabCA.crt
: Saves the self-signed CA certificate.subj
: Provides the Distinguished Name (DN) inline:C=US
: CountryO=My Homelab CA
: Organization (CA)CN=MyHomelabCA
: Common Name (CA)
The CA key (homelabCA.key) and CA certificate (homelabCA.crt) is now ready to be used to sign server certificates.
touch cert.cnf && nano cert.cnf
Use the attached cert.cnf file as a template:
# Country Name (C)
#Organization Name (O)
#Common Name (CN) - Set this to your server’s hostname or IP address.
# SAN (Subject Alternative Name), [alt-names] is required
# You can add as many hostname and IP entries as you wish
[req]
default_md = sha256
distinguished_name = req_distinguished_name
req_extensions = v3_ext
x509_extensions = v3_ext
prompt = no
[req_distinguished_name]
C = US
O = My Homelab
CN = pi.hole
[v3_ext]
subjectAltName = @alt_names
[alt_names]
DNS.1 = pi.hole # Default pihole hostname
DNS.2 = pihole-test # Replace with your server's hostname
DNS.3 = pihole-test.home.arpa # Replace with your server's FQDN
IP.1 = 10.10.10.115 # Replace with your Pi-hole IP
IP.2 = 10.10.10.116 # Another local IP if needed
Use Elliptic Curve Digital Signature Algorithm (ECDSA) to generate both the private key (tls.key
) and Certificate Signing Request (CSR) (tls.csr
).
openssl req -new -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -nodes -keyout tls.key -out tls.csr -config cert.cnf
-newkey ec
: Creates a new EC key.-pkeyopt ec_paramgen_curve:prime256v1
: Uses P-256 curve.-nodes
- No password on the private key.-keyout tls.key
: Saves the private key.-out tls.csr
: Saves the certificate signing request (CSR).-config cert.cnf
: Uses the config file for CSR details.
This generates your server certificate from the CSR.
openssl x509 -req -in tls.csr -CA homelabCA.crt -CAkey homelabCA.key -CAcreateserial -out tls.crt -days 365 -sha256 -extfile cert.cnf -extensions v3_ext
-req -in tls.csr
: Uses the Certificate Signing Request (CSR) for signing.-CA homelabCA.crt -CAkey homelabCA.key
: Uses our CA to sign the certificate.-CAcreateserial
:Generates a unique serial number.-out tls.crt
: Saves the signed certificate.-days 365
: Valid for 365 days (1 year).-extfile cert.cnf
-extensions v3_ext → Includes Subject Alternative Names (SAN)s.
cat tls.key tls.crt | tee tls.pem
sudo rm /etc/pihole/tls*
sudo cp tls.pem /etc/pihole
sudo service pihole-FTL restart
Step 10: Install homelabCA.crt
(CA) in Chrome (this is on your client machine running a browser, for example your Windows PC running Chrome)
Import homelabCA.crt
into your browser’s Trusted Root Certificate Store
- Copy
homelabCA.crt
to your local PC - Open
chrome://certificate-manager
in Chrome - Click Manage Imported Certificates
- Click Trusted Root Certification Authorities
- Click Import, Next, Finish
You can issue additional certificates for your other servers using the CA you created in step 2, and you do not have to re-install the CA certificate in your browser. Just run the commands listed in steps 4 and 5 again:
openssl req -new -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -nodes -keyout tls2.key -out tls2.csr -config cert2.cnf
openssl x509 -req -in tls.csr -CA homelabCA.crt -CAkey homelabCA.key -CAcreateserial -out tls2.crt -days 365 -sha256 -extfile cert2.cnf -extensions v3_ext
- Pros: Simple, no need to set up a CA.
- Cons: Must manually add each self-signed cert to your browser.
Summary: Generate a self-signed certificate and install it in your browser. You must manually trust each certificate, so this is adequate for a single server setup.
mkdir -p ~/crt && cd ~/crt
touch cert.cnf && nano cert.cnf
Use the attached cert.cnf file as a template:
# Country Name (C)
#Organization Name (O)
#Common Name (CN) - Set this to your server’s hostname or IP address.
# SAN (Subject Alternative Name), [alt-names] is required
# You can add as many hostname and IP entries as you wish
[req]
default_md = sha256
distinguished_name = req_distinguished_name
req_extensions = v3_ext
x509_extensions = v3_ext
prompt = no
[req_distinguished_name]
C = US
O = My Homelab
CN = pi.hole
[v3_ext]
subjectAltName = @alt_names
[alt_names]
DNS.1 = pi.hole # Default pihole hostname
DNS.2 = pihole-test # Replace with your server's hostname
DNS.3 = pihole-test.home.arpa # Replace with your server's FQDN
IP.1 = 10.10.10.115 # Replace with your Pi-hole IP
IP.2 = 10.10.10.116 # Another local IP if needed
Use Elliptic Curve Digital Signature Algorithm (ECDSA) to generate both the private key (tls.key
) and the Self-Signed Certificate (tls.crt
).
openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -nodes -days 365 -keyout tls.key -out tls.crt -config cert.cnf
x509
: Creates a self-signed certificate.-newkey ec
: Creates a new Elliptic Curve (EC) key.-pkeyopt ec_paramgen_curve:prime256v1
: Uses P-256 (NIST prime256v1) curve.-nodes
: Skips password protection.-days 365
: Valid for 365 days (1 year).-keyout tls.key
: Saves the private key.-out tls.crt
: Saves the self-signed certificate.-config cert.cnf
Uses cert configuration filecert.cnf
defined above.
cat tls.key tls.crt | tee tls.pem
sudo rm /etc/pihole/tls*
sudo cp tls.pem /etc/pihole
sudo service pihole-FTL restart
Step 8: Install tls.crt
(cert) in Chrome (this is on your client machine running a browser, for example your Windows PC running Chrome)
Import tls.crt
into your browser’s Trusted Root Certificate Store
- Copy
tls.crt
to your local PC - Open
chrome://certificate-manager
in Chrome - Click Manage Imported Certificates
- Click Trusted Root Certification Authorities
- Click Import, Next, Finish