lighttpd + ipv6 + tls (dehydrated)

Tue, 26. Apr 2022

Categories: en sysadmin Tags: lighttpd letsencrypt TLS ipv6

Years after having set up letsencrypt with dehydrated (a big thank you!), I was forced to revisit the configs due to an OS update (devuan chimaera).

And, finally, I wanted an ipv6 dual stack if possible. The prospect of having all lighttpd ssl configuration settings duplicated was unpleasant, however.

The final result came with a nice surprise in simplicity (line 18 and 19) because no other ssl config is required to achieve an ssllabs ‘A+’ rate:

 /etc/lighttpd/conf-available/12-tls-dehydrated.conf
$HTTP["scheme"] == "http" {
  # https://github.com/letsencrypt/letsencrypt/issues/94#issuecomment-156695088
  # http://redmine.lighttpd.net/projects/1/wiki/Docs_ModAlias
  # https://github.com/lukas2511/dehydrated/blob/master/docs/wellknown.md#lighttpd-example-config
  alias.url += (
    # must match WELLKNOWN in /var/www/dehydrate/config
    "/.well-known/acme-challenge/" => "/var/www/dehydrated/well-known/"
  )
}

# https://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_SSL#Cipher-Selection
# https://ssl-config.mozilla.org/#server=lighttpd&version=1.4.59&config=intermediate&openssl=1.1.1n&guideline=5.6
server.modules += (
  "mod_openssl",
)

$SERVER["socket"] == ":443"     { ssl.engine = "enable" } # ipv4
$SERVER["socket"] == "[::]:443" { ssl.engine = "enable" } # ipv6

ssl.openssl.ssl-conf-cmd = ("MinProtocol" => "TLSv1.2")
ssl.openssl.ssl-conf-cmd += ("Options" => "-ServerPreference")
# TLS modules besides mod_openssl might name ciphers differently
# See https://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_SSL
ssl.openssl.ssl-conf-cmd += ("CipherString" => "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384")

ssl.pemfile = "/var/www/dehydrated/certs/mro.name/privcert.pem"

include_shell "/etc/lighttpd/conf-available/12-tls-dehydrated.sh"

With the companion dash script

# /etc/lighttpd/conf-available/12-tls-dehydrated.sh
#!/bin/sh
# find domain names with certs managed with https://dehydrated.io/

ls /var/www/dehydrated/certs/*/privcert.pem \
| while read -r pem
do
  # TODO replace . with \.
  dom="$(basename "$(dirname "${pem}")")"
  cat <<EOF
  $HTTP["host"] =~ "^(.+\.)?${dom}" { ssl.pemfile = "${pem}" }
EOF
done

The only duplicate setting is enabling ssl.engine at all! Everything else suffices once in the global scope! And these settings come ready specific for the precise lighttpd version from ssl-config.mozilla.org!

Lighttpd brings the rest by default.

Activate that and be good:

$ sudo /usr/sbin/lighty-enable-mod tls-dehydrated
$ sudo service lighttpd restart