User Tools

Site Tools


Set Let's Encrypt certificate for web GUI

Requirements:

  • Lighttpd is listening at LAN
  • No other service then lighttpd is listening at port 80 at LAN interface (redirection of WAN port 80 is possible)

This article describes how to configure default lighttpd of Turris to use Let's Encrypt certificate and how to automatically renew the certificate.

Installation

Use the acme.sh script which is quite simple and have no prerequisites.
https://github.com/Neilpang/acme.sh

wget -O - https://get.acme.sh | sh

For more options: https://github.com/Neilpang/acme.sh/wiki/How-to-install

New certificate

Some notes:

  • no other service then lighttpd can be running at port 80 at LAN - such scenario is not covered
  • lighttpd must be turned off and on to not interfere with acme.sh
  • acme.sh has starting its own “server” for port 80 during domain verification
    • firewall must be updated to pass packets to port 80 temporarily
  • any redirection of port 80 at WAN must be temporarly modified to let HTTP traffic to pass to acme.sh

All things are going to happen in /root/.acme.sh (default setup)

Create file add80.gw (vi add80.gw)

add80.gw
 config redirect
         option target 'DNAT'
         option src 'wan'
         option dest 'lan'
         option proto 'tcp'
         option src_dport '80'
         option dest_ip '<TURRIS_IP>'  
         option dest_port '80'
         option name 'Turris  Lets encrypt'

Create file get_acme.sh (vi get_acme.sh)

get_acme.sh
 #!/bin/bash
 VER=1.1.0
 
 # Backup firewall config
 cp /etc/config/firewall  /etc/config/firewall~
 # Update firewall rules to remove any forward of port 80 on WAN (temporary port is 608036)
 cat /etc/config/firewall~ | sed -r "s/^(\s*)(option)(\s*)(src_dport)(\s*)'(80)'(.*)$/\1\2\3\4\5'60806'\7/" > /etc/config/firewall
 # Update firewall rules to allow access via port 80 from internet to acme.sh
 cat  "/root/.acme.sh/add80.gw" >> /etc/config/firewall
 /etc/init.d/firewall reload
 
 # Stop lighttpd as acme.sh is starting its own daemon
 /etc/init.d/lighttpd stop
 
 # Trigger request to Let's Encrypt (and ensure to have the directory)
 mkdir -p /etc/lighttpd/certs
 "/root/.acme.sh/acme.sh" --issue --standalone -d <DOMAIN> --certhome /etc/lighttpd/certs --ca-path /etc/ssl/certs
 
 # Prepare the certificates for lighttpd
 "/root/.acme.sh/acme.sh" --install-cert -d <DOMAIN> --certhome /etc/lighttpd/certs  --cert-file /etc/lighttpd/host.crt --key-file /etc/lighttpd/host.key --fullchain-file /etc/lighttpd/fullchain.crt --reloadcmd  "cat /etc/lighttpd/host.crt /etc/lighttpd/host.key > /etc/lighttpd/hostkey.pem"
 
 # Start lighttpd again
 /etc/init.d/lighttpd start
 
 # Restore firewall to original state
 mv /etc/config/firewall~ /etc/config/firewall
 /etc/init.d/firewall reload

Make the file readable and go.

chmod u+x /root/.acme.sh/get_acme.sh
/root/.acme.sh/get_acme.sh

Now the certificates are acquired and prepared for lighttpd.

Make a copy of SSL configuration file:

mkdir /etc/lighttpd/myconf.d
cp /etc/lighttpd/conf.d/ssl-enable.conf /etc/lighttpd/myconf.d/

Update the configuration file /etc/lighttpd/lighttpd.conf as follows:

#include "/etc/lighttpd/conf.d/*.conf"
include_shell "cat $(ls conf.d/* | grep -v ssl)"
include "/etc/lighttpd/myconf.d/*.conf"

Update the configuration file /etc/lighttpd/myconf.d/ssl-enable.conf as follows:

# This settings enables https with Let's Ecnrypt certificate

$SERVER["socket"] == ":443" {
        ssl.engine = "enable"
        ssl.pemfile = "/etc/lighttpd/hostkey.pem"
        ssl.ca-file = "/etc/lighttpd/fullchain.crt"
        # due to TLS v1.0 and v1.1 deprication browsers do not accept https on Turris anymore
        # this helped: (source: https://redmine.lighttpd.net/boards/2/topics/8536)
         ssl.openssl.ssl-conf-cmd = ("Ciphersuites" => "TLS_AES_128_GCM_SHA256")+("Protocol" => "-ALL, TLSv1.3")+("Curves" => "secp384r1")
         ssl.use-sslv2 = "disable" 
         ssl.use-sslv3 = "disable" 
}

$SERVER["socket"] == "[::]:443" {
        ssl.engine  = "enable"
        ssl.pemfile = "/etc/lighttpd/hostkey.pem"
        ssl.ca-file = "/etc/lighttpd/fullchain.crt"
        # due to TLS v1.0 and v1.1 deprication browsers do not accept https on Turris anymore
        # this helped: (source: https://redmine.lighttpd.net/boards/2/topics/8536)
         ssl.openssl.ssl-conf-cmd = ("Ciphersuites" => "TLS_AES_128_GCM_SHA256")+("Protocol" => "-ALL, TLSv1.3")+("Curves" => "secp384r1")
         ssl.use-sslv2 = "disable" 
         ssl.use-sslv3 = "disable" 
}

Then restart the lighttpd once more to load the Let's Encrypt certificate - /etc/init.d/lighttpd restart

Certificate renewal

Situation is very similar to new certificate. So the add80.gw will be reused.

Some notes (again):

  • no other service then lighttpd can be running at port 80 at LAN - such scenario is not covered
  • lighttpd must be turned off and on to not interfere with acme.sh
  • acme.sh has starting its own “server” for port 80 during domain verification
    • firewall must be updated to pass packets to port 80 temporarily
  • any redirection of port 80 at WAN must be temporarly modified to let HTTPS traffic to pass to acme.sh

Create file renew_acme.sh (vi renew_acme.sh)

renew_acme.sh
#!/bin/bash
VER=1.1.0
 
# Backup firewall config
cp /etc/config/firewall  /etc/config/firewall~
# Update firewall rules to remove any forward of port 80 on WAN (temporary port is 60806)
cat /etc/config/firewall~ | sed -r "s/^(\s*)(option)(\s*)(src_dport)(\s*)'(80)'(.*)$/\1\2\3\4\5'60806'\7/" > /etc/config/firewall
# Update firewall rules to allow access via port 80 from internet to acme.sh
cat  "/root/.acme.sh/add80.gw" >> /etc/config/firewall
/etc/init.d/firewall reload
 
# Stop lighttpd as acme.sh is starting its own daemon
/etc/init.d/lighttpd stop
 
# Trigger renewal request to Let's Encrypt
"/root/.acme.sh/acme.sh" --cron --certhome /etc/lighttpd/certs --ca-path /etc/ssl/certs
 
# Prepare the certificates for lighttpd
"/root/.acme.sh/acme.sh" --install-cert -d <DOMAIN> --certhome /etc/lighttpd/certs  --cert-file /etc/lighttpd/host.crt --key-file /etc/lighttpd/host.key --fullchain-file /etc/lighttpd/fullchain.crt --reloadcmd  "cat /etc/lighttpd/host.crt /etc/lighttpd/host.key > /etc/lighttpd/hostkey.pem"
 
# Start lighttpd again
/etc/init.d/lighttpd start
 
# Restore firewall to original state
mv /etc/config/firewall~ /etc/config/firewall
/etc/init.d/firewall reload

Now just make it executable

chmod u+x renew_acme.sh

As last step add this into cron with your own frequency and time. Let's Ecnrypt suggests daily but once a week should be enough. To edit cron use crontab -e

10 0 * * * "/root/.acme.sh"/renew_acme.sh > /dev/null