dns_godaddy_key = abcdefg dns_godaddy_secret = hijk
Certbot
A software tool for auto-renewal of TLS certificates using Let's Encrypt.
Certbot offers DNS plugins: instead of a regular HTTP plugin that configure the local webserver and requests the ACME server make a HTTP request, the DNS plugin interfaces with the domain registrar to set a TXT record and requests the ACME server to make a DNS request.
This means certbot
can provide two types of certificates:
- Domain/Subdomain-specific certificate
- Wildcard domain certificates
Domain-specific certificates
Easiest to use the nginx extension, when deploying on nginx web server. Simply add the configuration like so:
- /etc/nginx/sites-enabled/notes.pyuxiang.com
server { server_name notes.pyuxiang.com; listen 80; ...
then run certbot, which will perform domain name auto-discovery:
sudo certbot
Certificates can be renewed with sudo certbot renew
and deleted with sudo certbot delete
.
Logs for certbot
is located in /var/log/letsencrypt
. Example cron script:
# Let's Encrypt certificate auto-renewal (/var/log/letsencrypt) 0 0 * * 1 certbot renew
Enforce HTTPS
Other than using HSTS headers, server-side HTTPS can also be enforced in nginx using a redirect. This is automatically created by Certbot:
server { if ($host = pyuxiang.com) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; server_name pyuxiang.com; return 404; # managed by Certbot }
Wildcard certificates
GoDaddy
Here's an example for GoDaddy, with credentials (key + secret)1) obtained from their developer portal.
These credentials are ridiculously critical, so make sure they are given 0o660
permissions for root only.
Instructions below are for Ubuntu 22.04 LTS. Note that all these must be performed under the system python, due to permissions of secrets and write directories.
Install the pip
package if not already installed, as well as the required certbot
package and its extensions (for nginx and godaddy):
sudo apt install python3-pip sudo pip3 install -U certbot certbot-nginx certbot-dns-godaddy
Renew certificate for both root and wildcard domains (note that the credentials here are located at /etc/nginx/godaddy_credentials.ini
):
sudo certbot \ --installer nginx --authenticator dns-godaddy \ --dns-godaddy-credentials /etc/nginx/godaddy_credentials.ini \ --dns-godaddy-propagation-seconds 900 \ --keep-until-expiring --non-interactive --expand \ --server https://acme-v02.api.letsencrypt.org/directory \ --agree-tos --email pehyuxiang@gmail.com \ -d 'pyuxiang.com' -d '*.pyuxiang.com'
The --dns-godaddy-propagation-seconds
option sets the duration to wait for DNS changes to propagate after requesting for the certificate. Once certbot
terminates, confirm the certificate with:
sudo openssl x509 -in /etc/letsencrypt/live/pyuxiang.com/fullchain.pem -text
If the certificate is not automatically installed, e.g. server name was not provided in any of the server blocks, then run after doing so:
sudo certbot install --cert-name pyuxiang.com
Other registrars
For domain registrars with stringent API access requirements (or which do not support API access in the first place), a more involved setup can include setting up your own ACME-DNS server to serve the DNS challenges instead. This will involve adding a _acme-challenge
CNAME record to point to the server.
Otherwise, you can also setup using the manual TXT process with: sudo certbot certonly --manual --preferred-challenges dns -d "*.DOMAIN" -d "DOMAIN"
Deployment of wildcard certificates
Wildcard certificates can inevitably end up securing unintended subdomains. Avoid this by forcing a redirect to the root/redirection domain.
- /etc/nginx/sites-enabled/_https_redirect
# Placeholder to redirect all invalid transactions # directed at IP address, to snakeoil destination server { listen 80 default_server; listen 443 ssl default_server; include /etc/nginx/snippets/snakeoil.conf; return 404; } # Redirect all *.pyuxiang.com to root domain, # unless overridden by more specific subdomain server { listen 80; listen 443 ssl; # managed by Certbot server_name *.pyuxiang.com; ssl_certificate /etc/letsencrypt/live/pyuxiang.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/pyuxiang.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot return 301 https://pyuxiang.com; }
- Makefile
renew: sudo certbot \ --installer nginx --authenticator dns-godaddy \ --dns-godaddy-credentials /etc/nginx/dns01_credentials.ini \ --dns-godaddy-propagation-seconds 120 \ --keep-until-expiring --non-interactive --expand \ --server https://acme-v02.api.letsencrypt.org/directory \ --agree-tos --email pehyuxiang@gmail.com \ -d 'pyuxiang.com' -d '*.pyuxiang.com' manual: @echo "Do not explicitly change any certificates after deploying," @echo "i.e. select 'c' when asked." sudo certbot run \ --manual --preferred-challenges dns \ --installer nginx \ --keep-until-expiring --expand \ --agree-tos --email pehyuxiang@gmail.com \ -d 'pyuxiang.com' -d '*.pyuxiang.com'
Migrating away from Certbot now, due to the need for sudo.