how to install certbot for apache ubuntu 24.04
Use apt to get Certbot 2.9.0 for Apache on Ubuntu 24.04. We go show you how to avoid di ServerName error wey dey block your Let's Encrypt cert issuance.
Wetin you dey build
You dey build Apache site for Ubuntu 24.04 wey dey answer for HTTPS. You go use free Let's Encrypt certificate wey browser go trust. Certbot go issue am, and systemd timer go renew am automatically so you no go ever need to tink about am again. The command wey go do the work na just one line. Everything wey fit go wrong go happen before you reach that line: maybe vhost no get ServerName, or provider firewall don close port 80, or DNS still dey point to old server. Because of this, dis guide go focus mostly on di preconditions, and e go show di exact error string wey each mistake dey print.
Two small notes. If your web server na nginx, di flow na di same shape but di plugin and di configs go different — use nginx version of dis guide instead. And if di thing wey you dey secure na for internal use only — like admin panel for private address, or staging box wey nobody dey visit — you no need certificate authority at all; self-signed certificate go easy pass and e dey work offline.
Prerequisites, and the three ways this fails before Certbot even runs
- Apache already dey serve your site over plain HTTP. Certbot's Apache plugin dey edit existing site; e no dey create new one. If you dey start from bare VPS, first build the LAMP stack on Ubuntu 24.04 den come back — this guide na the missing TLS chapter for am.
- Public domain wey get A record for your VPS address. Let's Encrypt's HTTP-01 challenge mean say their validation servers must connect to your box from the internet: no NATed homelab without port forward, no
.localnames, and no bare IPs.dig +short example.commust return your VPS address, and if you change DNS within last hour, wait make old record's TTL finish before you start. - If AAAA record dey, e must correct. Let's Encrypt prefer IPv6 when AAAA record dey, so stale AAAA go make validation fail even if
curlfrom your laptop — probably on IPv4 — dey work fine. Publish correct AAAA or no publish any at all.
Ports 80 and 443 must open for ufw and for your provider's network firewall — most hosting panels get second firewall wey OS no dey see. HTTP-01 dey validate over port 80 specifically; you no fit run this one with 443-only.
sudo ufw allow "Apache Full"
sudo ufw statusIf you set all these things, the whole work na fifteen minutes, and ten of dem na to read.
Snap or apt Certbot? On 24.04, apt is finally fine
Certbot move to snap distribution years ago because of one big reason: distro packages dey stay old. Ubuntu 20.04 ship Certbot 0.40 and dem no change am, so the project tired to debug bugs wey don old for five years. For 24.04, that problem don finish — the archive ship Certbot 2.9.0, wey na current-generation release, and unattended-upgrades dey keep am patched. My recommendation for this OS: use apt. You go skip the snapd daemon, the Apache plugin go install inside the same transaction, and the renewal timer go integrate with systemd the normal Debian way.
sudo apt update
sudo apt install -y certbot python3-certbot-apache
certbot --versionCorrect result: certbot 2.9.0. The python3-certbot-apache package na the plugin wey dey read and edit your Apache configs — without am, certbot --apache go fail with The requested apache plugin does not appear to be installed.
Snap still dey correct for two cases: if you want the newest Certbot as e dey ship, or if you need DNS plugin wey dem only dey distribute as snap (some of the certbot-dns-* provider plugins na so). If you go that way:
sudo apt remove -y certbot python3-certbot-apache
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbotWhichever one you pick, no run both. Two installs mean two renewal schedulers go dey fight over /etc/letsencrypt, and the certbot wey your shell go find for PATH fit no be the one wey hold your certificates. The apt remove line wey dey above no be decoration.
The vhost Certbot edits must already exist — ServerName na everything
certbot --apache dey work by find the port-80 virtual host wey ServerName or ServerAlias match every -d domain wey you pass. E dey use am prove say you control the domain, then e go write SSL twin for that vhost. If no matching ServerName, no match — and Ubuntu default 000-default.conf dey come with ServerName commented out. That single commented line na the main reason why this guide one big command dey fail.
So before you touch Certbot, give the site proper name-based vhost. Create /etc/apache2/sites-available/example.com.conf:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com
ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined
</VirtualHost>Enable am and confirm say Apache fit parse am and route the name to am:
sudo a2ensite example.com.conf
sudo apache2ctl configtest
sudo systemctl reload apache2
sudo apache2ctl -Sconfigtest must print Syntax OK. If e print AH00558: apache2: Could not reliably determine the server's fully qualified domain name too, na warning about the global ServerName, no be your vhost — e no go affect anything here, and echo "ServerName $(hostname -f)" | sudo tee /etc/apache2/conf-available/servername.conf && sudo a2enconf servername && sudo systemctl reload apache2 go quiet am.
The -S output na the check wey matter. You need line like port 80 namevhost example.com (/etc/apache2/sites-enabled/example.com.conf:1) with alias www.example.com under am — Apache go report the sites-enabled symlink wey e actually read, no be the file wey you edit for sites-available. If example.com no dey list for port 80, Certbot no go fit find am either.
Issue the certificate: certbot --apache
sudo certbot --apache -d example.com -d www.example.comFirst time wey you run am, e go ask you three things: email address (wey dem go use for your ACME account and urgent CA notices; Let's Encrypt no dey send expiry warnings again, so you must monitor your renewals yourself), agreement to the Let's Encrypt terms, and if you want share your email with the EFF. No more redirect question: since Certbot 2.0, the Apache installer dey redirect HTTP to HTTPS by default, and na wetin you want. Use --no-redirect if you really need plain HTTP to keep serving content.
Success go look like dis, and you must read am well, no just skim am:
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/example.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/example.com/privkey.pem
This certificate expires on 2026-10-14.
Deploying certificate
Successfully deployed certificate for example.com to /etc/apache2/sites-available/example.com-le-ssl.conf
Successfully deployed certificate for www.example.com to /etc/apache2/sites-available/example.com-le-ssl.conf
Congratulations! You have successfully enabled HTTPS on https://example.com and https://www.example.comBehind dat message, Certbot do four things: e enable Apache's ssl module if e no don enable before, e write example.com-le-ssl.conf — which na copy of your vhost for *:443 with SSLEngine on and the certificate paths — e enable am, and e add RewriteRule block to the original port-80 vhost wey dey 301 everything to HTTPS. E no replace your original vhost file, e just edit am, and the SSL twin go dey sit beside am where you fit read every line wey e add.
Wey the certificate dey stay, and why you no suppose copy am
Everything dey under /etc/letsencrypt/live/example.com/: fullchain.pem (the certificate plus intermediate chain — wetin server suppose point to), privkey.pem (the private key, only root fit read), plus cert.pem and chain.pem for software wey want the pieces separate. These na symlinks inside /etc/letsencrypt/archive/, and na dat way renewal work: renewal dey write new files inside archive/ and dem dey change the symlinks to point to the new ones. If you point any other software to the live/ paths, e go pick up renewals without stress; if you copy the files go another place, you don set trap for yourself wey go cause outage for 90 days.
The other file wey important to know na /etc/letsencrypt/renewal/example.com.conf, wey dey record how dem issue this certificate — authenticator = apache, installer = apache, the domains — so renewal fit repeat the process without person, including how e go reload Apache after.
Renewal don already set — check am, no build new one
Let's Encrypt certificates dey last 90 days by design. The apt package wey you install don already set the machinery: one systemd timer wey dey run Certbot twice every day for different times. E dey renew any certificate wey get less than 30 days to expiry. No add cron job for top; second scheduler no dey add anything except log noise and e fit make you hit rate-limit.
systemctl list-timers certbot.timer
sudo certbot renew --dry-runThe first command go show say the timer dey active, with NEXT time somewhere within the next 24 hours — the schedule na twice daily with randomized delay, so the exact time no go easy to predict (if you use snap install, the timer na snap.certbot.renew.timer instead). The dry run dey do full renewal rehearsal against Let's Encrypt staging environment — real challenge, but no certificate go dey issued, and e no go touch your rate-limit. If everything correct, the result go end with:
Congratulations, all simulated renewals succeeded:
/etc/letsencrypt/live/example.com/fullchain.pem (success)If the dry run fail, the real renewal wey go happen in ~60 days go fail the same way — fix am now, while the current certificate still get plenty life for front. The main reason wey dey cause dis one na firewall rule wey person add after issuance wey close port 80 again.
Verify with curl, and wetin the padlock suppose talk
curl -sI http://example.com | head -n 3
curl -I https://example.com
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -issuer -datesThe first one suppose return HTTP/1.1 301 Moved Permanently with Location: https://example.com/ header — na dat redirect Certbot install. The second one suppose return HTTP/1.1 200 OK without any TLS complaint from curl. The third one go print the issuer — na O = Let's Encrypt line wey get short CN like R12 or E7 — and notAfter roughly 90 days out. For browser, you go see the padlock, and if you click am, e go show the same issuer. If curl dey work but browser dey warn you, e mean say na cached page or wrong hostname you dey look, no be certificate problem.
Multiple sites: one SAN certificate or one cert per site
Dem work well; dem dey renew the same way. If you get different sites for one box, run the issue command once for every site — each one go get its own directory under live/ and its own renewal config. If one domain get problem, e no go block how others dey renew. Na dis one I dey use normally.
If one site get many names, put dem all for one SAN certificate — one single cert fit carry up to 100 names. You don already do dis one above with example.com and www.example.com. If you want add name to certificate wey you don use before, reissue am and write the full new list:
sudo certbot --apache --cert-name example.com -d example.com -d www.example.com -d blog.example.comCertbot go see say the domain set don change, e go ask you to confirm the expansion, and e go replace the certificate for where e dey — same live/ path, so you no need touch anything else. Note say the list na replacement, e no be append: if you no put www for that command, the new certificate go just drop am without talk.
Wildcards need DNS-01, and usually you do not need a wildcard
HTTP-01 no fit issue *.example.com — to put file for web server na to show say you control one hostname only, no be whole namespace. Wildcards need DNS-01 challenge: Certbot go set TXT record for _acme-challenge.example.com. For real life, dis one mean say you need certbot-dns-* plugin with API credentials for your DNS provider, or you go dey hand-edit TXT records every time dem wan renew with --manual (e go hard — no plan for dis one). The full guide, from how TXT record work to how to use plugin for automatic renewal, dey for wildcard certificates with Certbot over DNS-01. Honest advice: if you get four subdomains wey you know, na better to use SAN certificate wey list all four instead of wildcard, and you no go need keep DNS API keys for your server.
Failure modes, with the strings you will see
Certbot refuse to start because Apache config don spoil.
The apache plugin is not working; there may be problems with your existing configuration.
The error was: MisconfigurationError('Error while running apache2ctl configtest.\n\nAction \'configtest\' failed.\nThe Apache error log may have more information.\n\nAH00526: Syntax error on line 12 of /etc/apache2/sites-enabled/example.com.conf')The plugin dey run configtest before e touch anything, and if Apache itself dey get wahala, the plugin go stop — the \ns na real words because Certbot dey print the exception's repr. Run sudo apache2ctl configtest yourself: e go tell you the file and line — usually na typo from hand-editing, a SSLCertificateFile wey point to path wey no dey again, or module wey dem mention but dem no enable. Fix am until e print Syntax OK, then rerun Certbot.
No vhost match the domain.
Unable to find a virtual host listening on port 80 which is currently the only challenge port.Na the missing-ServerName failure wey we talk before, but e catch am for issue time. Certbot search every enabled port-80 vhost for ServerName/ServerAlias wey match your -d, but e no find anything. sudo apache2ctl -S go show you wetin Apache dey route; add the ServerName line to the correct vhost, reload, then retry. Another one na when validation reach the wrong vhost — the challenge response go come back Invalid response ... 404 because another site catch the request. Same diagnosis, same tool: apache2ctl -S.
Validation timeout.
Certbot failed to authenticate some domains (authenticator: apache).
...
Detail: ...: Timeout during connect (likely firewall problem)Let's Encrypt no fit open TCP connection to port 80 for the address wey your DNS dey show. From most likely to least likely: your provider network firewall (different from ufw, wey dey hosting panel), ufw ruleset wey only allow 443 or only SSH, DNS still dey point to old server, or the stale-AAAA problem — their servers try IPv6, but your server only dey answer for IPv4. Test am from outside the VPS: run curl -I http://example.com from your laptop to see wetin their validator dey see.
You retry too many times and hit rate limit.
Error creating new order :: too many failed authorizations recently: see https://letsencrypt.org/docs/rate-limits/Let's Encrypt dey allow 5 failed validations per hostname per account per hour — since dem rework the rate-limit for 2025, e be like bucket wey dey refill, you dey get back roughly one retry every 12 minutes — so if you dey hammer retry against broken firewall, you go finish the limit fast. Waiting dey work, but the real fix na to change how you dey do am: after any failure, debug with the staging environment until e work.
sudo certbot certonly --apache --dry-run -d example.com -d www.example.comWatch the certonly: --dry-run na only certonly and renew subcommands dey accept, and the bare certbot --apache --dry-run form no go run at all, e go tell you --dry-run currently only works with the 'certonly' or 'renew' subcommands. The dry run dey validate against staging, wey get its own big limits and no dey issue real certificates, so you fit fail there all afternoon. Only rerun the real command once staging pass. The other limits — 50 certificates per registered domain per week, 5 duplicates of the same name set per week — you go only hit dem if script dey reissue in a loop.
Once HTTPS don up, remember say certificate dey secure the transport, no be the server: port 22 still dey take password guesses all day. To fix this one, use Fail2ban on Ubuntu 24.04 na the next thirty minutes wey you go spend.
FAQ
I suppose I go use snap or apt install Certbot for Apache for Ubuntu 24.04?
Use apt. Ubuntu 24.04 carry Certbot 2.9.0, wey current enough for everything for this guide, e dey get security patches through unattended-upgrades, and e no need snapd. Use snap only if you need the newest release sharp-sharp or if you need DNS plugin wey dem only dey distribute as snap — and if you go switch, make you apt remove certbot python3-certbot-apache first so two renewal schedulers no go dey work together.
Why Certbot dey talk "Unable to find a virtual host listening on port 80"?
Because no enabled port-80 vhost get ServerName or ServerAlias wey match the domain wey you pass with -d — Ubuntu default vhost carry ServerName wey dem don comment. Run sudo apache2ctl -S, find (or create) the vhost wey suppose carry that name, add ServerName example.com, reload Apache, and rerun Certbot.
How I go fix "Timeout during connect (likely firewall problem)"?
Let's Encrypt no fit reach port 80 for the address wey your DNS dey show. Check your provider network firewall for their panel and check ufw too, make sure dig +short example.com dey point to this VPS, and delete or fix any old AAAA record — validation prefer IPv6 if e dey exist. Confirm say the fix dey work from outside the server with curl -I http://example.com, then try am with sudo certbot certonly --apache --dry-run -d example.com before you do real issuance.
Certbot dey renew certificates automatically for Ubuntu 24.04?
Yes. The apt package dey install certbot.timer, wey na systemd timer wey dey run twice daily and dey renew any certificate wey get less than 30 days to expire, e go reload Apache after; the snap dey use snap.certbot.renew.timer for the same work. Verify am with systemctl list-timers certbot.timer and try am with sudo certbot renew --dry-run — no add your own cron job for top.
How I go get wildcard certificate with Certbot and Apache?
Wildcards need DNS-01 challenge: Certbot must put TXT record for _acme-challenge.example.com, wey mean say you need certbot-dns-* plugin wey get API credentials for your DNS provider (the --manual alternative need say you go hand-edit TXT records every time dem wan renew). If you only get small number of subdomains wey you know, SAN certificate wey list dem one-by-one easy pass and e no go need DNS API keys for server.