In order to provide proper TLS for your services, you will need a certificate signed by a trusted certificate authority (CA). The easiest option for now is to use the Let's Encrypt client by acme-client.
Howto
You will need to set up a httpd server in order for the acme-client to work. It is recommended to use openhttpd, click here to find out how to set up openhttpd.
First, copy the /etc/examples/acme-client.conf template:
$ doas cp /etc/examples/acme-client.conf /etc/acme-client.conf
authority letsencrypt {
api url "https://acme-v02.api.letsencrypt.org/directory"
account key "/etc/acme/letsencrypt-privkey.pem"
}
authority letsencrypt-staging {
api url "https://acme-staging.api.letsencrypt.org/directory"
account key "/etc/acme/letsencrypt-staging-privkey.pem"
}
domain example.com {
alternative names { secure.example.com }
domain key "/etc/ssl/private/example.com.key"
domain full chain certificate "/etc/ssl/example.com.fullchain.pem"
sign with letsencrypt
}
Replace example.com with your domain. If you didn't use any alternative names, in the past, having:
alternative names { }
would cause issues. So, if you have no alternative names, I recommend you comment that line out as follows:
# alternative names { secure.example.com }
Now, run acme-client:
$ doas acme-client -Fv example.com
Troubleshooting
If you run into errors, check to make sure:
# DNS is configured properly.
# The web server is configured properly. You must have a web server in order for the acme-client to work. (Don't be confused here if your web server seems not running in a web browser: the example config redirects all visits to the https port, that may not yet be working yet.)
# You have the proper permissions set on the folders in /var/www/. An example output would be,
$ ls -l /var | grep www
drwxr-xr-x 11 root daemon 512 Mar 28 05:28 www
$ ls -l /var/www
total 36
drwxr-xr-x 2 root daemon 512 Mar 28 22:16 acme
drwxr-xr-x 2 root daemon 512 Mar 14 06:12 bin
drwx-----T 2 www daemon 512 Oct 12 12:34 cache
drwxr-xr-x 2 root daemon 512 Mar 14 06:12 cgi-bin
drwxr-xr-x 2 root daemon 512 Mar 14 06:03 conf
drwxr-xr-x 3 root daemon 512 Oct 12 12:34 htdocs
drwxr-xr-x 2 root daemon 512 Mar 29 00:00 logs
drwxr-xr-x 2 root daemon 512 Oct 12 12:34 run
# Your firewall is not configured to block Let's Encrypt certification verification process. Typically it will initiate a few servers to connect to port 80 on your server.
Successful outcomes
A successful outcome would result in:
# A ASCII text file, suffixed with .key with your hostname in /etc/ssl/private e.g.
$ doas ls -l /etc/ssl/private
-r-------- 1 root wheel 3272 Mar 28 22:16 example.com.key
# A PEM certificate under /etc/ssl e.g.
$ ls -l /etc/ssl/*.pem
-r--r--r-- 1 root wheel 3937 Mar 28 22:16 example.com.fullchain.pem
It would have the following output of running acme-client, generating a certificate for example.com
acme-client: /etc/ssl/private/example.com.key: generated RSA domain key
acme-client: /etc/acme/letsencrypt-privkey.pem: generated RSA account key
acme-client: https://acme-v02.api.letsencrypt.org/directory: directories
acme-client: acme-v02.api.letsencrypt.org: DNS: 172.65.32.248
acme-client: 172.65.32.248: tls_close: EOF without close notify
acme-client: 172.65.32.248: tls_close: EOF without close notify
acme-client: dochngreq: https://acme-v02.api.letsencrypt.org/acme/authz-v3/3674632835
acme-client: 172.65.32.248: tls_close: EOF without close notify
acme-client: challenge, token: mylkLrPXTvdyiTbDDybKy7M-0JyqiBr0nOg8UXnJ0uDL, uri: https://acme-v02.api.letsencrypt.org/acme/chall-v3/3674632835/-1tUXQ, status: 0
acme-client: /var/www/acme/mylkLrPXTvdyiTbDDybKy7M-0JyqiBr0nOg8UXnJ0uDL: created
acme-client: https://acme-v02.api.letsencrypt.org/acme/chall-v3/3674632835/-1tUXQ: challenge
acme-client: 172.65.32.248: tls_close: EOF without close notify
acme-client: 172.65.32.248: tls_close: EOF without close notify
acme-client: order.status 0
acme-client: dochngreq: https://acme-v02.api.letsencrypt.org/acme/authz-v3/3674632835
acme-client: 172.65.32.248: tls_close: EOF without close notify
acme-client: challenge, token: mylkLrPXTvdyiTbDDybKy7M-0JyqiBr0nOg8UXnJ0uDL, uri: https://acme-v02.api.letsencrypt.org/acme/chall-v3/3674632835/-1tUXQ, status: 2
acme-client: 172.65.32.248: tls_close: EOF without close notify
acme-client: order.status 1
acme-client: https://acme-v02.api.letsencrypt.org/acme/finalize/81817869/2815341474: certificate
acme-client: 172.65.32.248: tls_close: EOF without close notify
acme-client: 172.65.32.248: tls_close: EOF without close notify
acme-client: order.status 3
acme-client: https://acme-v02.api.letsencrypt.org/acme/cert/vxsJMODZOeZxwiuyq9Bz6jqgoRRRUak8ZQ3ob: certificate
acme-client: 172.65.32.248: tls_close: EOF without close notify
acme-client: /etc/ssl/example.com.fullchain.pem: created
Common errors
Do not request domains you don't own
If you change the domains, you need to move the cert and request again