HTTPS enabled on Pi-hole web interface

By default, the Pi-hole web interface only accepts plain HTTP requests. In this short post, I’ll cover how to enable HTTPS on your Pi-hole web interface. For the purpose of this post, I’ll be using a purchased SSL certificate and not a configuration with Lets Encrypt.

Purchased certificate

When you purchase certificates, you usually get a zip file with a bunch of files and folders in it. In order to configure Lighttpd to use our certificates, we need 2 types of files: a pem-file and a ca-file.

The pem-file is a container format that includes the public certificate and other CA certificate files. Or it can consist of a whole certificate chain that includes the public key/private key and root certificates.

In our case, we will create a pem-file containing the private key and our domain certificate.

Conversely, the CA-file contains the server certificate of the Certificate Authority that signs your domain certificate. Most of the time, when you purchase an SSL certificate, it will come with a ca-bundle file. That bundle file contains the CA certificate of both intermediate and root servers.

Configure Lighttpd to use HTTPS

Now the only thing left is to configure Lighttpd to accept requests over HTTPS.

Keep in mind that you can’t just change the file /etc/lighttpd/lighttpd.conf. The reason for this is that the configuration file can be overwritten by a Pi-hole update.

That is why the /etc/lighttpd/external.conf file is there. All the configuration options you put in external.conf are automatically loaded when the lighttpd.conf file is read.

So go ahead and copy the configuration options beneath. Don’t forget to change the host address and make sure you change the pemfile and ca-file path so the correct paths where your certificate files reside.

server.modules += ( "mod_openssl" )

$HTTP["host"] == "pi-hole.lan.internal.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 cert, only for this specific host
  $SERVER["socket"] == ":443" {
    ssl.engine = "enable"
    ssl.pemfile = "/etc/lighttpd/certs/lan_internal_com.pem"
    ssl.ca-file =  "/etc/lighttpd/certs/lan_internal_com.ca-bundle"
    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")
    }
  }
}

Once the configuration to enable HTTPS is in place, restart the Lighttpd daemon:

$ sudo service lighttpd restart

If you like configuring your Pi-hole to use DNS-over-HTTPS, head over to my previous post.

Update

It seems that in some cases, mod-openssl isn’t installed by default. In case you run into an error in the form of: mod_openssl not found, you will first need to install the mod-openssl package

sudo apt-get reinstall lighttpd-mod-openssl