Every browser on the internet flags unencrypted sites. Search engines suppress them in rankings. That "Not Secure" label in the address bar sends visitors away faster than a slow page load. Running a public-facing site without HTTPS is not a tradeoff anymore, it is just a mistake.

Let's Encrypt solved the cost problem years ago: free, automated, widely trusted certificates that renew themselves. What trips people up is the setup, particularly once you move past the basics into wildcard certificates, multi-domain configurations, and renewal automation that actually works.

If you have already followed the first-time VPS setup guide, you may have a basic Certbot installation working. This article goes deeper: validation methods, web server configuration for both Nginx and Apache, wildcard certificates, multi-domain setups, and what to do when renewals break.

What Let's Encrypt Actually Does

Let's Encrypt is a certificate authority (CA) that issues domain-validated (DV) SSL/TLS certificates at no cost. It uses a protocol called ACME (Automatic Certificate Management Environment) to verify that you control a domain and, if verification passes, issues a certificate valid for 90 days.

The 90-day expiry is intentional. Short-lived certificates limit the window of exposure if a private key is compromised, and the expectation is that you automate renewal so the short lifespan never causes a problem.

Certbot is the most common ACME client, maintained by the Electronic Frontier Foundation. It handles the certificate request, domain validation, web server configuration changes, and renewal scheduling. There are other ACME clients (acme.sh, lego, Caddy has one built in), but Certbot is the default recommendation for most Linux VPS setups, and the one covered here.

Before You Start

You need three things in place before requesting a certificate:

  1. A domain name with DNS pointing at your server. Let's Encrypt validates that your server controls the domain. If the DNS A record does not resolve to your VPS IP, validation will fail. If you updated DNS recently, confirm propagation with nslookup yourdomain.com or dig yourdomain.com from your local machine.
  2. Ports 80 and 443 open in your firewall. HTTP-based validation needs port 80 reachable from the internet. HTTPS obviously needs 443. If you are running ufw, check with sudo ufw status. If these ports are blocked, Certbot cannot complete the challenge.
  3. A web server running (for plugin-based installs). If you plan to use the Nginx or Apache Certbot plugins, the web server must be installed and serving traffic. Standalone mode works without a web server, which is useful if you are running something else on port 80 or have not installed a web server yet.

If you are still setting up your server, the full VPS setup walkthrough covers this from the ground up. The security checklist includes firewall configuration and other hardening steps that should be completed before exposing services to the internet.

Installing Certbot

The recommended installation method is snap, which gives you the latest Certbot version regardless of your distribution's package repositories.

sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

If your system does not have snap or you prefer the distribution package manager:

Debian/Ubuntu:

sudo apt install certbot -y

Rocky Linux/AlmaLinux/RHEL:

sudo dnf install certbot -y

For the web server plugins, add the relevant package:

sudo apt install python3-certbot-nginx -y     # Nginx on Debian/Ubuntu
sudo apt install python3-certbot-apache -y    # Apache on Debian/Ubuntu
sudo dnf install python3-certbot-nginx -y     # Nginx on RHEL-based
sudo dnf install python3-certbot-apache -y    # Apache on RHEL-based

Getting a Certificate: Three Approaches

Certbot offers multiple ways to validate your domain and install the certificate. Which one to use depends on your web server and your level of comfort editing configuration files manually.

Option 1: Nginx Plugin (Recommended for Nginx Users)

This is the simplest path if you are running Nginx. Certbot reads your existing Nginx configuration, performs the ACME challenge, obtains the certificate, and modifies your server blocks to enable HTTPS with a redirect from HTTP.

sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

Certbot will prompt for an email address (used for renewal notices and urgent security warnings) and ask whether to redirect all HTTP traffic to HTTPS. Choose yes for the redirect.

After it completes, check the result:

sudo certbot certificates

This lists all installed certificates, their domains, expiry dates, and file paths.

Option 2: Apache Plugin

If you are running Apache instead of Nginx, the process is nearly identical:

sudo certbot --apache -d yourdomain.com -d www.yourdomain.com

Certbot modifies the Apache virtual host configuration to enable SSL and sets up the redirect. The same email and redirect prompts apply.

Option 3: Standalone Mode

Standalone mode runs its own temporary web server to complete the ACME challenge. It does not need Nginx, Apache, or any other web server to be installed. The tradeoff: whatever is using port 80 must be stopped first, because Certbot needs to bind to it.

sudo certbot certonly --standalone -d yourdomain.com -d www.yourdomain.com

The certonly flag tells Certbot to obtain the certificate without attempting to configure a web server. You will need to configure your web server (or application) to use the certificate files manually. The files land in /etc/letsencrypt/live/yourdomain.com/:

File Purpose
fullchain.pem Certificate + intermediate chain (this is what your web server serves)
privkey.pem Private key (keep this restricted, mode 0600)
cert.pem The certificate alone, without the chain
chain.pem The intermediate certificate(s) only

Most web servers and applications want fullchain.pem and privkey.pem.

Configuring Your Web Server Manually

If you used the Nginx or Apache plugin, Certbot already handled this. If you used standalone mode, or prefer manual configuration, here is what needs to change.

Nginx Manual Configuration

Edit your server block (typically in /etc/nginx/sites-available/yourdomain.com on Debian/Ubuntu or /etc/nginx/conf.d/yourdomain.conf on RHEL-based):

server {
    listen 443 ssl;
    server_name yourdomain.com www.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

    # Strong TLS settings
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers off;

    root /var/www/yourdomain.com;
    index index.html;
}

server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;
    return 301 https://$server_name$request_uri;
}

Test the configuration and reload:

sudo nginx -t
sudo systemctl reload nginx

Apache Manual Configuration

Enable the SSL module and the SSL site, then edit your virtual host:

sudo a2enmod ssl
sudo a2ensite default-ssl

In your virtual host file:

<VirtualHost *:443>
    ServerName yourdomain.com
    ServerAlias www.yourdomain.com

    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/yourdomain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/yourdomain.com/privkey.pem

    DocumentRoot /var/www/yourdomain.com
</VirtualHost>

<VirtualHost *:80>
    ServerName yourdomain.com
    Redirect permanent / https://yourdomain.com/
</VirtualHost>

Restart Apache:

sudo systemctl restart apache2     # Debian/Ubuntu
sudo systemctl restart httpd       # RHEL-based

Wildcard Certificates

A standard Let's Encrypt certificate covers specific domain names you list during the request. A wildcard certificate covers *.yourdomain.com, meaning it works for any subdomain: api.yourdomain.com, staging.yourdomain.com, mail.yourdomain.com, all with one certificate.

Wildcard certificates require DNS validation instead of HTTP validation. Certbot cannot verify a wildcard by placing a file on your web server because the wildcard covers names that may not even have a server yet.

sudo certbot certonly --manual --preferred-challenges dns -d "*.yourdomain.com" -d yourdomain.com

Certbot will prompt you to create a specific TXT record under _acme-challenge.yourdomain.com in your DNS. Add the record, wait for it to propagate (check with nslookup -q=TXT _acme-challenge.yourdomain.com), and then press Enter to continue.

The drawback of manual DNS validation: it cannot be automated directly. Each renewal requires you to update the TXT record. For automated wildcard renewals, you need a DNS plugin that talks to your DNS provider's API. Certbot has plugins for Cloudflare, Route53, DigitalOcean DNS, and others:

sudo apt install python3-certbot-dns-cloudflare -y

With the DNS plugin configured, renewals work automatically just like HTTP-validated certificates.

When wildcard certificates make sense:

  • You run many subdomains and want one certificate covering all of them
  • You frequently create new subdomains and do not want to re-issue certificates each time
  • Your staging and production environments share a parent domain

When they do not:

  • You have a single domain with no subdomains (a standard certificate is simpler)
  • Your DNS provider does not have a Certbot plugin and you do not want to update TXT records manually every 90 days

Automatic Renewal

Certbot schedules automatic renewal by default. On most systems, it installs either a systemd timer or a cron job that runs twice daily and renews any certificate within 30 days of expiry.

Verify the timer is active:

sudo systemctl status certbot.timer

Or check the cron entry:

cat /etc/cron.d/certbot

You can also test the renewal process without actually renewing:

sudo certbot renew --dry-run

If the dry run succeeds, your renewal pipeline is working. If it fails, the error message will tell you why (port 80 blocked, web server not running, DNS not resolving, plugin misconfigured).

Renewal Hooks

Certbot supports hooks that run after a successful renewal. The most common use: reloading the web server so it picks up the new certificate.

sudo certbot renew --deploy-hook "systemctl reload nginx"

To make this permanent, create a hook script:

sudo mkdir -p /etc/letsencrypt/renewal-hooks/deploy
sudo tee /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh > /dev/null <<'EOF'
#!/bin/bash
systemctl reload nginx
EOF
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh

Replace nginx with apache2 or httpd if you use Apache.

Common Problems and Fixes

"Challenge failed" or "Connection refused"

The most frequent cause: port 80 is not reachable from the internet. Check your firewall rules (sudo ufw status or sudo firewall-cmd --list-all). Also verify that no other process is occupying port 80 when using standalone mode (sudo ss -tlnp | grep :80).

If your server is behind a NAT or load balancer, HTTP-based challenges may not reach Certbot directly. In that case, use DNS validation instead.

"Too many requests" or Rate Limit Errors

Let's Encrypt enforces rate limits: a maximum of 50 certificates per registered domain per week, and failed validation attempts count toward separate limits. If you are testing, use the staging environment to avoid hitting production rate limits:

sudo certbot --nginx --staging -d yourdomain.com

Staging certificates are not trusted by browsers, but the process is identical and the rate limits are much more generous. Once your configuration works on staging, switch to production.

Renewal Fails Silently

The systemd timer may be active, but if the renewal command itself errors out, nothing alerts you by default. Check the renewal logs:

sudo cat /var/log/letsencrypt/letsencrypt.log

Common causes of silent renewal failure:

  • The web server is not running (Nginx/Apache plugin cannot complete the challenge)
  • Firewall rules changed since the original issue and port 80 is now blocked
  • A firewall or security group was added in the provider's control panel that blocks inbound HTTP
  • The DNS record was changed and no longer points to the server

Set up a monitoring check that alerts you if your certificate is within 14 days of expiring. An external SSL checker or a simple cron job that runs openssl s_client -connect yourdomain.com:443 </dev/null 2>/dev/null | openssl x509 -noout -enddate and emails you if the date is close will catch problems before visitors see certificate warnings.

Certificate for the Wrong Domain

If you accidentally issued a certificate for the wrong domain name, you do not need to revoke it. Just issue a new one for the correct domain. Certbot stores each certificate by its primary domain name and will not overwrite an unrelated certificate.

To remove an old, unwanted certificate:

sudo certbot delete --cert-name olddomain.com

Multi-Domain Certificates (SAN)

A single Let's Encrypt certificate can cover multiple domain names using Subject Alternative Names (SAN). This is different from a wildcard: instead of covering all subdomains, it covers a specific list of names you choose.

sudo certbot --nginx -d example.com -d www.example.com -d blog.example.com -d shop.example.com

All listed domains must resolve to the server and pass validation. This is useful when:

  • You host multiple related sites on the same server
  • You need both example.com and www.example.com covered (the most common multi-domain case)
  • You have a handful of specific subdomains rather than a dynamic set

The certificate appears as one entry in sudo certbot certificates and renews as a single unit.

Verifying Your Setup

After installation, confirm everything is working:

  1. Browser check: Visit https://yourdomain.com and verify the padlock icon appears. Click it to inspect the certificate details (issuer should be "Let's Encrypt", expiry should be roughly 90 days out).
  2. HTTP redirect: Visit http://yourdomain.com and confirm it redirects to HTTPS.
  3. SSL test: Run your domain through an online SSL checker to verify the certificate chain is complete and the TLS configuration is rated well. Incomplete chains (missing the intermediate certificate) cause trust failures in some browsers and mobile devices.
  4. Renewal dry run: sudo certbot renew --dry-run should complete without errors.

If the SSL test reports a weak configuration (old TLS versions enabled, weak ciphers), tighten your web server's SSL settings. At minimum, disable TLS 1.0 and 1.1 (both are deprecated) and allow only TLS 1.2 and 1.3.

Managed VPS Plans and SSL

If you are on a managed VPS plan, SSL certificate management may already be handled for you. Many managed providers include automatic Let's Encrypt provisioning through their control panel (cPanel, Plesk, or a custom dashboard). You click a button, the certificate is issued and renewed without touching the command line.

Check your provider's documentation or control panel before setting up Certbot manually on a managed plan. Running Certbot alongside a panel-managed certificate can cause conflicts: both try to manage the same files, and renewal hooks may interfere with each other.

On an unmanaged plan, all of the above is your responsibility. That is the tradeoff for the lower price and greater control. Browse the providers directory to compare what each provider includes, and read real user experiences to see how providers actually handle support when certificate issues arise.

Quick Reference

Task Command
Install Certbot via snap sudo snap install --classic certbot
Certificate with Nginx plugin sudo certbot --nginx -d domain.com -d www.domain.com
Certificate with Apache plugin sudo certbot --apache -d domain.com -d www.domain.com
Standalone certificate sudo certbot certonly --standalone -d domain.com
Wildcard certificate (manual DNS) sudo certbot certonly --manual --preferred-challenges dns -d "*.domain.com" -d domain.com
List all certificates sudo certbot certificates
Test renewal sudo certbot renew --dry-run
Force renewal sudo certbot renew --force-renewal
Delete a certificate sudo certbot delete --cert-name domain.com
Check renewal timer sudo systemctl status certbot.timer

What to Read Next

SSL is one piece of the broader security picture. The VPS security checklist covers the nine other steps you should complete before going live, from SSH hardening and firewalls to automated backups and monitoring.

If you are still early in your VPS setup, the first-time setup guide walks through the full sequence from first login to first deployment. For help choosing a provider that fits your needs, the providers directory has aggregate ratings and the user reviews page shows what real customers report about support quality, uptime, and overall reliability.