The Server

OpenBSD's webserver is called httpd and is very easy to use. This is the updated article with SSL. Here is the output from fc -l. I used these commands to get my server running

# install deps
$ pkg_add php git

# copy default configs, start services
$ cd /etc
$ cp examples/httpd.conf ./
$ cp examples/acme-client.conf ./
$ rcctl enable php74_fpm
$ rcctl start php74_fpm
$ rcctl enable httpd
$ rcctl start httpd

# edit configs
$ vi httpd.conf

To get certs, /etc/httpd.conf needs a few parts commented out. Super simple. Mine looks like this.

# $OpenBSD: httpd.conf,v 1.22 2020/11/04 10:34:18 denis Exp $

server "default" {
       listen on * port 80
       location "/.well-known/acme-challenge/*" {
               root "/acme"
               request strip 2
       }
#       location * {
#               block return 302 "https://$HTTP_HOST$REQUEST_URI"
#       }
}

#server "default" {
#       listen on * tls port 443
#       tls {
#               certificate "/etc/ssl/example.com.fullchain.pem"
#               key "/etc/ssl/private/example.com.key"
#       }
#       location "/pub/*" {
#               directory auto index
#       }
#       location "/.well-known/acme-challenge/*" {
#               root "/acme"
#               request strip 2
#       }
#}

And we also need to edit /etc/acme-client.conf. Mine looks like this. Go to the very last block. Replace domain your.domain with domain $your.actual.domainname. I commented out the alternative names section because I won't be running any subdomains.

#
# $OpenBSD: acme-client.conf,v 1.4 2020/09/17 09:13:06 florian Exp $
#
authority letsencrypt {
	api url "https://acme-v02.api.letsencrypt.org/directory"
	account key "/etc/acme/letsencrypt-privkey.pem"
}

authority letsencrypt-staging {
	api url "https://acme-staging-v02.api.letsencrypt.org/directory"
	account key "/etc/acme/letsencrypt-staging-privkey.pem"
}

authority buypass {
	api url "https://api.buypass.com/acme/directory"
	account key "/etc/acme/buypass-privkey.pem"
	contact "mailto:me@example.com"
}

authority buypass-test {
	api url "https://api.test4.buypass.no/acme/directory"
	account key "/etc/acme/buypass-test-privkey.pem"
	contact "mailto:me@example.com"
}

domain your.domain {
	#alternative names { secure.example.com }
	domain key "/etc/ssl/private/your.domain.key"
	domain full chain certificate "/etc/ssl/your.domain.fullchain.pem"
	sign with letsencrypt
}

Now run the commands to get a cert.

# restart httpd to use new config
$ rcctl restart httpd

# get certs
$ acme-client your.domain

# check that we actually got them
$ ls /etc/ssl/*fullchain*
$ ls /etc/ssl/private/*.key

Edit /etc/httpd.conf in order to configure httpd to use ssl. Mine looks like this. I am using php and blocking the .git directory.

# $OpenBSD: httpd.conf,v 1.22 2020/11/04 10:34:18 denis Exp $

server "default" {
	listen on * port 80
	location "/.well-known/acme-challenge/*" {
		root "/acme"
		request strip 2
	}
	location * {
		block return 302 "https://$HTTP_HOST$REQUEST_URI"
	}
}

server "default" {
	listen on * tls port 443
	directory index index.php
	location "*.php" {
		fastcgi socket "/run/php-fpm.sock"
	}
	location "*/.git/*"{
		block return 401
	}

	tls {
		certificate "/etc/ssl/your.domain.fullchain.pem"
		key "/etc/ssl/private/your.domain.key"
	}
	location "/pub/*" {
		directory auto index
	}
	location "/.well-known/acme-challenge/*" {
		root "/acme"
		request strip 2
	}
}

The last thing to do is restart httpd so it's using the new config and set a cron job for automatic cert renewal.

# new configs please 
$ rcctl restart httpd

# edit cron tab
$ crontab -e

and add a monthly job.

0 0 1 * *	acme-client your.doamain && rcctl reload httpd