Enabling HTTPS for your Pi-hole Web Interface

Yep. Looks like isolated out the reason - c.f. netstat reporting on listening 80 and 443:

80:

tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 12375/lighttpd
tcp6 0 0 :::80 :::* LISTEN 12375/lighttpd

443:

tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 12375/lighttpd

Can you connect now with curl or nc ?

Hmm above says only listening 443 for IPv4 and not IPv6.

EDIT: can try change port in below file for fun :wink:

/usr/share/lighttpd/use-ipv6.pl

Plus:

sudo service lighttpd restart

not dice on ths - tried changing 80 to 443 and after restart of lighttpd service the netstat still the same. Perhaps reading another config file.

Anyway - gotta get going on work now; look at this in evening.

Looks like the lighttpd guys came through. Need to have additional section below in external.conf. Tested and it makes IPv6 work.

Thanks to gstrauss (redmine.lighttpd.net) for solving this.

@wally3k - perhaps add this to the block with the change suggested as this should applicable to all

$SERVER["socket"] == "[::]:443" {
ssl.engine = "enable"
ssl.pemfile = "/home/username/combined.pem"
ssl.honor-cipher-order = "enable"
ssl.cipher-list = "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"
ssl.use-sslv2 = "disable"
ssl.use-sslv3 = "disable"
}

1 Like

Yeah you beat me to it.
Was bout to post below through trial error :wink:

pi@noads:~ $ sudo netstat -nltup | grep 'Proto\|lighttpd'
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      5977/lighttpd
tcp6       0      0 :::80                   :::*                    LISTEN      5977/lighttpd

pi@noads:~ $ sudo mkdir /etc/lighttpd/certs
pi@noads:~ $

pi@noads:~ $ cat pi.hole.crt pi.hole.key | sudo tee /etc/lighttpd/certs/pi.hole.pem
[..]

pi@noads:~ $ sudo chmod 600 /etc/lighttpd/certs/pi.hole.pem
pi@noads:~ $

pi@noads:~ $ sudo nano /etc/lighttpd/external.conf
$HTTP["host"] == "noads.dehakkelaar.nl" {
  # 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 = "/etc/letsencrypt/live/pihole.example.com/combined.pem"
#    ssl.ca-file =  "/etc/letsencrypt/live/pihole.example.com/fullchain.pem"
    ssl.pemfile = "/etc/lighttpd/certs/pi.hole.pem"
    ssl.honor-cipher-order = "enable"
    ssl.cipher-list = "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"
    ssl.use-sslv2 = "disable"
    ssl.use-sslv3 = "disable"
  }
  $SERVER["socket"] == "[::]:443" {
    ssl.engine = "enable"
#    ssl.pemfile = "/etc/letsencrypt/live/pihole.example.com/combined.pem"
#    ssl.ca-file =  "/etc/letsencrypt/live/pihole.example.com/fullchain.pem"
    ssl.pemfile = "/etc/lighttpd/certs/pi.hole.pem"
    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")
    }
  }
}

pi@noads:~ $ sudo service lighttpd restart
pi@noads:~ $

pi@noads:~ $ sudo netstat -nltup | grep 'Proto\|lighttpd'
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN
tcp6       0      0 :::80                   :::*                    LISTEN
tcp6       0      0 :::443                  :::*                    LISTEN

pi@noads:~ $ curl -Ivk https://[::1]
* Rebuilt URL to: https://[::1]/
*   Trying ::1...
* TCP_NODELAY set
* Connected to ::1 (::1) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: C=AU; ST=Some-State; O=Internet Widgits Pty Ltd; CN=noads.dehakkelaar.nl
*  start date: Sep  8 20:18:09 2019 GMT
*  expire date: Sep  5 20:18:09 2029 GMT
*  issuer: C=AU; ST=Some-State; O=Internet Widgits Pty Ltd; CN=noads.dehakkelaar.nl
*  SSL certificate verify result: self signed certificate (18), continuing anyway.
> HEAD / HTTP/1.1
> Host: [::1]
> User-Agent: curl/7.52.1
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Content-type: text/html; charset=UTF-8
Content-type: text/html; charset=UTF-8
< Date: Mon, 11 May 2020 03:13:38 GMT
Date: Mon, 11 May 2020 03:13:38 GMT
< Server: lighttpd/1.4.45
Server: lighttpd/1.4.45

<
* Curl_http_done: called premature == 0
* Connection #0 to host ::1 left intact

EDIT: added -k argument for curl for self signed certs.

2 Likes

double thumbs up for the learning through doing (for me, learning through googling hahahha)

slightly OT but perhaps something you can look into if you have a moment; does the conf file syntax support an "OR" operator coz right now it is a bit messy to have two blocks of code exactly the same if it possible to instead do:

$SERVER["socket"] == ":443" ((OR)) "[::]:443"

1 Like

Yeah same.
This one helped:

And I tried $SERVER["socket"] combos but to no avail.

Yeh thats a shame coz I have a few different hostnames in the cert and the kludgey way is to repeat the code block four times (2 for ipv4/ipv6 and 2 for internal/external hostnames) and would be much neater to have a simple
$HTTP["host"] == "pihole.ipv4.internal" OR "pihole.ipv6.internal" OR "pihole.ipv4.external.com" OR "pihole.ipv6.external.com"

Anyway; kludgey works and no need perfection for a oneoff thing.

Thanks for all the help

1 Like

14 posts were split to a new topic: Limit port 80 to https

Alternatively you can set a redirect from 80 to 443
$HTTP["scheme"] == "http" { url.redirect = ("" => "https://${url.authority}${url.path}${qsa}") }

I'm running Pi-hole 5.1.2 (Web Interface 5.1.1/FTL 5.2). I just followed the steps in this documentation.

The site is available via HTTPS and everything seems to be working fine, but whenever I run 'sudo systemctl status lighthttpd.service' or 'journalctl -xe' after restarting lighttpd, I see the following message:

lighttpd[9003]: 2020-11-11 12:13:49: (configfile.c.59) Warning: please add "mod_openssl" to server.modules list in lighttpd.conf. A future release of lighttpd 1.4.x *will not* automatically load mod_openssl and lighttpd *will not* use SSL/TLS where your lighttpd.conf contains ssl.* directives

I tried adding "mod_openssl" to a server.modules directive in external.conf and restarted lighttpd, but it failed to start:

server.modules = (
    "mod_openssl"
)

The output of journalctl -xe wasn't very helpful. I thought maybe adding server.modules to external.conf might completely override what was specified in lighttpd.conf, so I added the full list of modules found in lighttpd.conf + mod_openssl to external.conf and that also failed:

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

This is the output when I try to start lighttpd.service:

Nov 11 12:29:33 pihole systemd[1]: lighttpd.service: Service RestartSec=100ms expired, scheduling restart.
Nov 11 12:29:33 pihole systemd[1]: lighttpd.service: Scheduled restart job, restart counter is at 5.
Nov 11 12:29:33 pihole systemd[1]: Stopped Lighttpd Daemon.
Nov 11 12:29:33 pihole systemd[1]: lighttpd.service: Start request repeated too quickly.
Nov 11 12:29:33 pihole systemd[1]: lighttpd.service: Failed with result 'exit-code'.
Nov 11 12:29:33 pihole systemd[1]: Failed to start Lighttpd Daemon.

Evidently this message is benign right now but whenever lighttpd 1.4 is released, this will become an issue for anyone that enabled HTTPS. Any thoughts?

EDITED - I'm also seeing this message in the log after a successful start:

Nov 11 12:34:08 pihole lighttpd[10314]: 2020-11-11 12:34:08: (server.c.1493) WARNING: unknown config-key: alias.url (ignored)

server.modules += (
   "mod_openssl"
)

Ignore it.

That did the trick!

server.modules += (
   "mod_openssl"
)

Thanks!

1 Like

Will I run into issues if I attempt to use a (SSL) Wildcard certificate within the external.conf file?
ssl.pemfile = "/path/to/WildcardCertWithKey.pem"

After editing the external.conf file I tried testing the "lighttpd.conf" file as follows:

root@pi:~# lighttpd -f /etc/lighttpd/lighttpd.conf -tt
Enter PEM pass phrase: <PEM passphrase goes here>
(server.c.1493) WARNING: unknown config-key: alias.url (ignored)

Based on the output, everything seems to be "OK".
That being said, I am slightly concerned that I was prompted for the PEM pass phrase.
How is the lighttpd service supposed to run, if it doesn't know the passphrase to the PEM file?!?

What concerns me more is that I am unable to get the lighttpd service running.
As soon as I delete the contents of the external.conf file, I can (successfully) restart the lighttpd service.

Am I missing something obvious?
Many thanks!!!

root@pi:~# service lighttpd restart
Job for lighttpd.service failed because the control process exited with error code.
See "systemctl status lighttpd.service" and "journalctl -xe" for details.

root@pi:~# systemctl status lighttpd.service
**ā—** lighttpd.service - Lighttpd Daemon
Loaded: loaded (/lib/systemd/system/lighttpd.service; enabled; vendor preset: enabled)
Active: **failed** (Result: exit-code) since Wed 2020-12-02 21:14:56 EST; 5s ago
Process: 11734 ExecStartPre=/usr/sbin/lighttpd -tt -f /etc/lighttpd/lighttpd.conf **(code=exited, status=255/EXCEPTION)**
Dec 02 21:14:56 pi systemd[1]: lighttpd.service: Service RestartSec=100ms expired, scheduling restart.
Dec 02 21:14:56 pi systemd[1]: lighttpd.service: Scheduled restart job, restart counter is at 5.
Dec 02 21:14:56 pi systemd[1]: Stopped Lighttpd Daemon.
Dec 02 21:14:56 pi systemd[1]: **lighttpd.service: Start request repeated too quickly.**
Dec 02 21:14:56 pi systemd[1]: **lighttpd.service: Failed with result 'exit-code'.**
Dec 02 21:14:56 pi systemd[1]: **Failed to start Lighttpd Daemon.**

Hi, I would like to ask about this topic, I already make HTTPS but when I access the ip address. My IP Address not redirect to My HTTPS FQDN. Is there any way to redirect from pihole Web Admin IP Address to FQDN? Thank you. :slight_smile:

I couldn't do a week. My Domain address is available in Cloudflare. Works with Raspberry Apache2 at home. However, I couldn't integrate the pihole SSL as HTTPS. Cloudflare gave me the Origin Certificate, Private Key files. My file in the settings you are doing is like it doesn't sleep. CLOUDFLARE SSL files for any settings? My English is my apologies.

@DanSchaper , @WaLLy3K ,

Is it possible to do the same when we are using pi-hole in Docker ?

Iā€™m unabie to find any documentation to do that when we use Docker pi-hole.

Is it possible to have the same FAQ for docker with Caddy for example ?

Thank you very much for your help.

Best regards,