Let's Encrypt + certbot (Free SSL Certificates)
"Let's Encrypt + certbot" is a system for obtaining and automatically renewing SSL/TLS certificates for free. Let's Encrypt is a non-profit certificate authority (CA), and certbot is its official client tool. Running certbot --nginx or certbot --apache automates everything from obtaining the certificate to updating the web server configuration. Certificates are valid for 90 days, but by setting up automatic renewal via a systemd timer or cron, you can operate without worrying about expiration.
Syntax
# -----------------------------------------------
# Installing certbot (via snap — recommended)
# -----------------------------------------------
# Install the snap daemon (comes pre-installed on Ubuntu 20.04 and later)
# sudo apt install snapd
# Remove any existing apt version of certbot before installing the snap version
# sudo apt remove certbot
# Install the latest certbot via snap
# sudo snap install --classic certbot
# Create a symlink so the certbot command is available system-wide
# sudo ln -s /snap/bin/certbot /usr/bin/certbot
# -----------------------------------------------
# Obtaining and auto-configuring a certificate for Nginx
# -----------------------------------------------
# certbot --nginx -d {domain}
# → Automatically detects the Nginx config file and obtains a certificate
# → Also configures HTTPS redirects automatically
# Example: sudo certbot --nginx -d example.com -d www.example.com
# -----------------------------------------------
# Obtaining and auto-configuring a certificate for Apache
# -----------------------------------------------
# certbot --apache -d {domain}
# → Automatically detects the Apache config file and obtains a certificate
# Example: sudo certbot --apache -d example.com
# -----------------------------------------------
# Obtaining only the certificate (manual server configuration)
# -----------------------------------------------
# certbot certonly --webroot -w {document root} -d {domain}
# → Obtains only the certificate files without changing web server settings
# → Use this for custom setups not supported by --nginx / --apache
# Example: sudo certbot certonly --webroot -w /var/www/html -d example.com
# certbot certonly --standalone -d {domain}
# → certbot temporarily occupies port 80 to obtain the certificate
# → You must stop the web server before running this command
# Example: sudo certbot certonly --standalone -d example.com
# -----------------------------------------------
# Renewing certificates
# -----------------------------------------------
# certbot renew
# → Renews all certificates expiring within 30 days
# → Normally run automatically by a systemd timer or cron
# certbot renew --dry-run
# → Simulates the renewal process without actually renewing
# → Always run this after configuring automatic renewal
# -----------------------------------------------
# Managing certificates
# -----------------------------------------------
# certbot certificates
# → Lists all obtained certificates along with their expiration dates
# certbot delete --cert-name {certificate name}
# → Deletes a certificate that is no longer needed
Command Reference
| Command | Description |
|---|---|
certbot --nginx -d {domain} | Obtains a certificate for Nginx and automatically updates the configuration file. Specify multiple domains by repeating the -d option. |
certbot --apache -d {domain} | Obtains a certificate for Apache and automatically updates the configuration file. |
certbot certonly --webroot -w {root} -d {domain} | Obtains only the certificate files without changing the web server configuration. Use this when you want to manage the configuration manually. |
certbot certonly --standalone -d {domain} | certbot temporarily starts an HTTP server to handle the challenge. You must stop the web server beforehand. |
certbot renew | Renews all certificates expiring within 30 days. Normally runs automatically, so manual execution is not required. |
certbot renew --dry-run | Simulates the renewal process without actually renewing. Use this to verify your automatic renewal configuration. |
certbot certificates | Lists all obtained certificates, including their names, domains, expiration dates, and file paths. |
certbot delete --cert-name {certificate name} | Deletes a certificate that is no longer needed. The certificate name can be found with certbot certificates. |
certbot --nginx --expand -d {existing domain} -d {new domain} | Adds a domain to an existing certificate by expanding its SAN (Subject Alternative Name). |
certbot revoke --cert-path {certificate path} | Revokes a certificate. Use this when a private key has been compromised. |
Examples
Obtaining a certificate for Nginx
# ----------------------------------------------- # Install certbot via snap and obtain a certificate for Nginx # ----------------------------------------------- # Remove the apt version of certbot if installed (to avoid conflicts) sudo apt remove certbot # Install the latest certbot via snap sudo snap install --classic certbot # Make certbot available as /usr/bin/certbot from anywhere sudo ln -s /snap/bin/certbot /usr/bin/certbot # Obtain a certificate for okabe-lab.example.com # Nginx config is auto-detected and HTTPS is configured automatically sudo certbot --nginx -d okabe-lab.example.com # Check the certbot version certbot --version
Run the following command:
$ sudo certbot --nginx -d okabe-lab.example.com Saving debug log to /var/log/letsencrypt/letsencrypt.log Enter email address (used for urgent renewal and security notices) (Enter 'c' to cancel): okabe@example.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Please read the Terms of Service at https://letsencrypt.org/documents/LE-SA-v1.4-April-3-2024.pdf Do you agree? (Y)es/(N)o: Y - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Account registered. Requesting a certificate for okabe-lab.example.com Successfully received certificate. Certificate is saved at: /etc/letsencrypt/live/okabe-lab.example.com/fullchain.pem Key is saved at: /etc/letsencrypt/live/okabe-lab.example.com/privkey.pem This certificate expires on 2026-06-23. These files will be updated when the certificate renews. Deploying certificate to VirtualHost /etc/nginx/sites-enabled/okabe-lab Redirecting all traffic on port 80 to ssl in /etc/nginx/sites-enabled/okabe-lab - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Congratulations! You have successfully enabled HTTPS on https://okabe-lab.example.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Verifying automatic renewal configuration and running a dry-run test
# ----------------------------------------------- # Verify automatic renewal configuration and test with a dry run # ----------------------------------------------- # When installed via snap, a systemd timer is automatically configured # Check whether the timer is active sudo systemctl status snap.certbot.renew.timer # If using cron, check the crontab # (An entry often exists in /etc/cron.d/certbot) sudo cat /etc/cron.d/certbot # List all certificates and their expiration dates sudo certbot certificates # Test that the renewal process works without actually renewing # Always run this command after configuring automatic renewal sudo certbot renew --dry-run
Run the following command:
$ sudo certbot certificates
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Found the following certs:
Certificate Name: okabe-lab.example.com
Serial Number: 03e7a1b2c4d5e6f7a8b9c0d1e2f3a4b5c6d7
Key Type: ECDSA
Domains: okabe-lab.example.com
Expiry Date: 2026-06-23 01:23:45+00:00 (VALID: 89 days)
Certificate Path: /etc/letsencrypt/live/okabe-lab.example.com/fullchain.pem
Private Key Path: /etc/letsencrypt/live/okabe-lab.example.com/privkey.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
$ sudo certbot renew --dry-run
Saving debug log to /var/log/letsencrypt/letsencrypt.log
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/okabe-lab.example.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Account registered.
Simulating renewal of an existing certificate for okabe-lab.example.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations, all simulated renewals succeeded:
/etc/letsencrypt/live/okabe-lab.example.com/fullchain.pem (success)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Obtaining a certificate for Apache
# ----------------------------------------------- # Obtain a certificate for Apache # ----------------------------------------------- # Obtain a certificate for makise-lab.example.com for use with Apache # certbot auto-detects the Apache VirtualHost config and enables HTTPS sudo certbot --apache -d makise-lab.example.com # Verify that Apache is running correctly after obtaining the certificate sudo systemctl status apache2
Run the following command:
$ sudo certbot --apache -d makise-lab.example.com Saving debug log to /var/log/letsencrypt/letsencrypt.log Requesting a certificate for makise-lab.example.com Successfully received certificate. Certificate is saved at: /etc/letsencrypt/live/makise-lab.example.com/fullchain.pem Key is saved at: /etc/letsencrypt/live/makise-lab.example.com/privkey.pem This certificate expires on 2026-06-23. Deploying certificate to VirtualHost /etc/apache2/sites-enabled/makise-lab.conf Enabling available site: /etc/apache2/sites-enabled/makise-lab-le-ssl.conf Redirecting vhost in /etc/apache2/sites-enabled/makise-lab.conf to ssl vhost in /etc/apache2/sites-enabled/makise-lab-le-ssl.conf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Congratulations! You have successfully enabled HTTPS on https://makise-lab.example.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Obtaining only the certificate with certonly and configuring manually
# -----------------------------------------------
# Obtain only the certificate files and integrate them into Nginx manually
# -----------------------------------------------
# Obtain only the certificate files for shiina-mayuri.example.com
# --webroot uses the existing web server for the challenge (no need to stop it)
sudo certbot certonly --webroot \
-w /var/www/shiina-mayuri \
-d shiina-mayuri.example.com
# Verify the paths of the obtained certificate
sudo certbot certificates
# Manually add the following to /etc/nginx/sites-available/shiina-mayuri.conf:
#
# server {
# listen 443 ssl;
# server_name shiina-mayuri.example.com;
#
# ssl_certificate /etc/letsencrypt/live/shiina-mayuri.example.com/fullchain.pem;
# ssl_certificate_key /etc/letsencrypt/live/shiina-mayuri.example.com/privkey.pem;
#
# root /var/www/shiina-mayuri;
# index index.html;
# }
# Apply the configuration
sudo nginx -t && sudo systemctl reload nginx
Running these commands produces the following output:
$ sudo certbot certonly --webroot -w /var/www/shiina-mayuri -d shiina-mayuri.example.com Saving debug log to /var/log/letsencrypt/letsencrypt.log Requesting a certificate for shiina-mayuri.example.com Successfully received certificate. Certificate is saved at: /etc/letsencrypt/live/shiina-mayuri.example.com/fullchain.pem Key is saved at: /etc/letsencrypt/live/shiina-mayuri.example.com/privkey.pem This certificate expires on 2026-06-23. These files will be updated when the certificate renews. $ sudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
Overview
"Let's Encrypt + certbot" is widely used for enabling HTTPS on web servers, providing a free alternative to the SSL/TLS certificates that were traditionally paid. certbot is a client tool that implements Let's Encrypt's ACME protocol, automating everything from obtaining the certificate to integrating it into the web server configuration. Certificate validity is intentionally set to 90 days to reduce security risk from long-lived credentials. When installed via snap, a systemd timer called snap.certbot.renew.timer is registered automatically and performs renewal checks twice a day. After setting up your server, always run certbot renew --dry-run to simulate the renewal and confirm that automatic renewal is working correctly. Obtained certificate files are stored in /etc/letsencrypt/live/{domain}/; your web server configuration should reference two files: fullchain.pem (the certificate chain) and privkey.pem (the private key). For Nginx configuration, see Nginx Basic Configuration. For Apache configuration, see Apache Basic Configuration.
If you find any errors or copyright issues, please contact us.