Free SSL with Let's Encrypt on a VPS: the complete 2026 guide
How to get free SSL from Let's Encrypt on an Ubuntu or Debian VPS with Certbot or a panel: wildcards, auto-renewal, rate limits and fixes for common errors.

Key takeaways
- Let's Encrypt issues free SSL certificates that currently last 90 days and must be renewed automatically.
- HTTP-01 validation only uses port 80; wildcard certificates require DNS validation.
- From 10 February 2027 default certificates last 64 days, and from 16 February 2028 just 45 days.
- Let's Encrypt stopped sending expiry reminder emails on 4 June 2025, so you need your own monitoring.
To get free SSL from Let's Encrypt on a VPS you need three things: a domain that points to the server's IP, port 80 open to the internet, and an ACME client such as Certbot to request and renew the certificate. On Ubuntu with nginx that means installing Certbot and running sudo certbot --nginx; with a control panel such as ZoPanel, the certificate is issued and renewed automatically when you create the website.
This guide covers both routes, explains how Let's Encrypt validates your domain, how to get a wildcard certificate, which rate limits to know, the important certificate lifetime changes coming in 2027 and 2028, and how to fix the errors that make issuance fail.
How does Let's Encrypt work?
Let's Encrypt is a free, automated certificate authority (CA). Certificates are issued over the ACME protocol: a client on your server proves you control the domain, and Let's Encrypt issues a certificate that every major browser trusts.
There are two common ways to prove control, described in Let's Encrypt's challenge types documentation:
| Challenge | How it works | Pros | Cons |
|---|---|---|---|
| HTTP-01 | Serve a file at http://domain/.well-known/acme-challenge/ |
Simple, no DNS access needed | Port 80 only; no wildcards |
| DNS-01 | Create a _acme-challenge TXT record |
Wildcards (*.example.com), no port 80 needed |
Needs DNS API or control of the zone |
For ordinary websites HTTP-01 is all you need. Use DNS-01 only when you need a wildcard.
Before you install free SSL from Let's Encrypt
- The domain points to the right IP. Check:
dig +short example.com A
dig +short www.example.com A
dig +short example.com AAAA
If the domain has an AAAA (IPv6) record pointing somewhere else, validation can fail, because Let's Encrypt will try to connect over IPv6. Remove the wrong AAAA record or point it at the VPS's IPv6 address.
- Port 80 is open, in UFW and in your provider's cloud firewall:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
- nginx has a server block with
server_name example.com www.example.com;for the site.
If the domain is not pointed yet, see how to point a domain to a VPS.
Option 1: Install Let's Encrypt SSL by hand with Certbot
Install Certbot
Certbot is the ACME client from the EFF. The official Certbot instructions recommend the snap:
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/local/bin/certbot
On Debian 12 (no snap by default), or if you prefer apt packages, use the distribution's package:
sudo apt install certbot python3-certbot-nginx
Pick one method, not both.
Get a certificate for nginx
sudo certbot --nginx -d example.com -d www.example.com
Certbot asks for an email address and agreement to the terms, validates the domain over HTTP-01, then edits the nginx configuration to use the certificate and, if you choose, redirect HTTP to HTTPS. Files live in /etc/letsencrypt/live/example.com/.
To edit nginx yourself, run sudo certbot certonly --nginx -d example.com and add the fullchain.pem and privkey.pem paths to the server block.
Check automatic renewal
Both the snap and the apt package install a systemd timer for renewal. Check it:
systemctl list-timers | grep -i certbot
sudo certbot renew --dry-run
If the dry run succeeds, renewal is automated.
Wildcard certificates
Wildcards need DNS-01. certbot certonly --manual --preferred-challenges dns works, but it does not renew by itself: you would have to create a new TXT record by hand each time. In practice, use the Certbot DNS plugin for your DNS provider (Cloudflare, Route 53 and others) so Certbot creates the record through the provider's API.
Option 2: Free SSL on autopilot with ZoPanel
Once you manage more than a handful of sites, doing this per domain gets tedious. In ZoPanel, Let's Encrypt is the default (SSL docs):
- Set the Administrator email in Settings (Let's Encrypt registration needs it).
- Create the site under Websites → New website with Free SSL (Let's Encrypt) on.
- If the domain already points to the server, the certificate is issued straight away. If not, the site works over HTTP and ZoPanel re-checks DNS every hour; once the domain resolves to the server, the certificate is issued. After a failure, the next attempt waits 2, 4, 8 hours and so on, up to a day, so rate limits are never wasted.
- On the website's SSL tab, turn on Redirect HTTP to HTTPS. ZoPanel also sends a one-year HSTS header, so only turn it on when you intend to keep HTTPS.
What ZoPanel adds:
- Renewal: hourly checks, renewal when fewer than 30 days remain, and retries after 1, 2, 4, then 8 days if renewal fails.
- Alerts: SSL renewal failed with the exact error goes to the administrator and the site owner, and SSL expiring soon is sent daily once a certificate has fewer than 14 days left.
- Wildcards: install the DNS server, create the domain's zone (DNS) and tick Also *.example.com (wildcard) on the SSL tab. ZoPanel validates over DNS and renews automatically.
- Bought certificates: paste the PEM certificate and key into Custom certificate; ZoPanel checks that the key matches, the domain is right and it has not expired.
- Aliases that do not resolve yet are left out so they cannot fail the whole order, and are added on the next issue.
What is changing: shorter certificates and no reminder emails
Two changes make automation non-negotiable:
Let's Encrypt stopped sending expiry reminder emails on 4 June 2025 (announcement). If you relied on those emails to notice a failed renewal, you now need your own monitoring.
Certificate lifetimes are shrinking. According to Let's Encrypt's plan:
| Date | Change to the default profile |
|---|---|
| Today | 90-day certificates |
| 10 February 2027 | 64-day certificates; validation reuse drops to 10 days |
| 16 February 2028 | 45-day certificates; validation reuse drops to 7 hours |
Let's Encrypt recommends ACME Renewal Information (ARI) where your client supports it, or renewing about two-thirds of the way through a certificate's life. A fixed "renew every 60 days" cron job will stop working. Make sure your client schedules renewals from the real expiry date.
Let's Encrypt rate limits
From the rate limits page:
| Limit | Value |
|---|---|
| New certificates per registered domain | 50 per 7 days |
| Duplicate certificates (identical set of names) | 5 per 7 days |
| Failed validations per name, per account | 5 per hour |
| New orders per account | 300 per 3 hours |
The usual way to hit a limit is re-running the command while DNS is still wrong and running into the 5-failures-per-hour limit. When experimenting, use --dry-run or the staging environment (--test-cert).
Common SSL errors and how to fix them
| Symptom | Usual cause | Fix |
|---|---|---|
Timeout during connect |
Port 80 blocked in UFW or the cloud firewall | Open port 80 in both |
NXDOMAIN or wrong IP |
Domain not pointed yet, DNS not propagated | Check with dig, wait for the TTL |
| Validation fails although IPv4 is right | Wrong AAAA record | Remove or fix the AAAA record |
CAA record prevents issuance |
CAA allows only another CA | Add 0 issue "letsencrypt.org" |
| Site behind Cloudflare not issued automatically | Domain resolves to Cloudflare's IPs | Issue manually or use a Cloudflare Origin certificate |
| Browser says "not secure" after SSL | Mixed content (http:// images or scripts) |
Update URLs in the database or theme to https:// |
To check the certificate actually being served:
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -issuer -dates
For sites behind Cloudflare, see using Cloudflare with a VPS.
Conclusion
Free SSL from Let's Encrypt is easy: point the domain, open port 80, run Certbot and confirm renewal with --dry-run. What matters over the next few years is automation and monitoring, because certificates will get shorter and Let's Encrypt no longer emails you before they expire.
If you look after many sites, ZoPanel issues, renews and alerts on SSL for every website automatically, including on the Free plan (10 websites, 10 databases). The details are in the SSL docs.
Frequently asked questions
Is Let's Encrypt SSL really free?
Yes. Let's Encrypt is a non-profit certificate authority whose certificates are trusted by all major browsers, at no cost. You only need an ACME client such as Certbot, or a control panel that has one built in.
How long do Let's Encrypt certificates last?
The default is currently 90 days. Under the published plan, default certificates drop to 64 days from 10 February 2027 and to 45 days from 16 February 2028, so renewal has to be automated.
Can I get a wildcard certificate from Let's Encrypt?
Yes, but only with DNS validation (DNS-01), not HTTP. Use the Certbot DNS plugin for your DNS provider, or a panel that hosts the DNS zone, such as ZoPanel, so renewals stay automatic.
Why does Certbot time out during validation?
Usually port 80 is blocked by the server's firewall or the provider's cloud firewall, or the domain does not point to the right IP yet. Check with dig and open port 80 in both UFW and the cloud firewall.
Should I use a free or a paid SSL certificate?
For most sites, including online shops, a Let's Encrypt (DV) certificate encrypts traffic just as well as a paid DV certificate. Paid OV or EV certificates are only needed when your organisation or a contract requires validated company details.
Install ZoPanel free
One command on a fresh Ubuntu or Debian server. Up and running in minutes.
Install in 5 minutesKeep reading

How to secure an Ubuntu VPS: 10 steps for the first hour
Secure an Ubuntu VPS (24.04) step by step: SSH keys, no password logins, UFW, Fail2ban, automatic updates and backups, with exact commands and traps to avoid.

How to install WordPress on a VPS: manual LEMP and control panel
Install WordPress on a VPS running Ubuntu 24.04 or Debian 12, by hand with Nginx, PHP, MariaDB and Let's Encrypt or with a control panel, then secure it.

aaPanel alternatives: choosing a safer panel and how to move
Looking for an aaPanel alternative? Compare HestiaCP, CloudPanel, ZoPanel and cPanel on security, isolation and price, with a hardening checklist and move plan.