5.3.12. Install SSL certificate from Let's Encrypt using Certbot
One of the easiest ways to get a certificate from Let's Encrypt is to use Certbot. It allows you to automatically pass verification and get the necessary certificate.
Install Certbot
Certbot can be installed via the Snap package manager (recommended) or Python pip.
- Fedora
- Debian
- Ubuntu
- CentOS
- ArchLinux
- OpenSUSE
Information on other operating systems is available on the official site.
- Connect to the server via SSH.
- Install Snap (if not installed):
- Ubuntu and Debian:
sudo apt update; sudo apt install snapd - Fedora and CentOS:
sudo dnf install snapd- For older versions, use
yuminstead ofdnf:sudo yum install snapd
- Install the main Snap packages:
sudo snap install core; sudo snap refresh core - Install Certbot:
sudo snap install --classic certbot - Create a symbolic link for easier access to Certbot:
sudo ln -s /snap/bin/certbot /usr/bin/certbot
- Connect to the server via SSH.
- Install Python (if not installed):
- Ubuntu and Debian:
sudo apt update; sudo apt install python3 python3-venv libaugeas0 - Fedora and CentOS:
sudo dnf install python3 augeas-libs
- Create a virtual environment:
sudo python3 -m venv /opt/certbot/ sudo /opt/certbot/bin/pip install --upgrade pip - Install Certbot:
sudo /opt/certbot/bin/pip install certbot certbot-nginx - Create a symbolic link for easier access to Certbot:
sudo ln -s /opt/certbot/bin/certbot /usr/bin/certbot - Add a cron task to automatically renew the certificate:
echo "0 0,12 * * * root /opt/certbot/bin/python -c 'import random; import time; time.sleep(random.random() * 3600)' && sudo renew -q" | sudo tee -a /etc/crontab > /dev/null
Get certificate
Important points:
- You can only get a certificate for a working domain with address records correctly pointed to the server. It is impossible to get a certificate for an IP address without a domain.
- Certbot requests certificates from Let's Encrypt, which has its own limitations.
- To get the certificate, Certbot creates temporary files in the
.well-known/acme-challengesubdirectories inside the site directories, which Let's Encrypt then checks.
Important points:
- Installing the certificate temporarily stops the web server.
- The installation of certificates for Apache and nginx web servers is fully automated. The domains configured in the web server configuration files are used for installation. Ensure that the configuration files are set up correctly.
There are two ways to get a certificate:
- Get a certificate and change your web server settings (instead of
webservice, specify your web server —apacheornginx):sudo certbot --webservice - Get a certificate without changing your web server configuration (instead of
webservice, specify your web server —apacheornginx):sudo certbot certonly --webservice
If changes to the web server configuration were made manually or you need to verify that auto-renewal is working correctly, use the command:
sudo certbot renew --dry-run
Manually
Important points:
- To get the certificate, you'll need to manually create a verification DNS record.
- Manually getting a certificate doesn't affect how the web server works. Once you get the certificate, you'll need to install it yourself for the site on your server.
- A manually obtained certificate will not be automatically reissued upon expiration. To have the certificate automatically reissued, you must configure additional hook parameters
–manual-auth-hookand–manual-cleanup-hookto specify the path to the scripts for creating and deleting DNS verification records.
Getting a wildcard certificate is trickier than getting a regular one, since domain ownership is verified by creating a verification DNS record.
- Connect to the server via SSH.
- Install Certbot (if not installed).
- Execute the command:
certbot certonly --manual --preferred-challenges=dns --email admin@example.com --server https://acme-v02.api.letsencrypt.org/directory --agree-tos -d example.com -d *.example.comUse your data in the command:
admin@example.com— an email address that you can access, which will be used to receive important information about the project.-d example.com -d *.example.com— domains for which the certificate will be issued. Multiple domains can be specified using the-dparameter or listed without spaces, separated by commas. To get a wildcard certificate, you need to specify*.at the beginning of the domain.
- If the command is launched for the first time, you will need to complete a short registration process directly in the terminal and enter your details.
- After creating a certificate request, the terminal will display the following text:
Please deploy a DNS TXT record under the name: _acme-challenge.example.com. with the following value: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXAdd the DNS record as follows:
- "Subdomain" —
_acme-challenge. If the certificate is created for a subdomain, you should specify_acme-challenge.sub, where instead ofsubis your subdomain. - "Type" — "TXT".
- "Data" — data specified in the terminal (line
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXin example).
- Wait a few minutes and proceed to the next step to confirm the actions taken and verify the record created by pressing Enter twice. If you proceed to these steps too quickly, the records may not have time to update on the DNS side, which will result in a failed verification and require you to resubmit the request using a new verification code in the DNS record. You can check for the presence of a record for the subdomain
_acme-challengeusing the dig tool. - The created certificate files will be located in the directory
/etc/letsencrypt/live/example.com/, where instead ofexample.comwill be your domain for which the certificate was issued.
Automatically
Important points:
- Automatic certificate obtaining is a complex process that involves the use of additional hook parameters
–manual-auth-hookand–manual-cleanup-hook, which specify the path to scripts for creating and deleting verification DNS records using the API. - This article only provides examples of scripts for creating and deleting DNS records. Before using them, we strongly recommend that you save your current DNS records so that you can restore them if necessary.
- The script examples provided do not work for subdomains, but the certificate itself will be issued taking into account all possible subdomains.
- Connect to the server via SSH.
- Install Certbot (if not installed).
- Upload the sample scripts to the server in a suitable directory that Certbot can access, and instead of
AdmToolsToken, specify the API token for your account:- authenticator.sh
#!/bin/bash # Bearer authentication AUTH_TOKEN="AdmToolsToken" # Definitions for subdomain CREATE_DOMAIN="_acme-challenge" # Getting domain id DOMAIN_ID=$(curl -s -X POST "https://adm.tools/action/get_id/" \ -H "Authorization: Bearer $AUTH_TOKEN" \ -d "name=$CERTBOT_DOMAIN&type=domain" | \ grep -oP '(?<="domain_id":")[^"]+') if [ -z "$DOMAIN_ID" ]; then echo "Domain ID not found for $CERTBOT_DOMAIN" exit 1 fi # Getting list of domain records for deleting RECORDS=$(curl -s -X POST "https://adm.tools/action/dns/records_list/" \ -H "Authorization: Bearer $AUTH_TOKEN" \ -d "domain_id=$DOMAIN_ID" | jq -r '.response.list[] | select(.record == "_acme-challenge") | .id') # Deleting records for CREATE_DOMAIN subdomain for RECORD_ID in $RECORDS; do echo -e "delete $RECORD_ID \n " curl -s -X POST "https://adm.tools/action/dns/record_delete/" \ -H "Authorization: Bearer $AUTH_TOKEN" \ -d "subdomain_id=$RECORD_ID" done # Adding new record ADD_RECORD=$(curl -s -X POST "https://adm.tools/action/dns/record_add/" \ -H "Authorization: Bearer $AUTH_TOKEN" \ -d "domain_id=$DOMAIN_ID&type=TXT&record=$CREATE_DOMAIN&data=$CERTBOT_VALIDATION&priority=0") # Checking for created record if ! echo "$ADD_RECORD" | grep -q '"result":true'; then echo "Failed to add DNS record for $CREATE_DOMAIN" exit 1 fi # Waiting 5 minutes to spread changes sleep 300
- cleanup.sh
#!/bin/bash # Bearer authentication AUTH_TOKEN="AdmToolsToken" # Definitions for subdomain CREATE_DOMAIN="_acme-challenge" # Getting domain id DOMAIN_ID=$(curl -s -X POST "https://adm.tools/action/get_id/" \ -H "Authorization: Bearer $AUTH_TOKEN" \ -d "name=$CERTBOT_DOMAIN&type=domain" | \ grep -oP '(?<="domain_id":")[^"]+') if [ -z "$DOMAIN_ID" ]; then echo "Domain ID not found for $CERTBOT_DOMAIN" exit 1 fi # Getting list of domain records for deleting RECORDS=$(curl -s -X POST "https://adm.tools/action/dns/records_list/" \ -H "Authorization: Bearer $AUTH_TOKEN" \ -d "domain_id=$DOMAIN_ID" | jq -r '.response.list[] | select(.record == "_acme-challenge") | .id') # Deleting records for CREATE_DOMAIN subdomain for RECORD_ID in $RECORDS; do echo -e "delete $RECORD_ID \n " curl -s -X POST "https://adm.tools/action/dns/record_delete/" \ -H "Authorization: Bearer $AUTH_TOKEN" \ -d "subdomain_id=$RECORD_ID" done
- Set execution permissions for both scripts ( instead of
/path/to/use your path to the scripts):chmod 740 /path/to/authenticator.shchmod 740 /path/to/cleanup.sh - Execute the command:
certbot certonly --manual --preferred-challenges=dns --email admin@example.com --server https://acme-v02.api.letsencrypt.org/directory --agree-tos --manual-auth-hook /path/to/authenticator.sh --manual-cleanup-hook /path/to/cleanup.sh -d *.example.comIn the command, use your own data:
admin@example.com— mailbox for receiving information about the Certbot project.*.example.com— domain name for certificate issuance (with*.at the beginning).
- Scripts run for at least 5 minutes. If the execution was unsuccessful, the information in the DNS system may not have had time to update. If necessary, increase the value in the
sleepcommand in the first script. - The generated certificate files will be located in the directory
/etc/letsencrypt/live/example.com/, where instead ofexample.comwill be your domain for which the certificate was issued. Certbot will schedule the next certificate renewal shortly before its expiration using the same scripts. Do not move or delete them if everything went well, and check the correctness of the subsequent request.
Comments