In earlier articles I described how to setup vhosts with https in OpenBSD’s httpd, but in the end I got stuck because httpd did not have the flexibility I need in my webserver, so the switch back to nginx was eminent. Now let’s get that dynamic vhosting running with fully automated certificate renewal from Let’s Encypt!
First we setup a server at port 80 that serves the acme-challenge and sends everything else to https:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
# the acme-challenge
location /.well-known/acme-challenge {
rewrite ^/.well-known/acme-challenge/(.*) /$1 break;
root /acme;
}
# redirect everybody else to https
location / {
return 301 https://$host$request_uri;
}
}
Since OpenBSD’s nginx port does not allow the use of variables in the ssl_cerificate and ssl_certificate_key directives. I configured acme-client with only one certificate with a whole long list of alternative names. Kinda ugly, I know…
Activate this server and run:
$ doas acme-client -Fv example.com
When you have your certificate you can add it to the server configuration:
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name $host;
set $basepath "/vhosts";
ssl_certificate /etc/ssl/example.com.fullchain.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
if ($host ~ "^(.[^.]*)\.(.[^.]*)$") {
set $rootpath "$1.$2/www/";
}
if ($host ~ "^(.[^.]*)\.(.[^.]*)\.(.[^.]*)$") {
set $rootpath "$2.$3/$1/";
}
root $basepath/$rootpath;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
include common.conf;
}
$ doas rcctl reload nginx
And enjoy your dynamic vhosts with https. The only thing you need to do everytime you’ll add a (sub)domain is add it to /etc/acme-client.conf and renew your certificate.
