💾 Archived View for nox.im › posts › 2021 › 0702 › openbsd-webserver-with-httpd-and-letsencrypt captured on 2024-06-16 at 12:18:22. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2022-06-03)

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

OpenBSD Web Server with httpd and Let's Encrypt

Before starting with the acme-client and the httpd setup, I had created a Let's Encrypt account[1] with a registered account key.

1: created a Let's Encrypt account

Httpd config

add to `/etc/httpd.conf` the domain or default section the challenge path that is going to get hit for the certificate

    location "/.well-known/acme-challenge/*" {
        root "/acme"
        request strip 2
        directory no auto index
    }

and restart httpd

doas rcctl restart httpd

Acme client

Then configure the acme client

doas vi /etc/acme-client.conf
api_url="https://acme-v02.api.letsencrypt.org/directory"
authority letsencrypt {
        api url $api_url
        account key "/etc/acme/letsencrypt.pem"
}
domain nox.im {
    alternative names { www.nox.im }
    domain key "/etc/ssl/private/nox.im.key"
    domain full chain certificate "/etc/ssl/nox.im.fullchain.pem"
    sign with letsencrypt
}

Try to get the certificate

doas acme-client -v nox.im

If everything worked you should see the command terminate with

...
acme-client: /etc/ssl/nox.im.fullchain.pem: created

nice!

we then update the `/etc/httpd.conf` for the TLS key pair and redirect port 80 to https port 443:

ext_ip="*"

server "nox.im" {
    alias "www.nox.im"
    listen on $ext_ip port 80
    block return 301 "https://$SERVER_NAME$REQUEST_URI"
}

server "nox.im" {
    alias "www.nox.im"
    listen on $ext_ip tls port 443
    hsts
    tls {
      certificate "/etc/ssl/nox.im.fullchain.pem"
      key "/etc/ssl/private/nox.im.key"
    }
    log style combined
    root "/htdocs/nox.im"
    location "/.well-known/acme-challenge/*" {
        root "/acme"
        request strip 2
        directory no auto index
    }
}

#server "nox.im" {
#    listen on $ext_ip port 80
#    root "/htdocs/nox.im"
#    location "/.well-known/acme-challenge/*" {
#      root "/acme"
#      request strip 2
#        directory no auto index
#    }
#}

types {
        include "/usr/share/misc/mime.types"
}

to test the configuration without stopping httpd (no downtime!) we can run

doas httpd -n

If that works, restart httpd and we should now have https available

https://nox.im

See the recent post on a simple web analytics dashboard with GoAccess[1] for httpd log based, server side analytics.

1: web analytics dashboard with GoAccess

Renewal

We utilize periodic system maintenance daily which runs the user script /etc/daily.local, if it exists.

doas vi /etc/daily.local
#!/bin/sh

acme-client -v nox.im
rcctl reload httpd

and make it executable

doas chmod +x /etc/daily.local

The certificate is valid for 90 days, so it'll not do anything immediately but only renew it closer to expiration.

Troubleshooting

If your certificate doesn't renew you will get emailed by Let's Encrypt two weeks before expiry. It is best to just run the acme-client manually to diagnose the problem. I recently was messing with my keys and ran into the following issue.

acme-client -v nox.im
api_url = "https://acme-v02.api.letsencrypt.org/directory"
acme-client: /etc/ssl/private/nox.im.key: group read/writable or world read/writable
chmod g-r /etc/ssl/private/nox.im.key

SSL Labs

The SSL Server test performs an analysis of our server configuration, supported protocols, weak ciphers and its susceptibility to downgrade attacks. Our setup of OpenBSD httpd, libressl with Let's Encrypt effortlessly scores an A+ on SSL Labs[1].

1: SSL Labs

SSL Labs A+ score for nox.im[1]

1: SSL Labs A+ score for nox.im

And thereby nox.im made the top list too.

SSL Labs recent top ranked servers[1]

1: SSL Labs recent top ranked servers

DNS Certification Authority Authorization (CAA)

CAA DNS record allows to specify one or more Certification Authorities (CAs) to issue certificates for a given domain. CAA is specified in RFC6844[1] to improve of the public key infrastructure (PKI). Without CAA, any CA can issue a certificate for any domain name.

1: RFC6844

We can set a CAA via a DNS record called CAA (type 257) and restrict certificate issuance. For example, my nox.im CAA configuration for Let's Encrypt is as follows:

@ 10800 IN CAA 128 issue "letsencrypt.org"

CAs are expected to check this record and refuse issuance should they not find themselves on the whitelist.