Lets Encrypt on OpenBSD and FreeBSD
The
Progressive Label Notation
pln(5)
allows for initialization of state in one label followed by another label
which further acts on this state. Obtaining an certificate is one of many
such uses for this pattern, and if no work needs done simply call
exit
To skip the next script to skip to the next step.
OpenBSD: httpd(8), acme-client(1)
Start by installing two files Where the acme client configuration contains a
customized version of
/etc/examples/acme-client.conf
To obtain the initial certificate we need a minimal httpd configuration for the challenge that letsencrypt.org. This is a bootstrap stage and will be replaced by a more complete configuration after we have the keys for TLS
server "default" { listen on egress port 80 location "/.well-known/acme-challenge/*" { root "/acme" root strip 2 } } types { include "/usr/share/misc/mime.types" }
Once the cert is generated a subsequent rule can go ahead an replace
/etc/httpd.conf
with a config that includes the tls keys
# httpd.conf listen on * tls port 443 tls { key "/etc/ssl/private/scriptedconfiguration.org.key" certificate "/etc/ssl/scriptedconfiguration.org.crt" }
Since PLN files are executed in order, we can use on label to set up a configuration to bootstrap the web server, and a subsequent label to ensure that the final httpd configuration is in place. Finally install a weekly cron task to renew the certificate
# httpd.pln execute_with=doas acme_client: → [ -f "/etc/ssl/acme/private/privkey.pem" ] && exit → ./rinstall www/acme-httpd.conf /etc/httpd.conf → rcctl restart -f httpd → ./rinstall www/acme-client.conf /etc/acme-client.conf → acme-client scriptedconfiguration.org www: → ./rinstall vm2/httpd.conf /etc/httpd.conf && rcctl restart httpd cron: → ./rinstall vm2/weekly.local /etc/weekly.local
FreeBSD: nginx(8), lego(1)
Lego is portable ACME client that has a very helpful feature: it listens on HTTP is able to handle the initial challenge-response from Letsencrypt. Once we have obtained a certificate we may continue to use this built-in capability using a proxy
# nginx.conf server { listen 80; location ^~ /.well-known/acme-challenge/ { proxy_pass http://127.0.0.1:81; proxy_set_header Host $host; } }
As with OpenBSD, we can write the labels PLN configuration in order to sequence the configuration
# httpd.pln execute_with=sudo nginx_ssl_init: → [ -d /usr/home/gs/www/.lego ] && exit → lego --email="ericshane@eradman.com" --domains scriptedconfiguration.org --http --http.port :80 run nginx: → ./rinstall www/nginx.conf /usr/local/etc/nginx/nginx.conf && /usr/local/etc/rc.d/nginx restart