The author selected the COVID-19 Relief Fund to receive a donation as part of the Write for DOnations program.
The majority of Let’s Encrypt certificates are issued using HTTP validation, which allows for the installation of certificates on a single server. However, HTTP validation is not always suitable for issuing certificates for use on load-balanced websites, nor can you use this validation to issue wildcard certificates.
DNS validation allows for certificate issuance requests to be verified using DNS records, rather than by serving content over HTTP. This means that certificates can be issued simultaneously for a cluster of web servers running behind a load balancer, or for a system that isn’t directly accessible over the internet.
In this tutorial, you will use the certbot-dns-digitalocean hook for Certbot to issue a Let’s Encrypt certificate using DNS validation via the DigitalOcean API.
You can use the certbot-dns-digitalocean tool to integrate Certbot with DigitalOcean’s DNS management API, allowing the certificate validation records to be automatically configured on-the-fly when you request a certificate.
Another key benefit of certbot-dns-digitalocean is that you can use it to issue certificates for individual servers that may be running behind a load balancer, or are otherwise not directly accessible over HTTP. In these cases, you can’t use traditional HTTP certificate validation, unless you set the validation files on each and every server, which can be inconvenient. The certbot-dns-digitalocean tool is also useful if you want to issue a certificate for a server that isn’t accessible over the internet, for example an internal system or staging environment.
certbot-dns-digitalocean also fully supports wildcard certificates, which can only be issued using DNS validation.
To complete this tutorial, you will need:
An Ubuntu 20.04 server set up by following the Initial Server Setup with Ubuntu 20.04, including a sudo non-root user.
A domain name managed via your DigitalOcean account—that is, for managing DNS records. In this particular example, we will use your_domain
and subdomain.your_domain
, as well as *.your_domain
for a wildcard certificate, however you can adjust this for other domains or subdomains if required.
A DigitalOcean API key (Personal Access Token) with read and write permissions. To create one, visit How to Create a Personal Access Token.
Once you have these ready, log in to your server as your non-root user to begin.
In this step, you will install Certbot, which is a program to issue and manage Let’s Encrypt certificates.
Certbot is available within the official Ubuntu Apt repositories, so you can install it using the default system package manager:
Once the installation has completed, you can check with the following command:
This will output something similar to the following:
Outputcertbot 0.40.0
In this step you installed Certbot. Next, you will download and install the acme-dns-certbot hook.
Now that you’ve installed the base Certbot program, you can download and install certbot-dns-digitalocean, which will allow Certbot to operate in DNS validation mode using the DigitalOcean DNS management API.
Like Certbot itself, which you installed in Step 1, the certbot-dns-digitalocean utility is available within Ubuntu’s default repositories. However, the Certbot repository contains a more reliably updated version, so it is always recommended to use this where possible.
Continue by installing the package for certbot-dns-digitalocean:
Once the installation has completed, you need to set up a configuration file containing the DigitalOcean API key/Personal Access Token that you generated as part of the prerequisites.
Begin by creating the creds.ini
file in a private location:
Next, restrict the permissions on the file in order to make sure no other user on your server can read it:
Finally, open the file using your text editor and add your DigitalOcean access token:
The content of the file will be as follows:
dns_digitalocean_token = your_digitalocean_access_token
Once done, save and close the file.
Warning: Your DigitalOcean access token grants access to your DigitalOcean account, so you must protect it as you would a password. Do not share it with anyone or check it into a public code repository.
In this step, you downloaded and installed the certbot-dns-digitalocean utility and created a configuration file containing your API credentials.
In this step, you’ll issue a certificate using Certbot and the DigitalOcean API.
To issue your first certificate, run Certbot using the following arguments, making sure to specify the correct path to your credentials file as well as your domains:
Note: If you see an unsafe permissions on credentials configuration file
warning, this indicates that the file permissions have not been correctly restricted, thus allowing other users on your server to access your token. Please double-check with the chmod
command in Step 2.
Certbot will take a few seconds to request the certificate; you will then receive a message confirming that it has issued your certificate:
Output...
Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/your_domain/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/your_domain/privkey.pem
...
In the event that the certificate issuance fails, this may be because there wasn’t sufficient time for the DNS changes to propagate. You can optionally increase the DNS propagation delay to give more time for the verification DNS records to propagate and be picked up by Let’s Encrypt. The delay is 10 seconds by default, but you can increase this using the --dns-digitalocean-propagation-seconds
argument:
Finally, you can also use certbot-dns-digitalocean to issue wildcard certificates for your domain:
Note: In some cases, requesting multiple certificates for the same hostnames in a short time period can cause issuance to begin failing. This is due to rate limits and the DNS time-to-live (TTL) value, which can sometimes cause delays in new DNS changes being propagated.
To mitigate this, you may wish to wait out the duration of the TTL, or consider adjusting the --dns-digitalocean-propagation-seconds
option that was detailed earlier in this step.
In this step, you used Certbot with certbot-dns-digitalocean for the first time and issued your initial certificates.
In this final step, you will renew certificates using Certbot with certbot-dns-digitalocean.
Once your certificates are nearing expiry, Certbot is able to automatically renew them for you:
The renewal process can run start-to-finish without user interaction. It will also remember the configuration options that you specified during the initial setup.
By default, Certbot will run this as an automatic scheduled system task, meaning that no further maintenance is needed for your certificates. You can check that the scheduled task has been correctly installed by printing out the status of the associated system service, which is certbot.timer
:
This will output something similar to the following, which shows the loaded task scheduled to run twice per day:
Output● certbot.timer - Run certbot twice daily
Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; vendor preset: enabled)
Active: active (waiting) since Sun 2020-11-22 18:18:40 UTC; 2 weeks 6 days ago
Trigger: Sun 2020-12-13 7:17:57 UTC; 11h left
Nov 22 18:18:40 droplet1 systemd[1]: Started Run certbot twice daily.
However, to test that this is working without having to wait until nearer the expiry date of your certificate(s), you can trigger a ‘dry run’. This will simulate the renewal process without making any actual changes to your configuration.
You can trigger a dry run using the standard renew
command, but with the --dry-run
argument:
This will output something similar to the following, which will provide assurance that the renewal process is functioning correctly:
Output...
Cert not due for renewal, but simulating renewal for dry run
Plugins selected: Authenticator dns-digitalocean, Installer None
Renewing an existing certificate
Performing the following challenges:
dns-01 challenge for your_domain
dns-01 challenge for subdomain.your_domain
Waiting 10 seconds for DNS changes to propagate
Waiting for verification...
Cleaning up challenges
...
In this final step, you tested the automatic renewal process within Certbot.
In this tutorial, you set up Certbot with certbot-dns-digitalocean to issue certificates using DNS validation with the DigitalOcean DNS management API.
If you’re interested in learning more about certbot-dns-digitalocean, you may wish to review the official documentation for the utility:
Alternatively, if you aren’t using DigitalOcean to manage your DNS records, you may wish to check out How to Acquire a Let’s Encrypt Certificate using DNS Validation with acme-dns-certbot on Ubuntu 18.04, which is a provider-agnostic alternative to certbot-dns-digitalocean.
Finally, if you would like some further technical reading, you could dig into the details of ACME DNS validation by reviewing the relevant section of the official RFC document, which outlines how the process works:
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
I would strongly recommend adding a link to this page from the passthrough page in the Backend Configuration for SSL Passthrough as one of the recommended links at: https://docs.digitalocean.com/products/networking/load-balancers/how-to/ssl-passthrough/
As of 2024, when creating the personal access token you can create a token with limited scope for domain (create, read, update, delete) to use just for DNS validation which is far more secure than previously having no scope.
Thanks a lot!
Hi,
I followed all the process in my droplet, and now I have my ‘*.pem’ files. But I run my app as a docker image with docker-compose in the droples. Therefore, still my domain is not secure. However, I have certificate for this domain. My app is based on the Flask. I appreciate it if you would help me.