, 4 min read

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

Original post is here eklausmeier.goip.de/blog/2018/03-14-set-up-lets-encrypt-for-hiawatha-web-server.

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:

ACCOUNT_EMAIL_ADDRESS = your@mail.address
LE_CA_HOSTNAME = acme-v02.api.letsencrypt.org           # Production
. . .
LE_ISSUERS = Let's Encrypt Authority X3 \
             Let's Encrypt Authority X4 \

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:

Binding {
        Port = 443
        #TLScertFile = tls/hiawatha.pem
        TLScertFile = /etc/hiawatha/tls/www.eklausmeier.tk.pem
        Interface =
        MaxRequestSize = 2048
        TimeForRequest = 30
VirtualHost {
        Hostname = www.eklausmeier.tk, eklausmeier.tk,, klm.no-ip.org, klm.ddns.net, edh.no-ip.org, edh.ddns.net, klmport.no-ip.org, borussia
__3. Run PHP script.__ Now go through the following two-step process:
lefh register
lefh 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:

klm@nuc ~/letsencrypt: lefh request www.eklausmeier.tk
Authorizing www.eklausmeier.tk.
 - Retrieving HTTP authentication challenge.
 - Retrieving authorization key.
Authorizing eklausmeier.tk.
 - Retrieving HTTP authentication challenge.
 - Retrieving authorization key.
Authorizing klm.no-ip.org.
 - Retrieving HTTP authentication challenge.
 - Retrieving authorization key.
Authorizing klm.ddns.net.
 - Retrieving HTTP authentication challenge.
 - Retrieving authorization key.
Authorizing edh.no-ip.org.
 - Retrieving HTTP authentication challenge.
 - Retrieving authorization key.
Authorizing edh.ddns.net.
 - Retrieving HTTP authentication challenge.
 - Retrieving authorization key.
Authorizing klmport.no-ip.org.
 - Retrieving HTTP authentication challenge.
 - Retrieving authorization key.
Authorizing borussia.no-ip.org.
 - Retrieving HTTP authentication challenge.
 - Retrieving authorization key.
Generating RSA key.
Generating CSR.
Retrieving certificate.
Using www.eklausmeier.tk.pem as output file.
Writing private key and certificate to file.
Retrieving CA certificate.
Writing 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:

Description=Renew Let's Encrypt certificates

ExecStart=/path/to/letsencrypt renew restart

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

Description=Daily renewal of Let's Encrypt's certificates

OnCalendar=*-*-* 04:00:00
# Be kind to the Let's Encrypt servers: add a random delay of 0–3600 seconds


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:

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

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

Feb 27 04:05:01 nuc CROND[18069]: (root) CMD (pidof hiawatha && /root/letsencrypt/lefh renew restart)
Feb 28 04:05:01 nuc CROND[29689]: (root) CMD (pidof hiawatha && /root/letsencrypt/lefh renew restart)
Mar 01 04:05:01 nuc CROND[10260]: (root) CMD (pidof hiawatha && /root/letsencrypt/lefh renew restart)
Mar 02 04:05:01 nuc CROND[20212]: (root) CMD (pidof hiawatha && /root/letsencrypt/lefh renew restart)
Mar 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

cd .acme.sh
acme.sh --issue -d www.eklausmeier.tk -w /srv/http
cd www.eklausmeier.tk
cat 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.