TLS with Certbot§
To set up SSL/TLS access in Unit, you need certificate bundles. Although you can use self-signed certificates, it’s generally advisable to obtain certificates for your website from a certificate authority (CA). For this purpose, you may employ EFF’s Certbot that issues free certificates signed by Let’s Encrypt, a non-profit CA.
Generating Certificates§
Install Unit on your website’s server.
Install Certbot on the same server, choosing None of the above in the Software dropdown list and the server’s OS in the System dropdown list at EFF’s website.
Run certbot and follow its instructions to generate the certificate bundle. You will be prompted to enter the domain name of the website and validate domain ownership; the latter can be done differently.
To use a temporary server for authentication, stop any process listening on port 80 and run:
# certbot certonly --standalone
After the certificate bundle is successfully saved, restart the process that was listening on port 80.
If you can’t run the temporary server for some reason, use DNS records to validate your domain:
# certbot certonly --manual --preferred-challenges dns
Note
You must be able to edit the server’s DNS entries to use the second method. Certbot offers other domain validation methods (authenticators) as well, but they’re not discussed here for brevity.
Both commands above store the resulting
.pem
files as follows:/etc/letsencrypt/ └── live/ └── www.example.com ├── cert.pem ├── chain.pem ├── fullchain.pem └── privkey.pem
Create a certificate bundle fit for Unit and upload it to the
certificates
section of Unit’s control API:# cat /etc/letsencrypt/live/www.example.com/fullchain.pem \ /etc/letsencrypt/live/www.example.com/privkey.pem > bundle1.pem # curl -X PUT --data-binary @bundle1.pem \ --unix-socket /path/to/control.unit.sock \ http://localhost/certificates/certbot1 { "success": "Certificate chain uploaded." }
Create or update a listener to use the uploaded bundle in Unit:
# curl -X PUT --data-binary \ '{"pass": "applications/ssl_app", "tls": {"certificate": "certbot1"}}' \ --unix-socket /path/to/control.unit.sock \ 'http://localhost/config/listeners/*:443'
Try accessing your website via HTTPS:
$ curl https://www.example.com -v ... * TLSv1.3 (OUT), TLS handshake, Client hello (1): * TLSv1.3 (IN), TLS handshake, Server hello (2): * TLSv1.3 (IN), TLS Unknown, Certificate Status (22): * TLSv1.3 (IN), TLS handshake, Unknown (8): * TLSv1.3 (IN), TLS Unknown, Certificate Status (22): * TLSv1.3 (IN), TLS handshake, Certificate (11): * TLSv1.3 (IN), TLS Unknown, Certificate Status (22): * TLSv1.3 (IN), TLS handshake, CERT verify (15): * TLSv1.3 (IN), TLS Unknown, Certificate Status (22): * TLSv1.3 (IN), TLS handshake, Finished (20): * TLSv1.3 (OUT), TLS change cipher, Client hello (1): * TLSv1.3 (OUT), TLS Unknown, Certificate Status (22): * TLSv1.3 (OUT), TLS handshake, Finished (20): * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 * ALPN, server did not agree to a protocol * Server certificate: * subject: CN=www.example.com * start date: Sep 21 22:10:42 2020 GMT * expire date: Dec 20 22:10:42 2020 GMT ...
Renewing Certificates§
Certbot enables renewing the certificates manually or automatically. For manual renewal and rollover:
Repeat the steps above to renew the certificates and upload the new bundle under a different name:
# certbot certonly --standalone What would you like to do? - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1: Keep the existing certificate for now 2: Renew & replace the cert (may be subject to CA rate limits) # cat /etc/letsencrypt/live/www.example.com/fullchain.pem \ /etc/letsencrypt/live/www.example.com/privkey.pem > bundle2.pem # curl -X PUT --data-binary @bundle2.pem \ --unix-socket /path/to/control.unit.sock \ http://localhost/certificates/certbot2 { "success": "Certificate chain uploaded." }
Now you have two certificate bundles uploaded; Unit knows them as
certbot1
andcertbot2
. Optionally query thecertificates
section to review common details such as expiry dates, subjects, or issuers:# curl --unix-socket /path/to/control.unit.sock \ http://localhost/certificates
Update the listener, switching it to the renewed certificate bundle:
# curl -X PUT --data-binary 'certbot2' \ --unix-socket /path/to/control.unit.sock \ 'http://localhost/config/listeners/*:443/tls/certificate'
Note
There’s no need to shut Unit down; your server can stay online during the rollover.
Delete the expired bundle:
# curl -X DELETE --unix-socket /path/to/control.unit.sock \ 'http://localhost/certificates/certbot1' { "success": "Certificate deleted." }
Note
Currently, Certbot doesn’t have installer plugins that enable automatic certificate rollover in Unit. However, you can set up Certbot’s hooks using the commands above to the same effect.