Weblog

See the changelog for details.

Heiko
8 July 2020, 21:18
Successfully tested on OpenBSD, MacOS and Raspbian. Thank you.
Dale Farnsworth
9 July 2020, 01:25
Thank you Hugo. I upgraded my installation.
Chris Wadge
14 July 2020, 06:16
Took me a couple of days, since I was off the grid, but the deb repos are updated as well.
kewl
17 July 2020, 01:41
Thanks for the update I was waiting for these minor changes, this is very appreciated!
ATMOS
18 July 2020, 22:27
Awesome , very appreciated. I will try to convert it to rust with c2rust.
I'm very curious of the result, I'm sure it could benefit of few things like cargo and the ability to deploy from the .toml setup. it will also benefit from the ownership, borrowing , lifetime ( memory safety )
Curtis
19 July 2020, 01:29
Thanks a lot for the new release!
Zerof
28 July 2020, 14:23
Thanks Hugo.
nick
25 September 2020, 13:48
I have used your web server for 6 years .Hope it will be a good different choice and host code on github . Someone will still need it Thanks Hugo.
Hugo Leisink
25 September 2020, 14:00
sativista
20 October 2020, 01:03
Hi Hugo!
Very good work, congratulations, Hiawatha is awesome!
Man, what about uWSGI for python?
Hugo Leisink
20 October 2020, 18:14
I have no plans for uWSGI support. You can take a look at this work around.
Chris Peachment
15 November 2020, 00:23
I'm still happy using Hiawatha after about 10 years. Just discovered a possible mis-use in the Toolkit -> Match -> Rewrite or Redirect statement. The original URL is still stored in the REQUEST_URI environment value for CGI while the new URL is correctly broken into new SCRIPT_NAME and QUERY_STRING values. Is it correct to have the REQUEST_URI unchanged after a rewrite/redirect? Problem arises when using golang http functions because they look at the REQUEST_URI first and only if it is empty do they look at SCRIPT_NAME and QUERY_STRING. If the values were consistent then it would not matter which is used. I don't know if other web servers keep the old URI after a rewrite/redirect but it does not look correct to me. Please advise. Thanks, Chris
Hugo Leisink
15 November 2020, 10:02
Hi Chris. Yes, it is correct to have REQUEST_URI unchanged. No matter what rewriting the webserver does, what was requested by the client stays the same. And REQUEST_URI should contain what was requested.
Chris Peachment
15 November 2020, 21:05
Thanks for the response. I solved the issue by forcing REQUEST_URI to be empty before the Go code attempted to use it. Thanks, Chris
Markus
8 January 2021, 05:52
I'm about to run two instances of hiawatha on one machine.

This triggers my brain, thinking about naming. Assume, we have one machine with several server processes running on it. These can be [0..n] instances of hiawatha, nginx, apache, postfix, ... .

The substring "www", which I find as sub-strings in the defaults for directory names, user names, ... sounds like a generalisation for all web-servers on one machine. But they are used as if there is one and only one web server. Same thing for "hiawatha". Shouldn't we have a more abstract distinction for the various names?

What should we put in such names
- purpose
- kind
- portnumber
- ...
?

Any inspirations, how I should name my stuff?
Joe Schmoe
27 January 2021, 18:11
Anyone else experiencing problems with the letsencrypt script? When I run the command 'letsencrypt expire' I only get the following message rather than a list of the domains and days until the certificate expires.

'Looking up certificate expire time.'
Hugo Leisink
27 January 2021, 18:28
What is the value of the HIAWATHA_CERT_DIR setting in ~/.letsencrypt/letsencrypt.conf?
Vladas
28 January 2021, 08:39
Me too, lefh now sees old certs only. The location of new and old certs remains the same: {HIAWATHA_CONFIG_DIR}/tls
Vladas
28 January 2021, 09:01
And lefh now failed to renew the last old certificate:
> lefh renew
Renewing certificate for az.on.lt.
Generating RSA key.
Generating Certificate Signing Request (CSR).
Ordering certificate.
Getting authorization challenge for az.on.lt.
- Creating reponse for authorization challenge.
- Requesting authorization for host.
- HTTP error for /acme/chall-v3/10417624278/4Dw8UA.
- Error authorizing host az.on.lt
Hugo Leisink
28 January 2021, 11:40
It seems that LetsEncrypt changed the name of their signing server. Great. I hate it when they do unannounced shit like this. In letsencrypt.conf, add 'R3' to the LE_ISSUERS list. The X4 line can be removed. I expected that that would be the name of their next signing server, but it's not.

About the error, I also get errors like that from time to time. Try again a few minutes later and then it works. Seems their service is not 100% solid.
Vladas
28 January 2021, 13:28
Yes, LE renewed the last cert. And how to restore ‛lefh expire’? I've tried to replace X4 with R3, and appended R3 after X3 \ (in the same line) unsuccessfully, though.
Joe Schmoe
28 January 2021, 14:13
Just to be clear, replace the whole string "Let’s Encrypt Authority X3" with just "R3".

https://letsencrypt.org/certificates/

I'm guessing it's using the CN parameter for the Active configuration of the Intermediate Certificate. Compare with the Retired configuration.

Thanks Hugo!
Vladas
28 January 2021, 14:46
Hurray! Lefh expire works with just R3, thank you both!
Markus
27 February 2021, 03:43
Answering to my own post of 2021-01-08:

This is, what I did:

I have two Hiawatha instances running: "pub" and "acme". The "pub" instance serves my [https] web site, the "acme" instance only serves http as long as I need it to renew my Let's Encrypt certificate. The two instances have separate /etc/init.d files and are started separately under separate users
------- /etc/passwd ----------
http_pub:x:110:110::/var/http/my_host/pub:/bin/false
http_acme:x:111:111::/var/http/my_host/acme:/bin/false
------- /etc/passwd ----------
with parallel user groups. All users "http_*" are members of the old "www-data" group.
I'm using acme_tiny.py to obtain my certificate (see at the end)

The file system looks this way:
# ls -la /var/http/my_host/acme/
drwx--x--- 3 root http_acme 4096 Jan 13 22:54 .
drwxr-xr-x 4 root www-data 4096 Jan 13 22:54 ..
drwx--x--- 2 root http_acme 4096 Jan 13 18:51 localhost:80
drwx--x--- 3 root http_acme 4096 Jan 13 23:27 my_domain:80

# ls -la /var/http/my_host/pub/
drwx--x--- 12 root http_pub 4096 Jan 13 22:54 .
drwxr-xr-x 4 root www-data 4096 Jan 13 22:54 ..
drwx--x--- 2 root http_pub 4096 Jan 13 18:51 localhost:443
drwxr-x--- 2 root http_pub 4096 Feb 10 2020 my_domain.eu:443

# ls -la /var/log/myhost/http/
drwxr-x--- 4 root www-data 4096 Jan 13 16:57 .
drwxr-x--- 4 root http_acme 4096 Feb 26 20:03 acme
drwxr-x--- 6 root http_pub 4096 Jan 14 00:48 pub

# ls -l /var/log/my_host/http/acme/
drwx------ 2 http_acme http_acme 4096 Jan 13 17:13 my_domain.eu:80
-rw-r----- 1 http_acme http_acme 4446 Jan 23 16:06 garbage.log
drwx------ 2 http_acme http_acme 4096 Jan 13 17:02 localhost:80
-rw-r----- 1 http_acme http_acme 2136 Feb 26 20:03 system.log

# ls -l /var/log/my_host/http/pub/
-rw-r----- 1 http_pub http_pub 10944979 Jan 12 14:26 access.log
drwx--x--- 2 root http_pub 4096 Jun 20 2017 my_domain.eu:443
-rw-r----- 1 http_pub http_pub 2482875 Jan 12 14:26 error.log
-rw-r----- 1 http_pub http_pub 50178 Jan 11 21:49 exploit.log
-rw-r----- 1 http_pub http_pub 14719 Feb 25 15:12 garbage.log
-rw-r----- 1 http_pub http_pub 50786 Feb 26 21:49 system.log


My naming decisions in the config files:
------- /etc/hiawatha_acme/hiawatha.conf ----------
# VARIABLES
set ${proto0} = log
set ${proto1} = http
set ${if_host_0} = my_host
set ${if_ip_0} = 79.01.01.01
set ${port} = 80
set ${purpose} = acme
set ${server_instance_name} = ${purpose}
set ${site0} = localhost
set ${site1} = my_domain.eu
set ${instance_log_path} = /var/${proto0}/${if_host_0}/${proto1}/${server_instance_name}
set ${site0_log_path} = ${instance_log_path}/${site0}:${port}
set ${site1_log_path} = ${instance_log_path}/${site1}:${port}
set ${site_root} = /var/${proto1}/${if_host_0}/${server_instance_name}
set ${site0_root} = ${site_root}/${site0}:${port}/content
set ${site1_root} = ${site_root}/${site1}:${port}/content

# GENERAL SETTINGS
#
ServerId = ${proto1}_${server_instance_name}
SystemLogfile = ${instance_log_path}/system.log
GarbageLogfile = ${instance_log_path}/garbage.log
PIDfile = /var/run/hiawatha_${server_instance_name}.pid

## DEFAULT WEBSITE
Hostname = 127.0.0.2
WebsiteRoot = ${site0_root}
AccessLogfile = ${site0_log_path}/access.log
ErrorLogfile = ${site0_log_path}/error.log
ExploitLogfile = ${site0_log_path}/exploit.log

# BINDING SETTINGS
Binding {
BindingId = WAN_ACME
Interface = ${if_ip_0}
Port = ${port}
}

# VIRTUAL HOSTS
VirtualHost {
RequiredBinding = WAN_ACME
Hostname = ${site1}, www.${site1}
WebsiteRoot = ${site1_root}
StartFile = index.html
AllowDotFiles = yes
AccessLogfile = ${site1_log_path}/access.log
ErrorLogfile = ${site1_log_path}/error.log
}
------- /etc/hiawatha_acme/hiawatha.conf ----------

/etc/hiawatha/hiawatha.conf is the same except the following changes, and, of course, many more virtual hosts.

------- /etc/hiawatha/hiawatha.conf ----------
# VARIABLES
set ${port} = 443
set ${purpose} = pub

## DEFAULT WEBSITE
Hostname = 127.0.0.1

# BINDING SETTINGS
Binding {
BindingId = WAN_TLS
}

# VIRTUAL HOSTS
VirtualHost {
RequiredBinding = WAN_TLS
# AllowDotFiles = yes
}
------- /etc/hiawatha/hiawatha_acme.conf ----------


For completeness the changes in the rc scripts:
# hg diff -r 185 init.d/hiawatha
diff -r c9e6762d2665 init.d/hiawatha
--- a/init.d/hiawatha Thu Jan 14 19:04:43 2021 +0000
+++ b/init.d/hiawatha Fri Feb 26 23:01:06 2021 +0000
@@ -16,7 +16,7 @@
PATH="/bin:/usr/bin:/sbin:/usr/sbin"
HIAWATHA="/usr/sbin/hiawatha"
WIGWAM="/usr/sbin/wigwam"
-PIDFILE="/var/run/hiawatha.pid"
+PIDFILE="/var/run/hiawatha_pub.pid"

NORMAL="\033[0m"
RED="\033[00;31m"


# hg diff -r 183 init.d/hiawatha_acme
diff -r 3242669446e7 init.d/hiawatha_acme
--- a/init.d/hiawatha_acme Thu Jan 07 20:55:31 2021 +0000
+++ b/init.d/hiawatha_acme Fri Feb 26 23:02:18 2021 +0000
@@ -15,8 +15,10 @@

PATH="/bin:/usr/bin:/sbin:/usr/sbin"
HIAWATHA="/usr/sbin/hiawatha"
+HIAWATHA_PARAMS="-c /etc/hiawatha_acme"
WIGWAM="/usr/sbin/wigwam"
-PIDFILE="/var/run/hiawatha.pid"
+WIGWAM_PARAMS=${HIAWATHA_PARAMS}
+PIDFILE="/var/run/hiawatha_acme.pid"

NORMAL="\033[0m"
RED="\033[00;31m"
@@ -29,17 +31,17 @@
fi

function start_hiawatha {
- if [ -f ${PIDFILE} ]; then
- PID=`cat ${PIDFILE}`
+ if [ -f "${PIDFILE}" ]; then
+ PID=`cat "${PIDFILE}"`
if [ -d /proc/${PID} ]; then
echo -e "${YELLOW}Hiawatha is already running${NORMAL}"
return
fi

- rm -f ${PIDFILE}
+ rm -f "${PIDFILE}"
fi

- ${WIGWAM} -q
+ "${WIGWAM}" -q ${WIGWAM_PARAMS}
result=$?

if [ "${result}" != "0" ]; then
@@ -48,7 +50,7 @@
fi

echo -n "Starting webserver: "
- ${HIAWATHA}
+ "${HIAWATHA}" ${HIAWATHA_PARAMS}
result=$?
if [ "${result}" = "0" ]; then
echo -e "${GREEN}Hiawatha${NORMAL}"
@@ -59,14 +61,14 @@
}

function stop_hiawatha {
- if [ ! -f ${PIDFILE} ]; then
+ if [ ! -f "${PIDFILE}" ]; then
echo -e "Hiawatha${NORMAL}"
echo -e "${YELLOW}Hiawatha PID file not found${NORMAL}"
exit 0
fi

- PID=`cat ${PIDFILE}`
- rm -f ${PIDFILE}
+ PID=`cat "${PIDFILE}"`
+ rm -f "${PIDFILE}"

if [ ! -d /proc/${PID} ]; then
echo -e "Hiawatha${NORMAL}"
@@ -94,19 +96,19 @@

function config_check {
echo -e "${YELLOW}Configuration check via Wigwam...${NORMAL}"
- ${WIGWAM}
+ "${WIGWAM}" ${WIGWAM_PARAMS}
echo
echo -e "${YELLOW}Configuration check via Hiawatha...${NORMAL}"
- ${HIAWATHA} -k
+ "${HIAWATHA}" ${HIAWATHA_PARAMS} -k
}

function show_status {
- if [ ! -f $PIDFILE ]; then
+ if [ ! -f "$PIDFILE" ]; then
echo -e "${YELLOW}Hiawatha PID file not found, so Hiawatha is probably not running${NORMAL}"
exit 3
fi

- PID=`cat ${PIDFILE}`
+ PID=`cat "${PIDFILE}"`

if [ ! -d /proc/${PID} ]; then
echo -e "${RED}Hiawatha is not running but PID file exists${NORMAL}"


Obtaining the certificate with acme_tiny.py (off-topic):
------- ~pki/bin/my_domain.renew_letsencrypt ----------
domain=my_domain.eu
domain_root=~/etc/tls/"${domain}"
signed_crt="${domain_root}"/certs/"${domain}".letsencrypt.signed.crt
domain_key="${domain_root}"/private/"${domain}".key
( umask 0037
acme_tiny.py --account-key "${domain_root}"/private/letsencrypt.pki.security.sysop\@"${domain}".key \
--csr "${domain_root}"/csr/"${domain}".csr \
--acme-dir /var/http/my_host/acme/"${domain}":80/content/.well-known/acme-challenge \
> ${signed_crt} \
)
cat "${domain_key}" "${signed_crt}" > /etc/hiawatha/"${domain}".letsencrypt.chain.pem
------- ~pki/bin/my_domain.renew_letsencrypt ----------



Some architectural considerations, why to do it this way:
- complete separation of certificate procurement from main https-only website
- reuse of an existing web server package
- log directory handling compatible with rsyslog.conf:
$template per_month_per_facility_per_severity, "/var/log/%HOSTNAME%/%$YEAR%-%$MONTH%.%syslogfacility-text%.%syslogseverity-text%"
*.* -?per_month_per_facility_per_severity
- can start and stop acme-http-server process independently
- can handle firewall rules independently
- use one of the simplest acme clients


Open questions:
- why does Hiawatha's config syntax of the default web site differ from virtual sites?
- why does Hiawatha serve a default web site at all?
- why do I have to mention TLSCertFile in the Binding, when I have to mention one in every VirtualHost section?
- handling of variable names in the configuration file is slightly counter-intuitive
- why does Let's Encrypt check for control over port 80, when in fact they want to prove control over port 443 (each port can have its own controlling entity)?
All would be much simpler, if the challenges came in on the correct port (443).


I hope, some of you can find this inspiring and am curious about any, and in particular, critical feedback.


Best regards,

Markus

Chris Wadge
3 March 2021, 21:05
I've built a Debian package of Hiawatha 10.11-1, which has mbed TLS updated to 2.25.0. It's available in the usual places.
Vladas
6 March 2021, 13:43
Chris, perhaps DEBUG also should be removed from logfile.php, as Hugo suggested on https://www.hiawatha-webserver.org/weblog/133 — lefh renew completes its work after that, thank you.
Chris Wadge
12 March 2021, 23:02
Unofficial Debian packages for Hiawatha 10.11-2 are built & available for download, which include the fix @Vladas requested.

Changes since 10.11-1:
• mbed TLS updated to 2.26.0
• Bugfix: letsencrypt script fix