Enabling HTTPS for your Pi-hole Web Interface

I have followed this whole guide, made the cert, used certbot, but I get stuck at the end.
After I edit the lighttpd external.conf file, i can no longer access my /admin/ of my pihole, and I tried that with all the ports.
Nuking that file fixes it for me.
Yes, I replaced all the example.com with my own fqdm

1 Like

Thanks for this solution. I need it because i want to acces an other raspberry pi with domoticz on my netwerk via https. But.... (and sorry i am new)

I did step 1 and 2 but in the beginning of step 3 i am stuck
An error is shown if i copy and paste the first line of step 3:
pi@raspberrypi:~ $ sudo cat /etc/letsencrypt/live/mplace.nl/privkey.pemcat: /etc/letsencrypt/live/myfqdn.nl/privkey.pem: No such file or directory

What am i doing wrong?

Greets Gijs

And for those who would like a 'key-in-hand' script, I found that:
Let's Encrypt renewal for Lighttpd
It turns as a service.

Edit:

Certbot is EFF's tool to obtain certs from Let's Encrypt and (optionally) auto-enable HTTPS on your server. It can also act as a client for any other CA that uses the ACME protocol.

The easiest way to install Certbot is by visiting certbot.eff.org, where you can find the correct installation instructions for many web server and OS combinations.

1 Like

@WaLLy3K I ran into the following errors when following the instructions. I created a bug and it was suggested that a fix can be done by changing the instructions here. This is the bug I reported Lighttpd starts with warning about unknown config-key. · Issue #2248 · pi-hole/pi-hole · GitHub

The errors I am getting are:

(server.c.1295) WARNING: unknown config-key: alias.url (ignored)
I am also getting unknown config-key for ssl.use-compression

The solution I found:

fixed it by mod_alias in /etc/lighttpd/lighttpd.conf

so it looks like below:

server.modules = (
"mod_access",
"mod_accesslog",
"mod_auth",
"mod_expire",
"mod_compress",
"mod_redirect",
"mod_setenv",
"mod_rewrite",
"mod_alias"
)

so to fix this I comment it out ssl.use-compression = "disable" on /etc/lighttpd/external.conf

I am running:

lighttpd -v
lighttpd/1.4.45 (ssl) - a light and fast webserver
Build-Date: Jan 14 2017 21:07:19

I made sure I was up to date with pihole and raspberry pi 3. I hope this helps anyone out there.

1 Like

I have done everything as in the example, only that I run my own root CA, which certifies me the certificates. I have been doing this for quite some time, with various services in my private network. This also works quite well with pihole, but I got a warning, does anyone know anything about it?

pi@rpi15:~ $ sudo service lighttpd status
● lighttpd.service - Lighttpd Daemon
   Loaded: loaded (/lib/systemd/system/lighttpd.service; enabled; vendor preset: enabled)
   Active: active (running) since Sun 2018-07-15 13:21:00 CEST; 22s ago
  Process: 5200 ExecStartPre=/usr/sbin/lighttpd -tt -f /etc/lighttpd/lighttpd.conf (code=exited, status=0/SUCCESS)
 Main PID: 5210 (lighttpd)
   CGroup: /system.slice/lighttpd.service
           ├─5210 /usr/sbin/lighttpd -D -f /etc/lighttpd/lighttpd.conf
           ├─5223 /usr/bin/php-cgi
           ├─5224 /usr/bin/php-cgi
           ├─5225 /usr/bin/php-cgi
           ├─5226 /usr/bin/php-cgi
           └─5227 /usr/bin/php-cgi

Jul 15 13:21:00 rpi15 systemd[1]: Starting Lighttpd Daemon...
Jul 15 13:21:00 rpi15 lighttpd[5200]: 2018-07-15 13:21:00: (server.c.1295) WARNING: unknown config-key: ssl.use-compression (ignored)
Jul 15 13:21:00 rpi15 systemd[1]: Started Lighttpd Daemon.

mitag - I get same error message. Search resulted with it's default since lighttpd 1.4.28
Remove the ssl.use-compression = “disable” from /etc/lighttpd/external.conf and it will go away.

  • @WaLLy3K
    Like mitag, I used my own CA - however, it fails to serve the page over SSL/TLS. I tried using @fidelito17 method and modifying/adding the “mod_alias” to lighttpd.conf as well as commenting/removing the ssl.use-compression = “disable”

This site can’t be reached
dns1.domain.com refused to connect.

Over Chrome (version 67.0.3396.99) hit F12 - Security :

Certificate - valid and trusted
The connection to this site is using a valid, trusted server certificate issued by unknown name.

Resources - all served securely
All resources on this page are served securely.

The certificates do not seem to be the issue. Not sure what I'm missing here.
Please let me know if you have any ideas.

Steps taken :

  1. Modifying the ["host"] section /etc/lighttpd/external.conf file to dns1.domain.com
  1. Pointing the ssl.pemfile and ssl.ca-file to the respective directory
  • ssl.pemfile = "/home/pi/Downloads/dns1.pem"
  • ssl.ca-file = "/home/pi/Downloads/root.pem"
  1. Note - have tried RSA and ECDSA based CA's, and tried changing the ssl.cipher-list; always shows the error of refusing to connect. The FQDN does have an A record, and the certificate does have the SAN for the FQDN. Created the dns1.pem via cat server.crt server.key > dns1.pem

Permissions :
pi@dns1:~/Downloads$ ls -l
total 16
-rw-r--r-- 1 pi pi 8387 Jul 15 08:46 dns1.pem
-rw-r--r-- 1 pi pi 1838 Jul 15 07:46 root.pem

lighttpd -v : lighttpd/1.4.45 (ssl) - a light and fast webserver Build-Date: Jan 14 2017 21:07:19

openssl version : OpenSSL 1.1.0f 25 May 2017

Raspbian version : Linux version 4.14.52-v7+ (dc4@dc4-XPS13-9333) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611)) #1123 SMP Wed Jun 27 17:35:49 BST 2018

Edit / Update : The configuration was correct (certs, external.conf, etc) - originally was using Raspbian with Desktop, swapped over to the Stretch Lite and it worked right away. Found some blurb on reddit where pihole didn't cooperate with the desktop version. While I didn't see any issue with the DNS functionality on it, it looks like it prevented the TLS to the WebUI. Figured if someone else comes across this, can be used as a reference.

3 Likes

Yes, that helped, thank you!

Hi,

I have followed the tutorial provided by @WaLLy3K, and SSL works perfectly for the Web Interface of Pi-hole. However, I am experiencing the following stated issues:

The slowdowns are only occuring on a couple of websites, but according to the post this shouldn't happen. And whenever I try to reach a blocked domain over HTTPS I don't see the Pi-hole error page, but see the following error:
sslerror
Chrome presents error message ERR_SSL_UNRECOGNIZED_NAME_ALERT.

According to the following post:

I don't think this is the expected behaviour. Is there a way to fix this?
And yes, I replaced all the pihole.example.com url's with my own fqdn.

What am I doing wrong?

1 Like

Because the certificate is only for your domain, it can not be used for another domain. Trying to use it for another domain causes that error.

I get that, but according to the tutorial this problem should not occur:

But this isn't working as it should, as you can see it is conflicting with blocked HTTPS enabled domains.
What am I doing wrong?

You will still get HTTPS errors when they are blocked, because you do not have a valid cert for that blocked domain.

I just got this working after around an hour of playing around with it.

I'm running lighttpd/1.4.35 and PiHole v4.0 (latest) and here's how I got it to work.\

I'm using acme.sh to do my Let's Encrypt certificate stuff automatically through Cloudflare DNS.

add "mod_alias" to /etc/lighttpd/lighttpd.conf so it looks like

server.modules = (
        "mod_access",
        "mod_accesslog",
        "mod_auth",
        "mod_expire",
        "mod_compress",
        "mod_redirect",
        "mod_setenv",
        "mod_rewrite",
        "mod_alias"

)

I speculate that I will have to change this file every time I update PiHole now.

Then add external.conf as stated above

$HTTP["host"] == "url.FQDN.com" {
  # Ensure the Pi-hole Block Page knows that this is not a blocked domain
  setenv.add-environment = ("fqdn" => "true")

  # Enable the SSL engine with a LE cert, only for this specific host
  $SERVER["socket"] == ":443" {
    ssl.engine = "enable"
    ssl.pemfile = "/home/pi/.acme.sh/url.FQDN.com/combined.pem"
    ssl.ca-file =  "/home/pi/.acme.sh/url.FQDN.com/fullchain.cer"
    ssl.honor-cipher-order = "enable"
    ssl.cipher-list = "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"
    ssl.use-sslv2 = "disable"
    ssl.use-sslv3 = "disable"
  }

  # Redirect HTTP to HTTPS
  $HTTP["scheme"] == "http" {
    $HTTP["host"] =~ ".*" {
      url.redirect = (".*" => "https://%0$0")
    }
  }
}

Finally, I was doing port forwarding from port 80 on this Raspberry Pi to a random port exposed to the world and I didn't remember to change it from port 80 to 443 to get SSL to work correctly. So remember kids, change your port forwarding settings.

2 Likes

Hi ! Thanks for this FAQ.

Could you kindly integrate an info?
Which owner, group and permission must I set for the following file ?

/etc/lighttpd/external.conf

Thanks in advance

I had to modify the chaining

You use privkey + cert

I must use privkey + fullchain

This is because I'm using haproxy

I have a similar question. I followed the guide and it should only be enabled for my pi-hole fqdn. However, I first tested it just giving the IP address and also with the IP address I get the cert error, so I'm expecting, also any other domain will get the cert shown? Shouldn't it be only bound to the specific FQDN with the guide shown here?

Yes, that is exactly what I meant!
I don't know if @starbuck's message is the solution?

I now tried a bit around and it seems, that this is the expected behavior. As HTTPS get‘s enabled, there is a response on port 443, however the response is, that there is no response (port 443 „offline“) for all other sites. However, it looks not such fine, but there is no other solution like that and it won’t expire. Only alternative solution would be to issue certs for all blocked sites via an internal CA, but then it need to be spread out to all systems and it’s no good practice. I just wonder, why the IP is available, but maybe it’s because of missing any domain name.

1 Like

Thanks for the guide. I wanted my pihole admin interface to be reachable from both pihole.domain.local and pihole. The setting $HTTP["host"] == "pihole.domain.local" doesn't allow multiple hostnames though.

My solution (after a bit of googling) was to replace that line with:

$HTTP["host"] =~ "pihole($|\.domain\.local)" {

This will use regex instead of an absolute setting (the regex just accepts pihole OR pihole.domain.local).

Note: this might be obvious, but make sure your cert has a SAN (Subject Alternate Name) containing the shortname as well as the FQDN. Otherwise the cert won't be trusted/valid for the shortname.

Hope this helps anyone else looking to access their admin UI via the shortname or the FQDN.

1 Like

My question is can I use "Let's Encrypt" to secure Pi-hole if I do NOT have any of these:
* a website
* FQDN (Fully Qualified Domain Name)
* a web server
* hosting provider
* VPS

So far, I just have a simple Raspberry Pi (with Pi-hole installed) attached to the home router and it block ads successfully.

I have no idea if I can make use of "Let's Encrypt" to make Pi-hole more secure if I do not have any of the items in the list above.

Do I actually need "Let's Encrypt" to secure Pi-hole if I do not have any of the items in the list above?

Please advise.

Thanks a million.

You at least need a domain to get the Let's Encrypt certificate for, and you need to be able to port-forward your Pi-hole's web interface so that it can be accessed by that domain.