Published 2022-06-15.
Last modified 2024-01-01.
Time to read: 2 minutes.
The process of making wildcard SSL certificates can be hard to get right at first. However, I use wildcard SSL certificates for most of my internet domains, so it is important to me. This article distills the essence of what I have found to be important when creating these certificates.
Update – 9 months after writing this article, I wrote about a better way to generate wildcard SSL certificates: Wildcard SSL Certificates for Letsencrypt with Lego.
Making a Free Wildcard SSL Certificate
Certbot
powers EFF’s
Letsencrypt capability.
Source code is on GitHub.
Install certbot
on Debian distros such as Ubuntu as follows:
$ yes | sudo apt install certbot Preparing to unpack .../06-python3-zope.event_4.4-3_all.deb ... Unpacking python3-zope.event (4.4-3) ... Selecting previously unselected package python3-zope.component. Preparing to unpack .../07-python3-zope.component_4.3.0-3_all.deb ... Unpacking python3-zope.component (4.3.0-3) ... Selecting previously unselected package python3-certbot. Preparing to unpack .../08-python3-certbot_1.21.0-1build1_all.deb ... Unpacking python3-certbot (1.21.0-1build1) ... Selecting previously unselected package python3-icu. Preparing to unpack .../09-python3-icu_2.8.1-0ubuntu2_amd64.deb ... Unpacking python3-icu (2.8.1-0ubuntu2) ... Selecting previously unselected package certbot. Preparing to unpack .../10-certbot_1.21.0-1build1_all.deb ... Unpacking certbot (1.21.0-1build1) ... Setting up python3-configargparse (1.5.3-1) ... Setting up python3-requests-toolbelt (0.9.1-1) ... Setting up python3-parsedatetime (2.6-2) ... Setting up python3-icu (2.8.1-0ubuntu2) ... Setting up python3-zope.event (4.4-3) ... Setting up python3-zope.hookable (5.1.0-1build1) ... Setting up python3-josepy (1.10.0-1) ... Setting up python3-zope.component (4.3.0-3) ... Setting up python3-acme (1.21.0-1) ... Setting up python3-certbot (1.21.0-1build1) ... Setting up certbot (1.21.0-1build1) ... Created symlink /etc/systemd/system/timers.target.wants/certbot.timer → /lib/systemd/system/certbot.timer. Processing triggers for man-db (2.10.2-1) ... Scanning processes... Scanning processor microcode... Scanning linux images... Failed to retrieve available kernel versions. Failed to check for processor microcode upgrades. No services need to be restarted. No containers need to be restarted. No user sessions are running outdated binaries. No VM guests are running outdated hypervisor (qemu) binaries on this host.
certbot
has 2 subcommands of interest: certonly
(used when creating a certificate for the first time),
and renew
(used when updating a pre-existing certificate).
The creation process requires the user to do things before it can complete, so it can only be run interactively.
The files and directories creating by the process of creating a new SSL certificate should not be deleted.
Contrary to what the Letsencrypt certbot
documentation says, I have found that
these files and directories allow the renewal process to proceed without requiring user interaction, so it can be scripted.
Certbot Help Messages
Here is the help message for the certbot certonly
subcommand:
$ certbot certonly --help - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - certbot [SUBCOMMAND] [options] [-d DOMAIN] [-d DOMAIN] ...
Certbot can obtain and install HTTPS/TLS/SSL certificates. By default, it will attempt to use a webserver both for obtaining and installing the certificate. The most common SUBCOMMANDS and flags are:
obtain, install, and renew certificates: (default) run Obtain & install a certificate in your current webserver certonly Obtain or renew a certificate, but do not install it renew Renew all previously obtained certificates that are near expiry enhance Add security enhancements to your existing configuration -d DOMAINS Comma-separated list of domains to obtain a certificate for
(the certbot apache plugin is not installed) --standalone Run a standalone webserver for authentication (the certbot nginx plugin is not installed) --webroot Place files in a server's webroot folder for authentication --manual Obtain certificates interactively, or using shell script hooks
-n Run non-interactively --test-cert Obtain a test certificate from a staging server --dry-run Test "renew" or "certonly" without saving any certificates to disk
manage certificates: certificates Display information about certificates you have from Certbot revoke Revoke a certificate (supply --cert-name or --cert-path) delete Delete a certificate (supply --cert-name)
manage your account: register Create an ACME account unregister Deactivate an ACME account update_account Update an ACME account --agree-tos Agree to the ACME server's Subscriber Agreement -m EMAIL Email address for important account notifications
More detailed help:
-h, --help [TOPIC] print this message, or detailed help on a topic; the available TOPICS are:
all, automation, commands, paths, security, testing, or any of the subcommands or plugins (certonly, renew, install, register, nginx, apache, standalone, webroot, etc.) -h all print a detailed help page including all topics --version print the version number - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Here is the help message for the certbot certonly
subcommand:
$ certbot renew --help - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
certbot [SUBCOMMAND] [options] [-d DOMAIN] [-d DOMAIN] ...
Certbot can obtain and install HTTPS/TLS/SSL certificates. By default, it will attempt to use a webserver both for obtaining and installing the certificate. The most common SUBCOMMANDS and flags are:
obtain, install, and renew certificates: (default) run Obtain & install a certificate in your current webserver certonly Obtain or renew a certificate, but do not install it renew Renew all previously obtained certificates that are near expiry enhance Add security enhancements to your existing configuration -d DOMAINS Comma-separated list of domains to obtain a certificate for
(the certbot apache plugin is not installed) --standalone Run a standalone webserver for authentication (the certbot nginx plugin is not installed) --webroot Place files in a server's webroot folder for authentication --manual Obtain certificates interactively, or using shell script hooks
-n Run non-interactively --test-cert Obtain a test certificate from a staging server --dry-run Test "renew" or "certonly" without saving any certificates to disk
manage certificates: certificates Display information about certificates you have from Certbot revoke Revoke a certificate (supply --cert-name or --cert-path) delete Delete a certificate (supply --cert-name)
manage your account: register Create an ACME account unregister Deactivate an ACME account update_account Update an ACME account show_account Display account details --agree-tos Agree to the ACME server's Subscriber Agreement -m EMAIL Email address for important account notifications
More detailed help:
-h, --help [TOPIC] print this message, or detailed help on a topic; the available TOPICS are:
all, automation, commands, paths, security, testing, or any of the subcommands or plugins (certonly, renew, install, register, nginx, apache, standalone, webroot, etc.) -h all print a detailed help page including all topics --version print the version number - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Complete documentation for certbot
is here.
Generic DNS Authentication
I used certbot
to create a special file within the website as follows, without using sudo
.
I want a wildcard SSL certificate, which
requires certbot to use DNS authentication.
BTW, the following options include two -d
options,
one for the domain apex (mslinn.com
) and one for the subdomains (*.mslinn.com
)
$ certbot certonly \ --manual \ --agree-tos \ --preferred-challenges dns-01 \ --rsa-key-size 4096 \ -d mslinn.com -d *.mslinn.com \ --config-dir ~/.certbot/mslinn.com/config \ --logs-dir ~/.certbot/mslinn.com/logs \ --work-dir ~/.certbot/mslinn.com/work Saving debug log to /home/mslinn/.certbot/mslinn.com/logs/letsencrypt.log Enter email address (used for urgent renewal and security notices) (Enter 'c' to cancel): mslinn@mslinn.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Would you be willing, once your first certificate is successfully issued, to share your email address with the Electronic Frontier Foundation, a founding partner of the Let's Encrypt project and the non-profit organization that develops Certbot? We'd like to send you email about our work encrypting the web, EFF news, campaigns, and ways to support digital freedom. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (Y)es/(N)o: n Account registered. Requesting a certificate for mslinn.com and *.mslinn.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Please deploy a DNS TXT record under the name:
_acme-challenge.mslinn.com.
with the following value:
n6o3qMw5N7qxAzV4uNQePKxJjaw0f-Bo32CybWr-lhE
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Press Enter to Continue (This must be set up in addition to the previous challenges; do not remove, replace, or undo the previous challenge tasks yet. Note that you might be asked to create multiple distinct TXT records with the same name. This is permitted by DNS standards.) Before continuing, verify the TXT record has been deployed. Depending on the DNS provider, this may take some time, from a few seconds to multiple minutes. You can check if it has finished deploying with aid of online tools, such as the Google Admin Toolbox: https://toolbox.googleapps.com/apps/dig/#TXT/_acme-challenge.mslinn.com. Look for one or more bolded line(s) below the line ';ANSWER'. It should show the value(s) you’ve just added. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Press Enter to Continue Successfully received certificate. Certificate is saved at: /home/mslinn/.certbot/mslinn.com/config/live/mslinn.com/fullchain.pem Key is saved at: /home/mslinn/.certbot/mslinn.com/config/live/mslinn.com/privkey.pem This certificate expires on 2022-09-29. These files will be updated when the certificate renews. NEXT STEPS: - This certificate will not be renewed automatically. Autorenewal of --manual certificates requires the use of an authentication hook script (--manual-auth-hook) but one was not provided. To renew this certificate, repeat this same certbot command before the certificate’s expiry date. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
I made a bash script (~/.local/bin/sslCert
) to create SSL certificates, which performs the same steps as the above,
but it works for any site, and can renew certificates as well as create them:
#!/bin/bash function help { echo "Creates or updates an wildcard SSL certificate Usage: $(basename $0) DOMAIN Example: $(basename $0) scalacourses.com The relevant files are stored in ~/.certbot/DOMAIN/ Creating a new certificate requires an interactive user session; updating a certificate can be done in a cron job. Currently, the renew verb is capable of either renewing all installed certificates that are due to be renewed or renewing a single certificate specified by its name. If you would like to renew specific certificates by their domains, use the certonly command instead. The renew verb may provide other options for selecting certificates to renew in the future. Ask for help or search for solutions at https://community.letsencrypt.org See the logfile /home/mslinn/.certbot/ancientwarmth.com/logs/letsencrypt.log or re-run Certbot with -v for more details. BTW, you can test the date range of the certificate with this incantation: curl https://domain.com -vI --stderr - | grep 'date:' " exit 1 } if [ -z "$1" ]; then help; fi DOMAIN="$1" if [ -d "$HOME/.certbot/$DOMAIN" ]; then # Renew existing certificate CMD=certonly # renew OPTIONS=--force-renew else # Make new certificate (interactively) CMD=certonly unset OPTIONS fi certbot "$CMD" $OPTIONS \ --agree-tos \ --config-dir "$HOME/.certbot/$DOMAIN/config" \ -d "$DOMAIN" -d "*.$DOMAIN" \ --email mslinn@mslinn.com \ --logs-dir "$HOME/.certbot/$DOMAIN/logs" \ --manual \ --preferred-challenges dns-01 \ --rsa-key-size 4096 \ --work-dir "$HOME/.certbot/$DOMAIN/work"
Here is the help message for the script:
$ sslCert Creates or updates an wildcard SSL certificate Usage: sslCert DOMAIN Example: sslCert scalacourses.com The relevant files are stored in ~/.certbot/DOMAIN/ Creating a new certificate requires an interactive user session; updating a certificate can be done in a cron job.
The following crontab
entry causes the script to run every 60 days.
0 0 1 */2 * .local/bin/sslCert mslinn.com
The next time the script was run, output looked like:
$ sslCert mslinn.com Saving debug log to /home/mslinn/.certbot/mslinn.com/logs/letsencrypt.log Renewing an existing certificate for mslinn.com and *.mslinn.com
Successfully received certificate. Certificate is saved at: /home/mslinn/.certbot/mslinn.com/config/live/mslinn.com/fullchain.pem Key is saved at: /home/mslinn/.certbot/mslinn.com/config/live/mslinn.com/privkey.pem This certificate expires on 2022-12-13. These files will be updated when the certificate renews.
NEXT STEPS: - This certificate will not be renewed automatically. Autorenewal of --manual certificates requires the use of an authentication hook script (--manual-auth-hook) but one was not provided. To renew this certificate, repeat this same certbot command before the certificate's expiry date.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Checking the Certificate With A Web Browser
Microsoft Windows caches SSL certificates, which can prevent your web browser from detecting newly updated SSL certificates. To clear the Windows SSL cache:
- Press the Windows key, type
Internet Options
, and press Enter. - Select the Content tab.
- Click the Clear SSL state button.
- Click the OK button.