How to Install a Free SSL Certificate on Ubuntu
Get HTTPS on your Ubuntu server with a free Let's Encrypt certificate. Install, force redirect, test auto-renewal properly, and fix the errors that stop it working.
An SSL certificate turns http:// into https:// and puts the padlock in the address bar. It is free, it takes about five minutes, and there is no good reason to run a site without one.
We use Let's Encrypt, a free certificate authority trusted by every browser, and Certbot, which does the work and renews the certificate automatically.
Why this matters
- Browsers mark plain HTTP as "Not secure". People leave when they see that, especially on a login or checkout page.
- Without it, passwords travel in plain text and anyone on the same network can read them.
- Google uses HTTPS as a ranking signal. Small, but free.
- Modern browser features refuse to work without it — camera, microphone, location and service workers are all blocked on HTTP. This is why video calls fail on insecure sites.
Before you start
- A working web server. If you do not have one yet, start with how to install a LAMP server on Ubuntu.
- A domain already pointing at the server IP. This is the one that catches people — Let's Encrypt checks the domain really resolves to you before issuing anything.
- Ports 80 and 443 open in the firewall.
Check the domain first
dig +short yourdomain.com
That must print your server IP. If it prints nothing or a different address, DNS has not propagated yet. Wait — anything from a few minutes to a few hours — and do not start Certbot until it is right. Failed attempts count against a rate limit.
Step 1: Install Certbot
sudo apt update
sudo apt install certbot python3-certbot-apache -y
On Nginx, use python3-certbot-nginx instead.
Step 2: Open the firewall
sudo ufw allow 'Apache Full'
sudo ufw status
Port 443 must be open or the certificate will install and the site still will not load over HTTPS.
Step 3: Get the certificate
sudo certbot --apache -d yourdomain.com -d www.yourdomain.com
Include both the plain and www versions. If you only cover one, visitors to the other see a certificate warning, which looks worse than having no certificate at all.
Certbot asks for an email address — use a real one, because that is where expiry warnings go if renewal ever fails.
Choose the redirect
Certbot then asks whether to redirect HTTP traffic to HTTPS. Say yes. Without it both versions stay reachable, which splits your Google ranking between two addresses and leaves an insecure version live.
Step 4: Check it worked
Open https://yourdomain.com. You should see a padlock.
Then test properly at SSL Labs. Aim for grade A. Anything lower usually means an old TLS version is still enabled.
Also confirm the redirect works:
curl -I http://yourdomain.com
You want to see 301 and a Location: header pointing at the https:// address.
Step 5: Test auto-renewal — properly
Let's Encrypt certificates last 90 days. Certbot installs a timer to renew automatically, but you should confirm it actually works rather than discovering in three months that it does not.
sudo certbot renew --dry-run
A dry run simulates the whole thing without using up any rate limit. If it succeeds, renewal is genuinely working.
Check the timer is active too:
sudo systemctl status certbot.timer
Modern Certbot uses a systemd timer, so you do not need to add a cron job yourself. Adding one on top just runs it twice.
Wildcard certificates
If you need to cover every subdomain at once — blog., shop., mail. — you need a wildcard, and that requires DNS validation rather than the file check:
sudo certbot certonly --manual --preferred-challenges dns -d "*.yourdomain.com" -d yourdomain.com
Certbot gives you a TXT record to add at your DNS provider. Add it, wait for it to propagate, then press enter.
One warning: with --manual, renewal is also manual unless your DNS provider has a Certbot plugin. For most people separate certificates per subdomain are less trouble.
Common problems
"Challenge failed" or "DNS problem"
The domain does not point at this server yet. Run dig +short yourdomain.com and confirm it returns the right IP. This is the most common failure by a wide margin.
"Timeout during connect"
Port 80 is blocked. Let's Encrypt has to reach your server over HTTP to verify the domain, even though the result is an HTTPS certificate. Check UFW and your provider control panel firewall.
The padlock has a warning triangle
Mixed content: the page is HTTPS but is loading an image, script or stylesheet over HTTP. Open the browser console, find the HTTP URLs and change them to HTTPS.
"Too many certificates already issued"
You hit the rate limit — five per domain per week. Wait a week, and use --dry-run while testing so failed attempts do not count.
WordPress keeps redirecting to HTTP
The site URL is still stored as http://. Change both addresses in Settings → General, or in wp-config.php. See the WordPress-specific guide.
Renewal stopped working after a config change
Certbot edits your Apache config when it installs. If you later rewrote that file by hand, renewal can lose track of it. Run sudo certbot renew --dry-run after any web server config change.
Where to go next
- SSL on a WordPress site — extra steps for mixed content and stored URLs
- Video calling with NextCloud — needs valid SSL to work at all
- How to increase your website ranking — HTTPS is one piece of it