Configuring acme-client on OpenBSD
Table of Contents
I hate spending money on things I don't absolutely have to. Maybe that's why I like opensource. I also like encryption. Therefore, I really like acme-client on OpenBSD. They have such an easy setup for generating your own SSL certs for use by a web server. In the article, I will walk through not only the basic configs that I've used. I am also writing a follow-up article that will illustrate how to create a quick ansible playbook that will do all the heavy lifting for you.
There are plenty of articles out there about configuring acme-client for OpenBSD. I barely had to change anything to get the config working for me. One thing to note though, if you decide to use a staging authority, and if you get a weird 403 error when you try to pull your certs, you may have to remove /etc/acme/letsencrypt-privkey.pem. I had that issue myself while I was testing things out.
/etc/acme-client.conf
authority letsencrypt {
api url "https://acme-v01.api.letsencrypt.org/directory"
account key "/etc/acme/letsencrypt-privkey.pem"
}
domain www.example.com {
alternative names { example.com }
domain key "/etc/ssl/private/www.example.com.key"
domain certificate "/etc/ssl/www.example.com.crt"
domain full chain certificate "/etc/ssl/www.example.com.pem"
sign with letsencrypt
}
Next up is the httpd.conf. Again, not much to the configuration. OpenBSD does a pretty good job about making sure that people have to work hard to configure a service insecurily. Running this config through ssllabs yielded an A+ rating, and I consider myself an amateur web admin.
/etc/httpd.conf
chroot "/var/www"
ext_addr="*"
prefork 2
server "www.example.com" {
listen on $ext_addr tls port 443
alias "example.com"
root "/htdocs/public"
tls {
certificate "/etc/ssl/www.example.com.pem"
key "/etc/ssl/private/www.example.com.key"
ticket lifetime default
ciphers "secure"
}
hsts max-age 16000000
hsts preload
hsts subdomains
location "/.well-known/acme-challenge/*" {
root "/acme"
request strip 2
}
}
server "www.example.com" {
listen on $ext_addr port 80
alias "example.com"
block return 301 "https://www.example.com$REQUEST_URI"
location "/.well-known/acme-challenge/*" {
root "/acme"
request strip 2
}
}
The last step is to initialize the certs by running the command below:
acme-client -ADv www.example.com
The deep dive
Just to keep things a little more secure, I did enable hsts with these lines:
hsts max-age 16000000
hsts preload
hsts subdomains
Ciphers are limited to just the most secure available with:
ciphers "secure"
These little blocks are used by acme to verify that you actually own the domain you are requesting certs for
location "/.well-known/acme-challenge/*" {
root "/acme"
request strip 2
}
And that's pretty much it. Read about how to do this whole setup using ansible here.
Has been tested on OpenBSD 6.4