💾 Archived View for bgp.rocks › openbsd-httpd-and-lets-encrypt.gmi captured on 2021-11-30 at 20:18:30. Gemini links have been rewritten to link to archived content

View Raw

More Information

➡️ Next capture (2022-01-08)

-=-=-=-=-=-=-

OpenBSD httpd and Let's Encrypt

Published on 2021-04-23.

Prepare the zone

Before we do anything with httpd the DNS settings should already be done. There is no standard way of doing this, it all depends on the server administrator, who is running the DNS servers and what the end result should be. I have decided to use these settings:

bgp.rocks. A 46.23.94.208

bgp.rocks. AAAA 2a03:6000:6f69:605::208

bgp.rocks. CAA 0 issue "letsencrypt.org"

www.bgp.rocks. A 46.23.94.208

www.bgp.rocks. AAAA 2a03:6000:6f69:605::208

The [CAA entry](https://tools.ietf.org/html/rfc8659) is specifying that only [Let's Encrypt](https://letsencrypt.org/) is authorized to issue certificates for the bgp.rocks domain. It's not a necessary record to add, but I can do it so why not? :)

Configure httpd, part one

We will do this in a few steps. The first step is to get httpd up and running with a very basic configuration. I recommend taking a quick look at /etc/examples/httpd.conf and reading through the manual pages for [httpd](https://man.openbsd.org/httpd.8) and [httpd.conf](https://man.openbsd.org/httpd.conf.5).

Add the following into httpd.conf:

server "bgp.rocks" {

listen on * port 80

location "/.well-known/acme-challenge/*" {

root "/acme"

request strip 2

}

}

Verify that the configuration is good, and if so enable and start httpd:

# httpd -n

configuration OK

# rcctl enable httpd

# rcctl start httpd

httpd(ok)

That's all we have to in httpd.conf for now.

Configure acme-client

The [ACME protocol](https://en.wikipedia.org/wiki/Automated_Certificate_Management_Environment) is the magic that in the end enables us to get the certificates we want. There is a client included in OpenBSD base so no extra software needs to be installed.

cp /etc/examples/acme-client.conf /etc

mkdir -p -m 700 /etc/ssl/private

mkdir -p -m 755 /var/www/acme

Add the following into acme-client.conf:

domain bgp.rocks {

alternative names { www.bgp.rocks }

domain key "/etc/ssl/private/bgp.rocks.key"

domain full chain certificate "/etc/ssl/bgp.rocks.fullchain.pem"

sign with letsencrypt

}

Let's try and get those certificates we've been waiting for so long:

# acme-client -v bgp.rocks

[...]

acme-client: /etc/ssl/bgp.rocks.fullchain.pem: created

Common issues I ran into was DNS issues (A and AAAA record not updated) and forgetting to either open up port 80 in the firewall or forgetting to start httpd.

Configure httpd, part two

Now we can do the final configuration in httpd.conf and enable our website with TLS! Create the directory /var/www/htdocs/bgp.rocks and modify the httpd.conf file to contain the following:

server "bgp.rocks" {

alias www.bgp.rocks

listen on * port 80

block return 301 "https://bgp.rocks$REQUEST_URI"

}

server "bgp.rocks" {

listen on * tls port 443

# Not a typo, we're chroot'ed to /var/www

root "/htdocs/bgp.rocks"

tls {

certificate "/etc/ssl/bgp.rocks.fullchain.pem"

key "/etc/ssl/private/bgp.rocks.key"

}

location "/.well-known/acme-challenge/*" {

root "/acme"

request strip 2

}

}

server "www.bgp.rocks" {

listen on * tls port 443

tls {

certificate "/etc/ssl/bgp.rocks.fullchain.pem"

key "/etc/ssl/private/bgp.rocks.key"

}

block return 301 "https://bgp.rocks$REQUEST_URI"

}

This config will enable TLS on https://bgp.rocks and redirect non-secure HTTP connections and https://www.bgp.rocks to the non-www variant.

Let's see if it works:

$ curl -s --head http://www.bgp.rocks | grep Location

Location: https://bgp.rocks/

$ curl -s --head http://bgp.rocks | grep Location

Location: https://bgp.rocks/

$ curl -s --head https://www.bgp.rocks | grep Location

Location: https://bgp.rocks/

$ curl -s --head https://bgp.rocks | grep Location

(no output)

Success! We receive the Location header in return, redirecting us to the correct URL.

Final touch

All that's left is to run crontab -e and add the following to the bottom:

# Let's Encrypt

~ acme-client bgp.rocks && rcctl reload httpd

The ~ means "a random value (within the legal range)" ([src](https://man.openbsd.org/crontab.5)), which I didn't know about! The crontab entry can be trimmed to not run as often but acme-client will check the certificate and abort if it's not up for renewal, so no extra load is put on the Let's Encrypt servers.

If everything works as it should you should now have a httpd server up and running, with certificates from Let's Encrypt automatically being renewed when necessary. And oh, if you got some extra cash, have a think about [donating to Let's Encrypt](https://letsencrypt.org/donate/) for the service they're providing.