Have you ever wondered if it was possible to obtain an
Server Certificate before you migrate a website? I always assumed the
DNS had to be switched before the
certificate validation could take place. I've come to find there are more options available.
My company is currently in the process of moving all of our client production sites to a new server. Part of that effort is ensuring all sites be placed on
Let's Encrypt offers domain-validated certificates, meaning they have to check that the certificate request comes from a person who actually controls the domain. They do this by sending the client a unique token, and then making a web or DNS request to retrieve a key derived from that token.
There are two main options to obtain a
HTTP Challenge- Posting a specified
filein a specified location on a web site
DNS Challenge- Posting a specified
DNS recordin the domain name system
This is usually handled by adding a
token inside a
.well-known directory in your
Certbot can then confirm you actually control resources on the specified domain, and will sign a
This approach requires you to add specific
DNS TXT entry for each domain requested. This is useful when you haven't switched
DNS yet, but want to issue a
certificate in anticipation (for testing).
For more information on challenges, visit certbot's documentation.
We'll be discussing the
DNS Challenge approach for the rest of the article.
First we need to install
certbot along with all necessary dependencies.
# run as root apt-get update \ && apt-get install software-properties-common \ && add-apt-repository -y universe \ && add-apt-repository -y ppa:certbot/certbot \ && apt-get update \ && apt-get install -y python-certbot-apache
I won't be going over wildcard domains here, but they are an option. Refer to their documentation.
We now need to tell
certbot which domains we would like to issue a
certificate for. Remember to add each subdomain individually.
Since we may have multiple
vhosts per server, we decided to use the
# run as root # replace with your domain # add all relevant subdomains certbot --manual --preferred-challenges dns certonly \ -d yourwebsite.com \ -d www.yourwebsite.com \ # don't forget www binding -d staging.yourwebsite.com \ # example subdomain -d staging.stage1.yourwebsite.com # example long subdomain
Once you run the command above, it will prompt you to add a
DNS TXT record for each specified domain. It will look like this:
Please deploy a DNS TXT record under the name _acme-challenge.yourwebsite.com with the following value: [random-string-of-characters] Before continuing, verify the record is deployed. (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.) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Press Enter to Continue - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Now here's the important part. You need to remove the
base url from each
record name, like so:
|requested name from certbot||actual name to add in
Once you add the
DNS TXT records, and click
Continue through each challenge prompt respectively, the validation should pass.
Press Enter to Continue Waiting for verification... Cleaning up challenges IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/yourwebsite.com/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/yourwebsite.com/privkey.pem Your cert will expire on 2019-04-24. 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
Now that we have a valid certificate, we can update our
# inside the 443 binding SSLEngine On SSLCertificateFile /etc/letsencrypt/live/yourwebsite.com/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/yourwebsite.com/privkey.pem SSLCertificateChainFile /etc/letsencrypt/live/yourwebsite.com/chain.pem
sudo apachectl configtest # if syntax ok sudo apachectl restart
We'll leverage the
crontab of the
root user to automatically renew certificates that will expire soon.
# run as root # edit the crontab crontab -e
Then add the following two lines at the bottom:
# every Monday at 2:30am 30 2 * * 1 /usr/bin/certbot renew --deploy-hook "service apache2 reload" >> /var/log/letsencrypt/le-renew.log
certbot will try and renew any certificates marked for renewal once a week. We then use the
--deploy-hook to only reload
apache if necessary.
Special thanks to Daniel McCarney for the updated