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:
- 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.comordig yourdomain.comfrom your local machine. - 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 withsudo ufw status. If these ports are blocked, Certbot cannot complete the challenge. - 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.comandwww.example.comcovered (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:
- Browser check: Visit
https://yourdomain.comand 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). - HTTP redirect: Visit
http://yourdomain.comand confirm it redirects to HTTPS. - 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.
- Renewal dry run:
sudo certbot renew --dry-runshould 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.