Introduction

Since OpenBSD 5.9, the base system comes with acme-client: an open source implementation in C that requests a free HTTPS certificate from the Let’s Encrypt Certificate Authority. It is super simple to setup and even easier to use. And once your certificate is issued, the acme-renew script will ensure your website stays TLS encrypted for the remainder of its lifetime.

The following guide assumes OpenBSD 6.2, please refer to the relevant man pages for future releases.

Setup acme-client

Open the file /etc/acme-client.conf in your chosen editor to perform the following:

  1. ensure both instances of the agreement url contain the most up-to-date link;
  2. provide the domain(s) and any subdomains to be covered by the certificate(s);
  3. specify the path to output generated key and certificate files; and
  4. designate absolute path to challengedir where challenges should be sent to the web server.
# $OpenBSD: acme-client.conf,v 1.4 2017/03/22 11:14:14 benno Exp $
#
authority letsencrypt {
agreement url "https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf"
api url "https://acme-v01.api.letsencrypt.org/directory"
account key "/etc/acme/letsencrypt-privkey.pem"
}

authority letsencrypt-staging {
agreement url "https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf"
api url "https://acme-staging.api.letsencrypt.org/directory"
account key "/etc/acme/letsencrypt-staging-privkey.pem"
}

domain www.domain.tld {
alternative names { domain.tld sub1.domain.tld sub2.domain.tld sub3.domain.tld }
domain key "/etc/ssl/private/domain.tld.key"
domain certificate "/etc/ssl/domain.tld.crt"
domain full chain certificate "/etc/ssl/domain.tld.fullchain.pem"
sign with letsencrypt
challengedir "/var/www/acme"
}

That finishes acme-client setup.

Setup httpd

Edit /etc/httpd.conf so that the web server is able to handle requests from Let’s Encrypt who will issue challenges that need to be processed to determine that you are in control of the domains covered by the requested certificate(s). Ensure the relative /root path matches the absolute challengedir path provided in acme-client.conf.

ext_addr="*"

server "domain.tld" {
      alias www.domain.tld
      listen on $ext_addr port 80

      location "/.well-known/acme-challenge/*" {
              root "/acme"
              root strip 2
      }
}

Lines 7 to 10 are all that is needed to handle requests from the Certificate Authority. Before restarting the daemon, if it doesn't already exist, make and bestow ownership to the web server the acme directory in the httpd chroot where challenges will be processed:

# mkdir /var/www/acme
# chown -R www:www /var/www/acme
# rcctl restart httpd

That concludes httpd configuration for the certificate request.

Certificate Request

Before submitting the certificate signing request to Let’s Encrypt, ensure that any subdomains listed in acme-client.conf are properly setup with A or CNAME records with your nameserver or registrar; that is, requests to sub.domain.tld are actually directed to your web server. If all is in order, issue the request.

# acme-client -vvAD www.domain.tld

A successful result will output the public certificate, full chain of trust, and private key, into the ssl directory as specified in acme-client.conf:

# ls -lR /etc/ssl
-r--r--r--   1 root  wheel   2.3K Mar  2 01:31:03 2018 domain.tld.crt
-r--r--r--   1 root  wheel   3.9K Mar  2 01:31:03 2018 domain.tld.fullchain.pem

/etc/ssl/private:
-r--------  1 root  wheel   3.2K Mar  2 01:31:03 2018 domain.tld.key

Now to configure the web server to use TLS.

httpd TLS Configuration

With the free Let's Encrypt certificate, we can now configure httpd to redirect all insecure, unencrypted, plaintext HTTP requests to instead establish secure HTTPS connections with a couple simple server sections in the httpd.conf configuration file. If you want to keep allowing HTTP connections to your site, elide the second location directive in the first server section.

server "domain.tld" {
        alias www.domain.tld
        listen on * port 80
        listen on :: port 80
        root "/htdocs/domain.tld"
        location "/.well-known/acme-challenge/*" {
                root "/acme"
                request strip 2
        }
        location * {
                block return 301 "https://$HTTP_HOST$REQUEST_URI"
        }
}

server "domain.tld" {
        alias www.domain.tld
        listen on * tls port 443
        listen on :: tls port 443
        root "/htdocs/domain.tld"
        tls {
                certificate "/etc/ssl/domain.tld.fullchain.pem"
                key "/etc/ssl/private/domain.tld.key"
        }
        location "/.well-known/acme-challenge/*" {
                root "/acme"
                root strip 2
        }
}

And with that, your site is now serving TLS-encrypted sessions to protect the privacy of you and your visitors.


Comments

comments powered by Disqus