Let's Encrypt: Certbot with httpd on OpenBSD 6.4

created
( modified )
@nabbisen

Intro

Let’s Encrypt is “a free, automated, and open Certificate Authority”. Certbot is “an easy-to-use automatic client that fetches and deploys SSL/TLS certificates for your web server”, well known as “the official Let’s Encrypt client”.

I remember well how excited I felt when I read Let’s Encrypt’s “Our First Certificate Is Now Live” in 2015. How wonderful the goal of them is; it’s to “give people the digital certificates they need in order to enable HTTPS (SSL/TLS) for websites, for free” “to create a more secure and privacy-respecting Web”! Since 2018, they have begun to support even ACME v2 and Wildcard Certificate!

Well, in OpenBSD as well as other operation systems, it’s easy and comfortable to have their big help 😊

Envrionment

  • OS: OpenBSD 6.4 amd64
  • Web Server: OpenBSD’s httpd
  • Certification: Let’s Encrypt with Certbot 0.27

Reference

How To Install Certbot

Just:

# pkg_add certbot

How To Obtain Certificates

First, let’s prepare a directory as webroot:

# mkdir /var/www/%your-webroot%

Next, edit /etc/httpd.conf in order to build a web server of %your-domain% listening to Let’s Encrypt’s HTTP challenge for certification:

# [/etc/httpd.conf]

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

ext_addr = egress

# ...

cert_domain = %your-domain%
server $cert_domain {
        listen on $ext_addr port 80
        root "/%your-webroot%"
        directory auto index
}

Then reload the configuration:

# rcctl restart httpd

OK. We’re ready.

(* You don’t need to stop the web server temporarily to release port 80 for --standalone thanks to --webroot! *)

Let’s try to obtain a new certificate:

# certbot certonly --webroot -w /var/www/%your-webroot% -d %your-domain%

* Note: The meanings of the above subcommand and options are below according to the manual:

Subcommand/Option Description
certonly Obtain or renew a certificate, but do not install it.
--webroot Place files in a server’s webroot directory for authentication.
--webroot-path WEBROOT_PATH, -w WEBROOT_PATH Webroot / public_html path[s individually].
-d DOMAIN, --domains DOMAIN Specified domain[s individually].

Besides, it’s possible to omit --webroot -w /var/www/%your-webroot% because you are asked later (and so it becomes non-automatic process).

* Note: If it’s your first time, you are asked your email address where the CA (certificate authority) will send notification emails. Alternatively, you can use the -m EMAIL, --email EMAIL option on the command line.

Anyway, certbot outputs like this:

# certbot certonly --webroot -w /var/www/%your-webroot% -d %your-domain%

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for %your-domain%
Using the webroot path /var/www/%your-webroot% for all unmatched domains.
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/%your-domain%/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/%your-domain%/privkey.pem
   Your cert will expire on 20??-??-??. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

We receive the sweet “Congratulations!” message. Let’s reflect gotten fullchain.pem and privkey.pem in /etc/httpd.conf:

# [/etc/httpd.conf]

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

ext_addr = egress

# ...

#cert_domain = %your-domain%
#server $cert_domain {
#        listen on $ext_addr port 80
#        root "/%your-webroot%"
#        directory auto index
#}

server "%your-domain%" {
        listen on $ext_addr port 80
        block return 301 "https://$SERVER_NAME$REQUEST_URI"
}
server "%your-domain%" {
        listen on $ext_addr tls port 443
        tls {
                certificate     "/etc/letsencrypt/live/%your-domain%/fullchain.pem"
                key             "/etc/letsencrypt/live/%your-domain%/privkey.pem"
        }
        root "/%your-webroot%"
        directory auto index
}

And then:

# rcctl restart httpd

Now we obtain the web server to create HTTPS connection whenever it’s accessed at last!

How To Manage Obtained Certificates

Please bear in mind that Let’s Encript’s certificates are valid for 90 days and why it is.

These are the basic subcommands of certbot:

Subcommand Description
certificates List certificates managed by Certbot
renew Renew all certificates (or one specified with --cert-name)
delete Clean up all files related to a certificate
revoke Revoke a certificate specified with --cert-path or --cert-name
To list
# certbot certificates
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Found the following certs:
  Certificate Name: %your-domain%
    Domains: %your-domain%
    Expiry Date: 20??-??-?? ??:??:??+00:00 (VALID: 90 days)
    Certificate Path: /etc/letsencrypt/live/%your-domain%/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/%your-domain%/privkey.pem
  Certificate Name: ...
To renew

Simple usage is like this to “renew any previously-obtained certificates that expire in less than 30 days”:

# certbot renew

Pre/Post-Hooks are available:

# certbot renew --pre-hook "rcctl stop httpd" --post-hook "rcctl start httpd"
To delete

Delete a certificate completely:

# certbot delete --cert-name %your-domain%
✿ ✿ ✿

Happy serving 🌵


Comments or feedbacks are welcomed and appreciated.