Set-Up "Let's Encrypt" for Hiawatha Web-Server

· klm's blog


Original post is here: eklausmeier.goip.de

Google announced that starting with Chrome version 68 they will gradually mark HTTP-connections as "not secure". "Let's Encrypt" is a free service for web-masters to obtain certificates in an easy manner. Work on "Let's Encrypt" started in 2014.

Setting up "Let's Encrypt" with Hiawatha web-server is quite easy, although there are some pitfalls. I used the Arch Linux package for Hiawatha. There is also a ArchWiki page for Hiawatha.

Another detailed description is: Let’s Encrypt with Hiawatha (dead link) by Chris Wadge (dead link).

1. Unpacking and production-server setting. After installing the hiawatha Arch Linux package I unpacked the file /usr/share/hiawatha/letsencrypt.tar.gz -- this is no longer required. You have to edit the configuration file letsencrypt.conf at three places:

1ACCOUNT_EMAIL_ADDRESS = your@mail.address
2HIAWATHA_CERT_DIR = {HIAWATHA_CONFIG_DIR}/tls
3LE_CA_HOSTNAME = acme-v02.api.letsencrypt.org           # Production
4. . .
5LE_ISSUERS = Let's Encrypt Authority X3 \
6             Let's Encrypt Authority X4 \
7             R3

I struggled with the variable LE_CA_HOSTNAME. This has to be the productive "Let's Encrypt" server. Although you might register with the testing-server, you apparently cannot do anything else with the testing-server. So delete the testing-server. The rest of the configuration file is obvious to change.

In June 2021 I struggled with LE_ISSUERS as apparently R3 was missing. Adding it solved the problem that lefh returned zero, but did not actually return the expiration date or extend it in any way.

2. Configuration file. Now check your hiawatha.conf file:

 1Binding {
 2        Port = 443
 3        #TLScertFile = tls/hiawatha.pem
 4        TLScertFile = /etc/hiawatha/tls/www.eklausmeier.tk.pem
 5        Interface = 0.0.0.0
 6        MaxRequestSize = 2048
 7        TimeForRequest = 30
 8}
 9...
10VirtualHost {
11        Hostname = www.eklausmeier.tk, eklausmeier.tk, 192.168.178.24, klm.no-ip.org, klm.ddns.net, edh.no-ip.org, edh.ddns.net, klmport.no-ip.org, borussia
12        ...
13}

[more_WP_Tag]3. Run PHP script. Now go through the following two-step process:

1lefh register
2lefh request www.eklausmeier.tk

lefh is actually a PHP script, so you need package php installed, regardless whether you use PHP on your website. The last command generates the following output:

 1klm@nuc ~/letsencrypt: lefh request www.eklausmeier.tk
 2Authorizing www.eklausmeier.tk.
 3 - Retrieving HTTP authentication challenge.
 4 - Retrieving authorization key.
 5Authorizing eklausmeier.tk.
 6 - Retrieving HTTP authentication challenge.
 7 - Retrieving authorization key.
 8Authorizing klm.no-ip.org.
 9 - Retrieving HTTP authentication challenge.
10 - Retrieving authorization key.
11Authorizing klm.ddns.net.
12 - Retrieving HTTP authentication challenge.
13 - Retrieving authorization key.
14Authorizing edh.no-ip.org.
15 - Retrieving HTTP authentication challenge.
16 - Retrieving authorization key.
17Authorizing edh.ddns.net.
18 - Retrieving HTTP authentication challenge.
19 - Retrieving authorization key.
20Authorizing klmport.no-ip.org.
21 - Retrieving HTTP authentication challenge.
22 - Retrieving authorization key.
23Authorizing borussia.no-ip.org.
24 - Retrieving HTTP authentication challenge.
25 - Retrieving authorization key.
26Generating RSA key.
27Generating CSR.
28Retrieving certificate.
29Using www.eklausmeier.tk.pem as output file.
30Writing private key and certificate to file.
31Retrieving CA certificate.
32Writing CA certificate to file.

If you did not run above command as root: The generated certificate www.eklausmeier.tk.pem has then to be copied to /etc/hiawatha/tls, or to whatever location you have chosen above.

5. Renewing. Renewing is by either using cron or systemd timer, the latter being copied from ArchWiki. File /etc/systemd/system/letsencrypt-renew.service:

1[Unit]
2Description=Renew Let's Encrypt certificates
3Wants=network-online.target
4After=network-online.target
5
6[Service]
7Type=oneshot
8ExecStart=/path/to/letsencrypt renew restart

and file /etc/systemd/system/letsencrypt-renew.timer:

 1[Unit]
 2Description=Daily renewal of Let's Encrypt's certificates
 3
 4[Timer]
 5OnCalendar=*-*-* 04:00:00
 6# Be kind to the Let's Encrypt servers: add a random delay of 0–3600 seconds
 7RandomizedDelaySec=3600
 8Persistent=true
 9
10[Install]
11WantedBy=timers.target

I think cron is much easier to use than fiddling with systemd timer and system daemon-reload using root user. Instead, here is the simple crontab entry:

 1[root@nuc ~]# crontab -l
 2#             field          allowed values
 3#             -----          --------------
 4#             minute         0-59
 5#             hour           0-23
 6#             day of month   1-31
 7#             month          1-12 (or names, see below)
 8#             day of week    0-7 (0 or 7 is Sunday, or use names)
 9#
1005      04      *       *       *       pidof hiawatha && /root/letsencrypt/lefh renew restart

Checking crontab with journalctl | grep letsencrypt shows something like this:

1Feb 27 04:05:01 nuc CROND[18069]: (root) CMD (pidof hiawatha && /root/letsencrypt/lefh renew restart)
2Feb 28 04:05:01 nuc CROND[29689]: (root) CMD (pidof hiawatha && /root/letsencrypt/lefh renew restart)
3Mar 01 04:05:01 nuc CROND[10260]: (root) CMD (pidof hiawatha && /root/letsencrypt/lefh renew restart)
4Mar 02 04:05:01 nuc CROND[20212]: (root) CMD (pidof hiawatha && /root/letsencrypt/lefh renew restart)
5Mar 03 04:05:01 nuc CROND[28676]: (root) CMD (pidof hiawatha && /root/letsencrypt/lefh renew restart)

5. Testing. Two simple possibilites to check your site:

  1. SSL Server Test
  2. Responsinator

Output from SSL-labs below:

You can also use acme.sh. The commands are

1cd .acme.sh
2acme.sh --issue -d www.eklausmeier.tk -w /srv/http
3cd www.eklausmeier.tk
4cat www.eklausmeier.tk.key www.eklausmeier.tk.cer > www.eklausmeier.tk.pem

if /srv/http is your web-root (document root).

acme.sh has more than 6 kLOC and almost 100 options, while Hugo Leisink's lefh script is just 1.5 kLOC and has 5 options: register, request, expire, revoke.

Added 13-Jun-2021: The letsencrypt script is now called lefh, and is an official part of the hiawatha package. So there is no need to fiddle with tar-files any more. You have to add R3 to LE_ISSUERS.

Added 03-Aug-2023: Hiawatha moved from Arch Linux community repository to AUR repository.